diff --git a/.github/classifier.yml b/.github/classifier.yml index d66324e01fa..645a350b6ae 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -3,10 +3,16 @@ alwaysRequireAssignee: false, labelsRequiringAssignee: [ feature-request ], autoAssignees: { - api: [], + api: { + assignees: [ jrieken ], + assignLabel: false + }, color-picker: [], css-less-sass: [], - debug: [ isidorn ], + debug: { + assignees: [ isidorn ], + assignLabel: false + }, diff-editor: [], editor: [], editor-1000-limit: [], @@ -28,8 +34,22 @@ emmet: [ ramya-rao-a ], error-list: [], extensions: [], - file-encoding: [ bpasero ], - file-explorer: [ isidorn ], + file-encoding: { + assignees: [ bpasero ], + assignLabel: false + }, + file-io: { + assignees: [ bpasero ], + assignLabel: false + }, + file-watcher: { + assignees: [ bpasero ], + assignLabel: false + }, + file-explorer: { + assignees: [ isidorn ], + assignLabel: false + }, format: [], git: [ joaomoreno ], hot-exit: [ Tyriar ], @@ -44,26 +64,83 @@ languages basic: [], markdown: [ mjbvz ], merge-conflict: [ chrmarti ], + multi-root: { + assignees: [ bpasero ], + assignLabel: false + }, perf-profile: [], php: [ roblourens ], proxy: [], + remote: { + assignees: [ jrieken ], + assignLabel: false + }, scm: [], search: [ roblourens ], - snippets: [ jrieken ], + snippets: { + assignees: [ jrieken ], + assignLabel: false + }, tasks: [ dbaeumer ], telemetry: [], themes: [], typescript: [ mjbvz ], - workbench: [ bpasero ], - workbench-dnd: [ bpasero ], - workbench-editors: [ bpasero ], - workbench-feedback: [ bpasero ], - workbench-layout: [ bpasero ], - workbench-menu: [ bpasero ], - workbench-notifications: [ bpasero ], - workbench-state: [ bpasero ], - workbench-status: [ bpasero ], - workbench-tabs: [ bpasero ], - workbench-welcome: [ chrmarti ], + workbench: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-dnd: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-editors: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-electron: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-feedback: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-history: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-layout: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-menu: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-notifications: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-state: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-status: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-tabs: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-title: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-touchbar: { + assignees: [ bpasero ], + assignLabel: false + }, + workbench-welcome: [ chrmarti ] } } diff --git a/.github/insiders.yml b/.github/insiders.yml index 28192b556e5..5ad2cb40a96 100644 --- a/.github/insiders.yml +++ b/.github/insiders.yml @@ -1,4 +1,4 @@ { insidersLabel: 'insiders', - perform: true + perform: false } \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 1f28f9d55cb..d789e84c612 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,13 +52,18 @@ install: - yarn script: - - node_modules/.bin/gulp hygiene - node_modules/.bin/gulp electron --silent - node_modules/.bin/tsc -p ./src/tsconfig.monaco.json --noEmit - node_modules/.bin/gulp compile --silent --max_old_space_size=4096 - - node_modules/.bin/gulp optimize-vscode --silent --max_old_space_size=4096 - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./scripts/test.sh --coverage --reporter dot; else ./scripts/test.sh --reporter dot; fi - ./scripts/test-integration.sh after_success: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then node_modules/.bin/coveralls < .build/coverage/lcov.info; fi + +matrix: + include: + - os: linux + env: label=hygiene + script: node_modules/.bin/gulp hygiene + after_success: skip diff --git a/.vscode/launch.json b/.vscode/launch.json index 37898b81577..930f764b9b1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -129,6 +129,9 @@ "runtimeArgs": [ "--inspect=5875" ], + "skipFiles": [ + "**/winjs*.js" + ], "webRoot": "${workspaceFolder}" }, { diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 78a09a2db01..15b95986668 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -45,8 +45,8 @@ const nodeModules = ['electron', 'original-fs'] // Build const builtInExtensions = [ - { name: 'ms-vscode.node-debug', version: '1.20.2' }, - { name: 'ms-vscode.node-debug2', version: '1.20.0' } + { name: 'ms-vscode.node-debug', version: '1.20.3' }, + { name: 'ms-vscode.node-debug2', version: '1.20.1' } ]; const excludedExtensions = [ @@ -83,6 +83,7 @@ const vscodeResources = [ 'out-build/vs/workbench/services/files/**/*.exe', 'out-build/vs/workbench/services/files/**/*.md', 'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js', + 'out-build/vs/code/electron-browser/issue/issueReporter.js', '!**/test/**' ]; diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js index ee92561849e..89fb9d95264 100644 --- a/build/gulpfile.vscode.linux.js +++ b/build/gulpfile.vscode.linux.js @@ -110,8 +110,7 @@ function buildDebPackage(arch) { return shell.task([ 'chmod 755 ' + product.applicationName + '-' + debArch + '/DEBIAN/postinst ' + product.applicationName + '-' + debArch + '/DEBIAN/prerm ' + product.applicationName + '-' + debArch + '/DEBIAN/postrm', 'mkdir -p deb', - 'fakeroot dpkg-deb -b ' + product.applicationName + '-' + debArch + ' deb', - 'dpkg-scanpackages deb /dev/null > Packages' + 'fakeroot dpkg-deb -b ' + product.applicationName + '-' + debArch + ' deb' ], { cwd: '.build/linux/deb/' + debArch }); } diff --git a/build/tslint.json b/build/tslint.json index a85e98b95dc..15275279139 100644 --- a/build/tslint.json +++ b/build/tslint.json @@ -9,5 +9,6 @@ "always" ], "triple-equals": true - } + }, + "defaultSeverity": "warning" } \ No newline at end of file diff --git a/extensions/configuration-editing/src/extension.ts b/extensions/configuration-editing/src/extension.ts index e215f0fb5a9..aacb21ff777 100644 --- a/extensions/configuration-editing/src/extension.ts +++ b/extensions/configuration-editing/src/extension.ts @@ -30,6 +30,9 @@ export function activate(context: vscode.ExtensionContext): void { //extensions suggestions context.subscriptions.push(...registerExtensionsCompletions()); + //locale suggestions + context.subscriptions.push(registerLocaleCompletionsInLanguageDocument()); + // launch.json decorations context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => updateLaunchJsonDecorations(editor), null, context.subscriptions)); context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => { @@ -67,6 +70,44 @@ function registerSettingsCompletions(): vscode.Disposable { }); } +function registerLocaleCompletionsInLanguageDocument(): vscode.Disposable { + return vscode.languages.registerCompletionItemProvider({ pattern: '**/locale.json' }, { + provideCompletionItems(document, position, token) { + const location = getLocation(document.getText(), document.offsetAt(position)); + const range = document.getWordRangeAtPosition(position) || new vscode.Range(position, position); + if (location.path[0] === 'locale') { + const extensionsContent = parse(document.getText()); + return provideContributedLocalesProposals(range); + } + return []; + } + }); +} + +function provideContributedLocalesProposals(range: vscode.Range): vscode.ProviderResult { + const contributedLocales: string[] = []; + for (const extension of vscode.extensions.all) { + if (extension.packageJSON && extension.packageJSON['contributes'] && extension.packageJSON['contributes']['locales'] && extension.packageJSON['contributes']['locales'].length) { + const locales: { locale: string }[] = extension.packageJSON['contributes']['locales']; + for (const locale of locales) { + if (contributedLocales.indexOf(locale.locale) === -1) { + contributedLocales.push(locale.locale); + } + } + } + } + return contributedLocales.map(locale => { + const text = `"${locale}"`; + const item = new vscode.CompletionItem(text); + item.kind = vscode.CompletionItemKind.Value; + item.insertText = text; + item.range = range; + item.filterText = text; + return item; + }); +} + + interface IExtensionsContent { recommendations: string[]; } diff --git a/extensions/css/client/src/cssMain.ts b/extensions/css/client/src/cssMain.ts index 5e9f4d2ec7f..6c64c46a54e 100644 --- a/extensions/css/client/src/cssMain.ts +++ b/extensions/css/client/src/cssMain.ts @@ -104,7 +104,7 @@ export function activate(context: ExtensionContext) { indentationRules: indentationRules }); - const regionCompletionRegExpr = /^(\s*)(\/(\*\s*(#\w*)?)?)?/; + const regionCompletionRegExpr = /^(\s*)(\/(\*\s*(#\w*)?)?)?$/; languages.registerCompletionItemProvider(documentSelector, { provideCompletionItems(doc, pos) { let lineUntilPos = doc.getText(new Range(new Position(pos.line, 0), pos)); diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index 263bb63ed63..38326f318eb 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -310,14 +310,14 @@ "compile": "gulp compile-extension:emmet" }, "devDependencies": { - "@types/node": "7.0.43", + "@types/node": "8.0.33", "vscode": "1.0.1" }, "dependencies": { "@emmetio/html-matcher": "^0.3.3", "@emmetio/css-parser": "ramya-rao-a/css-parser#vscode", "@emmetio/math-expression": "^0.1.1", - "vscode-emmet-helper": "^1.1.20", + "vscode-emmet-helper": "^1.1.21", "vscode-languageserver-types": "^3.5.0", "image-size": "^0.5.2", "vscode-nls": "2.0.2" diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 09c531ed726..feee6d684eb 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -8,6 +8,7 @@ import { Node, HtmlNode, Rule, Property } from 'EmmetNode'; import { getEmmetHelper, getNode, getInnerRange, getMappingForIncludedLanguages, parseDocument, validate, getEmmetConfiguration, isStyleSheet, getEmmetMode } from './util'; const trimRegex = /[\u00a0]*[\d|#|\-|\*|\u2022]+\.?/; +const hexColorRegex = /^#\d+$/; interface ExpandAbbreviationInput { syntax: string; @@ -23,6 +24,7 @@ export function wrapWithAbbreviation(args: any) { } const editor = vscode.window.activeTextEditor; + let rootNode = parseDocument(editor.document, false); const syntax = getSyntaxFromArgs({ language: editor.document.languageId }); if (!syntax) { @@ -46,7 +48,13 @@ export function wrapWithAbbreviation(args: any) { editor.selections.forEach(selection => { let rangeToReplace: vscode.Range = selection.isReversed ? new vscode.Range(selection.active, selection.anchor) : selection; if (rangeToReplace.isEmpty) { - rangeToReplace = new vscode.Range(rangeToReplace.start.line, 0, rangeToReplace.start.line, editor.document.lineAt(rangeToReplace.start.line).text.length); + let { active } = selection; + let currentNode = getNode(rootNode, active, true); + if (currentNode && (currentNode.start.line === active.line || currentNode.end.line === active.line)) { + rangeToReplace = new vscode.Range(currentNode.start, currentNode.end); + } else { + rangeToReplace = new vscode.Range(rangeToReplace.start.line, 0, rangeToReplace.start.line, editor.document.lineAt(rangeToReplace.start.line).text.length); + } } const firstLineOfSelection = editor.document.lineAt(rangeToReplace.start).text.substr(rangeToReplace.start.character); @@ -232,17 +240,18 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen // Fix for https://github.com/Microsoft/vscode/issues/34162 // Other than sass, stylus, we can make use of the terminator tokens to validate position if (syntax !== 'sass' && syntax !== 'stylus' && currentNode.type === 'property') { + const abbreviation = document.getText(new vscode.Range(abbreviationRange.start.line, abbreviationRange.start.character, abbreviationRange.end.line, abbreviationRange.end.character)); const propertyNode = currentNode; if (propertyNode.terminatorToken && propertyNode.separator && position.isAfterOrEqual(propertyNode.separatorToken.end) && position.isBeforeOrEqual(propertyNode.terminatorToken.start)) { - return false; + return hexColorRegex.test(abbreviation); } if (!propertyNode.terminatorToken && propertyNode.separator && position.isAfterOrEqual(propertyNode.separatorToken.end)) { - return false; + return hexColorRegex.test(abbreviation); } } diff --git a/extensions/emmet/src/test/cssAbbreviationAction.test.ts b/extensions/emmet/src/test/cssAbbreviationAction.test.ts index 00b205c682a..5ff9460dad2 100644 --- a/extensions/emmet/src/test/cssAbbreviationAction.test.ts +++ b/extensions/emmet/src/test/cssAbbreviationAction.test.ts @@ -70,7 +70,7 @@ suite('Tests for Expand Abbreviations (CSS)', () => { .foo { margin: a margin: 10px; -} +} `; return withRandomFileEditor(testContent, 'css', (editor, doc) => { @@ -87,6 +87,36 @@ suite('Tests for Expand Abbreviations (CSS)', () => { }); }); + test('Allow hex color when typing property values when there is a property in the next line (CSS)', () => { + const testContent = ` +.foo { + margin: #12 + margin: 10px; +} + `; + + return withRandomFileEditor(testContent, 'css', (editor, doc) => { + editor.selection = new Selection(2, 12, 2, 12); + return expandEmmetAbbreviation(null).then(() => { + assert.equal(editor.document.getText(), testContent.replace('#12', '#121212')); + const cancelSrc = new CancellationTokenSource(); + const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 12), cancelSrc.token); + if (!completionPromise) { + assert.fail('Completion promise wasnt returned'); + return Promise.resolve(); + } + completionPromise.then(result => { + if (!result || !result.items || !result.items.length) { + assert.fail('Completion promise came back empty'); + return Promise.resolve(); + } + assert.equal(result.items[0].label, '#121212'); + }); + return Promise.resolve(); + }); + }); + }); + test('Skip when typing property values when there is a property in the previous line (CSS)', () => { const testContent = ` .foo { @@ -109,11 +139,41 @@ suite('Tests for Expand Abbreviations (CSS)', () => { }); }); + test('Allow hex color when typing property values when there is a property in the previous line (CSS)', () => { + const testContent = ` +.foo { + margin: 10px; + margin: #12 +} + `; + + return withRandomFileEditor(testContent, 'css', (editor, doc) => { + editor.selection = new Selection(3, 12, 3, 12); + return expandEmmetAbbreviation(null).then(() => { + assert.equal(editor.document.getText(), testContent.replace('#12', '#121212')); + const cancelSrc = new CancellationTokenSource(); + const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(3, 12), cancelSrc.token); + if (!completionPromise) { + assert.fail('Completion promise wasnt returned'); + return Promise.resolve(); + } + completionPromise.then(result => { + if (!result || !result.items || !result.items.length) { + assert.fail('Completion promise came back empty'); + return Promise.resolve(); + } + assert.equal(result.items[0].label, '#121212'); + }); + return Promise.resolve(); + }); + }); + }); + test('Skip when typing property values when it is the only property in the rule (CSS)', () => { const testContent = ` .foo { margin: a -} +} `; return withRandomFileEditor(testContent, 'css', (editor, doc) => { @@ -130,6 +190,35 @@ suite('Tests for Expand Abbreviations (CSS)', () => { }); }); + test('Allow hex colors when typing property values when it is the only property in the rule (CSS)', () => { + const testContent = ` +.foo { + margin: #12 +} + `; + + return withRandomFileEditor(testContent, 'css', (editor, doc) => { + editor.selection = new Selection(2, 12, 2, 12); + return expandEmmetAbbreviation(null).then(() => { + assert.equal(editor.document.getText(), testContent.replace('#12', '#121212')); + const cancelSrc = new CancellationTokenSource(); + const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 12), cancelSrc.token); + if (!completionPromise) { + assert.fail('Completion promise wasnt returned'); + return Promise.resolve(); + } + completionPromise.then(result => { + if (!result || !result.items || !result.items.length) { + assert.fail('Completion promise came back empty'); + return Promise.resolve(); + } + assert.equal(result.items[0].label, '#121212'); + }); + return Promise.resolve(); + }); + }); + }); + test('Expand abbreviation in completion list (CSS)', () => { const abbreviation = 'm10'; const expandedText = 'margin: 10px;'; diff --git a/extensions/emmet/src/test/wrapWithAbbreviation.test.ts b/extensions/emmet/src/test/wrapWithAbbreviation.test.ts index 2739fc496d9..801b24b273e 100644 --- a/extensions/emmet/src/test/wrapWithAbbreviation.test.ts +++ b/extensions/emmet/src/test/wrapWithAbbreviation.test.ts @@ -131,7 +131,63 @@ suite('Tests for Wrap with Abbreviations', () => { editor.selections = [new Selection(2, 0, 2, 0)]; const promise = wrapWithAbbreviation({ abbreviation: 'li.hello|c' }); if (!promise) { - assert.equal(1, 2, 'Wrap returned udnefined instead of promise.'); + assert.equal(1, 2, 'Wrap returned undefined instead of promise.'); + return Promise.resolve(); + } + return promise.then(() => { + assert.equal(editor.document.getText(), expectedContents); + return Promise.resolve(); + }); + }); + }); + + test('Wrap with abbreviation entire node when cursor is on opening tag', () => { + const contents = ` + + `; + const expectedContents = ` +
+ +
+ `; + + return withRandomFileEditor(contents, 'html', (editor, doc) => { + editor.selections = [new Selection(1, 1, 1, 1)]; + const promise = wrapWithAbbreviation({ abbreviation: 'div' }); + if (!promise) { + assert.equal(1, 2, 'Wrap returned undefined instead of promise.'); + return Promise.resolve(); + } + return promise.then(() => { + assert.equal(editor.document.getText(), expectedContents); + return Promise.resolve(); + }); + }); + }); + + test('Wrap with abbreviation entire node when cursor is on closing tag', () => { + const contents = ` + + `; + const expectedContents = ` +
+ +
+ `; + + return withRandomFileEditor(contents, 'html', (editor, doc) => { + editor.selections = [new Selection(3, 1, 3, 1)]; + const promise = wrapWithAbbreviation({ abbreviation: 'div' }); + if (!promise) { + assert.equal(1, 2, 'Wrap returned undefined instead of promise.'); return Promise.resolve(); } return promise.then(() => { @@ -160,7 +216,7 @@ suite('Tests for Wrap with Abbreviations', () => { editor.selections = [new Selection(2, 2, 3, 33)]; const promise = wrapIndividualLinesWithAbbreviation({ abbreviation: 'ul>li.hello$*' }); if (!promise) { - assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned udnefined.'); + assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned undefined.'); return Promise.resolve(); } return promise.then(() => { @@ -191,7 +247,7 @@ suite('Tests for Wrap with Abbreviations', () => { editor.selections = [new Selection(2, 2, 3, 33)]; const promise = wrapIndividualLinesWithAbbreviation({ abbreviation: 'ul>li.hello*|c' }); if (!promise) { - assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned udnefined.'); + assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned undefined.'); return Promise.resolve(); } return promise.then(() => { @@ -220,7 +276,7 @@ suite('Tests for Wrap with Abbreviations', () => { editor.selections = [new Selection(2, 3, 3, 16)]; const promise = wrapIndividualLinesWithAbbreviation({ abbreviation: 'ul>li.hello$*|t' }); if (!promise) { - assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned udnefined.'); + assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned undefined.'); return Promise.resolve(); } @@ -238,7 +294,7 @@ function testWrapWithAbbreviation(selections: Selection[], abbreviation: string, editor.selections = selections; const promise = wrapWithAbbreviation({ abbreviation }); if (!promise) { - assert.equal(1, 2, 'Wrap with Abbreviation returned udnefined.'); + assert.equal(1, 2, 'Wrap with Abbreviation returned undefined.'); return Promise.resolve(); } diff --git a/extensions/emmet/src/util.ts b/extensions/emmet/src/util.ts index 2acca80d142..02ac3f982b3 100644 --- a/extensions/emmet/src/util.ts +++ b/extensions/emmet/src/util.ts @@ -31,6 +31,11 @@ export function resolveUpdateExtensionsPath() { } if (_currentExtensionsPath !== extensionsPath) { _currentExtensionsPath = extensionsPath; + if (_currentExtensionsPath && !path.isAbsolute(_currentExtensionsPath)) { + vscode.window.showErrorMessage('The path provided in emmet.extensionsPath setting should be absolute path'); + _emmetHelper.updateExtensionsPath(); + return; + } _emmetHelper.updateExtensionsPath(_currentExtensionsPath).then(null, (err: string) => vscode.window.showErrorMessage(err)); } } @@ -331,7 +336,9 @@ export function getEmmetConfiguration(syntax: string) { showExpandedAbbreviation: emmetConfig['showExpandedAbbreviation'], showAbbreviationSuggestions: emmetConfig['showAbbreviationSuggestions'], syntaxProfiles, - variables: emmetConfig['variables'] + variables: emmetConfig['variables'], + excludeLanguages: emmetConfig['excludeLanguages'], + showSuggestionsAsSnippets: emmetConfig['showSuggestionsAsSnippets'] }; } diff --git a/extensions/emmet/yarn.lock b/extensions/emmet/yarn.lock index 95b87244b85..c3294d4438d 100644 --- a/extensions/emmet/yarn.lock +++ b/extensions/emmet/yarn.lock @@ -35,9 +35,9 @@ version "2.2.0" resolved "https://registry.yarnpkg.com/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz#46cffea119a0a003312a21c2d9b5628cb5fcd442" -"@types/node@7.0.43": - version "7.0.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c" +"@types/node@8.0.33": + version "8.0.33" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd" ajv@^5.1.0: version "5.3.0" @@ -1027,6 +1027,10 @@ json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" +jsonc-parser@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -2048,11 +2052,12 @@ vinyl@~2.0.1: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -vscode-emmet-helper@^1.1.20: - version "1.1.20" - resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.20.tgz#7523dc7f635f74e4becc44d4e519a9db5055a023" +vscode-emmet-helper@^1.1.21: + version "1.1.21" + resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.21.tgz#4c77c2c5f5acc316d9a47cc564a51a732609ef7b" dependencies: "@emmetio/extract-abbreviation" "^0.1.1" + jsonc-parser "^1.0.0" vscode-languageserver-types "^3.0.3" vscode-languageserver-types@^3.0.3: diff --git a/extensions/extension-editing/yarn.lock b/extensions/extension-editing/yarn.lock index 903a9f4e191..ce500bb28a0 100644 --- a/extensions/extension-editing/yarn.lock +++ b/extensions/extension-editing/yarn.lock @@ -31,8 +31,8 @@ linkify-it@^2.0.0: uc.micro "^1.0.1" markdown-it@^8.3.1: - version "8.3.1" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.3.1.tgz#2f4b622948ccdc193d66f3ca2d43125ac4ac7323" + version "8.4.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.0.tgz#e2400881bf171f7018ed1bd9da441dac8af6306d" dependencies: argparse "^1.0.7" entities "~1.1.1" diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 179c430eb4b..355d8b07a63 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -55,7 +55,7 @@ "config.enableLongCommitWarning": "Whether long commit messages should be warned about", "config.confirmSync": "Confirm before synchronizing git repositories", "config.countBadge": "Controls the git badge counter. `all` counts all changes. `tracked` counts only the tracked changes. `off` turns it off.", - "config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`. `all` shows all refs, `local` shows only the local branchs, `tags` shows only tags and `remote` shows only remote branches.", + "config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`. `all` shows all refs, `local` shows only the local branches, `tags` shows only tags and `remote` shows only remote branches.", "config.ignoreLegacyWarning": "Ignores the legacy Git warning", "config.ignoreMissingGitWarning": "Ignores the warning when Git is missing", "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository", @@ -70,4 +70,4 @@ "colors.ignored": "Color for ignored resources.", "colors.conflict": "Color for resources with conflicts.", "colors.submodule": "Color for submodule resources." -} \ No newline at end of file +} diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 10f4cd7150e..84a011a8881 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1448,7 +1448,7 @@ export class CommandCenter { if (shouldPrompt) { const message = localize('sync is unpredictable', "This action will push and pull commits to and from '{0}'.", HEAD.upstream); const yes = localize('ok', "OK"); - const neverAgain = localize('never again', "OK, Never Show Again"); + const neverAgain = localize('never again', "OK, Don't Show Again"); const pick = await window.showWarningMessage(message, { modal: true }, yes, neverAgain); if (pick === neverAgain) { diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index d3e07cd4da0..d82223f0099 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -77,7 +77,7 @@ async function _activate(context: ExtensionContext, disposables: Disposable[]): outputChannel.show(); const download = localize('downloadgit', "Download Git"); - const neverShowAgain = localize('neverShowAgain', "Don't show again"); + const neverShowAgain = localize('neverShowAgain', "Don't Show Again"); const choice = await window.showWarningMessage( localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."), download, @@ -116,7 +116,7 @@ async function checkGitVersion(info: IGit): Promise { } const update = localize('updateGit', "Update Git"); - const neverShowAgain = localize('neverShowAgain', "Don't show again"); + const neverShowAgain = localize('neverShowAgain', "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), diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index fadf17aa535..cd9c8a197a6 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -916,7 +916,7 @@ export class Repository implements Disposable { if (didHitLimit && !shouldIgnore && !this.didWarnAboutLimit) { const ok = { title: localize('ok', "OK"), isCloseAffordance: true }; - const neverAgain = { title: localize('neveragain', "Never Show Again") }; + const neverAgain = { title: localize('neveragain', "Don't Show Again") }; window.showWarningMessage(localize('huge', "The git repository at '{0}' has too many active changes, only a subset of Git features will be enabled.", this.repository.root), ok, neverAgain).then(result => { if (result === neverAgain) { diff --git a/extensions/html/client/src/htmlMain.ts b/extensions/html/client/src/htmlMain.ts index f5885b3654f..b4b84b3ee01 100644 --- a/extensions/html/client/src/htmlMain.ts +++ b/extensions/html/client/src/htmlMain.ts @@ -164,7 +164,7 @@ export function activate(context: ExtensionContext) { ], }); - const regionCompletionRegExpr = /^(\s*)(<(!(-(-\s*(#\w*)?)?)?)?)?/; + const regionCompletionRegExpr = /^(\s*)(<(!(-(-\s*(#\w*)?)?)?)?)?$/; languages.registerCompletionItemProvider(documentSelector, { provideCompletionItems(doc, pos) { let lineUntilPos = doc.getText(new Range(new Position(pos.line, 0), pos)); diff --git a/extensions/html/server/src/modes/javascriptMode.ts b/extensions/html/server/src/modes/javascriptMode.ts index a1d0c2850fc..7255840e3cf 100644 --- a/extensions/html/server/src/modes/javascriptMode.ts +++ b/extensions/html/server/src/modes/javascriptMode.ts @@ -85,7 +85,7 @@ export function getJavascriptMode(documentRegions: LanguageModelCache { - const queryUrl = 'http://registry.npmjs.org/' + encodeURIComponent(pack).replace('%40', '@'); + const queryUrl = 'https://registry.npmjs.org/' + encodeURIComponent(pack).replace('%40', '@'); return this.xhr({ url: queryUrl, agent: USER_AGENT diff --git a/extensions/merge-conflict/package.json b/extensions/merge-conflict/package.json index 02ca68b911e..1a0f35f9b34 100644 --- a/extensions/merge-conflict/package.json +++ b/extensions/merge-conflict/package.json @@ -24,51 +24,61 @@ { "category": "%command.category%", "title": "%command.accept.all-current%", + "original": "Accept All Current", "command": "merge-conflict.accept.all-current" }, { "category": "%command.category%", "title": "%command.accept.all-incoming%", + "original": "Accept All Incoming", "command": "merge-conflict.accept.all-incoming" }, { "category": "%command.category%", "title": "%command.accept.all-both%", + "original": "Accept All Both", "command": "merge-conflict.accept.all-both" }, { "category": "%command.category%", "title": "%command.accept.current%", + "original": "Accept Current", "command": "merge-conflict.accept.current" }, { "category": "%command.category%", "title": "%command.accept.incoming%", + "original": "Accept Incoming", "command": "merge-conflict.accept.incoming" }, { "category": "%command.category%", "title": "%command.accept.selection%", + "original": "Accept Selection", "command": "merge-conflict.accept.selection" }, { "category": "%command.category%", "title": "%command.accept.both%", + "original": "Accept Both", "command": "merge-conflict.accept.both" }, { "category": "%command.category%", "title": "%command.next%", + "original": "Next Conflict", "command": "merge-conflict.next" }, { "category": "%command.category%", "title": "%command.previous%", + "original": "Previous Conflict", "command": "merge-conflict.previous" }, { "category": "%command.category%", "title": "%command.compare%", + "original":"Compare Current Conflict", "command": "merge-conflict.compare" } ], diff --git a/extensions/merge-conflict/src/contentProvider.ts b/extensions/merge-conflict/src/contentProvider.ts index 37e5923e135..f83abbfbc03 100644 --- a/extensions/merge-conflict/src/contentProvider.ts +++ b/extensions/merge-conflict/src/contentProvider.ts @@ -9,6 +9,15 @@ export default class MergeConflictContentProvider implements vscode.TextDocument static scheme = 'merge-conflict.conflict-diff'; + constructor(private context: vscode.ExtensionContext) { + } + + begin() { + this.context.subscriptions.push( + vscode.workspace.registerTextDocumentContentProvider(MergeConflictContentProvider.scheme, this) + ); + } + dispose() { } diff --git a/extensions/merge-conflict/src/services.ts b/extensions/merge-conflict/src/services.ts index f3eb0e0630e..30fb478c6f8 100644 --- a/extensions/merge-conflict/src/services.ts +++ b/extensions/merge-conflict/src/services.ts @@ -28,7 +28,7 @@ export default class ServiceWrapper implements vscode.Disposable { documentTracker, new CommandHandler(documentTracker), new CodeLensProvider(documentTracker), - new ContentProvider(), + new ContentProvider(this.context), new Decorator(this.context, documentTracker), ); diff --git a/extensions/package.json b/extensions/package.json index ad30699b786..01f99336e66 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -3,9 +3,9 @@ "version": "0.0.1", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "2.7.0-insiders.20180108" + "typescript": "2.7.0-insiders.20180119" }, "scripts": { "postinstall": "node ./postinstall" } -} +} \ No newline at end of file diff --git a/extensions/theme-seti/build/update-icon-theme.js b/extensions/theme-seti/build/update-icon-theme.js index 955a9327e76..31d7bffe3a7 100644 --- a/extensions/theme-seti/build/update-icon-theme.js +++ b/extensions/theme-seti/build/update-icon-theme.js @@ -5,13 +5,13 @@ 'use strict'; -var path = require('path'); -var fs = require('fs'); -var https = require('https'); -var url = require('url'); +let path = require('path'); +let fs = require('fs'); +let https = require('https'); +let url = require('url'); function getCommitSha(repoId, repoPath) { - var commitInfo = 'https://api.github.com/repos/' + repoId + '/commits?path=' + repoPath; + let commitInfo = 'https://api.github.com/repos/' + repoId + '/commits?path=' + repoPath; return download(commitInfo).then(function (content) { try { let lastCommit = JSON.parse(content)[0]; @@ -23,7 +23,7 @@ function getCommitSha(repoId, repoPath) { return Promise.resolve(null); } }, function () { - console.err('Failed loading ' + commitInfo); + console.error('Failed loading ' + commitInfo); return Promise.resolve(null); }); } @@ -33,9 +33,9 @@ function download(source) { return readFile(source); } return new Promise((c, e) => { - var _url = url.parse(source); - var options = { host: _url.host, port: _url.port, path: _url.path, headers: { 'User-Agent': 'NodeJS' }}; - var content = ''; + let _url = url.parse(source); + let options = { host: _url.host, port: _url.port, path: _url.path, headers: { 'User-Agent': 'NodeJS' }}; + let content = ''; https.get(options, function (response) { response.on('data', function (data) { content += data.toString(); @@ -69,7 +69,7 @@ function downloadBinary(source, dest) { https.get(source, function (response) { switch(response.statusCode) { case 200: - var file = fs.createWriteStream(dest); + let file = fs.createWriteStream(dest); response.on('data', function(chunk){ file.write(chunk); }).on('end', function(){ @@ -96,16 +96,16 @@ function downloadBinary(source, dest) { function copyFile(fileName, dest) { return new Promise((c, e) => { - var cbCalled = false; + let cbCalled = false; function handleError(err) { if (!cbCalled) { e(err); cbCalled = true; } } - var rd = fs.createReadStream(fileName); + let rd = fs.createReadStream(fileName); rd.on("error", handleError); - var wr = fs.createWriteStream(dest); + let wr = fs.createWriteStream(dest); wr.on("error", handleError); wr.on("close", function() { if (!cbCalled) { @@ -118,10 +118,10 @@ function copyFile(fileName, dest) { } function darkenColor(color) { - var res = '#'; - for (var i = 1; i < 7; i+=2) { - var newVal = Math.round(parseInt('0x' + color.substr(i, 2), 16) * 0.9); - var hex = newVal.toString(16); + let res = '#'; + for (let i = 1; i < 7; i+=2) { + let newVal = Math.round(parseInt('0x' + color.substr(i, 2), 16) * 0.9); + let hex = newVal.toString(16); if (hex.length == 1) { res += '0'; } @@ -132,23 +132,23 @@ function darkenColor(color) { function getLanguageMappings() { let langMappings = {}; - var allExtensions = fs.readdirSync('..'); - for (var i= 0; i < allExtensions.length; i++) { + let allExtensions = fs.readdirSync('..'); + for (let i= 0; i < allExtensions.length; i++) { let dirPath = path.join('..', allExtensions[i], 'package.json'); if (fs.existsSync(dirPath)) { let content = fs.readFileSync(dirPath).toString(); let jsonContent = JSON.parse(content); let languages = jsonContent.contributes && jsonContent.contributes.languages; if (Array.isArray(languages)) { - for (var k = 0; k < languages.length; k++) { - var languageId = languages[k].id; + for (let k = 0; k < languages.length; k++) { + let languageId = languages[k].id; if (languageId) { - var extensions = languages[k].extensions; - var mapping = {}; + let extensions = languages[k].extensions; + let mapping = {}; if (Array.isArray(extensions)) { mapping.extensions = extensions.map(function (e) { return e.substr(1).toLowerCase(); }); } - var filenames = languages[k].filenames; + let filenames = languages[k].filenames; if (Array.isArray(filenames)) { mapping.fileNames = filenames.map(function (f) { return f.toLowerCase(); }); } @@ -161,43 +161,45 @@ function getLanguageMappings() { return langMappings; } -//var font = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti/seti.woff'; -var font = '../../../seti-ui/styles/_fonts/seti/seti.woff'; +//let font = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti/seti.woff'; +let font = '../../../seti-ui/styles/_fonts/seti/seti.woff'; exports.copyFont = function() { return downloadBinary(font, './icons/seti.woff'); }; -//var fontMappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti.less'; -//var mappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/components/icons/mapping.less'; -//var colors = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/ui-variables.less'; +//let fontMappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti.less'; +//let mappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/components/icons/mapping.less'; +//let colors = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/ui-variables.less'; -var fontMappings = '../../../seti-ui/styles/_fonts/seti.less'; -var mappings = '../../../seti-ui/styles/components/icons/mapping.less'; -var colors = '../../../seti-ui/styles/ui-variables.less'; +let fontMappings = '../../../seti-ui/styles/_fonts/seti.less'; +let mappings = '../../../seti-ui/styles/components/icons/mapping.less'; +let colors = '../../../seti-ui/styles/ui-variables.less'; exports.update = function () { console.log('Reading from ' + fontMappings); - var def2Content = {}; - var ext2Def = {}; - var fileName2Def = {}; - var def2ColorId = {}; - var colorId2Value = {}; - var lang2Def = {}; + let def2Content = {}; + let ext2Def = {}; + let fileName2Def = {}; + let def2ColorId = {}; + let colorId2Value = {}; + let lang2Def = {}; function writeFileIconContent(info) { - var iconDefinitions = {}; + let iconDefinitions = {}; + let allDefs = Object.keys(def2Content).sort(); - for (var def in def2Content) { - var entry = { fontCharacter: def2Content[def] }; - var colorId = def2ColorId[def]; + for (let i = 0; i < allDefs.length; i++) { + let def = allDefs[i]; + let entry = { fontCharacter: def2Content[def] }; + let colorId = def2ColorId[def]; if (colorId) { - var colorValue = colorId2Value[colorId]; + let colorValue = colorId2Value[colorId]; if (colorValue) { entry.fontColor = colorValue; - var entryInverse = { fontCharacter: entry.fontCharacter, fontColor: darkenColor(colorValue) }; + let entryInverse = { fontCharacter: entry.fontCharacter, fontColor: darkenColor(colorValue) }; iconDefinitions[def + '_light'] = entryInverse; } } @@ -205,8 +207,8 @@ exports.update = function () { } function getInvertSet(input) { - var result = {}; - for (var assoc in input) { + let result = {}; + for (let assoc in input) { let invertDef = input[assoc] + '_light'; if (iconDefinitions[invertDef]) { result[assoc] = invertDef; @@ -215,7 +217,7 @@ exports.update = function () { return result; } - var res = { + let res = { information_for_contributors: [ 'This file has been generated from data in https://github.com/jesseweed/seti-ui', '- icon definitions: https://github.com/jesseweed/seti-ui/blob/master/styles/_fonts/seti.less', @@ -246,40 +248,52 @@ exports.update = function () { version: 'https://github.com/jesseweed/seti-ui/commit/' + info.commitSha, }; - var path = './icons/vs-seti-icon-theme.json'; + let path = './icons/vs-seti-icon-theme.json'; fs.writeFileSync(path, JSON.stringify(res, null, '\t')); console.log('written ' + path); } - var match; + let match; return download(fontMappings).then(function (content) { - var regex = /@([\w-]+):\s*'(\\E[0-9A-F]+)';/g; + let regex = /@([\w-]+):\s*'(\\E[0-9A-F]+)';/g; + let contents = {}; while ((match = regex.exec(content)) !== null) { - def2Content['_' + match[1]] = match[2]; + contents[match[1]] = match[2]; } return download(mappings).then(function (content) { - var regex2 = /\.icon-(?:set|partial)\('([\w-\.]+)',\s*'([\w-]+)',\s*(@[\w-]+)\)/g; + let regex2 = /\.icon-(?:set|partial)\('([\w-\.]+)',\s*'([\w-]+)',\s*(@[\w-]+)\)/g; while ((match = regex2.exec(content)) !== null) { let pattern = match[1]; let def = '_' + match[2]; let colorId = match[3]; + let storedColorId = def2ColorId[def]; + let i = 1; + while (storedColorId && colorId !== storedColorId) { // different colors for the same def? + def = `_${match[2]}_${i}`; + storedColorId = def2ColorId[def]; + i++; + } + if (!def2ColorId[def]) { + def2ColorId[def] = colorId; + def2Content[def] = contents[match[2]]; + } + if (pattern[0] === '.') { ext2Def[pattern.substr(1).toLowerCase()] = def; } else { fileName2Def[pattern.toLowerCase()] = def; } - def2ColorId[def] = colorId; } // replace extensions for languageId - var langMappings = getLanguageMappings(); - for (var lang in langMappings) { - var mappings = langMappings[lang]; - var exts = mappings.extensions || []; - var fileNames = mappings.fileNames || []; - var preferredDef = null; + let langMappings = getLanguageMappings(); + for (let lang in langMappings) { + let mappings = langMappings[lang]; + let exts = mappings.extensions || []; + let fileNames = mappings.fileNames || []; + let preferredDef = null; // use the first file association for the preferred definition for (let i1 = 0; i1 < exts.length && !preferredDef; i1++) { preferredDef = ext2Def[exts[i1]]; @@ -307,7 +321,7 @@ exports.update = function () { return download(colors).then(function (content) { - var regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g; + let regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g; while ((match = regex3.exec(content)) !== null) { colorId2Value[match[1]] = match[2]; } diff --git a/extensions/theme-seti/icons/vs-seti-icon-theme.json b/extensions/theme-seti/icons/vs-seti-icon-theme.json index 1226c0dac6a..6aeb37e95c6 100644 --- a/extensions/theme-seti/icons/vs-seti-icon-theme.json +++ b/extensions/theme-seti/icons/vs-seti-icon-theme.json @@ -22,12 +22,6 @@ } ], "iconDefinitions": { - "_R": { - "fontCharacter": "\\E001" - }, - "_apple": { - "fontCharacter": "\\E002" - }, "_asm_light": { "fontCharacter": "\\E003", "fontColor": "#b8383d" @@ -68,6 +62,14 @@ "fontCharacter": "\\E007", "fontColor": "#cc3e44" }, + "_c_light": { + "fontCharacter": "\\E009", + "fontColor": "#498ba7" + }, + "_c": { + "fontCharacter": "\\E009", + "fontColor": "#519aba" + }, "_c-sharp_light": { "fontCharacter": "\\E008", "fontColor": "#498ba7" @@ -76,11 +78,19 @@ "fontCharacter": "\\E008", "fontColor": "#519aba" }, - "_c_light": { + "_c_1_light": { + "fontCharacter": "\\E009", + "fontColor": "#9068b0" + }, + "_c_1": { + "fontCharacter": "\\E009", + "fontColor": "#a074c4" + }, + "_c_2_light": { "fontCharacter": "\\E009", "fontColor": "#b7b73b" }, - "_c": { + "_c_2": { "fontCharacter": "\\E009", "fontColor": "#cbcb41" }, @@ -100,28 +110,35 @@ "fontCharacter": "\\E00B", "fontColor": "#cc3e44" }, - "_checkbox-unchecked": { - "fontCharacter": "\\E00C" - }, - "_checkbox": { - "fontCharacter": "\\E00D" - }, - "_cjsx": { - "fontCharacter": "\\E00E" - }, "_clock_light": { + "fontCharacter": "\\E00F", + "fontColor": "#498ba7" + }, + "_clock": { + "fontCharacter": "\\E00F", + "fontColor": "#519aba" + }, + "_clock_1_light": { "fontCharacter": "\\E00F", "fontColor": "#627379" }, - "_clock": { + "_clock_1": { "fontCharacter": "\\E00F", "fontColor": "#6d8086" }, "_clojure_light": { "fontCharacter": "\\E010", - "fontColor": "#498ba7" + "fontColor": "#7fae42" }, "_clojure": { + "fontCharacter": "\\E010", + "fontColor": "#8dc149" + }, + "_clojure_1_light": { + "fontCharacter": "\\E010", + "fontColor": "#498ba7" + }, + "_clojure_1": { "fontCharacter": "\\E010", "fontColor": "#519aba" }, @@ -141,9 +158,6 @@ "fontCharacter": "\\E012", "fontColor": "#cbcb41" }, - "_coffee_erb": { - "fontCharacter": "\\E013" - }, "_coldfusion_light": { "fontCharacter": "\\E014", "fontColor": "#498ba7" @@ -162,9 +176,17 @@ }, "_cpp_light": { "fontCharacter": "\\E016", - "fontColor": "#9068b0" + "fontColor": "#498ba7" }, "_cpp": { + "fontCharacter": "\\E016", + "fontColor": "#519aba" + }, + "_cpp_1_light": { + "fontCharacter": "\\E016", + "fontColor": "#9068b0" + }, + "_cpp_1": { "fontCharacter": "\\E016", "fontColor": "#a074c4" }, @@ -224,19 +246,37 @@ "fontCharacter": "\\E01D", "fontColor": "#d4d7d6" }, - "_deprecation-cop": { - "fontCharacter": "\\E01E" - }, "_docker_light": { "fontCharacter": "\\E01F", - "fontColor": "#dd4b78" + "fontColor": "#498ba7" }, "_docker": { "fontCharacter": "\\E01F", - "fontColor": "#f55385" + "fontColor": "#519aba" }, - "_editorconfig": { - "fontCharacter": "\\E020" + "_docker_1_light": { + "fontCharacter": "\\E01F", + "fontColor": "#455155" + }, + "_docker_1": { + "fontCharacter": "\\E01F", + "fontColor": "#4d5a5e" + }, + "_docker_2_light": { + "fontCharacter": "\\E01F", + "fontColor": "#7fae42" + }, + "_docker_2": { + "fontCharacter": "\\E01F", + "fontColor": "#8dc149" + }, + "_docker_3_light": { + "fontCharacter": "\\E01F", + "fontColor": "#dd4b78" + }, + "_docker_3": { + "fontCharacter": "\\E01F", + "fontColor": "#f55385" }, "_ejs_light": { "fontCharacter": "\\E021", @@ -270,14 +310,19 @@ "fontCharacter": "\\E024", "fontColor": "#519aba" }, - "_error": { - "fontCharacter": "\\E025" - }, "_eslint_light": { + "fontCharacter": "\\E026", + "fontColor": "#9068b0" + }, + "_eslint": { + "fontCharacter": "\\E026", + "fontColor": "#a074c4" + }, + "_eslint_1_light": { "fontCharacter": "\\E026", "fontColor": "#455155" }, - "_eslint": { + "_eslint_1": { "fontCharacter": "\\E026", "fontColor": "#4d5a5e" }, @@ -321,9 +366,6 @@ "fontCharacter": "\\E02B", "fontColor": "#e37933" }, - "_folder": { - "fontCharacter": "\\E02C" - }, "_font_light": { "fontCharacter": "\\E02D", "fontColor": "#b8383d" @@ -340,15 +382,6 @@ "fontCharacter": "\\E02E", "fontColor": "#41535b" }, - "_git_folder": { - "fontCharacter": "\\E02F" - }, - "_git_ignore": { - "fontCharacter": "\\E030" - }, - "_github": { - "fontCharacter": "\\E031" - }, "_go_light": { "fontCharacter": "\\E032", "fontColor": "#498ba7" @@ -397,9 +430,6 @@ "fontCharacter": "\\E037", "fontColor": "#cc3e44" }, - "_hacklang": { - "fontCharacter": "\\E038" - }, "_haml_light": { "fontCharacter": "\\E039", "fontColor": "#b8383d" @@ -418,9 +448,33 @@ }, "_haxe_light": { "fontCharacter": "\\E03B", - "fontColor": "#9068b0" + "fontColor": "#cc6d2e" }, "_haxe": { + "fontCharacter": "\\E03B", + "fontColor": "#e37933" + }, + "_haxe_1_light": { + "fontCharacter": "\\E03B", + "fontColor": "#b7b73b" + }, + "_haxe_1": { + "fontCharacter": "\\E03B", + "fontColor": "#cbcb41" + }, + "_haxe_2_light": { + "fontCharacter": "\\E03B", + "fontColor": "#498ba7" + }, + "_haxe_2": { + "fontCharacter": "\\E03B", + "fontColor": "#519aba" + }, + "_haxe_3_light": { + "fontCharacter": "\\E03B", + "fontColor": "#9068b0" + }, + "_haxe_3": { "fontCharacter": "\\E03B", "fontColor": "#a074c4" }, @@ -514,9 +568,25 @@ }, "_javascript_light": { "fontCharacter": "\\E047", - "fontColor": "#498ba7" + "fontColor": "#b7b73b" }, "_javascript": { + "fontCharacter": "\\E047", + "fontColor": "#cbcb41" + }, + "_javascript_1_light": { + "fontCharacter": "\\E047", + "fontColor": "#cc6d2e" + }, + "_javascript_1": { + "fontCharacter": "\\E047", + "fontColor": "#e37933" + }, + "_javascript_2_light": { + "fontCharacter": "\\E047", + "fontColor": "#498ba7" + }, + "_javascript_2": { "fontCharacter": "\\E047", "fontColor": "#519aba" }, @@ -536,9 +606,6 @@ "fontCharacter": "\\E049", "fontColor": "#cc3e44" }, - "_js_erb": { - "fontCharacter": "\\E04A" - }, "_json_light": { "fontCharacter": "\\E04B", "fontColor": "#b7b73b" @@ -573,9 +640,25 @@ }, "_license_light": { "fontCharacter": "\\E04F", - "fontColor": "#b8383d" + "fontColor": "#b7b73b" }, "_license": { + "fontCharacter": "\\E04F", + "fontColor": "#cbcb41" + }, + "_license_1_light": { + "fontCharacter": "\\E04F", + "fontColor": "#cc6d2e" + }, + "_license_1": { + "fontCharacter": "\\E04F", + "fontColor": "#e37933" + }, + "_license_2_light": { + "fontCharacter": "\\E04F", + "fontColor": "#b8383d" + }, + "_license_2": { "fontCharacter": "\\E04F", "fontColor": "#cc3e44" }, @@ -613,9 +696,33 @@ }, "_makefile_light": { "fontCharacter": "\\E054", - "fontColor": "#498ba7" + "fontColor": "#cc6d2e" }, "_makefile": { + "fontCharacter": "\\E054", + "fontColor": "#e37933" + }, + "_makefile_1_light": { + "fontCharacter": "\\E054", + "fontColor": "#9068b0" + }, + "_makefile_1": { + "fontCharacter": "\\E054", + "fontColor": "#a074c4" + }, + "_makefile_2_light": { + "fontCharacter": "\\E054", + "fontColor": "#627379" + }, + "_makefile_2": { + "fontCharacter": "\\E054", + "fontColor": "#6d8086" + }, + "_makefile_3_light": { + "fontCharacter": "\\E054", + "fontColor": "#498ba7" + }, + "_makefile_3": { "fontCharacter": "\\E054", "fontColor": "#519aba" }, @@ -651,14 +758,19 @@ "fontCharacter": "\\E058", "fontColor": "#e37933" }, - "_new-file": { - "fontCharacter": "\\E059" - }, "_npm_light": { + "fontCharacter": "\\E05A", + "fontColor": "#3b4b52" + }, + "_npm": { + "fontCharacter": "\\E05A", + "fontColor": "#41535b" + }, + "_npm_1_light": { "fontCharacter": "\\E05A", "fontColor": "#b8383d" }, - "_npm": { + "_npm_1": { "fontCharacter": "\\E05A", "fontColor": "#cc3e44" }, @@ -734,9 +846,6 @@ "fontCharacter": "\\E063", "fontColor": "#519aba" }, - "_project": { - "fontCharacter": "\\E064" - }, "_pug_light": { "fontCharacter": "\\E065", "fontColor": "#b8383d" @@ -761,9 +870,6 @@ "fontCharacter": "\\E067", "fontColor": "#519aba" }, - "_rails": { - "fontCharacter": "\\E068" - }, "_react_light": { "fontCharacter": "\\E069", "fontColor": "#498ba7" @@ -828,12 +934,6 @@ "fontCharacter": "\\E070", "fontColor": "#cc3e44" }, - "_search": { - "fontCharacter": "\\E071" - }, - "_settings": { - "fontCharacter": "\\E072" - }, "_shell_light": { "fontCharacter": "\\E073", "fontColor": "#455155" @@ -908,14 +1008,35 @@ }, "_tex_light": { "fontCharacter": "\\E07C", - "fontColor": "#bfc2c1" + "fontColor": "#498ba7" }, "_tex": { "fontCharacter": "\\E07C", - "fontColor": "#d4d7d6" + "fontColor": "#519aba" }, - "_time-cop": { - "fontCharacter": "\\E07D" + "_tex_1_light": { + "fontCharacter": "\\E07C", + "fontColor": "#b7b73b" + }, + "_tex_1": { + "fontCharacter": "\\E07C", + "fontColor": "#cbcb41" + }, + "_tex_2_light": { + "fontCharacter": "\\E07C", + "fontColor": "#cc6d2e" + }, + "_tex_2": { + "fontCharacter": "\\E07C", + "fontColor": "#e37933" + }, + "_tex_3_light": { + "fontCharacter": "\\E07C", + "fontColor": "#bfc2c1" + }, + "_tex_3": { + "fontCharacter": "\\E07C", + "fontColor": "#d4d7d6" }, "_todo": { "fontCharacter": "\\E07E" @@ -930,9 +1051,17 @@ }, "_typescript_light": { "fontCharacter": "\\E080", - "fontColor": "#b7b73b" + "fontColor": "#498ba7" }, "_typescript": { + "fontCharacter": "\\E080", + "fontColor": "#519aba" + }, + "_typescript_1_light": { + "fontCharacter": "\\E080", + "fontColor": "#b7b73b" + }, + "_typescript_1": { "fontCharacter": "\\E080", "fontColor": "#cbcb41" }, @@ -1026,9 +1155,17 @@ }, "_zip_light": { "fontCharacter": "\\E08C", - "fontColor": "#627379" + "fontColor": "#b8383d" }, "_zip": { + "fontCharacter": "\\E08C", + "fontColor": "#cc3e44" + }, + "_zip_1_light": { + "fontCharacter": "\\E08C", + "fontColor": "#627379" + }, + "_zip_1": { "fontCharacter": "\\E08C", "fontColor": "#6d8086" } @@ -1039,7 +1176,11 @@ "mdo": "_mdo", "asm": "_asm", "s": "_asm", - "h": "_c", + "h": "_c_1", + "hh": "_cpp_1", + "hpp": "_cpp_1", + "hxx": "_cpp_1", + "edn": "_clojure_1", "cfc": "_coldfusion", "cfm": "_coldfusion", "config": "_config", @@ -1077,13 +1218,13 @@ "hs": "_haskell", "lhs": "_haskell", "hx": "_haxe", - "hxs": "_haxe", - "hxp": "_haxe", - "hxml": "_haxe", + "hxs": "_haxe_1", + "hxp": "_haxe_2", + "hxml": "_haxe_3", "class": "_java", "classpath": "_java", "js.map": "_javascript", - "spec.js": "_javascript", + "spec.js": "_javascript_1", "es": "_javascript", "es5": "_javascript", "es7": "_javascript", @@ -1101,8 +1242,8 @@ "njs": "_nunjucks", "nj": "_nunjucks", "npm-debug.log": "_npm", - "npmignore": "_npm", - "npmrc": "_npm", + "npmignore": "_npm_1", + "npmrc": "_npm_1", "ml": "_ocaml", "mli": "_ocaml", "cmx": "_ocaml", @@ -1128,18 +1269,18 @@ "tf.json": "_terraform", "tfvars": "_terraform", "tex": "_tex", - "sty": "_tex", - "dtx": "_tex", - "ins": "_tex", + "sty": "_tex_1", + "dtx": "_tex_2", + "ins": "_tex_3", "txt": "_default", "toml": "_config", "twig": "_twig", - "spec.ts": "_typescript", + "spec.ts": "_typescript_1", "vala": "_vala", "vapi": "_vala", "vue": "_vue", "jar": "_zip", - "zip": "_zip", + "zip": "_zip_1", "wgt": "_wgt", "ai": "_illustrator", "psd": "_photoshop", @@ -1171,23 +1312,23 @@ "wav": "_audio", "babelrc": "_babel", "bowerrc": "_bower", - "dockerignore": "_docker", + "dockerignore": "_docker_1", "codeclimate.yml": "_code-climate", "eslintrc": "_eslint", "eslintrc.js": "_eslint", "eslintrc.yaml": "_eslint", "eslintrc.yml": "_eslint", "eslintrc.json": "_eslint", - "eslintignore": "_eslint", + "eslintignore": "_eslint_1", "firebaserc": "_firebase", - "jshintrc": "_javascript", - "jscsrc": "_javascript", + "jshintrc": "_javascript_2", + "jscsrc": "_javascript_2", "direnv": "_config", "env": "_config", "static": "_config", "editorconfig": "_config", "slugignore": "_config", - "tmp": "_clock", + "tmp": "_clock_1", "htaccess": "_config", "key": "_lock", "cert": "_lock", @@ -1206,9 +1347,9 @@ "mime.types": "_config", "jenkinsfile": "_jenkins", "bower.json": "_bower", - "docker-healthcheck": "_docker", - "docker-compose.yml": "_docker", - "docker-compose.yaml": "_docker", + "docker-healthcheck": "_docker_2", + "docker-compose.yml": "_docker_3", + "docker-compose.yaml": "_docker_3", "firebase.json": "_firebase", "geckodriver": "_firefox", "gruntfile.js": "_grunt", @@ -1226,11 +1367,11 @@ "license": "_license", "licence": "_license", "copying": "_license", - "compiling": "_license", - "contributing": "_license", - "qmakefile": "_makefile", - "omakefile": "_makefile", - "cmakelists.txt": "_makefile", + "compiling": "_license_1", + "contributing": "_license_2", + "qmakefile": "_makefile_1", + "omakefile": "_makefile_2", + "cmakelists.txt": "_makefile_3", "procfile": "_heroku", "todo": "_todo", "npm-debug.log": "_npm_ignored" @@ -1258,7 +1399,7 @@ "lua": "_lua", "makefile": "_makefile", "markdown": "_markdown", - "objective-c": "_c", + "objective-c": "_c_2", "perl": "_perl", "php": "_php", "powershell": "_powershell", @@ -1282,7 +1423,11 @@ "mdo": "_mdo_light", "asm": "_asm_light", "s": "_asm_light", - "h": "_c_light", + "h": "_c_1_light", + "hh": "_cpp_1_light", + "hpp": "_cpp_1_light", + "hxx": "_cpp_1_light", + "edn": "_clojure_1_light", "cfc": "_coldfusion_light", "cfm": "_coldfusion_light", "config": "_config_light", @@ -1320,13 +1465,13 @@ "hs": "_haskell_light", "lhs": "_haskell_light", "hx": "_haxe_light", - "hxs": "_haxe_light", - "hxp": "_haxe_light", - "hxml": "_haxe_light", + "hxs": "_haxe_1_light", + "hxp": "_haxe_2_light", + "hxml": "_haxe_3_light", "class": "_java_light", "classpath": "_java_light", "js.map": "_javascript_light", - "spec.js": "_javascript_light", + "spec.js": "_javascript_1_light", "es": "_javascript_light", "es5": "_javascript_light", "es7": "_javascript_light", @@ -1344,8 +1489,8 @@ "njs": "_nunjucks_light", "nj": "_nunjucks_light", "npm-debug.log": "_npm_light", - "npmignore": "_npm_light", - "npmrc": "_npm_light", + "npmignore": "_npm_1_light", + "npmrc": "_npm_1_light", "ml": "_ocaml_light", "mli": "_ocaml_light", "cmx": "_ocaml_light", @@ -1371,18 +1516,18 @@ "tf.json": "_terraform_light", "tfvars": "_terraform_light", "tex": "_tex_light", - "sty": "_tex_light", - "dtx": "_tex_light", - "ins": "_tex_light", + "sty": "_tex_1_light", + "dtx": "_tex_2_light", + "ins": "_tex_3_light", "txt": "_default_light", "toml": "_config_light", "twig": "_twig_light", - "spec.ts": "_typescript_light", + "spec.ts": "_typescript_1_light", "vala": "_vala_light", "vapi": "_vala_light", "vue": "_vue_light", "jar": "_zip_light", - "zip": "_zip_light", + "zip": "_zip_1_light", "wgt": "_wgt_light", "ai": "_illustrator_light", "psd": "_photoshop_light", @@ -1414,23 +1559,23 @@ "wav": "_audio_light", "babelrc": "_babel_light", "bowerrc": "_bower_light", - "dockerignore": "_docker_light", + "dockerignore": "_docker_1_light", "codeclimate.yml": "_code-climate_light", "eslintrc": "_eslint_light", "eslintrc.js": "_eslint_light", "eslintrc.yaml": "_eslint_light", "eslintrc.yml": "_eslint_light", "eslintrc.json": "_eslint_light", - "eslintignore": "_eslint_light", + "eslintignore": "_eslint_1_light", "firebaserc": "_firebase_light", - "jshintrc": "_javascript_light", - "jscsrc": "_javascript_light", + "jshintrc": "_javascript_2_light", + "jscsrc": "_javascript_2_light", "direnv": "_config_light", "env": "_config_light", "static": "_config_light", "editorconfig": "_config_light", "slugignore": "_config_light", - "tmp": "_clock_light", + "tmp": "_clock_1_light", "htaccess": "_config_light", "key": "_lock_light", "cert": "_lock_light", @@ -1459,7 +1604,7 @@ "lua": "_lua_light", "makefile": "_makefile_light", "markdown": "_markdown_light", - "objective-c": "_c_light", + "objective-c": "_c_2_light", "perl": "_perl_light", "php": "_php_light", "powershell": "_powershell_light", @@ -1489,9 +1634,9 @@ "mime.types": "_config_light", "jenkinsfile": "_jenkins_light", "bower.json": "_bower_light", - "docker-healthcheck": "_docker_light", - "docker-compose.yml": "_docker_light", - "docker-compose.yaml": "_docker_light", + "docker-healthcheck": "_docker_2_light", + "docker-compose.yml": "_docker_3_light", + "docker-compose.yaml": "_docker_3_light", "firebase.json": "_firebase_light", "geckodriver": "_firefox_light", "gruntfile.js": "_grunt_light", @@ -1509,11 +1654,11 @@ "license": "_license_light", "licence": "_license_light", "copying": "_license_light", - "compiling": "_license_light", - "contributing": "_license_light", - "qmakefile": "_makefile_light", - "omakefile": "_makefile_light", - "cmakelists.txt": "_makefile_light", + "compiling": "_license_1_light", + "contributing": "_license_2_light", + "qmakefile": "_makefile_1_light", + "omakefile": "_makefile_2_light", + "cmakelists.txt": "_makefile_3_light", "procfile": "_heroku_light", "npm-debug.log": "_npm_ignored_light" } diff --git a/extensions/typescript/src/features/completionItemProvider.ts b/extensions/typescript/src/features/completionItemProvider.ts index f58134b67bd..75c44273c7d 100644 --- a/extensions/typescript/src/features/completionItemProvider.ts +++ b/extensions/typescript/src/features/completionItemProvider.ts @@ -53,7 +53,7 @@ class MyCompletionItem extends CompletionItem { this.range = tsTextSpanToVsRange(tsEntry.replacementSpan); } - if (typeof (tsEntry as any).insertText === 'string') { + if (typeof tsEntry.insertText === 'string') { this.insertText = (tsEntry as any).insertText as string; if (tsEntry.replacementSpan) { diff --git a/extensions/typescript/src/features/quickFixProvider.ts b/extensions/typescript/src/features/quickFixProvider.ts index 21b7dabe37e..4c4a86d1d97 100644 --- a/extensions/typescript/src/features/quickFixProvider.ts +++ b/extensions/typescript/src/features/quickFixProvider.ts @@ -11,6 +11,10 @@ import { vsRangeToTsFileRange } from '../utils/convert'; import FormattingConfigurationManager from './formattingConfigurationManager'; import { getEditForCodeAction, applyCodeActionCommands } from '../utils/codeAction'; import { Command, CommandManager } from '../utils/commandManager'; +import { createWorkspaceEditFromFileCodeEdits } from '../utils/workspaceEdit'; + +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); class ApplyCodeActionCommand implements Command { public static readonly ID = '_typescript.applyCodeActionCommand'; @@ -34,11 +38,9 @@ class SupportedCodeActionProvider { private readonly client: ITypeScriptServiceClient ) { } - public async getSupportedActionsForContext(context: vscode.CodeActionContext): Promise> { + public async getFixableDiagnosticsForContext(context: vscode.CodeActionContext): Promise { const supportedActions = await this.supportedCodeActions; - return new Set(context.diagnostics - .map(diagnostic => +diagnostic.code) - .filter(code => supportedActions.has(code))); + return context.diagnostics.filter(diagnostic => supportedActions.has(+diagnostic.code)); } private get supportedCodeActions(): Thenable> { @@ -67,7 +69,7 @@ export default class TypeScriptQuickFixProvider implements vscode.CodeActionProv public async provideCodeActions( document: vscode.TextDocument, - range: vscode.Range, + _range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken ): Promise { @@ -80,23 +82,60 @@ export default class TypeScriptQuickFixProvider implements vscode.CodeActionProv return []; } - const supportedActions = await this.supportedCodeActionProvider.getSupportedActionsForContext(context); - if (!supportedActions.size) { + const fixableDiagnostics = await this.supportedCodeActionProvider.getFixableDiagnosticsForContext(context); + if (!fixableDiagnostics.length) { return []; } await this.formattingConfigurationManager.ensureFormatOptionsForDocument(document, token); - const args: Proto.CodeFixRequestArgs = { - ...vsRangeToTsFileRange(file, range), - errorCodes: Array.from(supportedActions) - }; - const response = await this.client.execute('getCodeFixes', args, token); - return (response.body || []).map(action => this.getCommandForAction(action)); + const results: vscode.CodeAction[] = []; + for (const diagnostic of fixableDiagnostics) { + results.push(...await this.getFixesForDiagnostic(file, diagnostic, token)); + } + return results; } - private getCommandForAction(tsAction: Proto.CodeAction): vscode.CodeAction { - const codeAction = new vscode.CodeAction(tsAction.description, getEditForCodeAction(this.client, tsAction)); + private async getFixesForDiagnostic( + file: string, + diagnostic: vscode.Diagnostic, + token: vscode.CancellationToken + ): Promise> { + const args: Proto.CodeFixRequestArgs = { + ...vsRangeToTsFileRange(file, diagnostic.range), + errorCodes: [+diagnostic.code] + }; + const codeFixesResponse = await this.client.execute('getCodeFixes', args, token); + if (codeFixesResponse.body) { + const results: vscode.CodeAction[] = []; + for (const tsCodeFix of codeFixesResponse.body) { + results.push(...await this.getAllFixesForTsCodeAction(file, diagnostic, tsCodeFix, token)); + } + return results; + } + return []; + } + + private async getAllFixesForTsCodeAction( + file: string, + diagnostic: vscode.Diagnostic, + tsAction: Proto.CodeFixAction, + token: vscode.CancellationToken + ): Promise> { + const singleFix = this.getSingleFixForTsCodeAction(diagnostic, tsAction); + const fixAll = await this.getFixAllForTsCodeAction(file, diagnostic, tsAction, token); + return fixAll ? [singleFix, fixAll] : [singleFix]; + } + + private getSingleFixForTsCodeAction( + diagnostic: vscode.Diagnostic, + tsAction: Proto.CodeFixAction + ): vscode.CodeAction { + const codeAction = new vscode.CodeAction( + tsAction.description, + getEditForCodeAction(this.client, tsAction)); + + codeAction.diagnostics = [diagnostic]; if (tsAction.commands) { codeAction.command = { command: ApplyCodeActionCommand.ID, @@ -106,4 +145,45 @@ export default class TypeScriptQuickFixProvider implements vscode.CodeActionProv } return codeAction; } + + private async getFixAllForTsCodeAction( + file: string, + diagnostic: vscode.Diagnostic, + tsAction: Proto.CodeFixAction, + token: vscode.CancellationToken + ): Promise { + if (!tsAction.fixId || !this.client.apiVersion.has270Features()) { + return undefined; + } + + const args: Proto.GetCombinedCodeFixRequestArgs = { + scope: { + type: 'file', + args: { file } + }, + fixId: tsAction.fixId + }; + + try { + const combinedCodeFixesResponse = await this.client.execute('getCombinedCodeFix', args, token); + if (!combinedCodeFixesResponse.body) { + return undefined; + } + + const codeAction = new vscode.CodeAction( + localize('fixAllInFileLabel', '{0} (Fix all in file)', tsAction.description), + createWorkspaceEditFromFileCodeEdits(this.client, combinedCodeFixesResponse.body.changes)); + codeAction.diagnostics = [diagnostic]; + if (tsAction.commands) { + codeAction.command = { + command: ApplyCodeActionCommand.ID, + arguments: [tsAction], + title: tsAction.description + }; + } + return codeAction; + } catch { + return undefined; + } + } } diff --git a/extensions/typescript/src/typescriptService.ts b/extensions/typescript/src/typescriptService.ts index fbcda9c7938..db51d60464c 100644 --- a/extensions/typescript/src/typescriptService.ts +++ b/extensions/typescript/src/typescriptService.ts @@ -61,6 +61,7 @@ export interface ITypeScriptServiceClient { execute(command: 'navtree', args: Proto.FileRequestArgs, token?: CancellationToken): Promise; execute(command: 'getCodeFixes', args: Proto.CodeFixRequestArgs, token?: CancellationToken): Promise; execute(command: 'getSupportedCodeFixes', args: null, token?: CancellationToken): Promise; + execute(command: 'getCombinedCodeFix', args: Proto.GetCombinedCodeFixRequestArgs, token?: CancellationToken): Promise; execute(command: 'docCommentTemplate', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise; execute(command: 'getApplicableRefactors', args: Proto.GetApplicableRefactorsRequestArgs, token?: CancellationToken): Promise; execute(command: 'getEditsForRefactor', args: Proto.GetEditsForRefactorRequestArgs, token?: CancellationToken): Promise; diff --git a/extensions/typescript/src/utils/api.ts b/extensions/typescript/src/utils/api.ts index 6e13c01a574..e4103a29231 100644 --- a/extensions/typescript/src/utils/api.ts +++ b/extensions/typescript/src/utils/api.ts @@ -7,6 +7,9 @@ import * as semver from 'semver'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); +import { memoize } from './memoize'; + + export default class API { public static readonly defaultVersion = new API('1.0.0', '1.0.0'); @@ -29,51 +32,68 @@ export default class API { private readonly version: string ) { } + @memoize public has203Features(): boolean { return semver.gte(this.version, '2.0.3'); } + @memoize public has206Features(): boolean { return semver.gte(this.version, '2.0.6'); } + @memoize public has208Features(): boolean { return semver.gte(this.version, '2.0.8'); } + @memoize public has213Features(): boolean { return semver.gte(this.version, '2.1.3'); } + @memoize public has220Features(): boolean { return semver.gte(this.version, '2.2.0'); } + @memoize public has222Features(): boolean { return semver.gte(this.version, '2.2.2'); } + @memoize public has230Features(): boolean { return semver.gte(this.version, '2.3.0'); } + @memoize public has234Features(): boolean { return semver.gte(this.version, '2.3.4'); } + @memoize public has240Features(): boolean { return semver.gte(this.version, '2.4.0'); } + @memoize public has250Features(): boolean { return semver.gte(this.version, '2.5.0'); } + @memoize public has260Features(): boolean { return semver.gte(this.version, '2.6.0'); } + @memoize public has262Features(): boolean { return semver.gte(this.version, '2.6.2'); } + + @memoize + public has270Features(): boolean { + return semver.gte(this.version, '2.7.0'); + } } \ No newline at end of file diff --git a/extensions/typescript/src/utils/codeAction.ts b/extensions/typescript/src/utils/codeAction.ts index e3fc0178af1..4c05629c78c 100644 --- a/extensions/typescript/src/utils/codeAction.ts +++ b/extensions/typescript/src/utils/codeAction.ts @@ -5,26 +5,16 @@ import { WorkspaceEdit, workspace } from 'vscode'; import * as Proto from '../protocol'; -import { tsTextSpanToVsRange } from './convert'; import { ITypeScriptServiceClient } from '../typescriptService'; +import { createWorkspaceEditFromFileCodeEdits } from './workspaceEdit'; export function getEditForCodeAction( client: ITypeScriptServiceClient, action: Proto.CodeAction ): WorkspaceEdit | undefined { - if (action.changes && action.changes.length) { - const workspaceEdit = new WorkspaceEdit(); - for (const change of action.changes) { - for (const textChange of change.textChanges) { - workspaceEdit.replace(client.asUrl(change.fileName), - tsTextSpanToVsRange(textChange), - textChange.newText); - } - } - - return workspaceEdit; - } - return undefined; + return action.changes && action.changes.length + ? createWorkspaceEditFromFileCodeEdits(client, action.changes) + : undefined; } export async function applyCodeAction( diff --git a/extensions/typescript/src/utils/memoize.ts b/extensions/typescript/src/utils/memoize.ts new file mode 100644 index 00000000000..beeb0035b89 --- /dev/null +++ b/extensions/typescript/src/utils/memoize.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export function memoize(_target: any, key: string, descriptor: any) { + let fnKey: string | undefined = undefined; + let fn: Function | undefined = undefined; + + if (typeof descriptor.value === 'function') { + fnKey = 'value'; + fn = descriptor.value; + } else if (typeof descriptor.get === 'function') { + fnKey = 'get'; + fn = descriptor.get; + } else { + throw new Error('not supported'); + } + + const memoizeKey = `$memoize$${key}`; + + descriptor[fnKey] = function (...args: any[]) { + if (!this.hasOwnProperty(memoizeKey)) { + Object.defineProperty(this, memoizeKey, { + configurable: false, + enumerable: false, + writable: false, + value: fn!.apply(this, args) + }); + } + + return this[memoizeKey]; + }; +} diff --git a/extensions/typescript/src/utils/versionStatus.ts b/extensions/typescript/src/utils/versionStatus.ts index 3ed92289670..69871458646 100644 --- a/extensions/typescript/src/utils/versionStatus.ts +++ b/extensions/typescript/src/utils/versionStatus.ts @@ -40,8 +40,10 @@ export default class VersionStatus { if (vscode.languages.match([languageModeIds.typescript, languageModeIds.typescriptreact], doc)) { if (this.normalizePath(doc.uri)) { this.versionBarEntry.show(); - return; + } else { + this.versionBarEntry.hide(); } + return; } if (!vscode.window.activeTextEditor.viewColumn) { diff --git a/extensions/typescript/src/utils/workspaceEdit.ts b/extensions/typescript/src/utils/workspaceEdit.ts new file mode 100644 index 00000000000..4cb29eb8467 --- /dev/null +++ b/extensions/typescript/src/utils/workspaceEdit.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as vscode from 'vscode'; +import { ITypeScriptServiceClient } from '../typescriptService'; +import * as Proto from '../protocol'; +import { tsTextSpanToVsRange } from './convert'; + +export function createWorkspaceEditFromFileCodeEdits( + client: ITypeScriptServiceClient, + edits: Iterable +): vscode.WorkspaceEdit { + const workspaceEdit = new vscode.WorkspaceEdit(); + for (const edit of edits) { + for (const textChange of edit.textChanges) { + workspaceEdit.replace(client.asUrl(edit.fileName), + tsTextSpanToVsRange(textChange), + textChange.newText); + } + } + + return workspaceEdit; +} \ No newline at end of file diff --git a/extensions/typescript/tsconfig.json b/extensions/typescript/tsconfig.json index 56de6915ae5..e9800fa4b00 100644 --- a/extensions/typescript/tsconfig.json +++ b/extensions/typescript/tsconfig.json @@ -12,7 +12,8 @@ "noUnusedLocals": true, "noUnusedParameters": true, "strict": true, - "alwaysStrict": true + "alwaysStrict": true, + "experimentalDecorators": true }, "include": [ "src/**/*" diff --git a/extensions/yaml/language-configuration.json b/extensions/yaml/language-configuration.json index cc1aa26cde6..010d773d3f3 100644 --- a/extensions/yaml/language-configuration.json +++ b/extensions/yaml/language-configuration.json @@ -23,5 +23,9 @@ ], "folding": { "offSide": true + }, + "indentationRules": { + "increaseIndentPattern": "^\\s*.*(:|-) ?(&\\w+)?(\\{[^}\"']*|\\([^)\"']*)?$", + "decreaseIndentPattern": "^\\s+\\}$" } -} \ No newline at end of file +} diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 64815a3eb3f..1fc13a8f83b 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,6 +2,6 @@ # yarn lockfile v1 -typescript@2.7.0-insiders.20180108: - version "2.7.0-insiders.20180108" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.0-insiders.20180108.tgz#b9230ca5a0020e92133f63e6a4272f8c1b301bdb" +typescript@2.7.0-insiders.20180119: + version "2.7.0-insiders.20180119" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.0-insiders.20180119.tgz#556c59eaabb0758dd1a2f0b0602a355746d33277" diff --git a/i18n/chs/extensions/git/out/autofetch.i18n.json b/i18n/chs/extensions/git/out/autofetch.i18n.json index 6df74592845..823bb93043f 100644 --- a/i18n/chs/extensions/git/out/autofetch.i18n.json +++ b/i18n/chs/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "是", + "read more": "了解详细信息", "no": "否", - "not now": "不是现在", - "suggest auto fetch": "是否启用自动抓取 Git 存储库?" + "not now": "稍后询问", + "suggest auto fetch": "您希望 Code 定期运行 \"git fetch\" 吗?" } \ No newline at end of file diff --git a/i18n/chs/extensions/git/out/commands.i18n.json b/i18n/chs/extensions/git/out/commands.i18n.json index 8f5f2a83f79..a19bebe875b 100644 --- a/i18n/chs/extensions/git/out/commands.i18n.json +++ b/i18n/chs/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\n此操作不可撤销,你当前的工作集将会永远丢失。", "yes discard tracked": "放弃 1 个已跟踪的文件", "yes discard tracked multiple": "放弃 {0} 个已跟踪的文件", + "unsaved files single": "以下文件尚未保存:{0}。\n\n您要在提交之前保存吗?", + "unsaved files": "当前有 {0} 个文件尚未保存。\n\n您要在提交之前保存吗?", + "save and commit": "全部保存并提交", + "commit": "仍要提交", "no staged changes": "现在没有暂存的更改以供提交\n\n是否要直接自动暂存所有更改并提交?", "always": "始终", "no changes": "没有要提交的更改。", @@ -64,12 +68,13 @@ "no remotes to pull": "存储库未配置任何从其中进行拉取的远程存储库。", "pick remote pull repo": "选择要从其拉取分支的远程位置", "no remotes to push": "存储库未配置任何要推送到的远程存储库。", - "push with tags success": "已成功带标签进行推送。", "nobranch": "请签出一个分支以推送到远程。", + "confirm publish branch": "分支“{0}”没有上游分支。您要发布此分支吗?", + "ok": "确定", + "push with tags success": "已成功带标签进行推送。", "pick remote": "选取要将分支“{0}”发布到的远程:", "sync is unpredictable": "此操作将推送提交至“{0}”,并从中拉取提交。", - "ok": "确定", - "never again": "好,永不再显示", + "never again": "确定,且不再显示", "no remotes to publish": "存储库未配置任何要发布到的远程存储库。", "no changes stash": "没有要储藏的更改。", "provide stash message": "提供储藏消息(可选)", diff --git a/i18n/chs/extensions/git/package.i18n.json b/i18n/chs/extensions/git/package.i18n.json index cb8443b7aec..7b47c05b8f9 100644 --- a/i18n/chs/extensions/git/package.i18n.json +++ b/i18n/chs/extensions/git/package.i18n.json @@ -54,12 +54,13 @@ "command.stashPopLatest": "弹出最新储藏", "config.enabled": "是否启用 Git", "config.path": "Git 可执行文件路径", + "config.autoRepositoryDetection": "是否自动检测存储库", "config.autorefresh": "是否启用自动刷新", "config.autofetch": "是否启用自动拉取", "config.enableLongCommitWarning": "是否针对长段提交消息进行警告", "config.confirmSync": "同步 GIT 存储库前请先进行确认", "config.countBadge": "控制 Git 徽章计数器。“all”计算所有更改。“tracked”只计算跟踪的更改。“off”关闭此功能。", - "config.checkoutType": "控制运行“签出到...”命令时列出的分支的类型。\"all\" 显示所有 refs,\"local\" 只显示本地分支,\"tags\" 只显示标记,\"remote\" 只显示远程分支。", + "config.checkoutType": "控制运行“签出到...”功能时列出的分支类型。\"all\" 显示所有 refs,\"local\" 只显示本地分支,\"tags\" 只显示标签,\"remote\" 只显示远程分支。", "config.ignoreLegacyWarning": "忽略旧版 Git 警告", "config.ignoreMissingGitWarning": "忽略“缺失 Git”警告", "config.ignoreLimitWarning": "忽略“存储库中存在大量更改”的警告", @@ -72,5 +73,6 @@ "colors.deleted": "已删除资源的颜色。", "colors.untracked": "未跟踪资源的颜色。", "colors.ignored": "已忽略资源的颜色。", - "colors.conflict": "存在冲突的资源的颜色。" + "colors.conflict": "存在冲突的资源的颜色。", + "colors.submodule": "子模块资源的颜色。" } \ No newline at end of file diff --git a/i18n/chs/extensions/typescript/out/commands.i18n.json b/i18n/chs/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..36b3b2d5f6b --- /dev/null +++ b/i18n/chs/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "请在 VS Code 中打开一个文件夹,以使用 TypeScript 或 JavaScript 项目", + "typescript.projectConfigUnsupportedFile": "无法确定 TypeScript 或 JavaScript 项目。不受支持的文件类型", + "typescript.projectConfigCouldNotGetInfo": "无法确定 TypeScript 或 JavaScript 项目", + "typescript.noTypeScriptProjectConfig": "文件不属于 TypeScript 项目", + "typescript.noJavaScriptProjectConfig": "文件不属于 JavaScript 项目", + "typescript.configureTsconfigQuickPick": "配置 tsconfig.json", + "typescript.configureJsconfigQuickPick": "配置 jsconfig.json", + "typescript.projectConfigLearnMore": "了解详细信息" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/chs/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/chs/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/base/node/ps.i18n.json b/i18n/chs/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..da69e94cccc --- /dev/null +++ b/i18n/chs/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "正在收集 CPU 与内存信息。这可能需要几秒钟的时间。" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/chs/src/vs/editor/common/config/commonEditorConfig.i18n.json index 9c145d8c4d9..b2f32f3d15b 100644 --- a/i18n/chs/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/chs/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "将行号显示为绝对行数。", "lineNumbers.relative": "将行号显示为与光标相隔的行数。", "lineNumbers.interval": "每 10 行显示一次行号。", - "lineNumbers": "控制行号的显示。可选值为 \"on\"、\"off\" 和 \"relative\"。", + "lineNumbers": "控制行号的显示。可选值为 \"on\"、\"off\"、\"relative\" 和 \"interval\"。", "rulers": "在一定数量的等宽字符后显示垂直标尺。输入多个值,显示多个标尺。若数组为空,则不绘制标尺。", "wordSeparators": "执行文字相关的导航或操作时将用作文字分隔符的字符", "tabSize": "一个制表符等于的空格数。该设置在 \"editor.detectIndentation\" 启用时根据文件内容可能会被覆盖。", @@ -72,6 +72,7 @@ "cursorBlinking": "控制光标动画样式,可能的值为 \"blink\"、\"smooth\"、\"phase\"、\"expand\" 和 \"solid\"", "mouseWheelZoom": "通过使用鼠标滚轮同时按住 Ctrl 可缩放编辑器的字体", "cursorStyle": "控制光标样式,接受的值为 \"block\"、\"block-outline\"、\"line\"、\"line-thin\" 、\"underline\" 和 \"underline-thin\"", + "lineCursorWidth": "当 editor.cursorStyle 设置为 \"line\" 时控制光标的宽度。", "fontLigatures": "启用字体连字", "hideCursorInOverviewRuler": "控制光标是否应隐藏在概述标尺中。", "renderWhitespace": "控制编辑器中呈现空白字符的方式,可能为“无”、“边界”和“全部”。“边界”选项不会在单词之间呈现单空格。", diff --git a/i18n/chs/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/chs/src/vs/editor/common/view/editorColorRegistry.i18n.json index 168dd2fb958..6d1dfc8be23 100644 --- a/i18n/chs/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/chs/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,7 @@ { "lineHighlight": "光标所在行高亮内容的背景颜色。", "lineHighlightBorderBox": "光标所在行四周边框的背景颜色。", - "rangeHighlight": "高亮范围的背景色,例如由 \"Quick Open\" 和“查找”功能高亮的范围。", + "rangeHighlight": "高亮范围的背景色,例如由 \"Quick Open\" 和“查找”功能高亮的范围。颜色必须透明,这样不会挡住其下的其他元素。", "caret": "编辑器光标颜色。", "editorCursorBackground": "编辑器光标的背景色。可以自定义块型光标覆盖字符的颜色。", "editorWhitespaces": "编辑器中空白字符的颜色。", diff --git a/i18n/chs/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/chs/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 8dc6ee58760..2e70001e92c 100644 --- a/i18n/chs/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/chs/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "转到下一个错误或警告", - "markerAction.previous.label": "转到上一个错误或警告", + "markerAction.next.label": "转到下一个问题 (错误、警告、信息)", + "markerAction.previous.label": "转到上一个问题 (错误、警告、信息)", "editorMarkerNavigationError": "编辑器标记导航小组件错误颜色。", "editorMarkerNavigationWarning": "编辑器标记导航小组件警告颜色。", "editorMarkerNavigationInfo": "编辑器标记导航小组件信息颜色。", diff --git a/i18n/chs/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/chs/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index 7926047995c..185a3d31620 100644 --- a/i18n/chs/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/chs/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "读取访问时符号的背景颜色,例如读取变量时。", - "wordHighlightStrong": "写入访问时符号的背景颜色,例如写入变量时。", + "wordHighlight": "进行读取访问操作时符号的背景颜色,例如读取变量时。颜色必须透明,这样不会挡住其下的其他元素。", + "wordHighlightStrong": "进行写入访问操作时符号的背景颜色,例如写入变量时。颜色必须透明,这样不会挡住其下的其他元素。", "overviewRulerWordHighlightForeground": "概述符号突出显示的标尺标记颜色。", "overviewRulerWordHighlightStrongForeground": "概述写访问符号突出显示的标尺标记颜色。", "wordHighlight.next.label": "转到下一个突出显示的符号", diff --git a/i18n/chs/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/chs/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index d14243882a7..dd181ef9f45 100644 --- a/i18n/chs/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/chs/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "“{0}”为无效菜单标识符", "missing.command": "菜单项引用未在“命令”部分进行定义的命令“{0}”。", "missing.altCommand": "菜单项引用了未在 \"commands\" 部分定义的替代命令“{0}”。", - "dupe.command": "菜单项引用的命令中默认和替代命令相同", - "nosupport.altCommand": "抱歉,目前仅有 \"editor/title\" 菜单的 \"navigation\" 组支持替代命令" + "dupe.command": "菜单项引用的命令中默认和替代命令相同" } \ No newline at end of file diff --git a/i18n/chs/src/vs/platform/environment/node/argv.i18n.json b/i18n/chs/src/vs/platform/environment/node/argv.i18n.json index 9a1faa5d983..30d7fd225a2 100644 --- a/i18n/chs/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/chs/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,35 @@ "diff": "将两个文件相互比较。", "add": "将文件夹添加到最后一个活动窗口。", "goto": "打开路径下的文件并定位到特定行和特定列。", - "locale": "要使用的区域设置(例如 en-US 或 zh-TW)。", "newWindow": "强制创建一个新的 Code 实例。", - "performance": "通过启用 \"Developer: Startup Performance\" 命令开始。", - "prof-startup": "启动期间运行 CPU 探查器", - "inspect-extensions": "允许进行扩展的调试与分析。检查开发人员工具可获取连接 URI。", - "inspect-brk-extensions": "允许在扩展主机在启动后暂停时进行扩展的调试与分析。检查开发人员工具可获取连接 URI。", "reuseWindow": "在上一活动窗口中强制打开文件或文件夹。", - "userDataDir": "指定存放用户数据的目录。此目录在以 root 身份运行时十分有用。", - "log": "使用的日志级别。默认值为 \"info\"。允许的值为 \"critical\" (关键)、\"error\" (错误)、\"warn\" (警告)、\"info\" (信息)、\"debug\" (调试)、\"trace\" (跟踪) 和 \"off\" (关闭)。", - "verbose": "打印详细输出(隐含 --wait 参数)。", "wait": "等文件关闭后再返回。", + "locale": "要使用的区域设置(例如 en-US 或 zh-TW)。", + "userDataDir": "指定存放用户数据的目录。此目录在以 root 身份运行时十分有用。", + "version": "打印版本。", + "help": "打印使用情况。", "extensionHomePath": "设置扩展的根路径。", "listExtensions": "列出已安装的扩展。", "showVersions": "使用 --list-extension 时,显示已安装扩展的版本。", "installExtension": "安装扩展。", "uninstallExtension": "卸载扩展。", "experimentalApis": "启用扩展程序实验性 api 功能。", - "disableExtensions": "禁用所有已安装的扩展。", - "disableGPU": "禁用 GPU 硬件加速。", + "verbose": "打印详细输出(隐含 --wait 参数)。", + "log": "使用的日志级别。默认值为 \"info\"。允许的值为 \"critical\" (关键)、\"error\" (错误)、\"warn\" (警告)、\"info\" (信息)、\"debug\" (调试)、\"trace\" (跟踪) 和 \"off\" (关闭)。", "status": "打印进程使用情况和诊断信息。", - "version": "打印版本。", - "help": "打印使用情况。", + "performance": "通过启用 \"Developer: Startup Performance\" 命令开始。", + "prof-startup": "启动期间运行 CPU 探查器", + "disableExtensions": "禁用所有已安装的扩展。", + "inspect-extensions": "允许进行扩展的调试与分析。检查开发人员工具可获取连接 URI。", + "inspect-brk-extensions": "允许在扩展主机在启动后暂停时进行扩展的调试与分析。检查开发人员工具可获取连接 URI。", + "disableGPU": "禁用 GPU 硬件加速。", + "uploadLogs": "将当前会话的日志上传到安全端点。", "usage": "使用情况", "options": "选项", "paths": "路径", - "optionsUpperCase": "选项" + "stdinWindows": "要读取其他程序的输出,请追加 \"-\" (例如 \"echo Hello World\" | {0} -')", + "stdinUnix": "要从 stdin 中读取,请追加 \"-\" (例如 \"ps aux | grep code | {0} -')", + "optionsUpperCase": "选项", + "extensionsManagement": "扩展管理", + "troubleshooting": "故障排查" } \ No newline at end of file diff --git a/i18n/chs/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/chs/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index a6e3a8ea7bc..c72b93d1de9 100644 --- a/i18n/chs/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/chs/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,15 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "扩展无效: package.json 不是 JSON 文件。", - "restartCodeLocal": "请先重启 Code 再重新安装 {0}。", + "restartCode": "请先重启 Code 再重新安装 {0}。", "installingOutdatedExtension": "您已安装此扩展的新版程序。是否要使用旧版覆盖?", "override": "覆盖", "cancel": "取消", - "notFoundCompatible": "无法安装。找不到与 VS Code 当前版本 ({1}) 兼容的扩展“{0}”。", - "quitCode": "无法安装,因为此扩展的一个过时实例仍在运行。请先完全重启 VS Code,再重新安装。", - "exitCode": "无法安装,因为此扩展的一个过时实例仍在运行。请先完全重启 VS Code,再重新安装。", + "errorInstallingDependencies": "安装依赖项时出错。{0}", + "notFoundCompatible": "无法安装“{0}”;没有可用的版本与 VS Code “{1}”兼容。", "notFoundCompatibleDependency": "无法安装。找不到与 VS Code 当前版本 ({1}) 兼容的依赖扩展“{0}”。", + "quitCode": "无法安装扩展。请在重启 VS Code 后重新安装。", + "exitCode": "无法安装扩展。请在重启 VS Code 后重新安装。", "uninstallDependeciesConfirmation": "要仅卸载“{0}”或者其依赖项也一起卸载?", "uninstallOnly": "仅", "uninstallAll": "全部", diff --git a/i18n/chs/src/vs/platform/message/common/message.i18n.json b/i18n/chs/src/vs/platform/message/common/message.i18n.json index 864f82423ea..6ab699b790e 100644 --- a/i18n/chs/src/vs/platform/message/common/message.i18n.json +++ b/i18n/chs/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "关闭", "later": "稍后", - "cancel": "取消" + "cancel": "取消", + "moreFile": "...1 个其他文件未显示", + "moreFiles": "...{0} 个其他文件未显示" } \ No newline at end of file diff --git a/i18n/chs/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/chs/src/vs/platform/theme/common/colorRegistry.i18n.json index 7c3d96dd488..0e3e7d546d3 100644 --- a/i18n/chs/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/chs/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,12 @@ "editorWidgetBorder": "编辑器小部件的边框颜色。此颜色仅在小部件有边框且不被小部件重写时适用。", "editorSelectionBackground": "编辑器所选内容的颜色。", "editorSelectionForeground": "用以彰显高对比度的所选文本的颜色。", - "editorInactiveSelection": "非活动编辑器中所选内容的颜色。", - "editorSelectionHighlight": "与所选内容具有相同内容的区域颜色。", + "editorInactiveSelection": "非活动编辑器选择内容的颜色。颜色必须透明,这样不会挡住其下的其他元素。", + "editorSelectionHighlight": "与已选项内容相同区域的颜色。颜色必须透明,这样不会挡住其下的其他元素。", "editorFindMatch": "当前搜索匹配项的颜色。", - "findMatchHighlight": "其他搜索匹配项的颜色。", - "findRangeHighlight": "限制搜索的范围的颜色。", - "hoverHighlight": "悬停提示显示时文本底下的高亮颜色。", + "findMatchHighlight": "其他搜索匹配项的颜色。颜色必须透明,这样不会挡住其下的其他元素。", + "findRangeHighlight": "搜索限制范围的颜色。颜色必须透明,这样不会挡住其下的其他元素。", + "hoverHighlight": "悬停提示显示时文本的高亮颜色。颜色必须透明,这样不会挡住其下的其他元素。", "hoverBackground": "编辑器悬停提示的背景颜色。", "hoverBorder": "光标悬停时编辑器的边框颜色。", "activeLinkForeground": "活动链接颜色。", @@ -76,12 +76,12 @@ "diffEditorRemoved": "被删除文本的背景颜色。", "diffEditorInsertedOutline": "插入的文本的轮廓颜色。", "diffEditorRemovedOutline": "被删除文本的轮廓颜色。", - "mergeCurrentHeaderBackground": "内联合并冲突中当前版本区域的标头背景色。", - "mergeCurrentContentBackground": "内联合并冲突中当前版本区域的内容背景色。", - "mergeIncomingHeaderBackground": "内联合并冲突中传入的版本区域的标头背景色。", - "mergeIncomingContentBackground": "内联合并冲突中传入的版本区域的内容背景色。", - "mergeCommonHeaderBackground": "内联合并冲突中共同祖先区域的标头背景色。", - "mergeCommonContentBackground": "内联合并冲突中共同祖先区域的内容背景色。", + "mergeCurrentHeaderBackground": "内联合并冲突中当前版本区域头部的背景色。颜色必须透明,这样不会挡住其下的其他元素。", + "mergeCurrentContentBackground": "内联合并冲突中当前版本区域内容的背景色。颜色必须透明,这样不会挡住其下的其他元素。", + "mergeIncomingHeaderBackground": "内联合并冲突中传入版本区域头部的背景色。颜色必须透明,这样不会挡住其下的其他元素。", + "mergeIncomingContentBackground": "内联合并冲突中传入版本区域内容的背景色。颜色必须透明,这样不会挡住其下的其他元素。", + "mergeCommonHeaderBackground": "内联合并冲突中共同上级区域头部的背景色。颜色必须透明,这样不会挡住其下的其他元素。", + "mergeCommonContentBackground": "内联合并冲突中共同上级区域内容的背景色。颜色必须透明,这样不会挡住其下的其他元素。", "mergeBorder": "内联合并冲突中标头和分割线的边框颜色。", "overviewRulerCurrentContentForeground": "内联合并冲突中当前版本区域的概览标尺前景色。", "overviewRulerIncomingContentForeground": "内联合并冲突中传入的版本区域的概览标尺前景色。", diff --git a/i18n/chs/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/chs/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..519a8e806a7 --- /dev/null +++ b/i18n/chs/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "saveParticipants": "正在运行保存参与程序..." +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/chs/src/vs/workbench/api/node/extHostTreeViews.i18n.json index 7bfb0b886de..26bd748a8a9 100644 --- a/i18n/chs/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/chs/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "treeView.notRegistered": "没有注册 ID 为“{0}”的树形图。", - "treeItem.notFound": "没有在树中找到 ID 为“{0}”的项目。", - "treeView.duplicateElement": "已注册元素 {0}。" + "treeView.duplicateElement": "ID 为 {0} 的元素已被注册" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/chs/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index 1893d29afa7..c8121010a5a 100644 --- a/i18n/chs/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "切换边栏位置", + "toggleSidebarPosition": "切换边栏位置", "view": "查看" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/chs/src/vs/workbench/browser/actions/workspaceActions.i18n.json index b282efac3d0..0ac87020d7b 100644 --- a/i18n/chs/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "打开文件...", "openFolder": "打开文件夹...", "openFileFolder": "打开...", - "addFolderToWorkspace": "将文件夹添加到工作区...", - "add": "添加(&&A)", - "addFolderToWorkspaceTitle": "将文件夹添加到工作区", "globalRemoveFolderFromWorkspace": "将文件夹从工作区删除…", - "removeFolderFromWorkspace": "将文件夹从工作区删除", - "openFolderSettings": "打开文件夹设置", "saveWorkspaceAsAction": "将工作区另存为...", "save": "保存(&&S)", "saveWorkspace": "保存工作区", "openWorkspaceAction": "打开工作区...", "openWorkspaceConfigFile": "打开工作区配置文件", - "openFolderAsWorkspaceInNewWindow": "在新窗口中将文件夹作为工作区打开", - "workspaceFolderPickerPlaceholder": "选择工作区文件夹" + "openFolderAsWorkspaceInNewWindow": "在新窗口中将文件夹作为工作区打开" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/chs/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..ff43d2fcbf7 --- /dev/null +++ b/i18n/chs/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "将文件夹添加到工作区...", + "add": "添加(&&A)", + "addFolderToWorkspaceTitle": "将文件夹添加到工作区", + "workspaceFolderPickerPlaceholder": "选择工作区文件夹" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index a2f0727f579..d2749a69222 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,18 @@ "groupThreePicker": "在第三组中显示编辑器", "allEditorsPicker": "显示所有已打开的编辑器", "view": "查看", - "file": "文件" + "file": "文件", + "close": "关闭", + "closeOthers": "关闭其他", + "closeRight": "关闭到右侧", + "closeAllUnmodified": "关闭未更改", + "closeAll": "全部关闭", + "keepOpen": "保持打开状态", + "toggleInlineView": "切换内联视图", + "showOpenedEditors": "显示打开的编辑器", + "keepEditor": "保留编辑器", + "closeEditorsInGroup": "关闭组中的所有编辑器", + "closeUnmodifiedEditors": "关闭组中未作更改的编辑器", + "closeOtherEditors": "关闭其他编辑器", + "closeRightEditors": "关闭右侧编辑器" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index dd3e01e846c..1d48cf8bccc 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "关闭编辑器", "revertAndCloseActiveEditor": "还原并关闭编辑器", "closeEditorsToTheLeft": "关闭左侧编辑器", - "closeEditorsToTheRight": "关闭右侧编辑器", "closeAllEditors": "关闭所有编辑器", - "closeUnmodifiedEditors": "关闭组中未作更改的编辑器", "closeEditorsInOtherGroups": "关闭其他组中的编辑器", - "closeOtherEditorsInGroup": "关闭其他编辑器", - "closeEditorsInGroup": "关闭组中的所有编辑器", "moveActiveGroupLeft": "向左移动编辑器组", "moveActiveGroupRight": "向右移动编辑器组", "minimizeOtherEditorGroups": "最小化其他编辑器组", "evenEditorGroups": "编辑器组平均宽度", "maximizeEditor": "最大化编辑器组并隐藏边栏", - "keepEditor": "保留编辑器", "openNextEditor": "打开下一个编辑器", "openPreviousEditor": "打开上一个编辑器", "nextEditorInGroup": "打开组中的下一个编辑器", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "在第一组中显示编辑器", "showEditorsInSecondGroup": "在第二组中显示编辑器", "showEditorsInThirdGroup": "在第三组中显示编辑器", - "showEditorsInGroup": "显示组中的编辑器", "showAllEditors": "显示所有编辑器", "openPreviousRecentlyUsedEditorInGroup": "打开组中上一个最近使用的编辑器", "openNextRecentlyUsedEditorInGroup": "打开组中下一个最近使用的编辑器", @@ -54,5 +48,8 @@ "moveEditorLeft": "向左移动编辑器", "moveEditorRight": "向右移动编辑器", "moveEditorToPreviousGroup": "将编辑器移动到上一组", - "moveEditorToNextGroup": "将编辑器移动到下一组" + "moveEditorToNextGroup": "将编辑器移动到下一组", + "moveEditorToFirstGroup": "将编辑器移动到第一组", + "moveEditorToSecondGroup": "将编辑器移动到第二组", + "moveEditorToThirdGroup": "将编辑器移动到第三组" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 9c9da616c68..94ef2c116b8 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "按标签或按组移动活动编辑器", "editorCommand.activeEditorMove.arg.name": "活动编辑器移动参数", - "editorCommand.activeEditorMove.arg.description": "参数属性:\n\t* \"to\": 提供向何处移动的字符串值。\n\t* \"by\": 提供移动的单位的字符串值。按选项卡或按组。\n\t* \"value\": 提供移动的位置数量或移动到的绝对位置的数字型值。", - "commandDeprecated": "已删除命令 **{0}**。你可以改用 **{1}**", - "openKeybindings": "配置键盘快捷方式" + "editorCommand.activeEditorMove.arg.description": "参数属性:\n\t* \"to\": 提供向何处移动的字符串值。\n\t* \"by\": 提供移动的单位的字符串值。按选项卡或按组。\n\t* \"value\": 提供移动的位置数量或移动到的绝对位置的数字型值。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index 9d821488d27..d5044cab660 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "文本文件比较编辑器。", "navigate.next.label": "下一个更改", "navigate.prev.label": "上一个更改", - "inlineDiffLabel": "切换到内联视图", - "sideBySideDiffLabel": "切换到并行视图" + "toggleIgnoreTrimWhitespace.label": "忽略可裁剪的空白字符" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index 90dedb611fa..d7a330cd5e2 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "关闭", - "closeOthers": "关闭其他", - "closeRight": "关闭到右侧", - "closeAll": "全部关闭", - "closeAllUnmodified": "关闭未更改", - "keepOpen": "保持打开状态", - "showOpenedEditors": "显示打开的编辑器", "araLabelEditorActions": "编辑器操作" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index 452ee0335c5..1b911dc5296 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[不受支持]", + "userIsAdmin": "[管理员]", + "userIsSudo": "[超级用户]", "devExtensionWindowTitlePrefix": "[扩展开发主机]" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/chs/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index e9347e0a6fe..8da27417ba2 100644 --- a/i18n/chs/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/chs/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "hideView": "从侧边栏中隐藏" + "hideView": "隐藏" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/common/theme.i18n.json b/i18n/chs/src/vs/workbench/common/theme.i18n.json index 8ebf8f723db..1b50f1b309f 100644 --- a/i18n/chs/src/vs/workbench/common/theme.i18n.json +++ b/i18n/chs/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "活动选项卡的背景色。在编辑器区域,选项卡是编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", "tabInactiveBackground": "非活动选项卡的背景色。在编辑器区域,选项卡是编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", + "tabHoverBackground": "选项卡被悬停时的背景色。选项卡是编辑器区域中编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", + "tabUnfocusedHoverBackground": "非焦点组选项卡被悬停时的背景色。选项卡是编辑器区域中编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", "tabBorder": "用于将选项卡彼此分隔开的边框。选项卡是编辑器区域中编辑器的容器。可在一个编辑器组中打开多个选项卡。可以存在多个编辑器组。", "tabActiveBorder": "用于高亮活动的选项卡的边框。选项卡是编辑器区域中编辑器的容器。可在一个编辑器组中打开多个选项卡。可以存在多个编辑器组。", "tabActiveUnfocusedBorder": "用于高亮一个失去焦点的编辑器组中的活动选项卡的边框。选项卡是编辑器区域中编辑器的容器。可在一个编辑器组中打开多个选项卡。可以存在多个编辑器组。", + "tabHoverBorder": "选项卡被悬停时用于突出显示的边框。选项卡是编辑器区域中编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", + "tabUnfocusedHoverBorder": "非焦点组选项卡被悬停时用于突出显示的边框。选项卡是编辑器区域中编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", "tabActiveForeground": "活动组中活动选项卡的前景色。在编辑器区域,选项卡是编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", "tabInactiveForeground": "活动组中非活动选项卡的前景色。在编辑器区域,选项卡是编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", "tabUnfocusedActiveForeground": "一个失去焦点的编辑器组中的活动选项卡的前景色。在编辑器区域,选项卡是编辑器的容器。可在一个编辑器组中打开多个选项卡。可以有多个编辑器组。", @@ -16,7 +20,7 @@ "editorGroupBackground": "编辑器组的背景颜色。编辑器组是编辑器的容器。此颜色在拖动编辑器组时显示。", "tabsContainerBackground": "启用选项卡时编辑器组标题的背景颜色。编辑器组是编辑器的容器。", "tabsContainerBorder": "选项卡启用时编辑器组标题的边框颜色。编辑器组是编辑器的容器。", - "editorGroupHeaderBackground": "禁用选项卡时编辑器组标题的背景颜色。编辑器组是编辑器的容器。", + "editorGroupHeaderBackground": "禁用选项卡 (\"workbench.editor.showTabs\": false) 时编辑器组标题颜色。编辑器组是编辑器的容器。", "editorGroupBorder": "将多个编辑器组彼此分隔开的颜色。编辑器组是编辑器的容器。", "editorDragAndDropBackground": "拖动编辑器时的背景颜色。此颜色应有透明度,以便编辑器内容能透过背景。", "panelBackground": "面板的背景色。面板显示在编辑器区域下方,可包含输出和集成终端等视图。", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "当没有打开文件夹时,用来使状态栏与侧边栏、编辑器分隔的状态栏边框颜色。状态栏显示在窗口底部。", "statusBarItemActiveBackground": "单击时的状态栏项背景色。状态栏显示在窗口底部。", "statusBarItemHoverBackground": "悬停时的状态栏项背景色。状态栏显示在窗口底部。", - "statusBarProminentItemBackground": "状态栏突出显示项的背景颜色。突出显示项比状态栏中的其他条目更显眼,表明其重要性更高。状态栏显示在窗口底部。", - "statusBarProminentItemHoverBackground": "状态栏突出显示项在悬停时的背景颜色。突出显示项比状态栏中的其他条目更显眼,表明其重要性更高。状态栏显示在窗口底部。", + "statusBarProminentItemBackground": "状态栏突出显示项的背景颜色。突出显示项比状态栏中的其他条目更醒目以表明其重要性。在命令面板中更改“切换 Tab 键是否移动焦点”可查看示例。状态栏显示在窗口底部。", + "statusBarProminentItemHoverBackground": "状态栏突出显示项在被悬停时的背景颜色。突出显示项比状态栏中的其他条目更醒目以表明其重要性。在命令面板中更改“切换 Tab 键是否移动焦点”可查看示例。状态栏显示在窗口底部。", "activityBarBackground": "活动栏背景色。活动栏显示在最左侧或最右侧,并允许在侧边栏的视图间切换。", "activityBarForeground": "活动栏前景色(例如用于图标)。活动栏显示在最左侧或最右侧,并允许在侧边栏的视图间切换。", "activityBarBorder": "活动栏分隔侧边栏的边框颜色。活动栏显示在最左侧或最右侧,并可以切换侧边栏的视图。", diff --git a/i18n/chs/src/vs/workbench/common/views.i18n.json b/i18n/chs/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..85f57daaba0 --- /dev/null +++ b/i18n/chs/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "ID 为“{0}”的视图在位置“{1}”已被注册" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/chs/src/vs/workbench/electron-browser/actions.i18n.json index 24ec2fcb7bd..f941d8a0956 100644 --- a/i18n/chs/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/chs/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "关闭编辑器", "closeWindow": "关闭窗口", "closeWorkspace": "关闭工作区", "noWorkspaceOpened": "此实例当前没有打开工作区,无法关闭。", @@ -52,21 +51,5 @@ "displayLanguage": "定义 VSCode 的显示语言。", "doc": "请参阅 {0},了解支持的语言列表。", "restart": "更改此值需要重启 VSCode。", - "fail.createSettings": "无法创建“{0}”({1})。", - "openLogsFolder": "打开日志文件夹", - "showLogs": "显示日志...", - "mainProcess": "主进程", - "sharedProcess": "共享进程", - "rendererProcess": "渲染器进程", - "extensionHost": "扩展主机", - "selectProcess": "选择进程", - "setLogLevel": "设置日志级别", - "trace": "跟踪", - "debug": "调试", - "info": "信息", - "warn": "警告", - "err": "错误", - "critical": "关键", - "off": "关闭", - "selectLogLevel": "选择日志级别" + "fail.createSettings": "无法创建“{0}”({1})。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/chs/src/vs/workbench/electron-browser/main.contribution.i18n.json index e93318a00b8..62b6aada113 100644 --- a/i18n/chs/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "查看", "help": "帮助", "file": "文件", - "developer": "开发者", "workspaces": "工作区", + "developer": "开发者", + "workbenchConfigurationTitle": "工作台", "showEditorTabs": "控制打开的编辑器是否显示在选项卡中。", "workbench.editor.labelFormat.default": "显示文件名。当启用选项卡且在同一组内有两个相同名称的文件时,将添加每个文件路径中可以用于区分的部分。在选项卡被禁用且编辑器活动时,将显示相对于工作区文件夹的路径。", "workbench.editor.labelFormat.short": "在文件的目录名之后显示文件名。", @@ -20,23 +21,23 @@ "showIcons": "控制打开的编辑器是否随图标一起显示。这还需启用图标主题。", "enablePreview": "控制是否将打开的编辑器显示为预览。预览编辑器将会重用至其被保留(例如,通过双击或编辑),且其字体样式将为斜体。", "enablePreviewFromQuickOpen": "控制 Quick Open 中打开的编辑器是否显示为预览。预览编辑器可以重新使用,直到将其保留(例如,通过双击或编辑)。", + "closeOnFileDelete": "控制文件被其他某些进程删除或重命名时是否应该自动关闭显示文件的编辑器。禁用此项会保持编辑器作为此类事件的脏文件打开。请注意,从应用程序内部进行删除操作会始终关闭编辑器,并且脏文件始终不会关闭以保存数据。", "editorOpenPositioning": "控制打开编辑器的位置。选择“左侧”或“右侧”以在当前活动位置的左侧或右侧打开编辑器。选择“第一个”或“最后一个”以从当前活动位置独立打开编辑器。", "revealIfOpen": "控制打开时编辑器是否显示在任何可见组中。如果禁用,编辑器会优先在当前活动编辑器组中打开。如果启用,会显示已打开的编辑器而不是在当前活动编辑器组中再次打开。请注意,有些情况下会忽略此设置,例如强制编辑器在特定组中或在当前活动组的边侧打开时。", + "swipeToNavigate": "使用三指横扫在打开的文件之间导航", "commandHistory": "控制命令面板中保留最近使用命令的数量。设置为 0 时禁用命令历史功能。", "preserveInput": "控制是否在再次打开命令面板时恢复上一次的输入内容。", "closeOnFocusLost": "控制 Quick Open 是否应在失去焦点时自动关闭。", "openDefaultSettings": "控制打开设置时是否打开显示所有默认设置的编辑器。", "sideBarLocation": "控制边栏的位置。它可显示在工作台的左侧或右侧。", + "panelDefaultLocation": "控制此面板的默认位置。可显示在工作台的底部或右侧。", "statusBarVisibility": "控制工作台底部状态栏的可见性。", "activityBarVisibility": "控制工作台中活动栏的可见性。", - "closeOnFileDelete": "控制文件被其他某些进程删除或重命名时是否应该自动关闭显示文件的编辑器。禁用此项会保持编辑器作为此类事件的脏文件打开。请注意,从应用程序内部进行删除操作会始终关闭编辑器,并且脏文件始终不会关闭以保存数据。", - "enableNaturalLanguageSettingsSearch": "控制是否在设置中启用自然语言搜索模式。", "fontAliasing": "控制工作台中字体的渲染方式\n- default: 次像素平滑字体。将在大多数非 retina 显示器上显示最清晰的文字\n- antialiased: 进行像素而不是次像素级别的字体平滑。可能会导致字体整体显示得更细\n- none: 禁用字体平滑。将显示边缘粗糙、有锯齿的文字", "workbench.fontAliasing.default": "次像素平滑字体。将在大多数非 retina 显示器上显示最清晰的文字。", "workbench.fontAliasing.antialiased": "进行像素而不是次像素级别的字体平滑。可能会导致字体整体显示得更细。", "workbench.fontAliasing.none": "禁用字体平滑。将显示边缘粗糙、有锯齿的文字。", - "swipeToNavigate": "使用三指横扫在打开的文件之间导航", - "workbenchConfigurationTitle": "工作台", + "enableNaturalLanguageSettingsSearch": "控制是否在设置中启用自然语言搜索模式。", "windowConfigurationTitle": "窗口", "window.openFilesInNewWindow.on": "文件将在新窗口中打开", "window.openFilesInNewWindow.off": "文件将在该文件的文件夹打开的窗口中打开,或在上一个活动窗口中打开", diff --git a/i18n/chs/src/vs/workbench/electron-browser/window.i18n.json b/i18n/chs/src/vs/workbench/electron-browser/window.i18n.json index b2c1d0e6763..a2e4b30b59e 100644 --- a/i18n/chs/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/chs/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "剪切", "copy": "复制", "paste": "粘贴", - "selectAll": "全选" + "selectAll": "全选", + "runningAsRoot": "不建议以 root 用户身份运行 {0}。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/chs/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index fd9702e842b..97d6fae2b3f 100644 --- a/i18n/chs/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "调试工具栏背景颜色。" + "debugToolBarBackground": "调试工具栏背景颜色。", + "debugToolBarBorder": "调试工具栏边框颜色。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/chs/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 3fee2b4ab47..0fa0e030ff2 100644 --- a/i18n/chs/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "调试对象", - "debug.terminal.not.available.error": "集成终端不可用" + "debug.terminal.title": "调试对象" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index f54abac52da..2db5cdad108 100644 --- a/i18n/chs/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "打开新命令提示符", "globalConsoleActionMacLinux": "打开新终端", "scopedConsoleActionWin": "在命令提示符中打开", - "scopedConsoleActionMacLinux": "在终端中打开", - "openFolderInIntegratedTerminal": "在终端中打开" + "scopedConsoleActionMacLinux": "在终端中打开" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index efe5507494d..325749e3e0c 100644 --- a/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,17 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "根据您最近打开的文件推荐此扩展。", + "neverShowAgain": "不再显示", + "close": "关闭", "workspaceRecommendation": "当前工作区的用户推荐此扩展。", + "fileBasedRecommendation": "根据您最近打开的文件推荐此扩展。", "exeBasedRecommendation": "根据你安装的 {0},向你推荐此扩展。", "reallyRecommended2": "建议对这种类型的文件使用“{0}”扩展。", "reallyRecommendedExtensionPack": "建议对这种类型的文件使用“{0}”扩展包。", "showRecommendations": "显示建议", "install": "安装", - "neverShowAgain": "不再显示", - "close": "关闭", + "showLanguageExtensions": "商店中有可以对 \".{0}\" 文件提供帮助的扩展。", + "searchMarketplace": "搜索应用商店", "workspaceRecommended": "此工作区具有扩展建议。", "installAll": "全部安装", "ignoreExtensionRecommendations": "你是否要忽略所有推荐的扩展?", diff --git a/i18n/chs/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.i18n.json b/i18n/chs/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.i18n.json index 93fab46db22..d11701056cf 100644 --- a/i18n/chs/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.i18n.json @@ -4,6 +4,9 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "installingVSIXExtension": "从 VSIX 安装扩展...", + "installingMarketPlaceExtension": "正在从应用商店安装扩展...", + "uninstallingExtension": "正在卸载扩展...", "enableDependeciesConfirmation": "启用“{0}”也会启用其依赖项。是否要继续?", "enable": "是", "doNotEnable": "否", diff --git a/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..475d836e696 --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "工作台", + "feedbackVisibility": "控制是否显示工作台底部状态栏中的 Twitter 反馈 (笑脸图标)。" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json b/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json index a2b15babb5f..84925c604c1 100644 --- a/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json @@ -16,6 +16,7 @@ "request a missing feature": "请求缺失功能", "tell us why?": "告诉我们原因?", "commentsHeader": "注释", + "showFeedback": "在状态栏中显示反馈笑脸图标", "tweet": "Tweet", "character left": "剩余字符", "characters left": "剩余字符", diff --git a/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..c5b0fd0e5a5 --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "hide": "隐藏" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 30c68b4c7ad..93681537820 100644 --- a/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,27 @@ "filesCategory": "文件", "revealInSideBar": "在侧边栏中显示", "acceptLocalChanges": "使用你的更改并覆盖磁盘上的内容。", - "revertLocalChanges": "放弃你的更改并还原为磁盘上的内容" + "revertLocalChanges": "放弃你的更改并还原为磁盘上的内容", + "copyPathOfActive": "复制活动文件的路径", + "saveAllInGroup": "保存组中的全部内容", + "saveFiles": "保存所有文件", + "revert": "还原文件", + "compareActiveWithSaved": "比较活动与已保存的文件", + "closeEditor": "关闭编辑器", + "view": "查看", + "openToSide": "打开到侧边", + "revealInWindows": "在资源管理器中显示", + "revealInMac": "在 Finder 中显示", + "openContainer": "打开所在的文件夹", + "copyPath": "复制路径", + "saveAll": "全部保存", + "compareWithSaved": "与已保存文件比较", + "compareWithSelected": "与已选项目进行比较", + "compareSource": "选择以进行比较", + "compareSelected": "将已选项进行比较", + "close": "关闭", + "closeOthers": "关闭其他", + "closeUnmodified": "关闭未更改", + "closeAll": "全部关闭", + "deleteFile": "永久删除" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index f9208415003..513e4e1f0d7 100644 --- a/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "重试", - "rename": "重命名", "newFile": "新建文件", "newFolder": "新建文件夹", + "rename": "重命名", + "delete": "删除", + "copyFile": "复制", + "pasteFile": "粘贴", + "retry": "重试", "openFolderFirst": "先打开一个文件夹,以在其中创建文件或文件夹。", "newUntitledFile": "新的无标题文件", "createNewFile": "新建文件", @@ -15,39 +18,32 @@ "deleteButtonLabelRecycleBin": "移动到回收站(&&M)", "deleteButtonLabelTrash": "移动到回收站(&&M)", "deleteButtonLabel": "删除(&&D)", + "dirtyMessageFilesDelete": "你删除的文件中具有未保存的更改。是否继续?", "dirtyMessageFolderOneDelete": "你正在删除的文件夹有 1 个文件具有未保存的更改。是否继续?", "dirtyMessageFolderDelete": "你正在删除的文件夹有 {0} 个文件具有未保存的更改。是否继续?", "dirtyMessageFileDelete": "你正在删除的文件具有未保存的更改。是否继续?", "dirtyWarning": "如果不保存,更改将丢失。", + "confirmMoveTrashMessageMultiple": "是否确定要删除以下 {0} 个文件?", "confirmMoveTrashMessageFolder": "是否确实要删除“{0}”及其内容?", "confirmMoveTrashMessageFile": "是否确实要删除“{0}”?", "undoBin": "可以从回收站还原。", "undoTrash": "可以从回收站还原。", "doNotAskAgain": "不再询问", + "confirmDeleteMessageMultiple": "是否确定要永久删除以下 {0} 个文件?", "confirmDeleteMessageFolder": "是否确定要永久删除“{0}”及其内容?", "confirmDeleteMessageFile": "是否确定要永久删除“{0}”?", "irreversible": "此操作不可逆!", "permDelete": "永久删除", - "delete": "删除", "importFiles": "导入文件", "confirmOverwrite": "目标文件夹中已存在具有相同名称的文件或文件夹。是否要替换它?", "replaceButtonLabel": "替换(&&R)", - "copyFile": "复制", - "pasteFile": "粘贴", + "fileDeleted": "文件已被删除或移动", + "fileIsAncestor": "复制的项目是目标文件夹的上级", "duplicateFile": "重复", - "openToSide": "打开到侧边", - "compareSource": "选择以进行比较", "globalCompareFile": "比较活动文件与...", "openFileToCompare": "首先打开文件以将其与另外一个文件比较。", - "compareWith": "将“{0}”与“{1}”比较", - "compareFiles": "比较文件", "refresh": "刷新", - "save": "保存", - "saveAs": "另存为...", - "saveAll": "全部保存", "saveAllInGroup": "保存组中的全部内容", - "saveFiles": "保存所有文件", - "revert": "还原文件", "focusOpenEditors": "专注于“打开的编辑器”视图", "focusFilesExplorer": "关注文件资源浏览器", "showInExplorer": "在侧边栏中显示活动文件", @@ -56,20 +52,11 @@ "refreshExplorer": "刷新资源管理器", "openFileInNewWindow": "在新窗口中打开活动文件", "openFileToShowInNewWindow": "请先打开要在新窗口中打开的文件", - "revealInWindows": "在资源管理器中显示", - "revealInMac": "在 Finder 中显示", - "openContainer": "打开所在的文件夹", - "revealActiveFileInWindows": "Windows 资源管理器中显示活动文件", - "revealActiveFileInMac": "在 Finder 中显示活动文件", - "openActiveFileContainer": "打开活动文件所在的文件夹", "copyPath": "复制路径", - "copyPathOfActive": "复制活动文件的路径", "emptyFileNameError": "必须提供文件或文件夹名。", "fileNameExistsError": "此位置已存在文件或文件夹 **{0}**。请选择其他名称。", "invalidFileNameError": "名称 **{0}** 作为文件或文件夹名无效。请选择其他名称。", "filePathTooLongError": "名称 **{0}** 导致路径太长。请选择更短的名称。", - "compareWithSaved": "比较活动与已保存的文件", - "modifiedLabel": "{0} (磁盘上) ↔ {1}", "compareWithClipboard": "比较活动文件与剪贴板", "clipboardComparisonLabel": "剪贴板 ↔ {0}" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index 702c021c5f3..e9a10faa823 100644 --- a/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "首先打开文件以复制其路径", - "openFileToReveal": "首先打开文件以展现" + "revealInWindows": "在资源管理器中显示", + "revealInMac": "在 Finder 中显示", + "openContainer": "打开所在的文件夹", + "saveAs": "另存为...", + "save": "保存", + "saveAll": "全部保存", + "removeFolderFromWorkspace": "将文件夹从工作区删除", + "genericRevertError": "未能还原“{0}”: {1}", + "modifiedLabel": "{0} (磁盘上) ↔ {1}", + "openFileToReveal": "首先打开文件以展现", + "openFileToCopy": "首先打开文件以复制其路径" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 63427668f5f..1d8701fe103 100644 --- a/i18n/chs/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,7 @@ "editorConfigurationTitle": "编辑器", "formatOnSave": "保存时设置文件的格式。格式化程序必须可用,不能自动保存文件,并且不能关闭编辑器。", "explorerConfigurationTitle": "文件资源管理器", - "openEditorsVisible": "在“打开的编辑器”窗格中显示的编辑器数量。将其设置为 0 可隐藏窗格。", - "dynamicHeight": "控制打开的编辑器部分的高度是否应动态适应元素数量。", + "openEditorsVisible": "在“打开的编辑器”窗格中显示的编辑器数量。", "autoReveal": "控制资源管理器是否应在打开文件时自动显示并选择它们。", "enableDragAndDrop": "控制资源管理器是否应该允许通过拖放移动文件和文件夹。", "confirmDragAndDrop": "控制在资源管理器内拖放移动文件或文件夹时是否进行确认。", diff --git a/i18n/chs/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/chs/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 8ebee88ce98..4911cddc49b 100644 --- a/i18n/chs/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,14 @@ // Do not edit this file. It is machine generated. { "userGuide": "使用右侧编辑器工具栏的操作来**撤消**你的更改或用你的更改来**覆盖**磁盘上的内容", - "discard": "放弃", + "overwriteElevated": "以管理员身份覆盖...", + "saveElevated": "以管理员身份重试...", "overwrite": "覆盖", "retry": "重试", - "readonlySaveError": "无法保存“{0}”: 文件写保护。选择“覆盖”以删除保护。 ", + "discard": "放弃", + "readonlySaveErrorAdmin": "无法保存“{0}”: 文件写保护。选择“以管理员身份覆盖”可作为管理员重试。 ", + "readonlySaveError": "无法保存“{0}”: 文件写保护。选择“覆盖”可尝试移除保护。", + "permissionDeniedSaveError": "无法保存“{0}”: 权限不足。选择“以管理员身份覆盖”可作为管理员重试。", "genericSaveError": "未能保存“{0}”: {1}", "staleSaveError": "无法保存“{0}”: 磁盘上的内容较新。单击 **比较** 以比较你的版本和磁盘上的版本。", "compareChanges": "比较", diff --git a/i18n/chs/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json b/i18n/chs/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json index d97098d02f7..0be09e75862 100644 --- a/i18n/chs/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json @@ -10,6 +10,7 @@ "dropFolder": "你是否要将文件夹添加到工作区?", "addFolders": "添加文件夹(&&A)", "addFolder": "添加文件夹(&&A)", + "confirmMultiMove": "是否确定要移动以下 {0} 个文件?", "confirmMove": "是否确实要移动“{0}”?", "doNotAskAgain": "不再询问", "moveButtonLabel": "移动(&&M)", diff --git a/i18n/chs/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/chs/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index 0c93f41d44d..f501bedc60f 100644 --- a/i18n/chs/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "打开的编辑器", "openEditosrSection": "打开的编辑器部分", - "dirtyCounter": "{0} 个未保存", - "saveAll": "全部保存", - "closeAllUnmodified": "关闭未更改", - "closeAll": "全部关闭", - "compareWithSaved": "与已保存文件比较", - "close": "关闭", - "closeOthers": "关闭其他" + "dirtyCounter": "{0} 个未保存" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..605730c3691 --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "mainLog": "日志(主进程)", + "sharedLog": "日志(共享进程)", + "rendererLog": "日志(窗口进程)", + "extensionsLog": "日志(扩展主机)", + "developer": "开发者" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/chs/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..66dcbba199b --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "打开日志文件夹", + "showLogs": "显示日志...", + "mainProcess": "主进程", + "sharedProcess": "共享进程", + "rendererProcess": "窗口", + "extensionHost": "扩展主机", + "selectProcess": "选择进程", + "openLogFile": "打开日志文件...", + "setLogLevel": "设置日志级别", + "trace": "跟踪", + "debug": "调试", + "info": "信息", + "warn": "警告", + "err": "错误", + "critical": "严重", + "off": "关闭", + "selectLogLevel": "选择日志级别" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/chs/src/vs/workbench/parts/markers/common/messages.i18n.json index 3e34c78c26a..8f40a40df02 100644 --- a/i18n/chs/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "viewCategory": "查看", - "problems.view.toggle.label": "切换显示问题视图", - "problems.view.focus.label": "聚焦于问题视图", + "problems.view.toggle.label": "切换问题 (错误、警告、信息) 视图", + "problems.view.focus.label": "聚焦于问题 (错误、警告、信息) 视图", "problems.panel.configuration.title": "问题预览", "problems.panel.configuration.autoreveal": "控制问题预览是否应在打开文件时自动显示它们。", "markers.panel.title.problems": "问题", diff --git a/i18n/chs/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..8942e4d51b6 --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "输出", + "logViewer": "日志查看器", + "viewCategory": "查看", + "clearOutput.label": "清除输出" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/chs/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..9d92ce92cd2 --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "{0} - 输出", + "channel": "“{0}”的输出通道" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json b/i18n/chs/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json index 34f4d8ea701..2ddff381a9b 100644 --- a/i18n/chs/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json @@ -17,6 +17,7 @@ "resetLabel": "重置键绑定", "showConflictsLabel": "显示冲突", "copyLabel": "复制", + "copyCommandLabel": "拷贝命令", "error": "编辑键绑定时发生错误“{0}”。请打开 \"keybindings.json\" 文件并检查。", "command": "命令", "keybinding": "键绑定", diff --git a/i18n/chs/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json b/i18n/chs/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json index c40e2e7cf77..56b8e2afaaf 100644 --- a/i18n/chs/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json @@ -11,6 +11,8 @@ "oneSettingFound": "1 个设置匹配", "settingsFound": "{0} 个设置匹配", "totalSettingsMessage": "总计 {0} 个设置", + "nlpResult": "自然语言结果", + "filterResult": "筛选结果", "defaultSettings": "默认设置", "defaultFolderSettings": "默认文件夹设置", "defaultEditorReadonly": "在右侧编辑器中编辑以覆盖默认值。", diff --git a/i18n/chs/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/chs/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index 5c28c560886..10c2fc221a5 100644 --- a/i18n/chs/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "试试自然语言搜索!", "defaultSettings": "将您的设置放入右侧编辑器以覆盖。", "noSettingsFound": "未找到设置。", "settingsSwitcherBarAriaLabel": "设置转换器", "userSettings": "用户设置", "workspaceSettings": "工作区设置", - "folderSettings": "文件夹设置", - "enableFuzzySearch": "启用自然语言搜索" + "folderSettings": "文件夹设置" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/chs/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index 26f355bb382..ef307afdfbd 100644 --- a/i18n/chs/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "常用设置", - "mostRelevant": "最相关", "defaultKeybindingsHeader": "通过将键绑定放入键绑定文件中来覆盖键绑定。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index 4fff98737e8..0f609a35000 100644 --- a/i18n/chs/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "查看", "commandsHandlerDescriptionDefault": "显示并运行命令", "gotoLineDescriptionMac": "转到行", "gotoLineDescriptionWin": "转到行", diff --git a/i18n/chs/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index cc08da73602..ebf378aac85 100644 --- a/i18n/chs/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,9 @@ "toggleGitViewlet": "显示 Git", "source control": "源代码管理", "toggleSCMViewlet": "显示源代码管理", - "view": "查看" + "view": "查看", + "scmConfigurationTitle": "源代码管理", + "alwaysShowProviders": "是否总是显示源代码管理提供程序部分。", + "diffDecorations": "控制编辑器中差异的显示效果。", + "inputCounter": "控制何时显示输入计数。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json b/i18n/chs/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json index eb08e1a3030..dc3530badc8 100644 --- a/i18n/chs/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json @@ -6,6 +6,9 @@ { "scm providers": "源代码管理提供程序", "hideRepository": "隐藏", + "commitMessageInfo": "当前行有 {0} 个字符", + "commitMessageCountdown": "当前行剩余 {0} 个字符", + "commitMessageWarning": "当前行比 {1} 超出 {0} 个字符", "installAdditionalSCMProviders": "安装其他源代码管理提供程序...", "no open repo": "没有活动的源代码管理提供程序。", "source control": "源代码管理", diff --git a/i18n/chs/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/chs/src/vs/workbench/parts/search/browser/searchActions.i18n.json index ebf392aa07d..65d9e1b855d 100644 --- a/i18n/chs/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "显示上一个搜索词", "showSearchViewlet": "显示搜索", "findInFiles": "在文件中查找", - "findInFilesWithSelectedText": "在文件中查找所选文本", "replaceInFiles": "在文件中替换", - "replaceInFilesWithSelectedText": "在文件中替换所选文本", "RefreshAction.label": "刷新", "CollapseDeepestExpandedLevelAction.label": "全部折叠", "ClearSearchResultsAction.label": "清除", diff --git a/i18n/chs/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index 971f3dddcce..b75ed7a9817 100644 --- a/i18n/chs/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "在文件夹中查找...", + "findInWorkspace": "在工作区中查找...", "showTriggerActions": "转到工作区中的符号...", "name": "搜索", "search": "搜索", + "showSearchViewlet": "显示搜索", "view": "查看", + "findInFiles": "在文件中查找", "openAnythingHandlerDescription": "转到文件", "openSymbolDescriptionNormal": "转到工作区中的符号", "searchOutputChannelTitle": "搜索", @@ -18,5 +22,6 @@ "useRipgrep": "控制是否在文本和文件搜索中使用 ripgrep", "useIgnoreFiles": "控制搜索文件时是否使用 .gitignore 和 .ignore 文件。", "search.quickOpen.includeSymbols": "配置为在 Quick Open 文件结果中包括全局符号搜索的结果。", - "search.followSymlinks": "控制是否在搜索中跟踪符号链接。" + "search.followSymlinks": "控制是否在搜索中跟踪符号链接。", + "search.smartCase": "若搜索词全为小写,则不区分大小写进行搜索,否则区分大小写进行搜索" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..b6d24a6f921 --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.scope": "(全局)", + "global.1": "({0})", + "new.global": "新建全局代码片段文件...", + "group.global": "现有代码片段", + "new.global.sep": "新代码片段", + "openSnippet.pickLanguage": "选择代码片段文件或创建代码片段", + "openSnippet.label": "配置用户代码片段", + "preferences": "首选项" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 6023eaf614f..84c29334b81 100644 --- a/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,13 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "选择代码片段的语言", - "openSnippet.errorOnCreate": "无法创建 {0}", - "openSnippet.label": "打开用户代码段", - "preferences": "首选项", "snippetSchema.json.default": "空代码片段", "snippetSchema.json": "用户代码片段配置", "snippetSchema.json.prefix": "在 Intellisense 中选择代码片段时将使用的前缀", "snippetSchema.json.body": "代码片段的内容。使用“$1”和“${1:defaultText}”定义光标位置,使用“$0”定义最终光标位置。使用“${varName}”和“${varName:defaultText}”插入变量值,例如“这是文件:$TM_FILENAME”。", - "snippetSchema.json.description": "代码片段描述。" + "snippetSchema.json.description": "代码片段描述。", + "snippetSchema.json.scope": "此代码片段适用语言的名称列表,例如 \"typescript,javascript\"。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..bfcf4616bc8 --- /dev/null +++ b/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "用户代码片段" +} \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index e4e7302f246..7c00034a89a 100644 --- a/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "“contributes.{0}.language”中存在未知的语言。提供的值: {1}", "invalid.path.0": "“contributes.{0}.path”中应为字符串。提供的值: {1}", + "invalid.language.0": "省略语言时,\"contributes.{0}.path\" 的值必须为一个 \".code-snippets\" 文件。提供的值: {1}", + "invalid.language": "“contributes.{0}.language”中存在未知的语言。提供的值: {1}", "invalid.path.1": "“contributes.{0}.path”({1})应包含在扩展的文件夹({2})内。这可能会使扩展不可移植。", "vscode.extension.contributes.snippets": "添加代码段。", "vscode.extension.contributes.snippets-language": "此代码片段参与的语言标识符。", "vscode.extension.contributes.snippets-path": "代码片段文件的路径。该路径相对于扩展文件夹,通常以 \"./snippets/\" 开头。", "badVariableUse": "扩展“{0}”中的一个或多个代码片段很可能混淆了片段变量和片段占位符 (有关详细信息,请访问 https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax )", "badFile": "无法读取代码片段文件“{0}”。", - "source.snippet": "用户代码片段", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0},{1}" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index 75d151b4bb5..199139684a9 100644 --- a/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -14,6 +14,7 @@ "terminal.integrated.shell.windows": "终端在 Windows 使用的 shell 路径。使用随 Windows 一起提供的 shell (cmd、PowerShell 或 Bash on Ubuntu) 时。", "terminal.integrated.shellArgs.windows": "在 Windows 终端上时使用的命令行参数。", "terminal.integrated.rightClickCopyPaste": "设置后,在终端内右键单击时,这将阻止显示上下文菜单,相反,它将在有选项时进行复制,并且在没有选项时进行粘贴。", + "terminal.integrated.copyOnSelection": "设置后,终端中选中的文字将被复制到剪贴板。", "terminal.integrated.fontFamily": "控制终端的字体系列,这在编辑器中是默认的。fontFamily 的值。", "terminal.integrated.fontSize": "控制终端的字号(以像素为单位)。", "terminal.integrated.lineHeight": "控制终端的行高,此数字乘上终端字号得到实际行高(以像素为单位)。", @@ -24,10 +25,12 @@ "terminal.integrated.setLocaleVariables": "控制是否在终端启动时设置区域设置变量,在 OS X 上默认设置为 true,在其他平台上为 false。", "terminal.integrated.cwd": "将在其中启动终端的一个显式起始路径,它用作 shell 进程的当前工作目录(cwd)。当根目录为不方便的 cwd 时,此路径在工作区设置中可能十分有用。", "terminal.integrated.confirmOnExit": "在存在活动终端会话的情况下,退出时是否要确认。", + "terminal.integrated.enableBell": "是否启用终端响铃。", "terminal.integrated.commandsToSkipShell": "一组命令 ID,其键绑定不发送到 shell 而始终由 Code 处理。这使得通常由 shell 使用的键绑定的使用效果与未将终端设为焦点时相同,例如按 Ctrl+P 启动 Quick Open。", "terminal.integrated.env.osx": "要添加到 VS Code 进程中的带有环境变量的对象,其会被 OS X 终端使用。", "terminal.integrated.env.linux": "要添加到 VS Code 进程中的带有环境变量的对象,其会被 Linux 终端使用。", "terminal.integrated.env.windows": "要添加到 VS Code 进程中的带有环境变量的对象,其会被 Windows 终端使用。", + "terminal.integrated.showExitAlert": "当退出代码非零时,显示“终端进程以某退出代码终止”的警告。", "terminalCategory": "终端", "viewCategory": "查看" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json b/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json index d96d23dca0e..6db35403434 100644 --- a/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json @@ -12,8 +12,11 @@ "workbench.action.terminal.selectAll": "全选", "workbench.action.terminal.deleteWordLeft": "删除左侧的字符", "workbench.action.terminal.deleteWordRight": "删除右侧的字符", + "workbench.action.terminal.enterLineNavigationMode": "进入按行导航模式", "workbench.action.terminal.new": "新建集成终端", "workbench.action.terminal.new.short": "新的终端", + "workbench.action.terminal.newWorkspacePlaceholder": "选择当前工作目录新建终端", + "workbench.action.terminal.newInActiveWorkspace": "新建集成终端 (活动工作区)", "workbench.action.terminal.focus": "聚焦于终端", "workbench.action.terminal.focusNext": "聚焦于下一终端", "workbench.action.terminal.focusPrevious": "聚焦于上一终端", diff --git a/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index 25d612371f7..feb3b9cc8cc 100644 --- a/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,7 @@ "terminal.integrated.chooseWindowsShellInfo": "可通过选择“自定义”按钮来更改默认的终端 shell。", "customize": "自定义", "cancel": "取消", - "never again": "我已了解,不再提示", + "never again": "确定,且不再显示", "terminal.integrated.chooseWindowsShell": "选择首选的终端 shell,你可稍后在设置中进行更改", "terminalService.terminalCloseConfirmationSingular": "存在一个活动的终端会话,是否要终止此会话?", "terminalService.terminalCloseConfirmationPlural": "存在 {0} 个活动的终端会话,是否要终止这些会话?" diff --git a/i18n/chs/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/chs/src/vs/workbench/parts/update/electron-browser/update.i18n.json index d43fc9ca29b..9460987e42b 100644 --- a/i18n/chs/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -23,6 +23,7 @@ "commandPalette": "命令面板...", "settings": "设置", "keyboardShortcuts": "键盘快捷方式", + "userSnippets": "用户代码片段", "selectTheme.label": "颜色主题", "themes.selectIconTheme.label": "文件图标主题", "not available": "更新不可用", diff --git a/i18n/chs/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/chs/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 80b697be3d3..fdbcd8bad77 100644 --- a/i18n/chs/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/chs/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "文件是目录", + "fileNotModifiedError": "自以下时间未修改的文件:", "fileBinaryError": "文件似乎是二进制文件,无法作为文档打开" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/services/files/node/fileService.i18n.json b/i18n/chs/src/vs/workbench/services/files/node/fileService.i18n.json index b385a7a0f15..234d233e533 100644 --- a/i18n/chs/src/vs/workbench/services/files/node/fileService.i18n.json +++ b/i18n/chs/src/vs/workbench/services/files/node/fileService.i18n.json @@ -10,6 +10,7 @@ "fileTooLargeError": "文件太大,无法打开", "fileNotFoundError": "找不到文件({0})", "fileBinaryError": "文件似乎是二进制文件,无法作为文档打开", + "filePermission": "写入文件时权限被拒绝 ({0})", "fileExists": "已存在要创建的文件 ({0})", "fileMoveConflict": "无法移动/复制。文件已存在于目标位置。", "unableToMoveCopyError": "无法移动/复制。文件将替换其所在的文件夹。", diff --git a/i18n/chs/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json b/i18n/chs/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json index af87ffb3672..6b16deb483d 100644 --- a/i18n/chs/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json +++ b/i18n/chs/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json @@ -22,5 +22,6 @@ "keybindings.json.when": "键处于活动状态时的条件。", "keybindings.json.args": "要传递给命令以执行的参数。", "keyboardConfigurationTitle": "键盘", - "dispatch": "控制按键的分派逻辑以使用 \"code\" (推荐) 或 \"keyCode\"。" + "dispatch": "控制按键的分派逻辑以使用 \"code\" (推荐) 或 \"keyCode\"。", + "touchbar.enabled": "启用键盘上的 macOS 触控栏按钮 (若可用)。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/chs/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index 6bee4318397..ba2101635d0 100644 --- a/i18n/chs/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/chs/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "是否要保存对 {0} 的更改?", "saveChangesMessages": "是否要保存对下列 {0} 个文件的更改?", - "moreFile": "...1 个其他文件未显示", - "moreFiles": "...{0} 个其他文件未显示", "saveAll": "全部保存(&&S)", "save": "保存(&&S)", "dontSave": "不保存(&&N)", diff --git a/i18n/chs/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/chs/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index af35cdf722b..fbf48931d61 100644 --- a/i18n/chs/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/chs/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "无文件图标", "iconThemeError": "文件图标主题未知或未安装。", "workbenchColors": "覆盖当前所选颜色主题的颜色。", - "editorColors": "覆盖当前所选颜色主题中的编辑器颜色和字体样式。", "editorColors.comments": "设置注释的颜色和样式", "editorColors.strings": "设置字符串文本的颜色和样式", "editorColors.keywords": "设置关键字的颜色和样式。", @@ -19,5 +18,6 @@ "editorColors.types": "设置类型定义与引用的颜色和样式。", "editorColors.functions": "设置函数定义与引用的颜色和样式。", "editorColors.variables": "设置变量定义和引用的颜色和样式。", - "editorColors.textMateRules": "使用 TextMate 主题规则设置颜色和样式(高级)。" + "editorColors.textMateRules": "使用 TextMate 主题规则设置颜色和样式(高级)。", + "editorColors": "覆盖当前所选颜色主题中的编辑器颜色和字体样式。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/chs/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 11ecec6e1ac..b9142ec415a 100644 --- a/i18n/chs/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/chs/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "无法写入工作区配置文件。请打开文件以更正错误或警告,然后重试。", "errorWorkspaceConfigurationFileDirty": "文件已变更,因此无法写入工作区配置文件。请先保存此文件,然后重试。", "openWorkspaceConfigurationFile": "打开工作区配置文件", - "close": "关闭", - "enterWorkspace.close": "关闭", - "enterWorkspace.dontShowAgain": "不再显示", - "enterWorkspace.moreInfo": "详细信息", - "enterWorkspace.prompt": "了解有关在 VS Code 中使用多个文件夹的详细信息。" + "close": "关闭" } \ No newline at end of file diff --git a/i18n/cht/extensions/git/out/autofetch.i18n.json b/i18n/cht/extensions/git/out/autofetch.i18n.json index 78cd65caa1f..a9b802babec 100644 --- a/i18n/cht/extensions/git/out/autofetch.i18n.json +++ b/i18n/cht/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "是", + "read more": "閱讀其他資訊", "no": "否", - "not now": "不是現在", - "suggest auto fetch": "是否啟用 Git 儲存庫的自動擷取?" + "not now": "稍後詢問我", + "suggest auto fetch": "您想要 Code 定期的執行 `git fetch` 嗎?" } \ No newline at end of file diff --git a/i18n/cht/extensions/git/out/commands.i18n.json b/i18n/cht/extensions/git/out/commands.i18n.json index 1ace18f1610..3362f487b3c 100644 --- a/i18n/cht/extensions/git/out/commands.i18n.json +++ b/i18n/cht/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\n這項動作無法復原,您會永久失去目前的工作集。", "yes discard tracked": "捨棄 1 個追蹤的檔案", "yes discard tracked multiple": "捨棄 {0} 個追蹤的檔案", + "unsaved files single": "下列檔案尚未儲存: {0}。\n\n您要在認可之前進行儲存嗎?", + "unsaved files": "有 {0} 個未儲存檔案。\n\n您要在認可之前進行儲存嗎?", + "save and commit": "儲存全部且認可", + "commit": "無論如何仍認可", "no staged changes": "沒有暫存變更進行提交\n\n您希望自動暫存您所有變更並直接提交?", "always": "永遠", "no changes": "沒有任何變更要認可。", @@ -64,12 +68,13 @@ "no remotes to pull": "您的儲存庫未設定要提取的遠端來源。", "pick remote pull repo": "挑選要將分支提取出的遠端", "no remotes to push": "您的儲存庫未設定要推送的遠端目標。", - "push with tags success": "已成功使用標籤推送。", "nobranch": "請簽出分支以推送到遠端。", + "confirm publish branch": "分支 '{0}' 沒有任何上游分支。 您仍想發布這個分支嗎?", + "ok": "確定", + "push with tags success": "已成功使用標籤推送。", "pick remote": "挑選要發行分支 '{0}' 的目標遠端:", "sync is unpredictable": "此動作會將認可發送至 '{0}' 及從中提取認可。", - "ok": "確定", - "never again": "確定不要再顯示", + "never again": "確定,不要再顯示", "no remotes to publish": "您的儲存庫未設定要發行的遠端目標。", "no changes stash": "沒有變更可供隱藏。", "provide stash message": "可選擇提供隱藏訊息", diff --git a/i18n/cht/extensions/git/package.i18n.json b/i18n/cht/extensions/git/package.i18n.json index 5bb3d198bb4..46908731864 100644 --- a/i18n/cht/extensions/git/package.i18n.json +++ b/i18n/cht/extensions/git/package.i18n.json @@ -54,12 +54,12 @@ "command.stashPopLatest": "快顯上一次的隱藏", "config.enabled": "是否啟用 GIT", "config.path": "Git 可執行檔的路徑", + "config.autoRepositoryDetection": "是否自動偵測儲存庫", "config.autorefresh": "是否啟用自動重新整理", "config.autofetch": "是否啟用自動擷取", "config.enableLongCommitWarning": "是否發出長認可訊息的警告", "config.confirmSync": "請先確認再同步處理 GIT 存放庫", "config.countBadge": "控制 git 徽章計數器。[全部] 會計算所有變更。[已追蹤] 只會計算追蹤的變更。[關閉] 會將其關閉。", - "config.checkoutType": "控制在執行 [簽出至...] 時,會列出那些類型的分支。[全部] 會顯示所有參考,[本機] 只會顯示本機分支,[標記] 只會顯示標記,[遠端] 只會顯示遠端分支。", "config.ignoreLegacyWarning": "略過舊的 Git 警告", "config.ignoreMissingGitWarning": "忽略遺漏 Git 時的警告", "config.ignoreLimitWarning": "當儲存庫中有過多變更時,略過警告。", @@ -72,5 +72,6 @@ "colors.deleted": "刪除資源的顏色", "colors.untracked": "未追蹤資源的顏色。", "colors.ignored": "忽略資源的顏色。", - "colors.conflict": "帶有衝突資源的顏色。" + "colors.conflict": "帶有衝突資源的顏色。", + "colors.submodule": "子模組資源的顏色" } \ No newline at end of file diff --git a/i18n/cht/extensions/typescript/out/commands.i18n.json b/i18n/cht/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..628429984fc --- /dev/null +++ b/i18n/cht/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "請在 VS Code 中開啟資料夾,以使用 TypeScript 或 JavaScript 專案", + "typescript.projectConfigUnsupportedFile": "無法判斷 TypeScript 或 JavaScript 專案。不支援的檔案類型", + "typescript.projectConfigCouldNotGetInfo": "無法判斷 TypeScript 或 JavaScript 專案", + "typescript.noTypeScriptProjectConfig": "檔案不是 TypeScript 專案的一部份", + "typescript.noJavaScriptProjectConfig": "檔案不是 JavaScript 專案的一部份", + "typescript.configureTsconfigQuickPick": "設定 tsconfig.json", + "typescript.configureJsconfigQuickPick": "設定 jsconfig.json", + "typescript.projectConfigLearnMore": "深入了解" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/cht/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/cht/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/base/node/ps.i18n.json b/i18n/cht/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..8a8bc9149d5 --- /dev/null +++ b/i18n/cht/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "收集 CPU 與記憶體資訊中,可能需要幾秒鐘的時間。" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/cht/src/vs/editor/common/config/commonEditorConfig.i18n.json index 71be40322db..1cd1bd85b24 100644 --- a/i18n/cht/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/cht/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "行號以絕對值顯示。", "lineNumbers.relative": "行號以目前游標的相對值顯示。", "lineNumbers.interval": "每 10 行顯示行號。", - "lineNumbers": "控制行號顯示方式。允許設定值包含 'on'、'off' 及 'relative'。", + "lineNumbers": "控制行號的顯示方式。允許的設定值為 'on'、 'off'、'relative' 及 'interval'", "rulers": "在特定的等寬字元數之後轉譯垂直尺規。有多個尺規就使用多個值。若陣列為空,則不繪製任何尺規。", "wordSeparators": "執行文字相關導覽或作業時將作為文字分隔符號的字元", "tabSize": "與 Tab 相等的空格數量。當 `editor.detectIndentation` 已開啟時,會根據檔案內容覆寫此設定。", @@ -72,6 +72,7 @@ "cursorBlinking": "控制游標動畫樣式,可能的值為 'blink'、'smooth'、'phase'、'expand' 和 'solid'", "mouseWheelZoom": "使用滑鼠滾輪並按住 Ctrl 時,縮放編輯器的字型", "cursorStyle": "控制游標樣式。接受的值為 'block'、'block-outline'、'line'、'line-thin'、'underline' 及 'underline-thin'", + "lineCursorWidth": "控制游標寬度,當 editor.cursorStyle 設定為 'line' 時。", "fontLigatures": "啟用連字字型", "hideCursorInOverviewRuler": "控制游標是否應隱藏在概觀尺規中。", "renderWhitespace": "控制編輯器轉譯空白字元的方式,可能為 'none'、'boundary' 及 'all'。'boundary' 選項不會轉譯字組間的單一空格。", diff --git a/i18n/cht/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/cht/src/vs/editor/common/view/editorColorRegistry.i18n.json index 85ff9ee951e..ab8fae3d2ec 100644 --- a/i18n/cht/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/cht/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,7 @@ { "lineHighlight": "目前游標位置行的反白顯示背景色彩。", "lineHighlightBorderBox": "目前游標位置行之周圍框線的背景色彩。", - "rangeHighlight": "反白顯示範圍的背景色彩,例如快速開啟與尋找功能。", + "rangeHighlight": "突顯顯示範圍的背景顏色,例如快速開啟和尋找功能。不能使用非透明的顏色來隱藏底層的樣式。", "caret": "編輯器游標的色彩。", "editorCursorBackground": "編輯器游標的背景色彩。允許自訂區塊游標重疊的字元色彩。", "editorWhitespaces": "編輯器中空白字元的色彩。", diff --git a/i18n/cht/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/cht/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 9fbf329131b..c569d86bd1a 100644 --- a/i18n/cht/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/cht/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "移至下一個錯誤或警告", - "markerAction.previous.label": "移至上一個錯誤或警告", "editorMarkerNavigationError": "編輯器標記導覽小工具錯誤的色彩。", "editorMarkerNavigationWarning": "編輯器標記導覽小工具警告的色彩。", "editorMarkerNavigationInfo": "編輯器標記導覽小工具資訊的色彩", diff --git a/i18n/cht/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/cht/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index 97c113d82f0..600c7e5e3d5 100644 --- a/i18n/cht/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/cht/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "讀取存取期間 (例如讀取變數時) 符號的背景色彩。", - "wordHighlightStrong": "寫入存取期間 (例如寫入變數時) 符號的背景色彩。", + "wordHighlight": "讀取存取符號時的背景顏色,如讀取變數。不能使用非透明的顏色來隱藏底層的樣式。", + "wordHighlightStrong": "寫入存取符號時的背景顏色,如寫入變數。不能使用非透明的顏色來隱藏底層的樣式。", "overviewRulerWordHighlightForeground": "符號醒目提示的概觀尺規標記色彩。", "overviewRulerWordHighlightStrongForeground": "寫入權限符號醒目提示的概觀尺規標記色彩。", "wordHighlight.next.label": "移至下一個反白符號", diff --git a/i18n/cht/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/cht/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index 3484e0af5e7..f1ab5b8686a 100644 --- a/i18n/cht/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/cht/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "`{0}` 不是有效的功能表識別碼", "missing.command": "功能表項目參考了 'commands' 區段中未定義的命令 `{0}`。", "missing.altCommand": "功能表項目參考了 'commands' 區段中未定義的替代命令 `{0}`。", - "dupe.command": "功能表項目參考了與預設相同的命令和替代命令", - "nosupport.altCommand": "很抱歉,目前只有 [編輯器/標題] 功能表的 [導覽] 群組支援替代命令" + "dupe.command": "功能表項目參考了與預設相同的命令和替代命令" } \ No newline at end of file diff --git a/i18n/cht/src/vs/platform/environment/node/argv.i18n.json b/i18n/cht/src/vs/platform/environment/node/argv.i18n.json index 0874564b4c9..4e6ecb355e3 100644 --- a/i18n/cht/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/cht/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,35 @@ "diff": "互相比較兩個檔案。", "add": "將資料夾新增至上一個使用中的視窗。", "goto": "在路徑上的指定行與字元位置開啟檔案。", - "locale": "要使用的地區設定 (例如 en-US 或 zh-TW)。", "newWindow": "強制執行 Code 的新執行個體。", - "performance": "在已啟用 'Developer: Startup Performance' 命令的情況下開始。", - "prof-startup": "啟動時執行 CPU 分析工具", - "inspect-extensions": "允許對擴充功能進行除錯和分析。檢查開發工具的連接 uri。", - "inspect-brk-extensions": "允許對擴展主機在啟動後暫停擴充功能進行除錯和分析。檢查開發工具中的連接 uri。", "reuseWindow": "強制在最近使用的視窗中開啟檔案或資料夾。", - "userDataDir": "指定保留使用者資料的目錄,這在以根目錄身分執行時有用。", - "log": "使用的日誌級別。預設為\"訊息\"。允許的值是 \"關鍵\"、\"錯誤\"、\"警告\"、\"訊息\"、\"偵錯\"、\"追蹤\"、\"關閉\"。", - "verbose": "列印詳細資訊輸出 (表示 --wait)。", "wait": "等候檔案在傳回前關閉。", + "locale": "要使用的地區設定 (例如 en-US 或 zh-TW)。", + "userDataDir": "指定保留使用者資料的目錄,這在以根目錄身分執行時有用。", + "version": "列印版本。", + "help": "列印使用方式。", "extensionHomePath": "設定擴充功能的根路徑。", "listExtensions": "列出已安裝的擴充功能。", "showVersions": "使用 --list-extension 時,顯示安裝的擴充功能版本。", "installExtension": "安裝擴充功能。", "uninstallExtension": "解除安裝擴充功能。", "experimentalApis": "為延伸模組啟用建議的 API 功能。", - "disableExtensions": "停用所有已安裝的擴充功能。", - "disableGPU": "停用 GPU 硬體加速。", + "verbose": "列印詳細資訊輸出 (表示 --wait)。", + "log": "使用的日誌級別。預設為\"訊息\"。允許的值是 \"關鍵\"、\"錯誤\"、\"警告\"、\"訊息\"、\"偵錯\"、\"追蹤\"、\"關閉\"。", "status": "列印進程使用方式和診斷資訊。", - "version": "列印版本。", - "help": "列印使用方式。", + "performance": "在已啟用 'Developer: Startup Performance' 命令的情況下開始。", + "prof-startup": "啟動時執行 CPU 分析工具", + "disableExtensions": "停用所有已安裝的擴充功能。", + "inspect-extensions": "允許對擴充功能進行除錯和分析。檢查開發工具的連接 uri。", + "inspect-brk-extensions": "允許對擴展主機在啟動後暫停擴充功能進行除錯和分析。檢查開發工具中的連接 uri。", + "disableGPU": "停用 GPU 硬體加速。", + "uploadLogs": "上傳目前的工作階段紀錄至安全的端點。", "usage": "使用方式", "options": "選項", "paths": "路徑", - "optionsUpperCase": "選項" + "stdinWindows": "從其他程式讀取輸出並附加 '-' (例: 'echo Hello World | {0} -')", + "stdinUnix": "從 stdin 讀取並附加 '-' (例: 'ps aux | grep code | {0} -')", + "optionsUpperCase": "選項", + "extensionsManagement": "擴充功能管理", + "troubleshooting": "疑難排解" } \ No newline at end of file diff --git a/i18n/cht/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/cht/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index bdd6cf53312..09a519ce52e 100644 --- a/i18n/cht/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/cht/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,15 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "擴充功能無效: package.json 不是 JSON 檔案。", - "restartCodeLocal": "請先重新啟動 Code,再重新安裝 {0}。", + "restartCode": "請先重新啟動 Code,再重新安裝 {0}。", "installingOutdatedExtension": "已安裝此擴充功能的較新版本。是否要使用舊版本覆蓋此項?", "override": "覆寫", "cancel": "取消", - "notFoundCompatible": "無法安裝,因為找不到相容於 VS Code 目前版本 '{1}' 的擴充功能 '{0}'。", - "quitCode": "無法安裝因為有過時的擴充功能仍在運行。請在重新安裝前退出並啟動 VS Code。", - "exitCode": "無法安裝因為有過時的擴充功能仍在運行。請在重新安裝前退出並啟動 VS Code。", + "errorInstallingDependencies": "安裝相依套件時發生錯誤。{0}", + "notFoundCompatible": "無法安裝 '{0}';沒有任何與 VS Code 相容的可用版本 '{1}'。", "notFoundCompatibleDependency": "無法安裝,因為找不到相容於 VS Code 目前版本 '{1}' 的相依擴充功能 '{0}'。", + "quitCode": "無法安裝擴充功能。重新安裝以前請重啟 VS Code。", + "exitCode": "無法安裝擴充功能。重新安裝以前請離開並再次啟動 VS Code。", "uninstallDependeciesConfirmation": "只要將 '{0}' 解除安裝,或要包含其相依性?", "uninstallOnly": "只有", "uninstallAll": "全部", diff --git a/i18n/cht/src/vs/platform/message/common/message.i18n.json b/i18n/cht/src/vs/platform/message/common/message.i18n.json index 7a9cbb1bf06..f23fb38d418 100644 --- a/i18n/cht/src/vs/platform/message/common/message.i18n.json +++ b/i18n/cht/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "關閉", "later": "稍後", - "cancel": "取消" + "cancel": "取消", + "moreFile": "...另外 1 個檔案未顯示", + "moreFiles": "...另外 {0} 個檔案未顯示" } \ No newline at end of file diff --git a/i18n/cht/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/cht/src/vs/platform/theme/common/colorRegistry.i18n.json index 4868c4bbc6c..b78729f262f 100644 --- a/i18n/cht/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/cht/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,12 @@ "editorWidgetBorder": "編輯器小工具的邊界色彩。小工具選擇擁有邊界或色彩未被小工具覆寫時,才會使用色彩。", "editorSelectionBackground": "編輯器選取範圍的色彩。", "editorSelectionForeground": "為選取的文字顏色高對比化", - "editorInactiveSelection": "非使用中之編輯器選取範圍的色彩。", - "editorSelectionHighlight": "選取時,內容相同之區域的色彩。", + "editorInactiveSelection": "在非使用中的編輯器的選取項目顏色。不能使用非透明的顏色來隱藏底層的樣式。", + "editorSelectionHighlight": "與選取項目相同的區域顏色。不能使用非透明的顏色來隱藏底層的樣式。", "editorFindMatch": "符合目前搜尋的色彩。", - "findMatchHighlight": "符合其他搜尋的色彩。", - "findRangeHighlight": "限制搜尋之範圍的色彩。", - "hoverHighlight": "在顯示了動態顯示的單字下方醒目提示。", + "findMatchHighlight": "符合搜尋條件的其他項目的顏色。不能使用非透明的顏色來隱藏底層的樣式。", + "findRangeHighlight": "為限制搜索的範圍著色。不能使用非透明的顏色來隱藏底層的樣式。", + "hoverHighlight": "突顯懸停顯示的文字。不能使用非透明的顏色來隱藏底層的樣式。", "hoverBackground": "編輯器動態顯示的背景色彩。", "hoverBorder": "編輯器動態顯示的框線色彩。", "activeLinkForeground": "使用中之連結的色彩。", @@ -76,12 +76,12 @@ "diffEditorRemoved": "移除文字的背景色彩。", "diffEditorInsertedOutline": "插入的文字外框色彩。", "diffEditorRemovedOutline": "移除的文字外框色彩。", - "mergeCurrentHeaderBackground": "目前內嵌合併衝突中的深色標題背景。", - "mergeCurrentContentBackground": "目前內嵌合併衝突中的內容背景。", - "mergeIncomingHeaderBackground": "傳入內嵌合併衝突中的深色標題背景。", - "mergeIncomingContentBackground": "傳入內嵌合併衝突中的內容背景。", - "mergeCommonHeaderBackground": "內嵌合併衝突中的共同始祖標題背景", - "mergeCommonContentBackground": "內嵌合併衝突中的共同始祖內容背景。", + "mergeCurrentHeaderBackground": "目前內嵌合併衝突中的深色標題背景。不能使用非透明的顏色來隱藏底層的樣式。", + "mergeCurrentContentBackground": "目前內嵌合併衝突中的內容背景。不能使用非透明的顏色來隱藏底層的樣式。", + "mergeIncomingHeaderBackground": "傳入內嵌合併衝突中的深色標題背景。不能使用非透明的顏色來隱藏底層的樣式。", + "mergeIncomingContentBackground": "傳入內嵌合併衝突中的內容背景。不能使用非透明的顏色來隱藏底層的樣式。", + "mergeCommonHeaderBackground": "內嵌合併衝突中的共同始祖標題背景。不能使用非透明的顏色來隱藏底層的樣式。", + "mergeCommonContentBackground": "內嵌合併衝突中的共同始祖內容背景。不能使用非透明的顏色來隱藏底層的樣式。", "mergeBorder": "內嵌合併衝突中標頭及分隔器的邊界色彩。", "overviewRulerCurrentContentForeground": "目前內嵌合併衝突的概觀尺規前景。", "overviewRulerIncomingContentForeground": "傳入內嵌合併衝突的概觀尺規前景。", diff --git a/i18n/cht/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/cht/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..c98475d49db --- /dev/null +++ b/i18n/cht/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "saveParticipants": "執行儲存參與者..." +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/cht/src/vs/workbench/api/node/extHostTreeViews.i18n.json index edc32bace6e..2df7e9c33f5 100644 --- a/i18n/cht/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/cht/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -4,7 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "treeView.notRegistered": "未註冊識別碼為 '{0}' 的樹狀檢視。", - "treeItem.notFound": "找不到識別碼為 '{0}' 的樹狀檢視。", - "treeView.duplicateElement": "元件{0}已被註冊" + "treeView.notRegistered": "未註冊識別碼為 '{0}' 的樹狀檢視。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/cht/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index 08df7a29ce5..16f408d9bec 100644 --- a/i18n/cht/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "切換提要欄位位置", "view": "檢視" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/cht/src/vs/workbench/browser/actions/workspaceActions.i18n.json index abe1e77c797..f5c23870560 100644 --- a/i18n/cht/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "開啟檔案...", "openFolder": "開啟資料夾...", "openFileFolder": "開啟...", - "addFolderToWorkspace": "將資料夾新增到工作區...", - "add": "新增", - "addFolderToWorkspaceTitle": "將資料夾新增到工作區", "globalRemoveFolderFromWorkspace": "將資料夾從工作區移除...", - "removeFolderFromWorkspace": "將資料夾從工作區移除", - "openFolderSettings": "開啟資料夾設定", "saveWorkspaceAsAction": "另存工作區為...", "save": "儲存(&&S)", "saveWorkspace": "儲存工作區", "openWorkspaceAction": "開啟工作區...", "openWorkspaceConfigFile": "開啟工作區組態檔", - "openFolderAsWorkspaceInNewWindow": "在新視窗中開啟資料夾作為工作區", - "workspaceFolderPickerPlaceholder": "選取工作區資料夾" + "openFolderAsWorkspaceInNewWindow": "在新視窗中開啟資料夾作為工作區" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/cht/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..19777945aa7 --- /dev/null +++ b/i18n/cht/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "將資料夾新增到工作區...", + "add": "新增", + "addFolderToWorkspaceTitle": "將資料夾新增到工作區", + "workspaceFolderPickerPlaceholder": "選取工作區資料夾" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/cht/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index fc25ce13ad0..9dbae940daf 100644 --- a/i18n/cht/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,17 @@ "groupThreePicker": "在第三個群組顯示編輯器", "allEditorsPicker": "顯示所有開啟的編輯器", "view": "檢視", - "file": "檔案" + "file": "檔案", + "close": "關閉", + "closeOthers": "關閉其他", + "closeRight": "關到右側", + "closeAllUnmodified": "關閉未變更的檔案", + "closeAll": "全部關閉", + "keepOpen": "保持開啟", + "showOpenedEditors": "顯示開啟的編輯器", + "keepEditor": "保留編輯器", + "closeEditorsInGroup": "關閉群組中的所有編輯器", + "closeUnmodifiedEditors": "在群組中關閉未修改的編輯器", + "closeOtherEditors": "關閉其他編輯器", + "closeRightEditors": "將編輯器關到右側" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/cht/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index 6f4e3589f00..6b3df89947b 100644 --- a/i18n/cht/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "關閉編輯器", "revertAndCloseActiveEditor": "還原並關閉編輯器", "closeEditorsToTheLeft": "將編輯器關到左側", - "closeEditorsToTheRight": "將編輯器關到右側", "closeAllEditors": "關閉所有編輯器", - "closeUnmodifiedEditors": "在群組中關閉未修改的編輯器", "closeEditorsInOtherGroups": "關閉其他群組中的編輯器", - "closeOtherEditorsInGroup": "關閉其他編輯器", - "closeEditorsInGroup": "關閉群組中的所有編輯器", "moveActiveGroupLeft": "將編輯器群組向左移", "moveActiveGroupRight": "將編輯器群組向右移", "minimizeOtherEditorGroups": "將其他編輯器群組最小化", "evenEditorGroups": "均分編輯器群組寬度", "maximizeEditor": "將編輯器群組最大化並隱藏側邊欄", - "keepEditor": "保留編輯器", "openNextEditor": "開啟下一個編輯器", "openPreviousEditor": "開啟上一個編輯器", "nextEditorInGroup": "開啟群組中下一個編輯器", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "在第一個群組顯示編輯器", "showEditorsInSecondGroup": "在第二個群組顯示編輯器", "showEditorsInThirdGroup": "在第三個群組顯示編輯器", - "showEditorsInGroup": "在群組顯示編輯器", "showAllEditors": "顯示所有編輯器", "openPreviousRecentlyUsedEditorInGroup": "開啟群組中上一個最近使用的編輯器", "openNextRecentlyUsedEditorInGroup": "開啟群組中下一個最近使用的編輯器", @@ -54,5 +48,8 @@ "moveEditorLeft": "將編輯器左移", "moveEditorRight": "將編輯器右移", "moveEditorToPreviousGroup": "將編輯器移入上一個群組", - "moveEditorToNextGroup": "將編輯器移入下一個群組" + "moveEditorToNextGroup": "將編輯器移入下一個群組", + "moveEditorToFirstGroup": "將編輯器移動到第一個群組", + "moveEditorToSecondGroup": "將編輯器移動到第二個群組", + "moveEditorToThirdGroup": "將編輯器移動到第三個群組" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/cht/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index f93bcde4036..043d904547f 100644 --- a/i18n/cht/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "以 tab 或群組為單位移動使用中的編輯器", "editorCommand.activeEditorMove.arg.name": "使用中編輯器的移動引數", - "editorCommand.activeEditorMove.arg.description": "引數屬性:\n\t* 'to': 提供移動目標位置的字串值。\n\t* 'by': 提供移動單位的字串值。\n\t* 'value': 提供移動單位的字串值。可依索引標籤或群組作為單位。", - "commandDeprecated": "已移除命令 **{0}**。您可以改用 **{1}**", - "openKeybindings": "設定鍵盤快速鍵" + "editorCommand.activeEditorMove.arg.description": "引數屬性:\n\t* 'to': 提供移動目標位置的字串值。\n\t* 'by': 提供移動單位的字串值。\n\t* 'value': 提供移動單位的字串值。可依索引標籤或群組作為單位。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/cht/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index 7071905be9d..b24baa1a2f4 100644 --- a/i18n/cht/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "文字檔比較編輯器。", "navigate.next.label": "下一個變更", "navigate.prev.label": "上一個變更", - "inlineDiffLabel": "切換至內嵌檢視", - "sideBySideDiffLabel": "切換至並排檢視" + "toggleIgnoreTrimWhitespace.label": "忽略修剪空白字元" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/cht/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index bfffed93b02..b9bd84d7409 100644 --- a/i18n/cht/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "關閉", - "closeOthers": "關閉其他", - "closeRight": "關到右側", - "closeAll": "全部關閉", - "closeAllUnmodified": "關閉未變更的檔案", - "keepOpen": "保持開啟", - "showOpenedEditors": "顯示開啟的編輯器", "araLabelEditorActions": "編輯器動作" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/cht/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index 03d11a86fb4..5b3642aebed 100644 --- a/i18n/cht/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[不支援]", + "userIsAdmin": "[系統管理員]", + "userIsSudo": "[超級使用者]", "devExtensionWindowTitlePrefix": "[Extension Development Host]" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/cht/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index e0fd97c7bae..529cc5594d3 100644 --- a/i18n/cht/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/cht/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "hideView": "從提要欄位隱藏" + "hideView": "隱藏" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/common/theme.i18n.json b/i18n/cht/src/vs/workbench/common/theme.i18n.json index 6be57ab281c..701339a9f63 100644 --- a/i18n/cht/src/vs/workbench/common/theme.i18n.json +++ b/i18n/cht/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "使用中之索引標籤的背景色彩。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", "tabInactiveBackground": "非使用中之索引標籤的背景色彩。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", + "tabHoverBackground": "當暫留索引標籤的背景色彩。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", + "tabUnfocusedHoverBackground": "當暫留非焦點群組中索引標籤的背景色彩。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。 ", "tabBorder": "用以分隔索引標籤彼此的框線。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", "tabActiveBorder": "用以醒目提示使用中索引標籤的框線。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", "tabActiveUnfocusedBorder": "用以在非焦點群組中醒目提示使用中索引標籤的框線。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。 ", + "tabHoverBorder": "用以反白顯示暫留時索引標籤的框線。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", + "tabUnfocusedHoverBorder": "在非焦點群組中反白顯示暫留時索引標籤的框線。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。 ", "tabActiveForeground": "使用中的群組內,使用中之索引標籤的前景色彩。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", "tabInactiveForeground": "使用中的群組內,非使用中之索引標籤的前景色彩。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", "tabUnfocusedActiveForeground": "非焦點群組中的使用中索引標籤前景色彩。索引標籤是編輯器在編輯器區域中的容器。同一個編輯器群組中的多個索引標籤可以同時開啟。可能會有多個編輯器群組。", @@ -16,7 +20,7 @@ "editorGroupBackground": "編輯器群組的背景色彩。編輯器群組是編輯器的容器。當拖曳編輯器群組時會顯示背景色彩。", "tabsContainerBackground": "當索引標籤啟用的時候編輯器群組標題的背景色彩。編輯器群組是編輯器的容器。", "tabsContainerBorder": "當索引標籤啟用時,編輯器群組標題的框線色彩。編輯器群組是編輯器的容器。", - "editorGroupHeaderBackground": "當索引標籤禁用的時候編輯器群組標題的背景顏色。編輯器群組是編輯器的容器。", + "editorGroupHeaderBackground": "當索引標籤禁用的時候編輯器群組標題的背景顏色 (`\"workbench.editor.showTabs\": false`)。編輯器群組是編輯器的容器。", "editorGroupBorder": "用以分隔多個編輯器群組彼此的色彩。編輯器群組是編輯器的容器。", "editorDragAndDropBackground": "拖拉編輯器時的背景顏色,可設置透明度讓內容穿透顯示.", "panelBackground": "面板的前景色彩。面板會顯示在編輯器區域的下方,其中包含諸如輸出與整合式終端機等檢視。", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "未開啟資料夾時,用以分隔資訊看板與編輯器的狀態列框線色彩。狀態列會顯示在視窗的底部。 ", "statusBarItemActiveBackground": "按下滑鼠按鈕時,狀態列項目的背景色彩。狀態列會顯示在視窗的底部。", "statusBarItemHoverBackground": "動態顯示時,狀態列項目的背景色彩。狀態列會顯示在視窗的底部。", - "statusBarProminentItemBackground": "狀態列突出項目的背景顏色。突出項目比狀態列的其他項目更顯眼,用於表示重要性更高。狀態列會顯示在視窗的底部。", - "statusBarProminentItemHoverBackground": "狀態列突出項目暫留時的背景顏色。突出項目比狀態列的其他項目更顯眼,用於表示重要性更高。狀態列會顯示在視窗的底部。", + "statusBarProminentItemBackground": "狀態列突出項目的背景顏色。突出項目比狀態列的其他項目更顯眼,用於表示重要性更高。從命令選擇區變更模式 `切換 Tab 鍵移動焦點` 來檢視範例。狀態列會顯示在視窗的底部。", + "statusBarProminentItemHoverBackground": "當暫留狀態列突出項目的背景顏色。突出項目比狀態列的其他項目更顯眼,用於表示重要性更高。從命令選擇區變更模式 `切換 Tab 鍵移動焦點` 來檢視範例。狀態列會顯示在視窗的底部。", "activityBarBackground": "活動列背景的色彩。活動列會顯示在最左側或最右側,並可切換不同的提要欄位檢視。", "activityBarForeground": "活動列的前背景色彩(例如用於圖示)。此活動列會顯示在最左側或最右側,讓您可以切換提要欄位的不同檢視。", "activityBarBorder": "用以分隔提要欄位的活動列框線色彩。此活動列會顯示在最左側或最右側,讓您可以切換提要欄位的不同檢視。", diff --git a/i18n/cht/src/vs/workbench/common/views.i18n.json b/i18n/cht/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..b6fbcb12ae3 --- /dev/null +++ b/i18n/cht/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "識別碼為 '{0}' 的檢視已在位置 '{1}' 註冊" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/cht/src/vs/workbench/electron-browser/actions.i18n.json index daf7e22d21e..c6e5b092bd1 100644 --- a/i18n/cht/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/cht/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "關閉編輯器", "closeWindow": "關閉視窗", "closeWorkspace": "關閉工作區", "noWorkspaceOpened": "此執行個體中目前沒有開啟的工作區可以關閉。", @@ -52,21 +51,5 @@ "displayLanguage": "定義 VSCode 的顯示語言。", "doc": "如需支援的語言清單,請參閱 {0}。", "restart": "改變設定值後需要重新啟動 VSCode.", - "fail.createSettings": "無法建立 '{0}' ({1})。", - "openLogsFolder": "開啟紀錄資料夾", - "showLogs": "顯示紀錄...。", - "mainProcess": "主要", - "sharedProcess": "共用", - "rendererProcess": "轉譯器", - "extensionHost": "延伸主機", - "selectProcess": "選取程序", - "setLogLevel": "設定記錄層級", - "trace": "追蹤", - "debug": "偵錯", - "info": "資訊", - "warn": "警告", - "err": "錯誤", - "critical": "關鍵", - "off": "關閉", - "selectLogLevel": "選擇日誌級別" + "fail.createSettings": "無法建立 '{0}' ({1})。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/cht/src/vs/workbench/electron-browser/main.contribution.i18n.json index 33e2c22230a..7ed98a41d84 100644 --- a/i18n/cht/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "檢視", "help": "說明", "file": "檔案", - "developer": "開發人員", "workspaces": "工作區", + "developer": "開發人員", + "workbenchConfigurationTitle": "工作台", "showEditorTabs": "控制已開啟的編輯器是否應顯示在索引標籤中。", "workbench.editor.labelFormat.default": "顯示檔案名稱。當啟用索引標籤,且同一個群組中有兩個檔案同名時,就會新增各個檔案路徑具有識別度的的區段。當停用索引標籤時,若編輯器在使用中,就會顯示與工作區資料夾相關的路徑。", "workbench.editor.labelFormat.short": "顯示檔案的名稱,並在名稱後接著該檔案的目錄名稱。", @@ -20,23 +21,23 @@ "showIcons": "控制開啟的編輯器是否搭配圖示顯示。這需要同時啟用圖示佈景主題。", "enablePreview": "控制已開啟的編輯器是否顯示為預覽。預覽編輯器會重複使用到被保留 (例如按兩下或進行編輯) 並以斜體字型樣式顯示為止。", "enablePreviewFromQuickOpen": "控制透過 Quick Open 所開啟的編輯器是否顯示為預覽。預覽編輯器會重複使用到被保留 (例如按兩下或進行編輯) 為止。", + "closeOnFileDelete": "控制顯示檔案的編輯器是否應在其他處理序刪除或重新命名該檔案時自動關閉。若停用此選項,當發生前述狀況時,編輯器會保持開啟,並呈現已變更的狀態。請注意,從應用程式內刪除一律會關閉編輯器,但已變更的檔案在資料未儲存前一律不會關閉。", "editorOpenPositioning": "控制編輯器的開啟位置。選取 [左] 或 [右] 可在目前使用中的編輯器左方或右方加以開啟。選取 [第一個] 或 [最後一個] 則可從目前使用中的編輯器另外加以開啟。", "revealIfOpen": "控制編輯器是否要在任何顯示的群組開啟時,在其中顯示。若啟用此選項,已經開啟的編輯器將會繼續顯示,而不會在目前使用中的編輯器群組中再開啟一次。請注意,有一些情況會忽略此設定,例如當強制編輯器在特定群組中開啟,或強制編輯器在目前使用中的群組旁開啟等情況。", + "swipeToNavigate": "利用三指水平撥動在開啟的檔案間瀏覽。", "commandHistory": "控制最近使用之命令的數量,以保留命令選擇區的記錄。設為 0 可停用命令列記錄。", "preserveInput": "控制下次開啟命令選擇區時,最後鍵入的輸入是否應該還原。", "closeOnFocusLost": "控制是否在 Quick Open 失去焦點時自動關閉。", "openDefaultSettings": "控制開啟設定時是否也會開啟顯示所有預設設定的編輯器。", "sideBarLocation": "控制項資訊看板的位置。可顯示於 Workbench 的左方或右方。", + "panelDefaultLocation": "控制面板的預設位置。可顯示在 Workbench 的底部或是右方。", "statusBarVisibility": "控制 Workbench 底端狀態列的可視性。", "activityBarVisibility": "控制活動列在 workbench 中的可見度。", - "closeOnFileDelete": "控制顯示檔案的編輯器是否應在其他處理序刪除或重新命名該檔案時自動關閉。若停用此選項,當發生前述狀況時,編輯器會保持開啟,並呈現已變更的狀態。請注意,從應用程式內刪除一律會關閉編輯器,但已變更的檔案在資料未儲存前一律不會關閉。", - "enableNaturalLanguageSettingsSearch": "控制是否啟用自然語言搜尋模式。", "fontAliasing": "在 Workbench 中控制字型鋸齒化的方法。- 預設: 子像素字型平滑處理。在大部分非 Retina 顯示器上會顯示出最銳利的文字- 已消除鋸齒: 相對於子像素,根據像素層級平滑字型。可讓字型整體顯得較細- 無: 停用字型平滑處理。文字會以鋸齒狀的銳邊顯示 ", "workbench.fontAliasing.default": "子像素字型平滑處理。在大部分非 Retina 顯示器上會顯示出最銳利的文字。", "workbench.fontAliasing.antialiased": "相對於子像素,根據像素層級平滑字型。可以讓字型整體顯得較細。", "workbench.fontAliasing.none": "禁用字體平滑.文字將會顯示鋸齒狀與鋒利的邊緣.", - "swipeToNavigate": "利用三指水平撥動在開啟的檔案間瀏覽。", - "workbenchConfigurationTitle": "工作台", + "enableNaturalLanguageSettingsSearch": "控制是否啟用自然語言搜尋模式。", "windowConfigurationTitle": "視窗", "window.openFilesInNewWindow.on": "檔案會在新視窗中開啟", "window.openFilesInNewWindow.off": "檔案會在開啟了檔案資料夾的視窗,或在上一個使用中的視窗中開啟", diff --git a/i18n/cht/src/vs/workbench/electron-browser/window.i18n.json b/i18n/cht/src/vs/workbench/electron-browser/window.i18n.json index 84c2c075664..8db2840ff19 100644 --- a/i18n/cht/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/cht/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "剪下", "copy": "複製", "paste": "貼上", - "selectAll": "全選" + "selectAll": "全選", + "runningAsRoot": "不建議以 root 身分執行 {0}。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/cht/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index 8bd875c749d..33b7f3d4467 100644 --- a/i18n/cht/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "偵錯工具列背景色彩。" + "debugToolBarBackground": "偵錯工具列背景色彩。", + "debugToolBarBorder": "偵錯工具列的邊框色彩" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/cht/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index c16e8f409d6..c127cd12e93 100644 --- a/i18n/cht/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "偵錯項目", - "debug.terminal.not.available.error": "整合式終端機無法使用" + "debug.terminal.title": "偵錯項目" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index cebab2d329a..370fe5dd948 100644 --- a/i18n/cht/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "開啟新的命令提示字元", "globalConsoleActionMacLinux": "開啟新的終端機", "scopedConsoleActionWin": "在命令提示字元中開啟", - "scopedConsoleActionMacLinux": "在終端機中開啟", - "openFolderInIntegratedTerminal": "在終端機中開啟" + "scopedConsoleActionMacLinux": "在終端機中開啟" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index 89b01309fa3..ac9779dde41 100644 --- a/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "根據您最近開啟的檔案,建議您使用此延伸模組。", + "neverShowAgain": "不要再顯示", + "close": "關閉", "workspaceRecommendation": "根據目前工作區的使用者,建議您使用此延伸模組。", + "fileBasedRecommendation": "根據您最近開啟的檔案,建議您使用此延伸模組。", "exeBasedRecommendation": "因為您已安裝 {0},所以建議您使用此延伸模組。", "reallyRecommended2": "建議對此檔案類型使用 '{0}' 延伸模組。", "reallyRecommendedExtensionPack": "建議對此檔案類型使用 '{0}' 延伸模組套件。", "showRecommendations": "顯示建議", "install": "安裝", - "neverShowAgain": "不要再顯示", - "close": "關閉", "workspaceRecommended": "此工作區具有擴充功能建議。", "installAll": "全部安裝", "ignoreExtensionRecommendations": "是否略過所有的延伸模組建議?", diff --git a/i18n/cht/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..37b9d5384a5 --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "工作台" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/cht/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..e8a6eb4e02c --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "hide": "隱藏" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 8edf8023225..8b0fa7e726f 100644 --- a/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,25 @@ "filesCategory": "檔案", "revealInSideBar": "在提要欄位中顯示", "acceptLocalChanges": "使用您的變更並覆寫磁碟內容 ", - "revertLocalChanges": "捨棄您的變更並還原成磁碟上的內容" + "revertLocalChanges": "捨棄您的變更並還原成磁碟上的內容", + "copyPathOfActive": "複製使用中檔案的路徑", + "saveAllInGroup": "全部儲存在群組中", + "saveFiles": "儲存所有檔案", + "revert": "還原檔案", + "compareActiveWithSaved": "比較使用中的檔案和已儲存的檔案", + "closeEditor": "關閉編輯器", + "view": "檢視", + "openToSide": "開至側邊", + "revealInWindows": "在檔案總管中顯示", + "revealInMac": "在 Finder 中顯示", + "openContainer": "開啟收納資料夾", + "copyPath": "複製路徑", + "saveAll": "全部儲存", + "compareWithSaved": "與已儲存的檔案比較", + "compareSource": "選取用以比較", + "close": "關閉", + "closeOthers": "關閉其他", + "closeUnmodified": "關閉未變更的檔案", + "closeAll": "全部關閉", + "deleteFile": "永久刪除" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index c32641ccebc..e173bdcc79b 100644 --- a/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "重試", - "rename": "重新命名", "newFile": "新增檔案", "newFolder": "新增資料夾", + "rename": "重新命名", + "delete": "刪除", + "copyFile": "複製", + "pasteFile": "貼上", + "retry": "重試", "openFolderFirst": "先開啟資料夾,以在其中建立檔案或資料夾。", "newUntitledFile": "新增未命名檔案", "createNewFile": "新增檔案", @@ -15,6 +18,7 @@ "deleteButtonLabelRecycleBin": "移至資源回收筒(&&M)", "deleteButtonLabelTrash": "移至垃圾筒(&&M)", "deleteButtonLabel": "刪除(&&D)", + "dirtyMessageFilesDelete": "您要刪除的檔案有未儲存的變更。要繼續嗎?", "dirtyMessageFolderOneDelete": "您要刪除的資料夾中 1 個檔案有未儲存的變更。要繼續嗎?", "dirtyMessageFolderDelete": "您要刪除的資料夾中 {0} 個檔案有未儲存的變更。要繼續嗎?", "dirtyMessageFileDelete": "您要刪除的檔案有未儲存的變更。要繼續嗎?", @@ -28,26 +32,16 @@ "confirmDeleteMessageFile": "您確定要永久刪除 '{0}' 嗎?", "irreversible": "此動作無法回復!", "permDelete": "永久刪除", - "delete": "刪除", "importFiles": "匯入檔案", "confirmOverwrite": "目的資料夾中已有同名的檔案或資料夾。要取代它嗎?", "replaceButtonLabel": "取代(&&R)", - "copyFile": "複製", - "pasteFile": "貼上", + "fileDeleted": "檔案被刪除或移動的同時", + "fileIsAncestor": "要複製的檔案是在目地資料夾的上層 ", "duplicateFile": "複製", - "openToSide": "開至側邊", - "compareSource": "選取用以比較", "globalCompareFile": "使用中檔案的比較對象...", "openFileToCompare": "先開啟檔案以與其他檔案進行比較", - "compareWith": "比較 '{0}' 與 '{1}'", - "compareFiles": "比較檔案", "refresh": "重新整理", - "save": "儲存", - "saveAs": "另存新檔...", - "saveAll": "全部儲存", "saveAllInGroup": "全部儲存在群組中", - "saveFiles": "儲存所有檔案", - "revert": "還原檔案", "focusOpenEditors": "聚焦在 [開放式編輯器] 檢視", "focusFilesExplorer": "將焦點設在檔案總管上", "showInExplorer": "在提要欄位中顯示使用中的檔案", @@ -56,20 +50,11 @@ "refreshExplorer": "重新整理 Explorer", "openFileInNewWindow": "在新視窗中開啟使用中的檔案", "openFileToShowInNewWindow": "先開啟檔案以在新視窗中開啟", - "revealInWindows": "在檔案總管中顯示", - "revealInMac": "在 Finder 中顯示", - "openContainer": "開啟收納資料夾", - "revealActiveFileInWindows": "在 Windows 檔案總管中顯示使用中的檔案", - "revealActiveFileInMac": "在 Finder 中顯示使用中的檔案", - "openActiveFileContainer": "開啟使用中檔案的收納資料夾", "copyPath": "複製路徑", - "copyPathOfActive": "複製使用中檔案的路徑", "emptyFileNameError": "必須提供檔案或資料夾名稱。", "fileNameExistsError": "這個位置已存在檔案或資料夾 **{0}**。請選擇不同的名稱。", "invalidFileNameError": "名稱 **{0}** 不能作為檔案或資料夾名稱。請選擇不同的名稱。", "filePathTooLongError": "名稱 **{0}** 導致路徑太長。請選擇較短的名稱。", - "compareWithSaved": "比較使用中的檔案和已儲存的檔案", - "modifiedLabel": "{0} (在磁碟上) ↔ {1}", "compareWithClipboard": "比較使用中的檔案和剪貼簿的檔案", "clipboardComparisonLabel": "剪貼簿 ↔ {0}" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index 75bdd951541..fabee1658dc 100644 --- a/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "先開啟檔案以複製其路徑", - "openFileToReveal": "先開啟檔案以顯示" + "revealInWindows": "在檔案總管中顯示", + "revealInMac": "在 Finder 中顯示", + "openContainer": "開啟收納資料夾", + "saveAs": "另存新檔...", + "save": "儲存", + "saveAll": "全部儲存", + "removeFolderFromWorkspace": "將資料夾從工作區移除", + "genericRevertError": "無法還原 '{0}': {1}", + "modifiedLabel": "{0} (在磁碟上) ↔ {1}", + "openFileToReveal": "先開啟檔案以顯示", + "openFileToCopy": "先開啟檔案以複製其路徑" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 867d603ca56..28e38af66ab 100644 --- a/i18n/cht/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,6 @@ "editorConfigurationTitle": "編輯器", "formatOnSave": "在儲存時設定檔案格式。格式器必須處於可用狀態、檔案不得自動儲存,且編輯器不得關機。", "explorerConfigurationTitle": "檔案總管", - "openEditorsVisible": "[開放式編輯器] 窗格中顯示的編輯器數目。將其設定為 0 以隱藏窗格。", - "dynamicHeight": "控制 [開放式編輯器] 區段的高度是否應依元素數目動態調整。", "autoReveal": "控制總管是否在開啟檔案時自動加以顯示及選取。", "enableDragAndDrop": "控制總管是否應該允許透過拖放功能移動檔案和資料夾。", "confirmDragAndDrop": "控制總管是否須要求確認,以透過拖放來移動檔案和資料夾。", diff --git a/i18n/cht/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/cht/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 7a6f0b075f7..1b0a86e7ea2 100644 --- a/i18n/cht/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,14 @@ // Do not edit this file. It is machine generated. { "userGuide": "在右方使用編輯器工具列中的動作來 **復原** 您的變更,或以您的變更 **覆寫** 磁碟上的內容", - "discard": "捨棄", + "overwriteElevated": "以系統管理者身分覆寫...", + "saveElevated": "以系統管理者身分重試", "overwrite": "覆寫", "retry": "重試", - "readonlySaveError": "無法儲存 '{0}': 檔案有防寫保護。請選取 [覆寫] 以移除保護。", + "discard": "捨棄", + "readonlySaveErrorAdmin": "無法儲存 '{0}': 檔案有防寫保護。請選取 [以系統管理者身分覆寫] 來做為系統管理者身分重試。 ", + "readonlySaveError": "無法儲存 '{0}': 檔案有防寫保護。請選取 [覆寫] 以嚐試移除保護。 ", + "permissionDeniedSaveError": "無法儲存 '{0}': 權限不足。請選取 [以系統管理者身分重試] 做為系統管理者身分重試。 ", "genericSaveError": "無法儲存 '{0}': {1}", "staleSaveError": "無法儲存 '{0}': 磁碟上的內容較新。請按一下 [比較],比較您的版本與磁碟上的版本。", "compareChanges": "比較", diff --git a/i18n/cht/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json b/i18n/cht/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json index bc42ca6193f..99aeb2ac46a 100644 --- a/i18n/cht/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json @@ -10,6 +10,7 @@ "dropFolder": "要在工作區新增資料夾嗎?", "addFolders": "新增資料夾(&A)", "addFolder": "新增資料夾(&A)", + "confirmMultiMove": "確定要移動以下 {0} 個文件嗎?", "confirmMove": "確定要移動 '{0}' 嗎?", "doNotAskAgain": "不要再詢問我", "moveButtonLabel": "移動(&&M)", diff --git a/i18n/cht/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/cht/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index b48ed12d518..bc39c809e3d 100644 --- a/i18n/cht/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "已開啟的編輯器", "openEditosrSection": "開放式編輯器區段", - "dirtyCounter": "{0} 未儲存", - "saveAll": "全部儲存", - "closeAllUnmodified": "關閉未變更的檔案", - "closeAll": "全部關閉", - "compareWithSaved": "與已儲存的檔案比較", - "close": "關閉", - "closeOthers": "關閉其他" + "dirtyCounter": "{0} 未儲存" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..2049a7686db --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "mainLog": "紀錄 (主要) ", + "sharedLog": "紀錄 (共享) ", + "rendererLog": "紀錄 (視窗)", + "extensionsLog": "紀錄 (延伸主機) ", + "developer": "開發人員" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/cht/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..ce58da3b756 --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "開啟紀錄資料夾", + "showLogs": "顯示紀錄...。", + "mainProcess": "主要", + "sharedProcess": "共享", + "rendererProcess": "視窗", + "extensionHost": "延伸主機", + "selectProcess": "選取程序", + "openLogFile": "開啟紀錄檔案...", + "setLogLevel": "設定記錄層級", + "trace": "追蹤", + "debug": "偵錯", + "info": "資訊", + "warn": "警告", + "err": "錯誤", + "critical": "嚴重", + "off": "關閉", + "selectLogLevel": "選擇紀錄層級" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/cht/src/vs/workbench/parts/markers/common/messages.i18n.json index 7fd5ffaf852..c754d02f873 100644 --- a/i18n/cht/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "viewCategory": "檢視", - "problems.view.toggle.label": "切換問題", - "problems.view.focus.label": "聚焦問題", "problems.panel.configuration.title": "[問題] 檢視", "problems.panel.configuration.autoreveal": "控制 [問題] 檢視是否應自動在開啟檔案時加以顯示", "markers.panel.title.problems": "問題", diff --git a/i18n/cht/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..8199db7ebb6 --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "輸出", + "logViewer": "紀錄檢視器", + "viewCategory": "檢視", + "clearOutput.label": "清除輸出" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/cht/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..23c47ff24dc --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "{0} - 輸出", + "channel": "'{0}' 的輸出通道" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/cht/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index 480c3d2dbc2..5c3acf7c7d6 100644 --- a/i18n/cht/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "試試自然語言搜尋!", "defaultSettings": "將您的設定放置於右方編輯器中以覆寫。", "noSettingsFound": "找不到任何設定。", "settingsSwitcherBarAriaLabel": "設定切換器", "userSettings": "使用者設定", "workspaceSettings": "工作區設定", - "folderSettings": "資料夾設定", - "enableFuzzySearch": "啟用自然語言搜尋" + "folderSettings": "資料夾設定" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/cht/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index 3aed5852085..4a5625894bd 100644 --- a/i18n/cht/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "經常使用的", - "mostRelevant": "最相關的", "defaultKeybindingsHeader": "將按鍵組合放入您的按鍵組合檔案中加以覆寫。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index 238b60d7007..6a7eae1ed19 100644 --- a/i18n/cht/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "檢視", "commandsHandlerDescriptionDefault": "顯示並執行命令", "gotoLineDescriptionMac": "移至行", "gotoLineDescriptionWin": "移至行", diff --git a/i18n/cht/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index c0bccd6864c..5485a14415f 100644 --- a/i18n/cht/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,9 @@ "toggleGitViewlet": "顯示 Git", "source control": "原始檔控制", "toggleSCMViewlet": "顯示 SCM", - "view": "檢視" + "view": "檢視", + "scmConfigurationTitle": "原始碼管理 (SCM)", + "alwaysShowProviders": "是否總是顯示原始檔控制提供者區段", + "diffDecorations": "控制差異裝飾於編輯器中", + "inputCounter": "控制何時顯示輸入計數器" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json b/i18n/cht/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json index 72f9807aa29..2b766995de4 100644 --- a/i18n/cht/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json @@ -6,6 +6,9 @@ { "scm providers": "原始檔控制提供者", "hideRepository": "隱藏", + "commitMessageInfo": "在目前行數有 {0} 個字元", + "commitMessageCountdown": "在目前行數剩餘 {0} 個字元", + "commitMessageWarning": "在目前行數有 {0} 個字元已超過 {1} 個", "installAdditionalSCMProviders": "安裝額外SCM提供者...", "no open repo": "沒有使用中的原始檔控制提供者。", "source control": "原始檔控制", diff --git a/i18n/cht/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/cht/src/vs/workbench/parts/search/browser/searchActions.i18n.json index 551008efc78..e52a383a212 100644 --- a/i18n/cht/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "顯示上一個搜尋字詞", "showSearchViewlet": "顯示搜尋", "findInFiles": "在檔案中尋找", - "findInFilesWithSelectedText": "在檔案中尋找選取的文字 ", "replaceInFiles": "檔案中取代", - "replaceInFilesWithSelectedText": "在檔案中取代為選取的文字", "RefreshAction.label": "重新整理", "CollapseDeepestExpandedLevelAction.label": "全部摺疊", "ClearSearchResultsAction.label": "清除", diff --git a/i18n/cht/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index 2737e83ab4e..1244f50ad8c 100644 --- a/i18n/cht/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "在資料夾中尋找...", + "findInWorkspace": "在工作區中尋找...", "showTriggerActions": "前往工作區中的符號...", "name": "搜尋", "search": "搜尋", + "showSearchViewlet": "顯示搜尋", "view": "檢視", + "findInFiles": "在檔案中尋找", "openAnythingHandlerDescription": "前往檔案", "openSymbolDescriptionNormal": "前往工作區中的符號", "searchOutputChannelTitle": "搜尋", diff --git a/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..dfb95035915 --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.scope": "(全域)", + "global.1": "({0})", + "new.global": "新增全域程式碼片段檔案...", + "group.global": "現有程式碼片段", + "new.global.sep": "新增程式碼片段", + "openSnippet.pickLanguage": "選取程式碼片段檔案或建立程式碼片段", + "openSnippet.label": "設定使用者程式碼片段", + "preferences": "喜好設定" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 10abf9bdd4d..115f5980d39 100644 --- a/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,10 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "為程式碼片段選取語言", - "openSnippet.errorOnCreate": "無法建立 {0}", - "openSnippet.label": "開啟使用者程式碼片段", - "preferences": "喜好設定", "snippetSchema.json.default": "空白程式碼片段", "snippetSchema.json": "使用者程式碼片段組態", "snippetSchema.json.prefix": "在 Intellisense 中選取程式碼片段時要使用的前置詞", diff --git a/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..4a43b9b0daf --- /dev/null +++ b/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "使用者程式碼片段" +} \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index e7261d392fd..bcbd784bf1c 100644 --- a/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "`contributes.{0}.language` 中的不明語言。提供的值: {1}", "invalid.path.0": "'contributes.{0}.path' 中應有字串。提供的值: {1}", + "invalid.language": "`contributes.{0}.language` 中的不明語言。提供的值: {1}", "invalid.path.1": "擴充功能資料夾 ({2}) 應包含 'contributes.{0}.path' ({1})。這可能會導致擴充功能無法移植。", "vscode.extension.contributes.snippets": "提供程式碼片段。", "vscode.extension.contributes.snippets-language": "要予以提供此程式碼片段的語言識別碼。", "vscode.extension.contributes.snippets-path": "程式碼片段檔案的路徑。此路徑是擴充功能資料夾的相對路徑,而且一般會以 './snippets/' 開頭。", "badVariableUse": "來自延伸模組 '{0}' 的一或多個程式碼片段很可能會混淆程式碼片段變數和程式碼片段預留位置 (如需更多詳細資料,請參閱 https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax)", "badFile": "無法讀取程式碼片段檔案 \"{0}\"。", - "source.snippet": "使用者程式碼片段", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0},{1}" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index 80abe8bb59c..d824ac236e9 100644 --- a/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -14,6 +14,7 @@ "terminal.integrated.shell.windows": "終端機在 Windows 上使用的殼層路徑。使用隨附於 Windows 的殼層 (cmd、PowerShell 或 Bash on Ubuntu) 時。", "terminal.integrated.shellArgs.windows": "在 Windows 終端機上時要使用的命令列引數。", "terminal.integrated.rightClickCopyPaste": "如有設定,這會防止在終端機內按滑鼠右鍵時顯示操作功能表,而是在有選取項目時複製、沒有選取項目時貼上。", + "terminal.integrated.copyOnSelection": "當設定時,在終端機中選擇的文字將會被複製至剪貼簿", "terminal.integrated.fontFamily": "控制終端機的字型家族,預設為 editor.fontFamily 的值。", "terminal.integrated.fontSize": "控制終端機的字型大小 (以像素為單位)。", "terminal.integrated.lineHeight": "控制終端機的行高,此數字會乘上終端機字型大小,以取得以像素為單位的實際行高。", diff --git a/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json b/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json index 40342458179..3338d6ea3da 100644 --- a/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json @@ -14,6 +14,8 @@ "workbench.action.terminal.deleteWordRight": "刪除右方文字", "workbench.action.terminal.new": "建立新的整合式終端機", "workbench.action.terminal.new.short": "新增終端機", + "workbench.action.terminal.newWorkspacePlaceholder": "為新的終端機選擇目前的工作目錄", + "workbench.action.terminal.newInActiveWorkspace": "建立新的整合式終端機 (於目前工作區)", "workbench.action.terminal.focus": "聚焦終端機", "workbench.action.terminal.focusNext": "聚焦下一個終端機", "workbench.action.terminal.focusPrevious": "聚焦上一個終端機", diff --git a/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index fc6b0624a08..331a28ddaf2 100644 --- a/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,6 @@ "terminal.integrated.chooseWindowsShellInfo": "您可以選取 [自訂] 按鈕變更預設的終端機殼層。", "customize": "自訂", "cancel": "取消", - "never again": "確定,不要再顯示", "terminal.integrated.chooseWindowsShell": "請選取所需的終端機殼層。您之後可以在設定中變更此選擇", "terminalService.terminalCloseConfirmationSingular": "仍有一個使用中的終端機工作階段。要予以終止嗎?", "terminalService.terminalCloseConfirmationPlural": "目前共有 {0} 個使用中的終端機工作階段。要予以終止嗎?" diff --git a/i18n/cht/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/cht/src/vs/workbench/parts/update/electron-browser/update.i18n.json index e043af15328..0090723f9a2 100644 --- a/i18n/cht/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -23,6 +23,7 @@ "commandPalette": "命令選擇區...", "settings": "設定", "keyboardShortcuts": "鍵盤快速鍵(&&K)", + "userSnippets": "使用者程式碼片段", "selectTheme.label": "色彩佈景主題", "themes.selectIconTheme.label": "檔案圖示佈景主題", "not available": "無可用更新", diff --git a/i18n/cht/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/cht/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 067f2923a48..106253b1f0c 100644 --- a/i18n/cht/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/cht/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "檔案是目錄", + "fileNotModifiedError": "未修改檔案的時間", "fileBinaryError": "檔案似乎是二進位檔,因此無法當做文字開啟" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/services/files/node/fileService.i18n.json b/i18n/cht/src/vs/workbench/services/files/node/fileService.i18n.json index de69c42ba6c..d44f480acd2 100644 --- a/i18n/cht/src/vs/workbench/services/files/node/fileService.i18n.json +++ b/i18n/cht/src/vs/workbench/services/files/node/fileService.i18n.json @@ -10,6 +10,7 @@ "fileTooLargeError": "檔案太大無法開啟", "fileNotFoundError": "找不到檔案 ({0})", "fileBinaryError": "檔案似乎是二進位檔,因此無法當做文字開啟", + "filePermission": "寫至檔案 ({0}) 的權限遭拒", "fileExists": "要建立的檔案已存在 ({0})", "fileMoveConflict": "無法移動/複製。目的地已存在檔案。", "unableToMoveCopyError": "無法移動/複製。檔案會取代其所在的資料夾。", diff --git a/i18n/cht/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json b/i18n/cht/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json index 3d15720ddec..2068790ab0f 100644 --- a/i18n/cht/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json +++ b/i18n/cht/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json @@ -22,5 +22,6 @@ "keybindings.json.when": "按鍵為使用中時的條件。", "keybindings.json.args": "要傳遞至命令加以執行的引數。", "keyboardConfigurationTitle": "鍵盤", - "dispatch": "控制按下按鍵時的分派邏輯 (使用 'code' (建議使用) 或 'keyCode')。" + "dispatch": "控制按下按鍵時的分派邏輯 (使用 'code' (建議使用) 或 'keyCode')。", + "touchbar.enabled": "啟用鍵盤上的 macOS 觸摸板按鈕 (如果可用)。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/cht/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index 5fb9fd9998b..fe4c04e35cd 100644 --- a/i18n/cht/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/cht/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "要儲存對 {0} 所做的變更嗎?", "saveChangesMessages": "要儲存對下列 {0} 個檔案所做的變更嗎?", - "moreFile": "...另外 1 個檔案未顯示", - "moreFiles": "...另外 {0} 個檔案未顯示", "saveAll": "全部儲存(&&S)", "save": "儲存(&&S)", "dontSave": "不要儲存(&&N)", diff --git a/i18n/cht/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/cht/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index 939ead9df9c..8096baf2953 100644 --- a/i18n/cht/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/cht/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "No file icons", "iconThemeError": "File icon theme is unknown or not installed.", "workbenchColors": "依目前選擇的彩色佈景主題覆寫顏色", - "editorColors": "依目前選取的色彩佈景主題覆寫編輯器色彩與字型樣式。", "editorColors.comments": "設定註解的色彩與樣式", "editorColors.strings": "設定字串常值的色彩與樣式。", "editorColors.keywords": "設定關鍵字的色彩與樣式。", @@ -19,5 +18,6 @@ "editorColors.types": "設定型別宣告與參考的色彩與樣式。", "editorColors.functions": "設定函式宣告與參考的色彩與樣式。", "editorColors.variables": "設定變數宣告與參考的色彩與樣式。", - "editorColors.textMateRules": "使用 TextMate 佈景主題規則設定色彩與樣式 (進階)。" + "editorColors.textMateRules": "使用 TextMate 佈景主題規則設定色彩與樣式 (進階)。", + "editorColors": "依目前選取的色彩佈景主題覆寫編輯器色彩與字型樣式。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/cht/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 283d3809ddb..e0710f14e3f 100644 --- a/i18n/cht/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/cht/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "無法寫入工作區組態檔。請開啟檔案更正其中的錯誤/警告,然後再試一次。 ", "errorWorkspaceConfigurationFileDirty": "因為檔案已變更,所以無法寫入工作區組態檔。請將其儲存,然後再試一次。", "openWorkspaceConfigurationFile": "開啟工作區組態檔", - "close": "關閉", - "enterWorkspace.close": "關閉", - "enterWorkspace.dontShowAgain": "不要再顯示", - "enterWorkspace.moreInfo": "詳細資訊", - "enterWorkspace.prompt": "深入了解在 VS Code 中使用多個資料夾。" + "close": "關閉" } \ No newline at end of file diff --git a/i18n/deu/extensions/git/out/autofetch.i18n.json b/i18n/deu/extensions/git/out/autofetch.i18n.json index e1242008fcf..5a1bb589fb2 100644 --- a/i18n/deu/extensions/git/out/autofetch.i18n.json +++ b/i18n/deu/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "Ja", + "read more": "Weitere Informationen", "no": "Nein", - "not now": "Nicht jetzt", - "suggest auto fetch": "Möchten Sie das automatische Abrufen von Git-Repositorys aktivieren?" + "not now": "Erneut nachfragen", + "suggest auto fetch": "Möchten Sie Code regelmäßig `git fetch` ausführen lassen?" } \ No newline at end of file diff --git a/i18n/deu/extensions/git/out/commands.i18n.json b/i18n/deu/extensions/git/out/commands.i18n.json index 27787e3b3d4..106aebcff97 100644 --- a/i18n/deu/extensions/git/out/commands.i18n.json +++ b/i18n/deu/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\nDies kann NICHT rückgängig gemacht werden, und Ihr aktueller Arbeitssatz geht DAUERHAFT verloren.", "yes discard tracked": "1 verfolgte Datei verwerfen", "yes discard tracked multiple": "{0} verfolgte Dateien verwerfen", + "unsaved files single": "Die folgende Datei ist nicht gespeichert: {0}.\n\nMöchten Sie diese vor dem Committen speichern?", + "unsaved files": "{0} Dateien sind nicht gespeichert.\n\nMöchten Sie diese vor dem Committen speichern?", + "save and commit": "Alles speichern und committen", + "commit": "Trotzdem committen", "no staged changes": "Es sind keine Änderungen bereitgestellt.\n\nMöchten Sie alle Ihre Änderungen automatisch bereitstellen und direkt committen?", "always": "Immer", "no changes": "Keine Änderungen zum Speichern vorhanden.", @@ -64,12 +68,11 @@ "no remotes to pull": "In Ihrem Repository wurden keine Remoteelemente für den Pull konfiguriert.", "pick remote pull repo": "Remoteelement zum Pullen des Branch auswählen", "no remotes to push": "In Ihrem Repository wurden keine Remoteelemente für den Push konfiguriert.", - "push with tags success": "Push mit Tags erfolgreich ausgeführt.", "nobranch": "Wählen Sie ein Branch für den Push zu einem Remoteelement aus.", + "ok": "OK", + "push with tags success": "Push mit Tags erfolgreich ausgeführt.", "pick remote": "Remotespeicherort auswählen, an dem der Branch \"{0}\" veröffentlicht wird:", "sync is unpredictable": "Mit dieser Aktion werden Commits per Push und Pull an und von \"{0}\" übertragen.", - "ok": "OK", - "never again": "OK, nicht mehr anzeigen", "no remotes to publish": "In Ihrem Repository wurden keine Remoteelemente für die Veröffentlichung konfiguriert.", "no changes stash": "Es sind keine Änderungen vorhanden, für die ein Stash ausgeführt werden kann.", "provide stash message": "Geben Sie optional eine Stash-Nachricht ein.", diff --git a/i18n/deu/extensions/git/out/repository.i18n.json b/i18n/deu/extensions/git/out/repository.i18n.json index 9c6af561332..cb3c5c9809f 100644 --- a/i18n/deu/extensions/git/out/repository.i18n.json +++ b/i18n/deu/extensions/git/out/repository.i18n.json @@ -27,6 +27,6 @@ "staged changes": "Bereitgestellte Änderungen", "changes": "Änderungen", "ok": "OK", - "neveragain": "Nie wieder anzeigen", + "neveragain": "Nicht mehr anzeigen", "huge": "Das Git-Repository unter {0} umfasst zu viele aktive Änderungen. Nur ein Teil der Git-Features wird aktiviert." } \ No newline at end of file diff --git a/i18n/deu/extensions/git/package.i18n.json b/i18n/deu/extensions/git/package.i18n.json index de4d841dd21..eba5779a178 100644 --- a/i18n/deu/extensions/git/package.i18n.json +++ b/i18n/deu/extensions/git/package.i18n.json @@ -54,12 +54,12 @@ "command.stashPopLatest": "Pop für letzten Stash ausführen", "config.enabled": "Gibt an, ob Git aktiviert ist.", "config.path": "Der Pfad zur ausführbaren Git-Datei.", + "config.autoRepositoryDetection": "Ob Repositorien automatisch erkannt werden sollen", "config.autorefresh": "Gibt an, ob die automatische Aktualisierung aktiviert ist.", "config.autofetch": "Gibt an, ob automatischer Abruf aktiviert ist.", "config.enableLongCommitWarning": "Gibt an, ob Warnungen zu langen Commitnachrichten erfolgen sollen.", "config.confirmSync": "Vor dem Synchronisieren von Git-Repositorys bestätigen.", "config.countBadge": "Steuert die Git-Badgeanzahl. \"Alle\" zählt alle Änderungen. \"tracked\" (Nachverfolgt) zählt nur die nachverfolgten Änderungen. \"off\" (Aus) deaktiviert dies.", - "config.checkoutType": "Steuert, welcher Branchtyp beim Ausführen von \"Auschecken an...\" aufgelistet wird. \"Alle\" zeigt alle Verweise an, \"Lokal\" nur die lokalen Branches, \"Tags\" zeigt nur Tags an, und \"Remote\" zeigt nur Remotebranches an.", "config.ignoreLegacyWarning": "Ignoriert die Legacy-Git-Warnung.", "config.ignoreMissingGitWarning": "Ignoriert die Warnung, wenn Git fehlt", "config.ignoreLimitWarning": "Ignoriert Warnung bei zu hoher Anzahl von Änderungen in einem Repository", @@ -72,5 +72,6 @@ "colors.deleted": "Farbe für gelöschten Ressourcen.", "colors.untracked": "Farbe für nicht verfolgte Ressourcen.", "colors.ignored": "Farbe für ignorierte Ressourcen.", - "colors.conflict": "Farbe für Ressourcen mit Konflikten." + "colors.conflict": "Farbe für Ressourcen mit Konflikten.", + "colors.submodule": "Farbe für Submodul-Ressourcen." } \ No newline at end of file diff --git a/i18n/deu/extensions/typescript/out/commands.i18n.json b/i18n/deu/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..abb5c164718 --- /dev/null +++ b/i18n/deu/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "Öffnen Sie einen Ordner in VS Code, um ein TypeScript- oder JavaScript-Projekt zu verwenden.", + "typescript.projectConfigUnsupportedFile": "TypeScript- oder JavaScript-Projekt konnte nicht ermittelt werden. Nicht unterstützter Dateityp.", + "typescript.projectConfigCouldNotGetInfo": "TypeScript- oder JavaScript-Projekt konnte nicht ermittelt werden.", + "typescript.noTypeScriptProjectConfig": "Datei ist nicht Teil eines TypeScript-Projekts.", + "typescript.noJavaScriptProjectConfig": "Datei ist nicht Teil eines JavaScript-Projekts.", + "typescript.configureTsconfigQuickPick": "tsconfig.json konfigurieren", + "typescript.configureJsconfigQuickPick": "jsconfig.json konfigurieren", + "typescript.projectConfigLearnMore": "Weitere Informationen" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/deu/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/deu/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/base/node/ps.i18n.json b/i18n/deu/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..eb881148d8c --- /dev/null +++ b/i18n/deu/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "Sammeln von CPU- und Speicherinformationen. Dies kann einige Sekunden dauern." +} \ No newline at end of file diff --git a/i18n/deu/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/deu/src/vs/editor/common/config/commonEditorConfig.i18n.json index 42d65e250ff..ed57dd20d06 100644 --- a/i18n/deu/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/deu/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "Zeilennummern werden als absolute Zahl dargestellt.", "lineNumbers.relative": "Zeilennummern werden als Abstand in Zeilen an Cursorposition dargestellt.", "lineNumbers.interval": "Zeilennummern werden alle 10 Zeilen dargestellt.", - "lineNumbers": "Steuert die Anzeige von Zeilennummern. Mögliche Werte sind \"Ein\", \"Aus\" und \"Relativ\".", + "lineNumbers": "Steuert die Anzeige von Zeilennummern. Mögliche Werte sind \"on\", \"off\", \"relative\" und \"interval\".", "rulers": "Vertikale Linien nach einer bestimmten Anzahl von Monospace Zeichen zeichnen. Verwenden Sie mehrere Werte für mehrere Linien. Keine Linie wird gezeichnet, wenn das Array leer ist.", "wordSeparators": "Zeichen, die als Worttrennzeichen verwendet werden, wenn wortbezogene Navigationen oder Vorgänge ausgeführt werden.", "tabSize": "Die Anzahl der Leerzeichen, denen ein Tabstopp entspricht. Diese Einstellung wird basierend auf dem Inhalt der Datei überschrieben, wenn \"editor.detectIndentation\" aktiviert ist.", @@ -72,6 +72,7 @@ "cursorBlinking": "Steuert den Cursoranimationsstil. Gültige Werte sind \"blink\", \"smooth\", \"phase\", \"expand\" und \"solid\".", "mouseWheelZoom": "Schriftart des Editors vergrößern, wenn das Mausrad verwendet und die STRG-TASTE gedrückt wird", "cursorStyle": "Steuert den Cursorstil. Gültige Werte sind \"block\", \"block-outline\", \"line\", \"line-thin\", \"underline\" und \"underline-thin\".", + "lineCursorWidth": "Steuert die Breite des Cursors, falls editor.cursorStyle auf \"line\" gestellt ist.", "fontLigatures": "Aktiviert Schriftartligaturen.", "hideCursorInOverviewRuler": "Steuert die Sichtbarkeit des Cursors im Übersichtslineal.", "renderWhitespace": "Steuert, wie der Editor Leerzeichen rendert. Mögliche Optionen: \"none\", \"boundary\" und \"all\". Die Option \"boundary\" rendert keine einzelnen Leerzeichen zwischen Wörtern.", diff --git a/i18n/deu/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/deu/src/vs/editor/common/view/editorColorRegistry.i18n.json index fa37f670425..7c9c0c38962 100644 --- a/i18n/deu/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/deu/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,7 @@ { "lineHighlight": "Hintergrundfarbe zur Hervorhebung der Zeile an der Cursorposition.", "lineHighlightBorderBox": "Hintergrundfarbe für den Rahmen um die Zeile an der Cursorposition.", - "rangeHighlight": "Hintergrundfarbe hervorgehobener Bereiche (beispielsweise durch Features wie Quick Open und Suche).", + "rangeHighlight": "Hintergrundfarbe hervorgehobener Bereiche, beispielsweise durch Features wie Quick Open und Suche. Die Farbe muss durchsichtig sein, um dahinterliegende Dekorationen nicht zu verbergen. ", "caret": "Farbe des Cursors im Editor.", "editorCursorBackground": "Hintergrundfarbe vom Editor-Cursor. Erlaubt die Anpassung der Farbe von einem Zeichen, welches von einem Block-Cursor überdeckt wird.", "editorWhitespaces": "Farbe der Leerzeichen im Editor.", diff --git a/i18n/deu/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/deu/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 02553773e89..f0964e09e29 100644 --- a/i18n/deu/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/deu/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "Gehe zum nächsten Fehler oder zur nächsten Warnung", - "markerAction.previous.label": "Gehe zum vorherigen Fehler oder zur vorherigen Warnung", + "markerAction.next.label": "Gehe zu nächstem Problem (Fehler, Warnung, Information)", + "markerAction.previous.label": "Gehe zu vorigem Problem (Fehler, Warnung, Information)", "editorMarkerNavigationError": "Editormarkierung: Farbe bei Fehler des Navigationswidgets.", "editorMarkerNavigationWarning": "Editormarkierung: Farbe bei Warnung des Navigationswidgets.", "editorMarkerNavigationInfo": "Editormarkierung: Farbe bei Warnung des Navigationswidgets.", diff --git a/i18n/deu/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/deu/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index d706ff2e9b2..494db968f98 100644 --- a/i18n/deu/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/deu/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "Hintergrundfarbe eines Symbols beim Lesezugriff (beispielsweise beim Lesen einer Variablen).", - "wordHighlightStrong": "Hintergrundfarbe eines Symbols beim Schreibzugriff (beispielsweise beim Schreiben in eine Variable).", + "wordHighlight": "Hintergrundfarbe eines Symbols bei Lesezugriff, beispielsweise dem Lesen einer Variable. Die Farbe muss durchsichtig sein, um nicht dahinterliegende Dekorationen zu verbergen.", + "wordHighlightStrong": "Hintergrundfarbe eines Symbols bei Schreibzugriff, beispielsweise dem Schreiben einer Variable. Die Farbe muss durchsichtig sein, um nicht dahinterliegende Dekorationen zu verbergen.", "overviewRulerWordHighlightForeground": "Übersichtslineal-Markierungsfarbe für Symbolhervorhebungen.", "overviewRulerWordHighlightStrongForeground": "Übersichtslineal-Markierungsfarbe für Schreibzugriffs-Symbolhervorhebungen.", "wordHighlight.next.label": "Gehe zur nächsten Symbolhervorhebungen", diff --git a/i18n/deu/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/deu/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index 5cd50df300a..30e3fed7ba6 100644 --- a/i18n/deu/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/deu/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "\"{0}\" ist kein gültiger Menübezeichner.", "missing.command": "Das Menüelement verweist auf einen Befehl \"{0}\", der im Abschnitt \"commands\" nicht definiert ist.", "missing.altCommand": "Das Menüelement verweist auf einen Alternativbefehl \"{0}\", der im Abschnitt \"commands\" nicht definiert ist.", - "dupe.command": "Das Menüelement verweist auf den gleichen Befehl wie der Standard- und der Alternativbefehl.", - "nosupport.altCommand": "Leider unterstützt zurzeit nur die Gruppe \"navigation\" des Menüs \"editor/title\" Alternativbefehle." + "dupe.command": "Das Menüelement verweist auf den gleichen Befehl wie der Standard- und der Alternativbefehl." } \ No newline at end of file diff --git a/i18n/deu/src/vs/platform/environment/node/argv.i18n.json b/i18n/deu/src/vs/platform/environment/node/argv.i18n.json index e990ea9bf1e..dac01ef64d6 100644 --- a/i18n/deu/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/deu/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,35 @@ "diff": "Vergleicht zwei Dateien.", "add": "Fügt einen oder mehrere Ordner zum letzten aktiven Fenster hinzu.", "goto": "Öffnet eine Datei im Pfad in der angegebenen Zeile und an der Zeichenposition.", - "locale": "Das zu verwendende Gebietsschema (z. B. en-US oder zh-TW).", "newWindow": "Erzwingt eine neue Instanz des Codes.", - "performance": "Startet mit aktiviertem Befehl \"Developer: Startup Performance\".", - "prof-startup": "CPU-Profiler beim Start ausführen", - "inspect-extensions": "Erlaubt Debugging und Profiling für Erweiterungen. Überprüfen Sie die Entwicklertools für die Verbindungs-URI.", - "inspect-brk-extensions": "Erlaubt Debugging und Profiling für Erweiterungen, wobei der Erweiterungs-Host nach dem Starten pausiert wird. Überprüfen Sie die Entwicklertools für die Verbindungs-URI.", "reuseWindow": "Erzwingt das Öffnen einer Datei oder eines Ordners im letzten aktiven Fenster.", - "userDataDir": "Gibt das Verzeichnis an, in dem Benutzerdaten gespeichert werden. Nützlich, wenn die Ausführung als \"root\" erfolgt.", - "log": "Log-Level zu verwenden. Standardwert ist \"Info\". Zulässige Werte sind \"kritisch\", \"Fehler\", \"warnen\", \"Info\", \"debug\", \"verfolgen\", \"aus\".", - "verbose": "Ausführliche Ausgabe (impliziert \"-wait\").", "wait": "Warten Sie, bis die Dateien geschlossen sind, bevor Sie zurück gehen können.", + "locale": "Das zu verwendende Gebietsschema (z. B. en-US oder zh-TW).", + "userDataDir": "Gibt das Verzeichnis an, in dem Benutzerdaten gespeichert werden. Nützlich, wenn die Ausführung als \"root\" erfolgt.", + "version": "Gibt die Version aus.", + "help": "Gibt die Syntax aus.", "extensionHomePath": "Legen Sie den Stammpfad für Extensions fest.", "listExtensions": "Listet die installierten Extensions auf.", "showVersions": "Zeigt Versionen der installierten Erweiterungen an, wenn \"--list-extension\" verwendet wird.", "installExtension": "Installiert eine Extension.", "uninstallExtension": "Deinstalliert eine Extension.", "experimentalApis": "Aktiviert vorgeschlagene API-Features für eine Erweiterung.", - "disableExtensions": "Deaktiviert alle installierten Extensions.", - "disableGPU": "Deaktiviert die GPU-Hardwarebeschleunigung.", + "verbose": "Ausführliche Ausgabe (impliziert \"-wait\").", + "log": "Log-Level zu verwenden. Standardwert ist \"Info\". Zulässige Werte sind \"kritisch\", \"Fehler\", \"warnen\", \"Info\", \"debug\", \"verfolgen\", \"aus\".", "status": "Prozessnutzungs- und Diagnose-Informationen ausgeben.", - "version": "Gibt die Version aus.", - "help": "Gibt die Syntax aus.", + "performance": "Startet mit aktiviertem Befehl \"Developer: Startup Performance\".", + "prof-startup": "CPU-Profiler beim Start ausführen", + "disableExtensions": "Deaktiviert alle installierten Extensions.", + "inspect-extensions": "Erlaubt Debugging und Profiling für Erweiterungen. Überprüfen Sie die Entwicklertools für die Verbindungs-URI.", + "inspect-brk-extensions": "Erlaubt Debugging und Profiling für Erweiterungen, wobei der Erweiterungs-Host nach dem Starten pausiert wird. Überprüfen Sie die Entwicklertools für die Verbindungs-URI.", + "disableGPU": "Deaktiviert die GPU-Hardwarebeschleunigung.", + "uploadLogs": "Lädt die Logs der aktuellen Sitzung an einem sicheren Endpunkt hoch.", "usage": "Verwendung", "options": "Optionen", "paths": "Pfade", - "optionsUpperCase": "Optionen" + "stdinWindows": "Zum Einlesen von Ausgaben eines anderen Programms hängen Sie '-' an (z.B. 'echo Hello World | {0} -')", + "stdinUnix": "Zum Einlesen von stdin hängen Sie '-' an (z.B. 'ps aux | grep code | {0} -')", + "optionsUpperCase": "Optionen", + "extensionsManagement": "Erweiterungsverwaltung", + "troubleshooting": "Problembehandlung" } \ No newline at end of file diff --git a/i18n/deu/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/deu/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index 256756a3fdd..bd3552bcdfe 100644 --- a/i18n/deu/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/deu/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,15 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "Die Erweiterung ist ungültig: \"package.json\" ist keine JSON-Datei.", - "restartCodeLocal": "Bitte starten Sie Code vor der Neuinstallation von {0} neu.", + "restartCode": "Bitte starten Sie Code vor der Neuinstallation von {0} neu.", "installingOutdatedExtension": "Eine neuere Version dieser Erweiterung ist bereits installiert. Möchten Sie diese mit der älteren Version überschreiben?", "override": "Überschreiben", "cancel": "Abbrechen", - "notFoundCompatible": "Kann nicht installiert werden, da die Erweiterung '{0}', die mit der aktuellen Version '{1}' von VS Code kompatibel ist, nicht gefunden werden kann.", - "quitCode": "Kann nicht installiert werden, da noch eine veraltete Instanz der Erweiterung ausgeführt wird. Bitte beenden und VS Code neu starten vor der Neuinstallation.", - "exitCode": "Kann nicht installiert werden, da noch eine veraltete Instanz der Erweiterung ausgeführt wird. Bitte beenden und VS Code neu starten vor der Neuinstallation.", + "errorInstallingDependencies": "Fehler während Installation der Abhängigkeiten. {0}", + "notFoundCompatible": "'{0}' kann nicht installiert werden: Es gibt keine mit VS Code '{1}' kompatible Version.", "notFoundCompatibleDependency": "Kann nicht installiert werden, da die abhängige Erweiterung '{0}', die mit der aktuellen VS Code Version '{1}' kompatibel ist, nicht gefunden werden kann. ", + "quitCode": "Fehler bei der Installation der Erweiterung. Beenden und starten Sie VS Code vor der erneuten Installation neu.", + "exitCode": "Fehler bei der Installation der Erweiterung. Beenden und starten Sie VS Code vor der erneuten Installation neu.", "uninstallDependeciesConfirmation": "Möchten Sie nur \"{0}\" oder auch die zugehörigen Abhängigkeiten deinstallieren?", "uninstallOnly": "Nur", "uninstallAll": "Alle", diff --git a/i18n/deu/src/vs/platform/message/common/message.i18n.json b/i18n/deu/src/vs/platform/message/common/message.i18n.json index f4286f9eb78..774ad662835 100644 --- a/i18n/deu/src/vs/platform/message/common/message.i18n.json +++ b/i18n/deu/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "Schließen", "later": "Später", - "cancel": "Abbrechen" + "cancel": "Abbrechen", + "moreFile": "...1 weitere Datei wird nicht angezeigt", + "moreFiles": "...{0} weitere Dateien werden nicht angezeigt" } \ No newline at end of file diff --git a/i18n/deu/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/deu/src/vs/platform/theme/common/colorRegistry.i18n.json index 93785571085..9159f1402da 100644 --- a/i18n/deu/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/deu/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,10 @@ "editorWidgetBorder": "Rahmenfarbe von Editorwigdets. Die Farbe wird nur verwendet, wenn für das Widget ein Rahmen verwendet wird und die Farbe nicht von einem Widget überschrieben wird.", "editorSelectionBackground": "Farbe der Editor-Auswahl.", "editorSelectionForeground": "Farbe des gewählten Text für einen hohen Kontrast", - "editorInactiveSelection": "Farbe der Auswahl in einem inaktiven Editor.", - "editorSelectionHighlight": "Farbe für Bereiche, deren Inhalt der Auswahl entspricht.", + "editorInactiveSelection": "Farbe der Auswahl in einem inaktiven Editor. Die Farbe muss durchsichtig sein, um dahinterliegende Dekorationen nicht zu verbergen. ", + "editorSelectionHighlight": "Farbe für Bereiche, deren Inhalt der Auswahl entspricht. Die Farbe muss durchsichtig sein, um dahinterliegende Dekorationen nicht zu verbergen.", "editorFindMatch": "Farbe des aktuellen Suchergebnisses.", - "findMatchHighlight": "Farbe der anderen Suchtreffer.", - "findRangeHighlight": "Farbe des Bereichs zur Einschränkung der Suche.", - "hoverHighlight": "Hervorhebung eines Worts, unter dem ein Mauszeiger angezeigt wird.", + "findMatchHighlight": "Farbe der anderen Suchergebnisse. Die Farbe muss durchsichtig sein, um dahinterliegende Dekorationen nicht zu verbergen. ", "hoverBackground": "Background color of the editor hover.", "hoverBorder": "Rahmenfarbe des Editor-Mauszeigers.", "activeLinkForeground": "Farbe der aktiven Links.", @@ -76,12 +74,10 @@ "diffEditorRemoved": "Hintergrundfarbe für entfernten Text.", "diffEditorInsertedOutline": "Konturfarbe für eingefügten Text.", "diffEditorRemovedOutline": "Konturfarbe für entfernten Text.", - "mergeCurrentHeaderBackground": "Aktueller Kopfzeilenhintergrund in Inline-Mergingkonflikten.", - "mergeCurrentContentBackground": "Aktueller Inhaltshintergrund in Inline-Mergingkonflikten.", - "mergeIncomingHeaderBackground": "Eingehender Kopfzeilenhintergrund in Inline-Mergingkonflikten. ", - "mergeIncomingContentBackground": "Eingehender Inhaltshintergrund in Inline-Mergingkonflikten.", - "mergeCommonHeaderBackground": "Kopfzeilenhintergrund des gemeinsamen übergeordneten Elements bei Inlinezusammenführungskonflikten. ", - "mergeCommonContentBackground": "Inhaltshintergrund des gemeinsamen übergeordneten Elements bei Inlinezusammenführungskonflikten.", + "mergeCurrentHeaderBackground": "Aktueller Kopfzeilenhintergrund in Inline-Mergingkonflikten. Die Farbe muss durchsichtig sein, um dahinterliegende Dekorationen nicht zu verbergen.", + "mergeCurrentContentBackground": "Aktueller Inhaltshintergrund in Inline-Mergingkonflikten. Die Farbe muss durchsichtig sein, um dahinterliegende Dekorationen nicht zu verbergen. ", + "mergeIncomingHeaderBackground": "Hintergrund für eingehende Kopfzeile in Inline-Mergingkonflikten. Die Farbe muss durchsichtig sein, um dahinterliegende Dekorationen nicht zu verbergen. ", + "mergeIncomingContentBackground": "Hintergrund für eingehenden Inhalt in Inline-Mergingkonflikten. Die Farbe muss durchsichtig sein, um dahinterliegende Dekorationen nicht zu verbergen. ", "mergeBorder": "Rahmenfarbe für Kopfzeilen und die Aufteilung in Inline-Mergingkonflikten.", "overviewRulerCurrentContentForeground": "Aktueller Übersichtslineal-Vordergrund für Inline-Mergingkonflikte.", "overviewRulerIncomingContentForeground": "Eingehender Übersichtslineal-Vordergrund für Inline-Mergingkonflikte. ", diff --git a/i18n/deu/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/deu/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/deu/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/deu/src/vs/workbench/api/node/extHostTreeViews.i18n.json index 76a36688913..d76ac6f1642 100644 --- a/i18n/deu/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/deu/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -4,7 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "treeView.notRegistered": "Kein Treeviw mit der id '{0}' registriert.", - "treeItem.notFound": "Kein Tree-Eintrag mit der id '{0}' gefunden.", - "treeView.duplicateElement": "Element {0} ist bereit registriert." + "treeView.notRegistered": "Kein Treeviw mit der id '{0}' registriert." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/deu/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index c676a1ca340..c0039e0b445 100644 --- a/i18n/deu/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "Position der Seitenleiste wechseln", "view": "Anzeigen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/deu/src/vs/workbench/browser/actions/workspaceActions.i18n.json index 174408464b6..79911f9a8b9 100644 --- a/i18n/deu/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "Datei öffnen...", "openFolder": "Ordner öffnen...", "openFileFolder": "Öffnen...", - "addFolderToWorkspace": "Ordner zum Arbeitsbereich hinzufügen...", - "add": "&&Hinzufügen", - "addFolderToWorkspaceTitle": "Ordner zum Arbeitsbereich hinzufügen", "globalRemoveFolderFromWorkspace": "Ordner aus dem Arbeitsbereich entfernen...", - "removeFolderFromWorkspace": "Ordner aus dem Arbeitsbereich entfernen", - "openFolderSettings": "Ordnereinstellungen öffnen", "saveWorkspaceAsAction": "Arbeitsbereich speichern unter...", "save": "&&Speichern", "saveWorkspace": "Arbeitsbereich speichern", "openWorkspaceAction": "Arbeitsbereich öffnen...", "openWorkspaceConfigFile": "Konfigurationsdatei des Arbeitsbereichs öffnen", - "openFolderAsWorkspaceInNewWindow": "Ordner als Arbeitsbereich in neuem Fenster öffnen", - "workspaceFolderPickerPlaceholder": "Arbeitsbereichsordner auswählen" + "openFolderAsWorkspaceInNewWindow": "Ordner als Arbeitsbereich in neuem Fenster öffnen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/deu/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..60a543c8bba --- /dev/null +++ b/i18n/deu/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "Ordner zum Arbeitsbereich hinzufügen...", + "add": "&&Hinzufügen", + "addFolderToWorkspaceTitle": "Ordner zum Arbeitsbereich hinzufügen", + "workspaceFolderPickerPlaceholder": "Arbeitsbereichsordner auswählen" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/deu/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index 0812b9299a4..95de712113e 100644 --- a/i18n/deu/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,17 @@ "groupThreePicker": "Editoren in dritter Gruppe anzeigen", "allEditorsPicker": "Alle geöffneten Editoren anzeigen", "view": "Anzeigen", - "file": "Datei" + "file": "Datei", + "close": "Schließen", + "closeOthers": "Andere schließen", + "closeRight": "Rechts schließen", + "closeAllUnmodified": "Nicht geänderte schließen", + "closeAll": "Alle schließen", + "keepOpen": "Geöffnet lassen", + "showOpenedEditors": "Geöffnete Editoren anzeigen", + "keepEditor": "Editor beibehalten", + "closeEditorsInGroup": "Alle Editoren in der Gruppe schließen", + "closeUnmodifiedEditors": "Nicht geänderte Editoren in der Gruppe schließen", + "closeOtherEditors": "Andere Editoren schließen", + "closeRightEditors": "Editoren rechts schließen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/deu/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index eea7eefe298..f94ad3ec09a 100644 --- a/i18n/deu/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "Editor schließen", "revertAndCloseActiveEditor": "Wiederherstellen und Editor schließen", "closeEditorsToTheLeft": "Editoren links schließen", - "closeEditorsToTheRight": "Editoren rechts schließen", "closeAllEditors": "Alle Editoren schließen", - "closeUnmodifiedEditors": "Nicht geänderte Editoren in der Gruppe schließen", "closeEditorsInOtherGroups": "Editoren in anderen Gruppen schließen", - "closeOtherEditorsInGroup": "Andere Editoren schließen", - "closeEditorsInGroup": "Alle Editoren in der Gruppe schließen", "moveActiveGroupLeft": "Editor-Gruppe nach links verschieben", "moveActiveGroupRight": "Editor-Gruppe nach rechts verschieben", "minimizeOtherEditorGroups": "Andere Editor-Gruppen minimieren", "evenEditorGroups": "Gleichmäßige Breite der Editor-Gruppe", "maximizeEditor": "Editor-Gruppe maximieren und Randleiste ausblenden", - "keepEditor": "Editor beibehalten", "openNextEditor": "Nächsten Editor öffnen", "openPreviousEditor": "Vorherigen Editor öffnen", "nextEditorInGroup": "Nächsten Editor in der Gruppe öffnen", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "Editoren in erster Gruppe anzeigen", "showEditorsInSecondGroup": "Editoren in zweiter Gruppe anzeigen", "showEditorsInThirdGroup": "Editoren in dritter Gruppe anzeigen", - "showEditorsInGroup": "Editoren in der Gruppe anzeigen", "showAllEditors": "Alle Editoren anzeigen", "openPreviousRecentlyUsedEditorInGroup": "Vorherigen zuletzt verwendeten Editor in der Gruppe öffnen", "openNextRecentlyUsedEditorInGroup": "Nächsten zuletzt verwendeten Editor in der Gruppe öffnen", diff --git a/i18n/deu/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/deu/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 2b4ef55801b..9080d3ad0fb 100644 --- a/i18n/deu/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "Aktiven Editor nach Tabstopps oder Gruppen verschieben", "editorCommand.activeEditorMove.arg.name": "Argument zum Verschieben des aktiven Editors", - "editorCommand.activeEditorMove.arg.description": "Argumenteigenschaften:\n\t* \"to\": Ein Zeichenfolgenwert, der das Ziel des Verschiebungsvorgangs angibt.\n\t* \"by\": Ein Zeichenfolgenwert, der die Einheit für die Verschiebung angibt (nach Registerkarte oder nach Gruppe).\n\t* \"value\": Ein Zahlenwert, der angibt, um wie viele Positionen verschoben wird. Es kann auch die absolute Position für die Verschiebung angegeben werden.\n", - "commandDeprecated": "Der Befehl **{0}** wurde entfernt. Sie können stattdessen **{1}** verwenden.", - "openKeybindings": "Tastenkombinationen konfigurieren" + "editorCommand.activeEditorMove.arg.description": "Argumenteigenschaften:\n\t* \"to\": Ein Zeichenfolgenwert, der das Ziel des Verschiebungsvorgangs angibt.\n\t* \"by\": Ein Zeichenfolgenwert, der die Einheit für die Verschiebung angibt (nach Registerkarte oder nach Gruppe).\n\t* \"value\": Ein Zahlenwert, der angibt, um wie viele Positionen verschoben wird. Es kann auch die absolute Position für die Verschiebung angegeben werden.\n" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/deu/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index f5bb0f97396..c46090d7419 100644 --- a/i18n/deu/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "Textdateivergleichs-Editor", "navigate.next.label": "Nächste Änderung", "navigate.prev.label": "Vorherige Änderung", - "inlineDiffLabel": "Zur Inlineansicht wechseln", - "sideBySideDiffLabel": "Zur Parallelansicht wechseln" + "toggleIgnoreTrimWhitespace.label": "Keine Leerzeichen entfernen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/deu/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index 33a0388a647..4b868884b77 100644 --- a/i18n/deu/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "Schließen", - "closeOthers": "Andere schließen", - "closeRight": "Rechts schließen", - "closeAll": "Alle schließen", - "closeAllUnmodified": "Nicht geänderte schließen", - "keepOpen": "Geöffnet lassen", - "showOpenedEditors": "Geöffnete Editoren anzeigen", "araLabelEditorActions": "Editor-Aktionen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/deu/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index 5618ae8213a..4697a7de886 100644 --- a/i18n/deu/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[Nicht unterstützt]", + "userIsAdmin": "[Administrator]", + "userIsSudo": "[Superuser]", "devExtensionWindowTitlePrefix": "[Erweiterungsentwicklungshost]" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/deu/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index 147a1680ae9..8b6ad71cd4e 100644 --- a/i18n/deu/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/deu/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -3,6 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{ - "hideView": "Auf Randleiste ausblenden" -} \ No newline at end of file +{} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/common/theme.i18n.json b/i18n/deu/src/vs/workbench/common/theme.i18n.json index 4336f732bee..56819e7b1df 100644 --- a/i18n/deu/src/vs/workbench/common/theme.i18n.json +++ b/i18n/deu/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "Hintergrundfarbe der aktiven Registerkarte. Registerkarten sind die Container für Editors im Editorbereich. In einer Editorgruppe können mehrere Registerkarten geöffnet werden. Mehrere Editorgruppen können vorhanden sein.", "tabInactiveBackground": "Hintergrundfarbe der inaktiven Registerkarte. Registerkarten sind die Container für Editors im Editorbereich. In einer Editorgruppe können mehrere Registerkarten geöffnet werden. Mehrere Editorgruppen können vorhanden sein.", + "tabHoverBackground": "Hintergrundfarbe der Registerkarte beim Daraufzeigen. Registerkarten sind die Container für Editoren im Editorbereich. In einer Editorgruppe können mehrere Registerkarten geöffnet werden. Mehrere Editorgruppen können vorhanden sein.", + "tabUnfocusedHoverBackground": "Hintergrundfarbe für Registerkarten in einer unfokussierten Gruppe beim Daraufzeigen. Registerkarten sind die Container für Editoren im Editor-Bereich. In einer Editor-Gruppe können mehrere Registerkarten geöffnet werden. Mehrere Editor-Gruppen sind möglich.", "tabBorder": "Rahmen zum Trennen von Registerkarten. Registerkarten sind die Container für Editoren im Editor-Bereich. In einer Editor-Gruppe können mehrere Registerkarten geöffnet werden. Mehrere Editor-Gruppen sind möglich.", "tabActiveBorder": "Rahmen zum Hervorheben aktiver Registerkarten. Registerkarten sind die Container für Editoren im Editor-Bereich. In einer Editor-Gruppe können mehrere Registerkarten geöffnet werden. Mehrere Editor-Gruppen sind möglich.", "tabActiveUnfocusedBorder": "Rahmen zum Hervorheben aktiver Registerkarten in einer unfokussierten Gruppe. Registerkarten sind die Container für Editoren im Editor-Bereich. In einer Editor-Gruppe können mehrere Registerkarten geöffnet werden. Mehrere Editor-Gruppen sind möglich.", + "tabHoverBorder": "Rahmen zum Hervorheben von Registerkarten beim Daraufzeigen. Registerkarten sind die Container für Editoren im Editor-Bereich. In einer Editor-Gruppe können mehrere Registerkarten geöffnet werden. Mehrere Editor-Gruppen sind möglich.", + "tabUnfocusedHoverBorder": "Rahmen zum Hervorheben von Registerkarten in einer unfokussierten Gruppe beim Daraufzeigen. Registerkarten sind die Container für Editoren im Editor-Bereich. In einer Editor-Gruppe können mehrere Registerkarten geöffnet werden. Mehrere Editor-Gruppen sind möglich.", "tabActiveForeground": "Vordergrundfarbe der aktiven Registerkarte in einer aktiven Gruppe. Registerkarten sind die Container für Editors im Editorbereich. In einer Editorgruppe können mehrere Registerkarten geöffnet werden. Mehrere Editorgruppen können vorhanden sein.", "tabInactiveForeground": "Vordergrundfarbe der inaktiven Registerkarte in einer aktiven Gruppe. Registerkarten sind die Container für Editors im Editorbereich. In einer Editorgruppe können mehrere Registerkarten geöffnet werden. Mehrere Editorgruppen können vorhanden sein.", "tabUnfocusedActiveForeground": "Vordergrundfarbe für aktive Registerkarten in einer unfokussierten Gruppe. Registerkarten sind die Container für Editoren im Editor-Bereich. In einer Editor-Gruppe können mehrere Registerkarten geöffnet werden. Mehrere Editor-Gruppen sind möglich.", @@ -16,7 +20,7 @@ "editorGroupBackground": "Hintergrundfarbe einer Editor-Gruppe. Editor-Gruppen sind die Container der Editoren. Die Hintergrundfarbe wird beim Ziehen von Editoren angezeigt.", "tabsContainerBackground": "Hintergrundfarbe der Titelüberschrift der Editor-Gruppe, wenn die Registerkarten deaktiviert sind. Editor-Gruppen sind die Container der Editoren.", "tabsContainerBorder": "Rahmenfarbe der Titelüberschrift der Editor-Gruppe, wenn die Registerkarten deaktiviert sind. Editor-Gruppen sind die Container der Editoren.", - "editorGroupHeaderBackground": "Hintergrundfarbe der Titelüberschrift des Editors, wenn die Registerkarten deaktiviert sind. Editor-Gruppen sind die Container der Editoren.", + "editorGroupHeaderBackground": "Hintergrundfarbe der Editorgruppen-Titelüberschrift, wenn Registerkarten deaktiviert sind (`\"workbench.editor.showTabs\": false`). Editor-Gruppen sind die Container für Editoren.", "editorGroupBorder": "Farbe zum Trennen mehrerer Editor-Gruppen. Editor-Gruppen sind die Container der Editoren.", "editorDragAndDropBackground": " Hintergrundfarbe beim Ziehen von Editoren. Die Farbe muss transparent sein, damit der Editor-Inhalt noch sichtbar sind.", "panelBackground": "Hintergrundfarbe des Panels. Panels werden unter dem Editorbereich angezeigt und enthalten Ansichten wie die Ausgabe und das integrierte Terminal.", @@ -33,8 +37,6 @@ "statusBarNoFolderBorder": "Rahmenfarbe der Statusleiste zur Abtrennung von der Randleiste und dem Editor, wenn kein Ordner geöffnet ist. Die Statusleiste wird unten im Fenster angezeigt.", "statusBarItemActiveBackground": "Hintergrundfarbe für Statusleistenelemente beim Klicken. Die Statusleiste wird am unteren Rand des Fensters angezeigt.", "statusBarItemHoverBackground": "Hintergrundfarbe der Statusleistenelemente beim Daraufzeigen. Die Statusleiste wird am unteren Seitenrand angezeigt.", - "statusBarProminentItemBackground": "Hintergrundfarbe für markante Elemente der Statusleiste. Markante Elemente sind im Vergleich zu anderen Statusleisteneinträgen hervorgehoben, um auf ihre Bedeutung hinzuweisen. Die Statusleiste wird unten im Fenster angezeigt.", - "statusBarProminentItemHoverBackground": "Hintergrundfarbe für markante Elemente der Statusleiste, wenn auf diese gezeigt wird. Markante Elemente sind im Vergleich zu anderen Statusleisteneinträgen hervorgehoben, um auf ihre Bedeutung hinzuweisen. Die Statusleiste wird unten im Fenster angezeigt.", "activityBarBackground": "Hintergrundfarbe der Aktivitätsleiste. Die Aktivitätsleiste wird ganz links oder rechts angezeigt und ermöglicht das Wechseln zwischen verschiedenen Ansichten der Seitenleiste.", "activityBarForeground": "Vordergrundfarbe der Aktivitätsleiste (z. B. für Symbole). Die Aktivitätsleiste wird ganz links oder rechts angezeigt und ermöglicht das Wechseln zwischen verschiedenen Ansichten der Seitenleiste.", "activityBarBorder": "Rahmenfarbe der Aktivitätsleiste für die Abtrennung von der Seitenleiste. Die Aktivitätsleiste wird ganz links oder rechts angezeigt und ermöglicht das Wechseln zwischen verschiedenen Ansichten der Seitenleiste.", diff --git a/i18n/deu/src/vs/workbench/common/views.i18n.json b/i18n/deu/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..a36d97eb0e0 --- /dev/null +++ b/i18n/deu/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "Eine Ansicht mit der ID \"{0}\" ist am Speicherort \"{1}\" bereits registriert." +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/deu/src/vs/workbench/electron-browser/actions.i18n.json index 7331216a594..4f7255a9d91 100644 --- a/i18n/deu/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/deu/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "Editor schließen", "closeWindow": "Fenster schließen", "closeWorkspace": "Arbeitsbereich schließen", "noWorkspaceOpened": "Zurzeit ist kein Arbeitsbereich in dieser Instanz geöffnet, der geschlossen werden kann.", @@ -52,21 +51,5 @@ "displayLanguage": "Definiert die Anzeigesprache von VSCode.", "doc": "Unter {0} finden Sie eine Liste der unterstützten Sprachen.", "restart": "Das Ändern dieses Wertes erfordert einen Neustart von VSCode.", - "fail.createSettings": "{0} ({1}) kann nicht erstellt werden.", - "openLogsFolder": "Protokollordner öffnen", - "showLogs": "Protokolle anzeigen...", - "mainProcess": "Main", - "sharedProcess": "Geteilt", - "rendererProcess": "Renderer", - "extensionHost": "Erweiterungshost", - "selectProcess": "Prozess auswählen", - "setLogLevel": "Protokollstufe festlegen", - "trace": "Spur", - "debug": "Debuggen", - "info": "Info", - "warn": "Warnung", - "err": "Fehler", - "critical": "Kritisch", - "off": "Aus", - "selectLogLevel": "Protokollstufe auswählen" + "fail.createSettings": "{0} ({1}) kann nicht erstellt werden." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/deu/src/vs/workbench/electron-browser/main.contribution.i18n.json index 2a2af0f320b..aba53ab9214 100644 --- a/i18n/deu/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "Anzeigen", "help": "Hilfe", "file": "Datei", - "developer": "Entwickler", "workspaces": "Arbeitsbereiche", + "developer": "Entwickler", + "workbenchConfigurationTitle": "Workbench", "showEditorTabs": "Steuert, ob geöffnete Editoren auf Registerkarten angezeigt werden sollen.", "workbench.editor.labelFormat.default": "Zeigt den Namen der Datei. Wenn Registerkarten aktiviert sind und zwei Dateien in einer Gruppe den gleichen Namen haben, werden die unterscheidenden Abschnitte der Pfade jeder Datei hinzugefügt. Wenn die Registerkarten deaktiviert sind, wird der Pfad relativ zum Arbeitsbereich-Ordner angezeigt, wenn der Editor aktiv ist. ", "workbench.editor.labelFormat.short": "Den Namen der Datei anzeigen, gefolgt von dessen Verzeichnisnamen.", @@ -20,23 +21,23 @@ "showIcons": "Steuert, ob geöffnete Editoren mit einem Symbol angezeigt werden sollen. Hierzu muss auch ein Symboldesign aktiviert werden.", "enablePreview": "Steuert, ob geöffnete Editoren als Vorschau angezeigt werden. Vorschau-Editoren werden wiederverwendet, bis sie gespeichert werden (z. B. über Doppelklicken oder Bearbeiten), und sie werden mit kursivem Schriftschnitt angezeigt.", "enablePreviewFromQuickOpen": "Steuert, ob geöffnete Editoren aus Quick Open als Vorschau angezeigt werden. Vorschau-Editoren werden wiederverwendet, bis sie gespeichert werden (z. B. über Doppelklicken oder Bearbeiten).", + "closeOnFileDelete": "Steuert, ob Editoren, die eine Datei anzeigen, automatisch geschlossen werden sollen, wenn die Datei von einem anderen Prozess umbenannt oder gelöscht wird. Wenn Sie diese Option deaktivieren, bleibt der Editor bei einem solchen Ereignis als geändert offen. Bei Löschvorgängen innerhalb der Anwendung wird der Editor immer geschlossen, und geänderte Dateien werden nie geschlossen, damit Ihre Daten nicht verloren gehen.", "editorOpenPositioning": "Steuert, wo Editoren geöffnet werden. Wählen Sie \"links\" oder \"rechts\", um Editoren links oder rechts neben dem derzeit aktiven Editor zu öffnen. Wählen Sie \"erster\" oder \"letzter\", um Editoren unabhängig vom derzeit aktiven Editor zu öffnen.", "revealIfOpen": "Steuert, ob ein geöffneter Editor in einer der sichtbaren Gruppen angezeigt wird. Ist diese Option deaktiviert, wird ein Editor vorzugsweise in der aktuell aktiven Editorgruppe geöffnet. Ist diese Option aktiviert, wird ein bereits geöffneter Editor angezeigt und nicht in der aktuell aktiven Editorgruppe erneut geöffnet. In einigen Fällen wird diese Einstellung ignoriert, z. B. wenn das Öffnen eines Editors in einer bestimmten Gruppe oder neben der aktuell aktiven Gruppe erzwungen wird.", + "swipeToNavigate": "Hiermit navigieren Sie per waagrechtem Wischen mit drei Fingen zwischen geöffneten Dateien.", "commandHistory": "Steuert, ob die Anzahl zuletzt verwendeter Befehle im Verlauf für die Befehlspalette gespeichert wird. Legen Sie diese Option auf 0 fest, um den Befehlsverlauf zu deaktivieren.", "preserveInput": "Steuert, ob die letzte typisierte Eingabe in die Befehlspalette beim nächsten Öffnen wiederhergestellt wird.", "closeOnFocusLost": "Steuert, ob Quick Open automatisch geschlossen werden soll, sobald das Feature den Fokus verliert.", "openDefaultSettings": "Steuert, ob beim Öffnen der Einstellungen auch ein Editor geöffnet wird, der alle Standardeinstellungen anzeigt.", "sideBarLocation": "Steuert die Position der Seitenleiste. Diese kann entweder links oder rechts von der Workbench angezeigt werden.", + "panelDefaultLocation": "Steuert die Standardposition des Panels. Dieses kann entweder unterhalb oder rechts von der Workbench angezeigt werden.", "statusBarVisibility": "Steuert die Sichtbarkeit der Statusleiste im unteren Bereich der Workbench.", "activityBarVisibility": "Steuert die Sichtbarkeit der Aktivitätsleiste in der Workbench.", - "closeOnFileDelete": "Steuert, ob Editoren, die eine Datei anzeigen, automatisch geschlossen werden sollen, wenn die Datei von einem anderen Prozess umbenannt oder gelöscht wird. Wenn Sie diese Option deaktivieren, bleibt der Editor bei einem solchen Ereignis als geändert offen. Bei Löschvorgängen innerhalb der Anwendung wird der Editor immer geschlossen, und geänderte Dateien werden nie geschlossen, damit Ihre Daten nicht verloren gehen.", - "enableNaturalLanguageSettingsSearch": "Steuert, ob der Suchmodus mit natürlicher Sprache für die Einstellungen aktiviert werden soll.", "fontAliasing": "Steuert die Schriftartaliasingmethode in der Workbench.\n- default: Subpixel-Schriftartglättung. Auf den meisten Nicht-Retina-Displays wird Text bei dieser Einstellung am schärfsten dargestellt.\n- antialiased: Glättet die Schriftart auf der Pixelebene (im Gegensatz zur Subpixelebene). Bei dieser Einstellung kann die Schriftart insgesamt heller wirken.\n- none: Deaktiviert die Schriftartglättung. Text wird mit gezackten scharfen Kanten dargestellt.\n", "workbench.fontAliasing.default": "Subpixel-Schriftartglättung. Auf den meisten Nicht-Retina-Displays wird Text bei dieser Einstellung am schärfsten dargestellt.", "workbench.fontAliasing.antialiased": "Glättet die Schriftart auf der Pixelebene (im Gegensatz zur Subpixelebene). Bei dieser Einstellung kann die Schriftart insgesamt heller wirken.", "workbench.fontAliasing.none": "Deaktiviert die Schriftartglättung. Text wird mit gezackten scharfen Kanten dargestellt.", - "swipeToNavigate": "Hiermit navigieren Sie per waagrechtem Wischen mit drei Fingen zwischen geöffneten Dateien.", - "workbenchConfigurationTitle": "Workbench", + "enableNaturalLanguageSettingsSearch": "Steuert, ob der Suchmodus mit natürlicher Sprache für die Einstellungen aktiviert werden soll.", "windowConfigurationTitle": "Fenster", "window.openFilesInNewWindow.on": "Dateien werden in einem neuen Fenster geöffnet.", "window.openFilesInNewWindow.off": "Dateien werden im Fenster mit dem geöffneten Dateiordner oder im letzten aktiven Fenster geöffnet.", diff --git a/i18n/deu/src/vs/workbench/electron-browser/window.i18n.json b/i18n/deu/src/vs/workbench/electron-browser/window.i18n.json index dac54eb81af..ea9b198df1d 100644 --- a/i18n/deu/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/deu/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "Ausschneiden", "copy": "Kopieren", "paste": "Einfügen", - "selectAll": "Alles auswählen" + "selectAll": "Alles auswählen", + "runningAsRoot": "Es wird nicht empfohlen, {0} als Root-Benutzer auszuführen." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/deu/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index e3b17702d86..adbe0beedd6 100644 --- a/i18n/deu/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "Hintergrundfarbe der Debug-Symbolleiste." + "debugToolBarBackground": "Hintergrundfarbe der Debug-Symbolleiste.", + "debugToolBarBorder": "Rahmenfarbe der Debug-Symbolleiste." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/deu/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 3352485c42b..23af77e5fa7 100644 --- a/i18n/deu/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "Zu debuggende Komponente", - "debug.terminal.not.available.error": "Integriertes Terminal nicht verfügbar" + "debug.terminal.title": "Zu debuggende Komponente" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 0b10a031064..6e06fdbca61 100644 --- a/i18n/deu/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "Neue Eingabeaufforderung öffnen", "globalConsoleActionMacLinux": "Neues Terminal öffnen", "scopedConsoleActionWin": "In Eingabeaufforderung öffnen", - "scopedConsoleActionMacLinux": "In Terminal öffnen", - "openFolderInIntegratedTerminal": "In Terminal öffnen" + "scopedConsoleActionMacLinux": "In Terminal öffnen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index 9cde3634e76..8ece38ff002 100644 --- a/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "Ausgehend von den kürzlich geöffneten Dateien wird diese Erweiterung empfohlen.", + "neverShowAgain": "Nicht mehr anzeigen", + "close": "Schließen", "workspaceRecommendation": "Diese Erweiterung wird von Benutzern des aktuellen Arbeitsbereichs empfohlen.", + "fileBasedRecommendation": "Ausgehend von den kürzlich geöffneten Dateien wird diese Erweiterung empfohlen.", "exeBasedRecommendation": "Diese Erweiterung wird empfohlen, da Sie {0} installiert haben.", "reallyRecommended2": "Für diesen Dateityp wird die Erweiterung \"{0}\" empfohlen.", "reallyRecommendedExtensionPack": "Für diesen Dateityp wird das Erweiterungspaket \"{0}\" empfohlen.", "showRecommendations": "Empfehlungen anzeigen", "install": "Installieren", - "neverShowAgain": "Nicht mehr anzeigen", - "close": "Schließen", "workspaceRecommended": "Für diesen Arbeitsbereich sind Erweiterungsempfehlungen verfügbar.", "installAll": "Alle installieren", "ignoreExtensionRecommendations": "Möchten Sie alle Erweiterungsempfehlungen ignorieren?", diff --git a/i18n/deu/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..b9d7e353c74 --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "Workbench" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/deu/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 46de1e8541a..f77129048a6 100644 --- a/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,25 @@ "filesCategory": "Datei", "revealInSideBar": "In Seitenleiste anzeigen", "acceptLocalChanges": "Änderungen verwenden und Datenträgerinhalte überschreiben", - "revertLocalChanges": "Änderungen verwerfen und Datenträgerinhalte wiederherstellen" + "revertLocalChanges": "Änderungen verwerfen und Datenträgerinhalte wiederherstellen", + "copyPathOfActive": "Pfad der aktiven Datei kopieren", + "saveAllInGroup": "Alle in der Gruppe speichern", + "saveFiles": "Alle Dateien speichern", + "revert": "Datei wiederherstellen", + "compareActiveWithSaved": "Aktive Datei mit gespeicherter Datei vergleichen", + "closeEditor": "Editor schließen", + "view": "Anzeigen", + "openToSide": "Zur Seite öffnen", + "revealInWindows": "Im Explorer anzeigen", + "revealInMac": "Im Finder anzeigen", + "openContainer": "Enthaltenden Ordner öffnen", + "copyPath": "Pfad kopieren", + "saveAll": "Alle speichern", + "compareWithSaved": "Mit gespeicherter Datei vergleichen", + "compareSource": "Für Vergleich auswählen", + "close": "Schließen", + "closeOthers": "Andere schließen", + "closeUnmodified": "Nicht geänderte schließen", + "closeAll": "Alle schließen", + "deleteFile": "Endgültig löschen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 4d300a15634..3e34e541dce 100644 --- a/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "Wiederholen", - "rename": "Umbenennen", "newFile": "Neue Datei", "newFolder": "Neuer Ordner", + "rename": "Umbenennen", + "delete": "Löschen", + "copyFile": "Kopieren", + "pasteFile": "Einfügen", + "retry": "Wiederholen", "openFolderFirst": "Öffnet zuerst einen Ordner, in dem Dateien oder Ordner erstellt werden.", "newUntitledFile": "Neue unbenannte Datei", "createNewFile": "Neue Datei", @@ -28,26 +31,14 @@ "confirmDeleteMessageFile": "Möchten Sie \"{0}\" wirklich endgültig löschen?", "irreversible": "Diese Aktion kann nicht rückgängig gemacht werden.", "permDelete": "Endgültig löschen", - "delete": "Löschen", "importFiles": "Dateien importieren", "confirmOverwrite": "Im Zielordner ist bereits eine Datei oder ein Ordner mit dem gleichen Namen vorhanden. Möchten Sie sie bzw. ihn ersetzen?", "replaceButtonLabel": "&&Ersetzen", - "copyFile": "Kopieren", - "pasteFile": "Einfügen", "duplicateFile": "Duplikat", - "openToSide": "Zur Seite öffnen", - "compareSource": "Für Vergleich auswählen", "globalCompareFile": "Aktive Datei vergleichen mit...", "openFileToCompare": "Zuerst eine Datei öffnen, um diese mit einer anderen Datei zu vergleichen", - "compareWith": "'{0}' mit '{1}' vergleichen", - "compareFiles": "Dateien vergleichen", "refresh": "Aktualisieren", - "save": "Speichern", - "saveAs": "Speichern unter...", - "saveAll": "Alle speichern", "saveAllInGroup": "Alle in der Gruppe speichern", - "saveFiles": "Alle Dateien speichern", - "revert": "Datei wiederherstellen", "focusOpenEditors": "Fokus auf Ansicht \"Geöffnete Editoren\"", "focusFilesExplorer": "Fokus auf Datei-Explorer", "showInExplorer": "Aktive Datei in Seitenleiste anzeigen", @@ -56,20 +47,11 @@ "refreshExplorer": "Explorer aktualisieren", "openFileInNewWindow": "Aktive Datei in neuem Fenster öffnen", "openFileToShowInNewWindow": "Datei zuerst öffnen, um sie in einem neuen Fenster zu öffnen", - "revealInWindows": "Im Explorer anzeigen", - "revealInMac": "Im Finder anzeigen", - "openContainer": "Enthaltenden Ordner öffnen", - "revealActiveFileInWindows": "Aktive Datei im Windows-Explorer anzeigen", - "revealActiveFileInMac": "Aktive Datei im Finder anzeigen", - "openActiveFileContainer": "Enthaltenden Ordner der aktiven Datei öffnen", "copyPath": "Pfad kopieren", - "copyPathOfActive": "Pfad der aktiven Datei kopieren", "emptyFileNameError": "Es muss ein Datei- oder Ordnername angegeben werden.", "fileNameExistsError": "Eine Datei oder ein Ordner **{0}** ist an diesem Ort bereits vorhanden. Wählen Sie einen anderen Namen.", "invalidFileNameError": "Der Name **{0}** ist als Datei- oder Ordnername ungültig. Bitte wählen Sie einen anderen Namen aus.", "filePathTooLongError": "Der Name **{0}** führt zu einem Pfad, der zu lang ist. Wählen Sie einen kürzeren Namen.", - "compareWithSaved": "Aktive Datei mit gespeicherter Datei vergleichen", - "modifiedLabel": "{0} (auf Datenträger) ↔ {1}", "compareWithClipboard": "Aktive Datei mit Zwischenablage vergleichen", "clipboardComparisonLabel": "Zwischenablage ↔ {0}" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index c248ffc5682..4113e1a3018 100644 --- a/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "Datei zuerst öffnen, um ihren Pfad zu kopieren", - "openFileToReveal": "Datei zuerst öffnen, um sie anzuzeigen" + "revealInWindows": "Im Explorer anzeigen", + "revealInMac": "Im Finder anzeigen", + "openContainer": "Enthaltenden Ordner öffnen", + "saveAs": "Speichern unter...", + "save": "Speichern", + "saveAll": "Alle speichern", + "removeFolderFromWorkspace": "Ordner aus dem Arbeitsbereich entfernen", + "genericRevertError": "Fehler beim Zurücksetzen von '{0}': {1}", + "modifiedLabel": "{0} (auf Datenträger) ↔ {1}", + "openFileToReveal": "Datei zuerst öffnen, um sie anzuzeigen", + "openFileToCopy": "Datei zuerst öffnen, um ihren Pfad zu kopieren" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 00a2164ceaa..2ddf50e3ffc 100644 --- a/i18n/deu/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,6 @@ "editorConfigurationTitle": "Editor", "formatOnSave": "Hiermit wird eine Datei beim Speichern formatiert. Es muss ein Formatierer vorhanden sein, die Datei darf nicht automatisch gespeichert werden, und der Editor darf nicht geschlossen werden.", "explorerConfigurationTitle": "Datei-Explorer", - "openEditorsVisible": "Die Anzahl der Editoren, die im Bereich \"Geöffnete Editoren\" angezeigt werden. Legen Sie diesen Wert auf 0 fest, um den Bereich auszublenden.", - "dynamicHeight": "Steuert, ob sich die Höhe des Abschnitts \"Geöffnete Editoren\" dynamisch an die Anzahl der Elemente anpassen soll.", "autoReveal": "Steuert, ob der Explorer Dateien beim Öffnen automatisch anzeigen und auswählen soll.", "enableDragAndDrop": "Steuert, ob der Explorer das Verschieben von Dateien und Ordnern mithilfe von Drag Drop zulassen soll.", "confirmDragAndDrop": "Steuert, ob der Explorer um Bestätigung bittet, um Dateien und Ordner per Drag & Drop zu verschieben.", diff --git a/i18n/deu/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/deu/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 55ed6344bee..25a34e50d39 100644 --- a/i18n/deu/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,14 @@ // Do not edit this file. It is machine generated. { "userGuide": "Verwenden Sie die Aktionen auf der Editor-Symbolleiste auf der rechten Seite, um Ihre Änderungen **rückgängig zu machen** oder den Inhalt auf dem Datenträger mit Ihren Änderungen zu **überschreiben**.", - "discard": "Verwerfen", + "overwriteElevated": "Als Admin überschreiben...", + "saveElevated": "Als Admin wiederholen...", "overwrite": "Überschreiben", "retry": "Wiederholen", - "readonlySaveError": "Fehler beim Speichern von \"{0}\": Die Datei ist schreibgeschützt. Wählen Sie 'Überschreiben' aus, um den Schutz aufzuheben.", + "discard": "Verwerfen", + "readonlySaveErrorAdmin": "Fehler beim Speichern von '{0}': Datei ist schreibgeschützt. 'Als Admin überschreiben' auswählen, um den Vorgang als Administrator zu wiederholen. ", + "readonlySaveError": "Fehler beim Speichern von '{0}': Datei ist schreibgeschützt. Wählen Sie 'Überschreiben' aus, um den Schutz aufzuheben.", + "permissionDeniedSaveError": "Fehler beim Speichern von '{0}': Unzureichende Zugriffsrechte. Wählen Sie 'Als Admin wiederholen' aus, um den Vorgang als Admin zu wiederholen.", "genericSaveError": "Fehler beim Speichern von \"{0}\": {1}.", "staleSaveError": "Fehler beim Speichern von \"{0}\": Der Inhalt auf dem Datenträger ist neuer. Klicken Sie auf **Vergleichen**, um Ihre Version mit der Version auf dem Datenträger zu vergleichen.", "compareChanges": "Vergleichen", diff --git a/i18n/deu/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/deu/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index a5003c84539..41368e44e5a 100644 --- a/i18n/deu/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "Geöffnete Editoren", "openEditosrSection": "Abschnitt \"Geöffnete Editoren\"", - "dirtyCounter": "{0} nicht gespeichert", - "saveAll": "Alle speichern", - "closeAllUnmodified": "Nicht geänderte schließen", - "closeAll": "Alle schließen", - "compareWithSaved": "Mit gespeicherter Datei vergleichen", - "close": "Schließen", - "closeOthers": "Andere schließen" + "dirtyCounter": "{0} nicht gespeichert" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..9ef6f12276a --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "developer": "Entwickler" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/deu/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..2a19c259b0d --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,19 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "Protokollordner öffnen", + "showLogs": "Protokolle anzeigen...", + "rendererProcess": "Fenster", + "extensionHost": "Erweiterungshost", + "setLogLevel": "Protokollstufe festlegen", + "debug": "Debuggen", + "info": "Info", + "warn": "Warnung", + "err": "Fehler", + "critical": "Kritisch", + "off": "Aus", + "selectLogLevel": "Protokollstufe auswählen" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/deu/src/vs/workbench/parts/markers/common/messages.i18n.json index f9df98f6f17..4fe33d4fdf6 100644 --- a/i18n/deu/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "viewCategory": "Anzeigen", - "problems.view.toggle.label": "Probleme umschalten", - "problems.view.focus.label": "Probleme fokussieren", "problems.panel.configuration.title": "Ansicht \"Probleme\"", "problems.panel.configuration.autoreveal": "Steuert, ob die Ansicht \"Probleme\" automatisch Dateien anzeigen sollte, wenn diese geöffnet werden.", "markers.panel.title.problems": "Probleme", diff --git a/i18n/deu/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..a49f4a37242 --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "Ausgabe", + "viewCategory": "Anzeigen", + "clearOutput.label": "Ausgabe löschen" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/deu/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..95b7cc617b7 --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "{0} - Ausgabe", + "channel": "Ausgabekanal für '{0}'" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/deu/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index 26e5d28d658..fb9b2bd366a 100644 --- a/i18n/deu/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "Testen Sie das Suchen mit natürlicher Sprache!", "defaultSettings": "Platzieren Sie Ihre Einstellungen zum Überschreiben im Editor auf der rechten Seite.", "noSettingsFound": "Keine Einstellungen gefunden.", "settingsSwitcherBarAriaLabel": "Einstellungsumschaltung", "userSettings": "Benutzereinstellungen", "workspaceSettings": "Arbeitsbereichseinstellungen", - "folderSettings": "Ordnereinstellungen", - "enableFuzzySearch": "Suchen mit natürlicher Sprache aktivieren" + "folderSettings": "Ordnereinstellungen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/deu/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index 74ffcdff9a1..f93cea2858c 100644 --- a/i18n/deu/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "Am häufigsten verwendet", - "mostRelevant": "Relevantesten", "defaultKeybindingsHeader": "Überschreiben Sie Tastenzuordnungen, indem Sie sie in die Tastenzuordnungsdatei einfügen." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index f5e2daabe29..2ca5c08b0a9 100644 --- a/i18n/deu/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "Anzeigen", "commandsHandlerDescriptionDefault": "Befehle anzeigen und ausführen", "gotoLineDescriptionMac": "Gehe zu Zeile", "gotoLineDescriptionWin": "Gehe zu Zeile", diff --git a/i18n/deu/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index cfb59dde790..114466fcfbf 100644 --- a/i18n/deu/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,8 @@ "toggleGitViewlet": "Git anzeigen", "source control": "Quellcodeverwaltung", "toggleSCMViewlet": "SCM anzeigen", - "view": "Anzeigen" + "view": "Anzeigen", + "scmConfigurationTitle": "SCM", + "alwaysShowProviders": "Ob der Quellcodeverwaltungsanbieter-Abschnitt immer angezeigt wird.", + "inputCounter": "Steuert die Anzeige des Eingabezählers." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json b/i18n/deu/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json index 6119d2359c6..faa904ce1ab 100644 --- a/i18n/deu/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json @@ -6,6 +6,8 @@ { "scm providers": "Quellcodeanbieter", "hideRepository": "Ausblenden", + "commitMessageInfo": "{0} Zeichen in aktueller Zeile", + "commitMessageCountdown": "{0} Zeichen in der aktuellen Zeile verbleibend", "installAdditionalSCMProviders": "Installiere weiter SCM Provider...", "no open repo": "Es gibt keine aktiven Quellcodeanbieter.", "source control": "Quellcodeverwaltung", diff --git a/i18n/deu/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/deu/src/vs/workbench/parts/search/browser/searchActions.i18n.json index f4671bfc3a8..365328f0126 100644 --- a/i18n/deu/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "Vorherigen Suchbegriff anzeigen", "showSearchViewlet": "Suche anzeigen", "findInFiles": "In Dateien suchen", - "findInFilesWithSelectedText": "In Dateien mit ausgewähltem Text suchen", "replaceInFiles": "In Dateien ersetzen", - "replaceInFilesWithSelectedText": "In Dateien mit ausgewähltem Text ersetzen", "RefreshAction.label": "Aktualisieren", "CollapseDeepestExpandedLevelAction.label": "Alle zuklappen", "ClearSearchResultsAction.label": "Löschen", diff --git a/i18n/deu/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index a765a1ac06f..e32b687f050 100644 --- a/i18n/deu/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "In Ordner suchen...", + "findInWorkspace": "In Arbeitsbereich suchen...", "showTriggerActions": "Zu Symbol im Arbeitsbereich wechseln...", "name": "Suchen", "search": "Suchen", + "showSearchViewlet": "Suche anzeigen", "view": "Anzeigen", + "findInFiles": "In Dateien suchen", "openAnythingHandlerDescription": "Zu Datei wechseln", "openSymbolDescriptionNormal": "Zu Symbol im Arbeitsbereich wechseln", "searchOutputChannelTitle": "Suchen", diff --git a/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..fa89fddbd1a --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.1": "({0})", + "preferences": "Einstellungen" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 7a1c949566e..6d4c86fa94f 100644 --- a/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,10 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "Sprache für Codeausschnitt auswählen", - "openSnippet.errorOnCreate": "\"{0}\" kann nicht erstellt werden.", - "openSnippet.label": "Benutzercodeausschnitte öffnen", - "preferences": "Einstellungen", "snippetSchema.json.default": "Leerer Codeausschnitt", "snippetSchema.json": "Benutzerkonfiguration des Codeausschnitts", "snippetSchema.json.prefix": "Das Präfix, das beim Auswählen des Codeausschnitts in IntelliSense verwendet werden soll.", diff --git a/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..3daae2bbcbd --- /dev/null +++ b/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "Benutzercodeausschnitt" +} \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index e67d5f89a93..f989f6698dc 100644 --- a/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "Unbekannte Sprache in \"contributes.{0}.language\". Bereitgestellter Wert: {1}", "invalid.path.0": "Expected string in `contributes.{0}.path`. Provided value: {1}", + "invalid.language": "Unbekannte Sprache in \"contributes.{0}.language\". Bereitgestellter Wert: {1}", "invalid.path.1": "Es wurde erwartet, dass \"contributes.{0}.path\" ({1}) im Ordner ({2}) der Erweiterung enthalten ist. Dies führt ggf. dazu, dass die Erweiterung nicht portierbar ist.", "vscode.extension.contributes.snippets": "Trägt Codeausschnitte bei.", "vscode.extension.contributes.snippets-language": "Der Sprachbezeichner, für den dieser Codeausschnitt beigetragen wird.", "vscode.extension.contributes.snippets-path": "Der Pfad der Codeausschnittdatei. Der Pfad ist relativ zum Erweiterungsordner und beginnt normalerweise mit \". /snippets/\".", "badVariableUse": "Bei mindestens einem Ausschnitt von der Erweiterung \"{0}\" sind Ausschnittsvariablen und Ausschnittsplatzhalter vertauscht (weitere Informationen finden Sie unter https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax).", "badFile": "Die Ausschnittsdatei \"{0}\" konnte nicht gelesen werden.", - "source.snippet": "Benutzercodeausschnitt", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index bc6dee18ad0..e6464f3ff18 100644 --- a/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -14,6 +14,7 @@ "terminal.integrated.shell.windows": "Der Pfad der Shell, den das Terminal unter Windows verwendet, wenn in Windows enthaltene Terminals verwendet werden (cmd, PowerShell oder Bash unter Ubuntu).", "terminal.integrated.shellArgs.windows": "Die Befehlszeilenargumente, die im Windows-Terminal verwendet werden sollen.", "terminal.integrated.rightClickCopyPaste": "Wenn dies festgelegt ist, erscheint das Kontextmenü bei einem Rechtsklick im Terminal nicht mehr. Stattdessen erfolgen die Vorgänge Kopieren, wenn eine Auswahl vorgenommen wurde, sowie Einfügen, wenn keine Auswahl vorgenommen wurde.", + "terminal.integrated.copyOnSelection": "Wenn gesetzt, wird der im Terminal ausgewählte Text in die Zwischenablage kopiert.", "terminal.integrated.fontFamily": "Steuert die Schriftartfamilie des Terminals. Der Standardwert ist \"editor.fontFamily\".", "terminal.integrated.fontSize": "Steuert den Schriftgrad des Terminals in Pixeln.", "terminal.integrated.lineHeight": "Steuert die Zeilenhöhe für das Terminal. Dieser Wert wird mit dem Schriftgrad des Terminals multipliziert, um die tatsächliche Zeilenhöhe in Pixeln zu erhalten.", diff --git a/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json b/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json index 93a8b04286a..edacb0183b5 100644 --- a/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json @@ -14,6 +14,8 @@ "workbench.action.terminal.deleteWordRight": "Wort rechts löschen", "workbench.action.terminal.new": "Neues integriertes Terminal erstellen", "workbench.action.terminal.new.short": "Neues Terminal", + "workbench.action.terminal.newWorkspacePlaceholder": "Aktuelles Arbeitsverzeichnis für neues Terminal auswählen", + "workbench.action.terminal.newInActiveWorkspace": "Neues integriertes Terminal erstellen (in aktivem Arbeitsbereich)", "workbench.action.terminal.focus": "Fokus im Terminal", "workbench.action.terminal.focusNext": "Fokus im nächsten Terminal", "workbench.action.terminal.focusPrevious": "Fokus im vorherigen Terminal", diff --git a/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json b/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json index 76d17079ae8..35f0add77c1 100644 --- a/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json @@ -8,6 +8,5 @@ "terminal.foreground": "Die Vordergrundfarbe des Terminal.", "terminalCursor.foreground": "Die Vordergrundfarbe des Terminalcursors.", "terminalCursor.background": "Die Hintergrundfarbe des Terminalcursors. Ermöglicht das Anpassen der Farbe eines Zeichens, das von einem Blockcursor überdeckt wird.", - "terminal.selectionBackground": "Die Auswahlvordergrundfarbe des Terminals.", - "terminal.ansiColor": "\"{0}\": ANSI-Farbe im Terminal" + "terminal.selectionBackground": "Die Auswahlvordergrundfarbe des Terminals." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index ac6f1dfc78c..a768c43ba81 100644 --- a/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,6 @@ "terminal.integrated.chooseWindowsShellInfo": "Sie können die Standardterminalshell über die Schaltfläche \"Anpassen\" ändern.", "customize": "Anpassen", "cancel": "Abbrechen", - "never again": "OK, nicht mehr anzeigen", "terminal.integrated.chooseWindowsShell": "Wählen Sie Ihre bevorzugte Terminalshell. Sie können diese später in Ihren Einstellungen ändern.", "terminalService.terminalCloseConfirmationSingular": "Eine aktive Terminalsitzung ist vorhanden. Möchten Sie sie beenden?", "terminalService.terminalCloseConfirmationPlural": "{0} aktive Terminalsitzungen sind vorhanden. Möchten Sie sie beenden?" diff --git a/i18n/deu/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/deu/src/vs/workbench/parts/update/electron-browser/update.i18n.json index 7c24ef226ba..58c22d0ae12 100644 --- a/i18n/deu/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -13,7 +13,7 @@ "read the release notes": "Willkommen bei {0} v{1}! Möchten Sie die Hinweise zu dieser Version lesen?", "licenseChanged": "Unsere Lizenzbedingungen haben sich geändert. Bitte lesen Sie die neuen Bedingungen.", "license": "Lizenz lesen", - "neveragain": "Nie wieder anzeigen", + "neveragain": "Nicht mehr anzeigen", "64bitisavailable": "{0} für 64-Bit-Windows ist jetzt verfügbar!", "learn more": "Weitere Informationen", "updateIsReady": "Neues {0}-Update verfügbar.", @@ -23,6 +23,7 @@ "commandPalette": "Befehlspalette...", "settings": "Einstellungen", "keyboardShortcuts": "Tastenkombinationen", + "userSnippets": "Benutzercodeausschnitte", "selectTheme.label": "Farbdesign", "themes.selectIconTheme.label": "Dateisymboldesign", "not available": "Aktualisierungen nicht verfügbar", diff --git a/i18n/deu/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/deu/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index ed6cda9de2a..bf366f305f3 100644 --- a/i18n/deu/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/deu/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "Die Datei ist ein Verzeichnis", + "fileNotModifiedError": "Datei nicht geändert seit", "fileBinaryError": "Die Datei scheint eine Binärdatei zu sein und kann nicht als Text geöffnet werden." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/services/files/node/fileService.i18n.json b/i18n/deu/src/vs/workbench/services/files/node/fileService.i18n.json index c16b29bce92..7f863867abd 100644 --- a/i18n/deu/src/vs/workbench/services/files/node/fileService.i18n.json +++ b/i18n/deu/src/vs/workbench/services/files/node/fileService.i18n.json @@ -10,6 +10,7 @@ "fileTooLargeError": "Die Datei ist zu groß, um sie zu öffnen.", "fileNotFoundError": "Die Datei wurde nicht gefunden ({0}).", "fileBinaryError": "Die Datei scheint eine Binärdatei zu sein und kann nicht als Text geöffnet werden.", + "filePermission": "Schreibzugriff auf Datei ({0}) verweigert", "fileExists": "Die zu erstellende Datei ist bereits vorhanden ({0}). ", "fileMoveConflict": "Verschieben/Kopieren kann nicht ausgeführt werden. Die Datei ist am Ziel bereits vorhanden.", "unableToMoveCopyError": "Der Verschiebe-/Kopiervorgang kann nicht ausgeführt werden. Die Datei würde den Ordner ersetzen, in dem sie enthalten ist.", diff --git a/i18n/deu/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json b/i18n/deu/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json index 32304e03cea..2fb3a8af237 100644 --- a/i18n/deu/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json +++ b/i18n/deu/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json @@ -22,5 +22,6 @@ "keybindings.json.when": "Die Bedingung, wann der Schlüssel aktiv ist.", "keybindings.json.args": "Argumente, die an den auszuführenden Befehl übergeben werden sollen.", "keyboardConfigurationTitle": "Tastatur", - "dispatch": "Steuert die Abgangslogik, sodass bei einem Tastendruck entweder \"code\" (empfohlen) oder \"keyCode\" verwendet wird." + "dispatch": "Steuert die Abgangslogik, sodass bei einem Tastendruck entweder \"code\" (empfohlen) oder \"keyCode\" verwendet wird.", + "touchbar.enabled": "Aktiviert die macOS-Touchbar-Schaltflächen der Tastatur, sofern verfügbar." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/deu/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index 1e2d38883dc..f953949ef00 100644 --- a/i18n/deu/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/deu/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "Möchten Sie die Änderungen speichern, die Sie an \"{0}\" vorgenommen haben?", "saveChangesMessages": "Möchten Sie die an den folgenden {0}-Dateien vorgenommenen Änderungen speichern?", - "moreFile": "...1 weitere Datei wird nicht angezeigt", - "moreFiles": "...{0} weitere Dateien werden nicht angezeigt", "saveAll": "&&Alle speichern", "save": "&&Speichern", "dontSave": "&&Nicht speichern", diff --git a/i18n/deu/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/deu/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index 7d1b7fccbe0..957e2448664 100644 --- a/i18n/deu/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/deu/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "No file icons", "iconThemeError": "File icon theme is unknown or not installed.", "workbenchColors": "Überschreibt Farben aus dem derzeit ausgewählte Farbdesign.", - "editorColors": "Überschreibt Editorfarben und den Schriftschnitt aus dem momentan ausgewählten Farbdesign.", "editorColors.comments": "Legt die Farben und Stile für Kommentare fest.", "editorColors.strings": "Legt die Farben und Stile für Zeichenfolgenliterale fest.", "editorColors.keywords": "Legt die Farben und Stile für Schlüsselwörter fest.", @@ -19,5 +18,6 @@ "editorColors.types": "Legt die Farben und Stile für Typdeklarationen und Verweise fest.", "editorColors.functions": "Legt die Farben und Stile für Funktionsdeklarationen und Verweise fest.", "editorColors.variables": "Legt die Farben und Stile für Variablendeklarationen und Verweise fest.", - "editorColors.textMateRules": "Legt Farben und Stile mithilfe von Textmate-Designregeln fest (erweitert)." + "editorColors.textMateRules": "Legt Farben und Stile mithilfe von Textmate-Designregeln fest (erweitert).", + "editorColors": "Überschreibt Editorfarben und den Schriftschnitt aus dem momentan ausgewählten Farbdesign." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/deu/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 67d01f0f0d4..ded36282a85 100644 --- a/i18n/deu/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/deu/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "In die Konfigurationsdatei des Arbeitsbereichs kann nicht geschrieben werden. Öffnen Sie die Datei, um Fehler/Warnungen darin zu beheben, und versuchen Sie es noch mal.", "errorWorkspaceConfigurationFileDirty": "In die Konfigurationsdatei des Arbeitsbereichs kann nicht geschrieben werden, weil sie geändert wurde. Speichern Sie die Datei, und versuchen Sie es noch mal.", "openWorkspaceConfigurationFile": "Konfigurationsdatei des Arbeitsbereichs öffnen", - "close": "Schließen", - "enterWorkspace.close": "Schließen", - "enterWorkspace.dontShowAgain": "Nicht mehr anzeigen", - "enterWorkspace.moreInfo": "Weitere Informationen", - "enterWorkspace.prompt": "Weitere Informationen zum Arbeiten mit mehreren Ordnern in VS Code." + "close": "Schließen" } \ No newline at end of file diff --git a/i18n/esn/extensions/git/out/autofetch.i18n.json b/i18n/esn/extensions/git/out/autofetch.i18n.json index 270030fe345..98972c6f0a2 100644 --- a/i18n/esn/extensions/git/out/autofetch.i18n.json +++ b/i18n/esn/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "yes": "Sí", - "no": "No", - "not now": "Ahora No", - "suggest auto fetch": "¿Desea habilitar la búsqueda automática de repositorios de Git?" + "read more": "Leer más", + "no": "No" } \ No newline at end of file diff --git a/i18n/esn/extensions/git/out/commands.i18n.json b/i18n/esn/extensions/git/out/commands.i18n.json index 2258e175547..3be82274dd3 100644 --- a/i18n/esn/extensions/git/out/commands.i18n.json +++ b/i18n/esn/extensions/git/out/commands.i18n.json @@ -64,12 +64,11 @@ "no remotes to pull": "El repositorio no tiene remotos configurados de los que extraer.", "pick remote pull repo": "Seleccione un origen remoto desde el que extraer la rama", "no remotes to push": "El repositorio no tiene remotos configurados en los que insertar.", - "push with tags success": "Insertado con etiquetas correctamente.", "nobranch": "Extraiga del repositorio una rama para insertar un remoto.", + "ok": "Aceptar", + "push with tags success": "Insertado con etiquetas correctamente.", "pick remote": "Seleccionar un elemento remoto para publicar la rama '{0}':", "sync is unpredictable": "Esta acción insertará y extraerá confirmaciones en '{0}'.", - "ok": "Aceptar", - "never again": "De acuerdo, no volver a mostrar este mensaje.", "no remotes to publish": "El repositorio no tiene remotos configurados en los que publicar.", "no changes stash": "No existen cambios para el guardado provisional.", "provide stash message": "Opcionalmente, proporcionar un mensaje para el guardado provisional", diff --git a/i18n/esn/extensions/git/package.i18n.json b/i18n/esn/extensions/git/package.i18n.json index c0bb492d13e..9dab8cc59ce 100644 --- a/i18n/esn/extensions/git/package.i18n.json +++ b/i18n/esn/extensions/git/package.i18n.json @@ -59,7 +59,6 @@ "config.enableLongCommitWarning": "Si se debe advertir sobre los mensajes de confirmación largos", "config.confirmSync": "Confirmar antes de sincronizar repositorios GIT", "config.countBadge": "Controla el contador de insignia de Git. \"Todo\" cuenta todos los cambios. \"Seguimiento\" solamente cuenta los cambios realizados. \"Desactivado\" lo desconecta.", - "config.checkoutType": "Controla el tipo de ramas listadas cuando ejecuta \"Desproteger\". \"Todo\" muetra todas las referencias, \"local\" solamente las ramas locales y \"remoto\" las ramas remotas.", "config.ignoreLegacyWarning": "Ignora las advertencias hereradas de Git", "config.ignoreMissingGitWarning": "Ignora la advertencia cuando falta Git", "config.ignoreLimitWarning": "\nIgnora advertencias cuando se encuentran muchos cambios en un repositorio.", diff --git a/i18n/esn/extensions/typescript/out/commands.i18n.json b/i18n/esn/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..cfccf2b7bf9 --- /dev/null +++ b/i18n/esn/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "Abra una carpeta en VS Code para usar un proyecto de TypeScript o JavaScript", + "typescript.projectConfigUnsupportedFile": "No se pudo determinar el proyecto de TypeScript o JavaScript. Tipo de archivo no compatible", + "typescript.projectConfigCouldNotGetInfo": "No se pudo determinar el proyecto de TypeScript o JavaScript", + "typescript.noTypeScriptProjectConfig": "El archivo no forma parte de un proyecto de TypeScript", + "typescript.noJavaScriptProjectConfig": "El archivo no forma parte de un proyecto de JavaScript", + "typescript.configureTsconfigQuickPick": "Configurar tsconfig.json", + "typescript.configureJsconfigQuickPick": "Configurar jsconfig.json", + "typescript.projectConfigLearnMore": "Más información" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/esn/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/esn/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/base/node/ps.i18n.json b/i18n/esn/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..a4dbd804fb4 --- /dev/null +++ b/i18n/esn/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "Recopilando información de memoria y CPU. Esto puede tardar unos segundos. " +} \ No newline at end of file diff --git a/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json index 582dfe7c78f..9e12f7523e1 100644 --- a/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "Los números de línea se muestran como un número absoluto.", "lineNumbers.relative": "Los números de línea se muestran como distancia en líneas a la posición del cursor.", "lineNumbers.interval": "Los números de línea se muestran cada 10 líneas.", - "lineNumbers": "Controla la visualización de números de línea. Los valores posibles son 'on', 'off' y 'relative'.", + "lineNumbers": "Controla la visualización de números de línea. Los valores posibles son 'on', 'off', 'relative' e 'interval'.", "rulers": "Representar reglas verticales después de un cierto número de caracteres monoespacio. Usar multiples valores para multiples reglas. No se dibuja ninguna regla si la matriz esta vacía.", "wordSeparators": "Caracteres que se usarán como separadores de palabras al realizar operaciones o navegaciones relacionadas con palabras.", "tabSize": "El número de espacios a los que equivale una tabulación. Este valor se invalida según el contenido del archivo cuando `editor.detectIndentation` está activado.", @@ -72,6 +72,7 @@ "cursorBlinking": "Controlar el estilo de animación del cursor. Los valores posibles son \"blink\", \"smooth\", \"phase\", \"expand\" y \"solid\".", "mouseWheelZoom": "Ampliar la fuente del editor cuando se use la rueda del mouse mientras se presiona Ctrl", "cursorStyle": "Controla el estilo del cursor. Los valores aceptados son \"block\", \"block-outline\", \"line\", \"line-thin\", \"underline\" y \"underline-thin\"", + "lineCursorWidth": "Controla el ancho del cursor cuando editor.cursorStyle se establece a 'line'", "fontLigatures": "Habilita las ligaduras tipográficas.", "hideCursorInOverviewRuler": "Controla si el cursor debe ocultarse en la regla de visión general.", "renderWhitespace": "Controla cómo debe representar el editor los espacios en blanco. Las posibilidades son \"none\", \"boundary\" y \"all\". La opción \"boundary\" no representa los espacios individuales entre palabras.", diff --git a/i18n/esn/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/esn/src/vs/editor/common/view/editorColorRegistry.i18n.json index 9cd43302e16..240fd1d7416 100644 --- a/i18n/esn/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/esn/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,7 @@ { "lineHighlight": "Color de fondo del resaltado de línea en la posición del cursor.", "lineHighlightBorderBox": "Color de fondo del borde alrededor de la línea en la posición del cursor.", - "rangeHighlight": "Color de fondo de los intervalos resaltados; por ejemplo, para Apertura Rápida y Buscar.", + "rangeHighlight": "Color de fondo de los rangos resaltados, como por ejemplo las características de abrir rápidamente y encontrar. El color no debe ser opaco para no ocultar las decoraciones subyacentes.", "caret": "Color del cursor del editor.", "editorCursorBackground": "Color de fondo del cursor de edición. Permite personalizar el color del carácter solapado por el bloque del cursor.", "editorWhitespaces": "Color de los caracteres de espacio en blanco del editor.", diff --git a/i18n/esn/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/esn/src/vs/editor/contrib/gotoError/gotoError.i18n.json index a46ce2aad76..19b5ca523e8 100644 --- a/i18n/esn/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/esn/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "Ir al error o la advertencia siguiente", - "markerAction.previous.label": "Ir al error o la advertencia anterior", + "markerAction.next.label": "Ir al siguiente problema (Error, Advertencia, Información)", + "markerAction.previous.label": "Ir al problema anterior (Error, Advertencia, Información)", "editorMarkerNavigationError": "Color de los errores del widget de navegación de marcadores del editor.", "editorMarkerNavigationWarning": "Color de las advertencias del widget de navegación de marcadores del editor.", "editorMarkerNavigationInfo": "Color del widget informativo marcador de navegación en el editor.", diff --git a/i18n/esn/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/esn/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index ce1db0c57f2..700a3162a41 100644 --- a/i18n/esn/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/esn/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "Color de fondo de un símbolo durante el acceso de lectura; por ejemplo, cuando se lee una variable.", - "wordHighlightStrong": "Color de fondo de un símbolo durante el acceso de escritura; por ejemplo, cuando se escribe una variable.", + "wordHighlight": "Color de fondo de un símbolo durante el acceso de lectura, como leer una variable. El color no debe ser opaco para no ocultar las decoraciones subyacentes.", + "wordHighlightStrong": "Color de fondo de un símbolo durante el acceso de escritura, como escribir en una variable. El color no debe ser opaco para no ocultar las decoraciones subyacentes.", "overviewRulerWordHighlightForeground": "Color de marcador de regla de información general para símbolos resaltados.", "overviewRulerWordHighlightStrongForeground": "Color de marcador de regla de información general para símbolos de acceso de escritura resaltados. ", "wordHighlight.next.label": "Ir al siguiente símbolo destacado", diff --git a/i18n/esn/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/esn/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index fc4e80ef3e4..660d6b834cb 100644 --- a/i18n/esn/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/esn/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "`{0}` no es un identificador de menú válido", "missing.command": "El elemento de menú hace referencia a un comando `{0}` que no está definido en la sección 'commands'.", "missing.altCommand": "El elemento de menú hace referencia a un comando alternativo `{0}` que no está definido en la sección 'commands'.", - "dupe.command": "El elemento de menú hace referencia al mismo comando que el comando predeterminado y el comando alternativo", - "nosupport.altCommand": "Actualmente, solo el grupo 'navigation' del menú 'editor/title' es compatible con los comandos alternativos" + "dupe.command": "El elemento de menú hace referencia al mismo comando que el comando predeterminado y el comando alternativo" } \ No newline at end of file diff --git a/i18n/esn/src/vs/platform/environment/node/argv.i18n.json b/i18n/esn/src/vs/platform/environment/node/argv.i18n.json index 37027504432..65665985d3d 100644 --- a/i18n/esn/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/esn/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,32 @@ "diff": "Comparar dos archivos entre sí.", "add": "Agregar carpetas a la última ventana activa.", "goto": "Abrir un archivo en la ruta de acceso de la línea y posición de carácter especificadas.", - "locale": "La configuración regional que se usará (por ejemplo, en-US o zh-TW).", "newWindow": "Fuerce una nueva instancia de Code.", - "performance": "Comience con el comando 'Developer: Startup Performance' habilitado.", - "prof-startup": "Ejecutar generador de perfiles de CPU durante el inicio", - "inspect-extensions": "Permitir la depuración y el perfil de las extensiones. Revisar las herramientas de desarrollador para la conexión uri.", - "inspect-brk-extensions": "Permitir la depuración y el perfil de las extensiones con el host de la extensión pausado después del inicio. Revisar las herramientas de desarrollador para la conexión uri.", "reuseWindow": "Fuerce la apertura de un archivo o carpeta en la última ventana activa.", - "userDataDir": "Especifica el directorio en que se conservan los datos de usuario; es útil cuando se ejecuta como raíz.", - "log": "Nivel de registro a utilizar. Por defecto es 'info'. Los valores permitidos son 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'.", - "verbose": "Imprima salidas detalladas (implica --wait).", "wait": "Espere a que los archivos sean cerrados antes de volver.", + "locale": "La configuración regional que se usará (por ejemplo, en-US o zh-TW).", + "userDataDir": "Especifica el directorio en que se conservan los datos de usuario; es útil cuando se ejecuta como raíz.", + "version": "Versión de impresión.", + "help": "Imprima el uso.", "extensionHomePath": "Establezca la ruta de acceso raíz para las extensiones.", "listExtensions": "Enumere las extensiones instaladas.", "showVersions": "Muestra las versiones de las extensiones instaladas cuando se usa --list-extension.", "installExtension": "Instala una extensión.", "uninstallExtension": "Desinstala una extensión.", "experimentalApis": "Habilita características de API propuestas para una extensión.", - "disableExtensions": "Deshabilite todas las extensiones instaladas.", - "disableGPU": "Deshabilita la aceleración de hardware de GPU.", + "verbose": "Imprima salidas detalladas (implica --wait).", + "log": "Nivel de registro a utilizar. Por defecto es 'info'. Los valores permitidos son 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'.", "status": "Imprimir el uso del proceso y la información de diagnóstico.", - "version": "Versión de impresión.", - "help": "Imprima el uso.", + "performance": "Comience con el comando 'Developer: Startup Performance' habilitado.", + "prof-startup": "Ejecutar generador de perfiles de CPU durante el inicio", + "disableExtensions": "Deshabilite todas las extensiones instaladas.", + "inspect-extensions": "Permitir la depuración y el perfil de las extensiones. Revisar las herramientas de desarrollador para la conexión uri.", + "inspect-brk-extensions": "Permitir la depuración y el perfil de las extensiones con el host de la extensión pausado después del inicio. Revisar las herramientas de desarrollador para la conexión uri.", + "disableGPU": "Deshabilita la aceleración de hardware de GPU.", "usage": "Uso", "options": "opciones", "paths": "rutas de acceso", - "optionsUpperCase": "Opciones" + "optionsUpperCase": "Opciones", + "extensionsManagement": "Gestión de extensiones", + "troubleshooting": "Solución de problemas" } \ No newline at end of file diff --git a/i18n/esn/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/esn/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index 645d8566a96..f654894f7d5 100644 --- a/i18n/esn/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/esn/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,13 +5,11 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "Extensión no válida: package.json no es un archivo JSON.", - "restartCodeLocal": "Reinicie Code antes de volver a instalar {0}.", + "restartCode": "Reinicie Code antes de volver a instalar {0}.", "installingOutdatedExtension": "Una versión más nueva de esta extensión ya está instalada. ¿Desea anular esto con la versión anterior?", "override": "Anular", "cancel": "Cancelar", - "notFoundCompatible": "No se puede instalar porque no se encuentra la extensión '{0}' compatible con la versión actual '{1}' del VS Code.", - "quitCode": "No se puede instalar porque todavía se está ejecutando una instancia obsoleta de la extensión. Por favor, salga e inicie el VS Code antes de volver a instalarlo.\n", - "exitCode": "No se puede instalar porque todavía se está ejecutando una instancia obsoleta de la extensión. Por favor, salga e inicie VS Code antes de volver a instalarlo.", + "errorInstallingDependencies": "Error instalando dependencias. {0}", "notFoundCompatibleDependency": "No se puede instalar porque no se encuentra la extensión dependiente '{0}' compatible con la versión actual '{1}' del VS Code.", "uninstallDependeciesConfirmation": "¿Quiere desinstalar solo '{0}' o también sus dependencias?", "uninstallOnly": "Solo", diff --git a/i18n/esn/src/vs/platform/message/common/message.i18n.json b/i18n/esn/src/vs/platform/message/common/message.i18n.json index 9058cce900d..8e3765bff6e 100644 --- a/i18n/esn/src/vs/platform/message/common/message.i18n.json +++ b/i18n/esn/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "Cerrar", "later": "Más tarde", - "cancel": "Cancelar" + "cancel": "Cancelar", + "moreFile": "...1 archivo más que no se muestra", + "moreFiles": "...{0} archivos más que no se muestran" } \ No newline at end of file diff --git a/i18n/esn/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/esn/src/vs/platform/theme/common/colorRegistry.i18n.json index 9f8669717f0..139c4515643 100644 --- a/i18n/esn/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/esn/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,8 @@ "editorWidgetBorder": "Color de borde de los widgets del editor. El color solo se usa si el widget elige tener un borde y no invalida el color.", "editorSelectionBackground": "Color de la selección del editor.", "editorSelectionForeground": "Color del texto seleccionado para alto contraste.", - "editorInactiveSelection": "Color de la selección en un editor inactivo.", - "editorSelectionHighlight": "Color de las regiones con el mismo contenido que la selección.", + "editorInactiveSelection": "Color de la selección en un editor inactivo. El color no debe ser opaco para no ocultar las decoraciones subyacentes.", "editorFindMatch": "Color de la coincidencia de búsqueda actual.", - "findMatchHighlight": "Color de las demás coincidencias de búsqueda.", - "findRangeHighlight": "Color del intervalo que limita la búsqueda.", - "hoverHighlight": "Resaltado debajo de la palabra para la que se muestra un recuadro al mantener el puntero.", "hoverBackground": "Color de fondo al mantener el puntero en el editor.", "hoverBorder": "Color del borde al mantener el puntero en el editor.", "activeLinkForeground": "Color de los vínculos activos.", @@ -76,12 +72,6 @@ "diffEditorRemoved": "Color de fondo para el texto quitado.", "diffEditorInsertedOutline": "Color de contorno para el texto insertado.", "diffEditorRemovedOutline": "Color de contorno para el texto quitado.", - "mergeCurrentHeaderBackground": "Fondo del encabezado actual en conflictos de combinación alineados.", - "mergeCurrentContentBackground": "Fondo del contenido actual en conflictos de combinación alineados.", - "mergeIncomingHeaderBackground": "Fondo del encabezado de entrada en conflictos de combinación alineados.", - "mergeIncomingContentBackground": "Fondo del contenido de entrada en conflcitos de combinación alineados.", - "mergeCommonHeaderBackground": "Fondo del encabezado de ancestros comunes en conflictos de combinación alineados.", - "mergeCommonContentBackground": "Fondo del contenido de ancestros comunes en conflictos de combinación alineados.", "mergeBorder": "Color del borde en los encabezados y el divisor en conflictos de combinación alineados.", "overviewRulerCurrentContentForeground": "Primer plano de la regla de visión general actual para conflictos de combinación alineados.", "overviewRulerIncomingContentForeground": "Primer plano de regla de visión general de entrada para conflictos de combinación alineados.", diff --git a/i18n/esn/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/esn/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/esn/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/esn/src/vs/workbench/api/node/extHostTreeViews.i18n.json index 1127a4ec4f8..e897d06ac34 100644 --- a/i18n/esn/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/esn/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -4,7 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "treeView.notRegistered": "No se ha registrado ninga vista del árbol con id '{0}'.", - "treeItem.notFound": "No se encontró ningún item del árbol con id '{0}'.", - "treeView.duplicateElement": "El elemento '{0}' ya está registrado" + "treeView.notRegistered": "No se ha registrado ninga vista del árbol con id '{0}'." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/esn/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index 9caf1c7c012..ac538fe6a5b 100644 --- a/i18n/esn/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/esn/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "Alternar la ubicación de la barra lateral", "view": "Ver" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/esn/src/vs/workbench/browser/actions/workspaceActions.i18n.json index 1e2b99a1870..9f92beb9392 100644 --- a/i18n/esn/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/esn/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "Abrir archivo...", "openFolder": "Abrir carpeta...", "openFileFolder": "Abrir...", - "addFolderToWorkspace": "Agregar carpeta al área de trabajo...", - "add": "&& Agregar", - "addFolderToWorkspaceTitle": "Agregar carpeta al área de trabajo", "globalRemoveFolderFromWorkspace": "Quitar carpeta del Área de trabajo...", - "removeFolderFromWorkspace": "Quitar carpeta del área de trabajo", - "openFolderSettings": "Abrir Configuración de carpeta", "saveWorkspaceAsAction": "Guardar área de trabajo como...", "save": "&&Guardar", "saveWorkspace": "Guardar área de trabajo", "openWorkspaceAction": "Abrir área de trabajo...", "openWorkspaceConfigFile": "Abrir archivo de configuración del área de trabajo", - "openFolderAsWorkspaceInNewWindow": "Abrir carpeta como Área de trabajo en una Nueva Ventana", - "workspaceFolderPickerPlaceholder": "Seleccionar la carpeta del área de trabajo" + "openFolderAsWorkspaceInNewWindow": "Abrir carpeta como Área de trabajo en una Nueva Ventana" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/esn/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..832cb0abb68 --- /dev/null +++ b/i18n/esn/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "Agregar carpeta al área de trabajo...", + "addFolderToWorkspaceTitle": "Agregar carpeta al área de trabajo", + "workspaceFolderPickerPlaceholder": "Seleccionar la carpeta del área de trabajo" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/esn/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index ae6d0079e4c..0e9cbb0a9e2 100644 --- a/i18n/esn/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,17 @@ "groupThreePicker": "Mostrar editores del tercer grupo", "allEditorsPicker": "Mostrar todos los editores abiertos", "view": "Ver", - "file": "Archivo" + "file": "Archivo", + "close": "Cerrar", + "closeOthers": "Cerrar otros", + "closeRight": "Cerrar a la derecha", + "closeAllUnmodified": "Cerrar los que no se han modificado", + "closeAll": "Cerrar todo", + "keepOpen": "Mantener abierto", + "showOpenedEditors": "Mostrar editores abiertos", + "keepEditor": "Mantener editor", + "closeEditorsInGroup": "Cerrar todos los editores del grupo", + "closeUnmodifiedEditors": "Cerrar los editores en el grupo sin modificar", + "closeOtherEditors": "Cerrar otros editores", + "closeRightEditors": "Cerrar los editores a la derecha" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/esn/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index f88c82cd9df..93badc7f42a 100644 --- a/i18n/esn/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/esn/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "Cerrar editor", "revertAndCloseActiveEditor": "Revertir y cerrar el editor", "closeEditorsToTheLeft": "Cerrar los editores a la izquierda", - "closeEditorsToTheRight": "Cerrar los editores a la derecha", "closeAllEditors": "Cerrar todos los editores", - "closeUnmodifiedEditors": "Cerrar los editores en el grupo sin modificar", "closeEditorsInOtherGroups": "Cerrar los editores de otros grupos", - "closeOtherEditorsInGroup": "Cerrar otros editores", - "closeEditorsInGroup": "Cerrar todos los editores del grupo", "moveActiveGroupLeft": "Mover el grupo de editores a la izquierda", "moveActiveGroupRight": "Mover el grupo de editores a la derecha", "minimizeOtherEditorGroups": "Minimizar otros grupos de editores", "evenEditorGroups": "Uniformar anchos del grupo de editores", "maximizeEditor": "Maximizar el grupo de editores y ocultar la barra lateral", - "keepEditor": "Mantener editor", "openNextEditor": "Abrir el editor siguiente", "openPreviousEditor": "Abrir el editor anterior", "nextEditorInGroup": "Abrir el siguiente editor del grupo", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "Mostrar editores del primer grupo", "showEditorsInSecondGroup": "Mostrar editores del segundo grupo", "showEditorsInThirdGroup": "Mostrar editores del tercer grupo", - "showEditorsInGroup": "Mostrar los editores del grupo", "showAllEditors": "Mostrar todos los editores", "openPreviousRecentlyUsedEditorInGroup": "Abrir el editor recientemente usado anterior en el grupo", "openNextRecentlyUsedEditorInGroup": "Abrir el siguiente editor recientemente usado en el grupo", diff --git a/i18n/esn/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/esn/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index a44acd1dea7..441fc68d0e6 100644 --- a/i18n/esn/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/esn/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "Mover el editor activo por tabulaciones o grupos", "editorCommand.activeEditorMove.arg.name": "Argumento para mover el editor activo", - "editorCommand.activeEditorMove.arg.description": "Propiedades del argumento:\n * 'to': cadena de valor que proporciona dónde moverse.\n\t* 'by': cadena de valor que proporciona la unidad de medida para moverse. Por pestaña o por grupo.\n\t* 'value': valor numérico que proporciona cuantas posiciones o una posición absoluta para mover.", - "commandDeprecated": "El comando **{0}** se ha quitado. Puede usar en su lugar **{1}**", - "openKeybindings": "Configurar métodos abreviados de teclado" + "editorCommand.activeEditorMove.arg.description": "Propiedades del argumento:\n * 'to': cadena de valor que proporciona dónde moverse.\n\t* 'by': cadena de valor que proporciona la unidad de medida para moverse. Por pestaña o por grupo.\n\t* 'value': valor numérico que proporciona cuantas posiciones o una posición absoluta para mover." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/esn/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index d1ec23e2db6..8fda6300549 100644 --- a/i18n/esn/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/esn/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -10,7 +10,5 @@ "editableEditorWithInputAriaLabel": "{0}. Editor de comparación de archivos de texto.", "editableEditorAriaLabel": "Editor de comparación de archivos de texto.", "navigate.next.label": "Cambio siguiente", - "navigate.prev.label": "Cambio anterior", - "inlineDiffLabel": "Cambiar a vista alineada", - "sideBySideDiffLabel": "Cambiar a vista en paralelo" + "navigate.prev.label": "Cambio anterior" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/esn/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index 49c85dbc052..d7236689da9 100644 --- a/i18n/esn/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/esn/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "Cerrar", - "closeOthers": "Cerrar otros", - "closeRight": "Cerrar a la derecha", - "closeAll": "Cerrar todo", - "closeAllUnmodified": "Cerrar los no modificados", - "keepOpen": "Mantener abierto", - "showOpenedEditors": "Mostrar editores abiertos", "araLabelEditorActions": "Acciones del editor" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/esn/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index e4776f8c605..8b6ad71cd4e 100644 --- a/i18n/esn/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/esn/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -3,6 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{ - "hideView": "Ocultar en la barra lateral" -} \ No newline at end of file +{} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/common/theme.i18n.json b/i18n/esn/src/vs/workbench/common/theme.i18n.json index 323cb6d934f..1f48fa2867d 100644 --- a/i18n/esn/src/vs/workbench/common/theme.i18n.json +++ b/i18n/esn/src/vs/workbench/common/theme.i18n.json @@ -16,7 +16,6 @@ "editorGroupBackground": "Color de fondo de un grupo de editores. Los grupos de editores son los contenedores de los editores. El color de fondo se ve cuando se mueven arrastrando los grupos de editores.", "tabsContainerBackground": "Color de fondo del encabezado del título del grupo de editores cuando las fichas están habilitadas. Los grupos de editores son contenedores de editores.", "tabsContainerBorder": "Color de borde del encabezado del título del grupo de editores cuando las fichas están habilitadas. Los grupos de editores son contenedores de editores.", - "editorGroupHeaderBackground": "Color de fondo del encabezado del título del grupo de editores cuando las fichas están deshabilitadas. Los grupos de editores son contenedores de editores.", "editorGroupBorder": "Color para separar varios grupos de editores entre sí. Los grupos de editores son los contenedores de los editores.", "editorDragAndDropBackground": "Color de fondo cuando se arrastran los editores. El color debería tener transparencia para que el contenido del editor pueda brillar a su través.", "panelBackground": "Color de fondo del panel. Los paneles se muestran debajo del área de editores y contienen vistas, como Salida y Terminal integrado.", @@ -33,8 +32,6 @@ "statusBarNoFolderBorder": "Color de borde de la barra de estado que separa la barra lateral y el editor cuando no hay ninguna carpeta abierta. La barra de estado se muestra en la parte inferior de la ventana.", "statusBarItemActiveBackground": "Color de fondo de un elemento de la barra de estado al hacer clic. La barra de estado se muestra en la parte inferior de la ventana.", "statusBarItemHoverBackground": "Color de fondo de un elemento de la barra de estado al mantener el puntero. La barra de estado se muestra en la parte inferior de la ventana.", - "statusBarProminentItemBackground": "Color de fondo de los elementos destacados en la barra de estado. Estos elementos sobresalen para indicar importancia. La barra de estado está ubicada en la parte inferior de la ventana.", - "statusBarProminentItemHoverBackground": "Color de fondo de los elementos destacados en la barra de estado cuando se mantiene el mouse sobre estos elementos. Estos elementos sobresalen para indicar importancia. La barra de estado está ubicada en la parte inferior de la ventana.", "activityBarBackground": "Color de fondo de la barra de actividad, que se muestra en el lado izquierdo o derecho y que permite cambiar entre diferentes vistas de la barra lateral.", "activityBarForeground": "Color de fondo de la barra de actividad (por ejemplo utilizado por los iconos). La barra de actividad muestra en el lado izquierdo o derecho y permite cambiar entre diferentes vistas de la barra lateral.", "activityBarBorder": "Color de borde de la barra de actividad que separa la barra lateral. La barra de actividad se muestra en el extremo derecho o izquierdo y permite cambiar entre las vistas de la barra lateral.", diff --git a/i18n/esn/src/vs/workbench/common/views.i18n.json b/i18n/esn/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..f22e31a7e45 --- /dev/null +++ b/i18n/esn/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "Ya existe una vista registrada con el identificador '{0}' en la ubicación '{1}'" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/esn/src/vs/workbench/electron-browser/actions.i18n.json index 81432663720..c875a388e03 100644 --- a/i18n/esn/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/esn/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "Cerrar editor", "closeWindow": "Cerrar ventana", "closeWorkspace": "Cerrar área de trabajo", "noWorkspaceOpened": "No hay ninguna área de trabajo abierta en esta instancia para cerrarla.", @@ -52,21 +51,5 @@ "displayLanguage": "Define el lenguaje para mostrar de VSCode.", "doc": "Consulte {0} para obtener una lista de idiomas compatibles.", "restart": "Al cambiar el valor se requiere reiniciar VSCode.", - "fail.createSettings": "No se puede crear '{0}' ({1}).", - "openLogsFolder": "Abrir carpeta de registros", - "showLogs": "Mostrar registros...", - "mainProcess": "Principal", - "sharedProcess": "Compartido", - "rendererProcess": "Renderizador", - "extensionHost": "Host de extensión", - "selectProcess": "Seleccionar proceso", - "setLogLevel": "Establecer nivel de registro", - "trace": "Seguimiento", - "debug": "Depurar", - "info": "Información", - "warn": "Advertencia", - "err": "Error", - "critical": "Crítico", - "off": "Apagado", - "selectLogLevel": "Seleccione el nivel de registro" + "fail.createSettings": "No se puede crear '{0}' ({1})." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/esn/src/vs/workbench/electron-browser/main.contribution.i18n.json index f2abdd8deaf..dd5456c4e0f 100644 --- a/i18n/esn/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "Ver", "help": "Ayuda", "file": "Archivo", - "developer": "Desarrollador", "workspaces": "Áreas de trabajo", + "developer": "Desarrollador", + "workbenchConfigurationTitle": "Área de trabajo", "showEditorTabs": "Controla si los editores abiertos se deben mostrar o no en pestañas.", "workbench.editor.labelFormat.default": "Mostrar el nombre del archivo. Cuando están habilitadas las pestañas y dos archivos tienen el mismo nombre en un grupo se agregan las secciones de distinguinshing de ruta de cada archivo. Cuando se desactivan las pestañas, se muestra la ruta de acceso relativa a la carpeta de trabajo si el editor está activo.", "workbench.editor.labelFormat.short": "Mostrar el nombre del archivo seguido de su nombre de directorio.", @@ -20,8 +21,10 @@ "showIcons": "Controla si los editores abiertos deben mostrarse o no con un icono. Requiere que también se habilite un tema de icono.", "enablePreview": "Controla si los editores abiertos se muestran en vista previa. Los editores en vista previa se reutilizan hasta que se guardan (por ejemplo, mediante doble clic o editándolos) y se muestran en cursiva.", "enablePreviewFromQuickOpen": "Controla si los editores abiertos mediante Quick Open se muestran en modo de vista previa. Los editores en modo de vista previa se reutilizan hasta que se conservan (por ejemplo, mediante doble clic o editándolos).", + "closeOnFileDelete": "Controla si los editores que muestran un archivo deben cerrarse automáticamente cuando otro proceso elimina el archivo o le cambia el nombre. Si se deshabilita esta opción y se da alguna de estas circunstancias, se mantiene el editor abierto con modificaciones. Tenga en cuenta que, cuando se eliminan archivos desde la aplicación, siempre se cierra el editor y que los archivos con modificaciones no se cierran nunca para preservar los datos.", "editorOpenPositioning": "Controla dónde se abren los editores. Seleccione 'izquierda' o 'derecha' para abrir los editores situados a la izquierda o la derecha del que está actualmente activo. Seleccione 'primero' o 'último' para abrir los editores con independencia del que esté actualmente activo. ", "revealIfOpen": "Controla si un editor se muestra en alguno de los grupos visibles cuando se abre. Si se deshabilita esta opción, un editor preferirá abrirse en el grupo de editores activo en ese momento. Si se habilita, un editor ya abierto se mostrará en lugar de volver a abrirse en el grupo de editores activo. Tenga en cuenta que hay casos en los que esta opción se omite; por ejemplo, cuando se fuerza la apertura de un editor en un grupo específico o junto al grupo activo actual.", + "swipeToNavigate": "Navegar entre achivos abiertos utlizando la pulsación de tres dedos para deslizar horizontalmante.", "commandHistory": "Controla el número de comandos utilizados recientemente que se mantendrán en el historial de la paleta de comandos. Establezca el valor a 0 para desactivar el historial de comandos.", "preserveInput": "Controla si la última entrada introducida en la paleta de comandos debería ser restaurada cuando sea abierta la próxima vez.", "closeOnFocusLost": "Controla si Quick Open debe cerrarse automáticamente cuando pierde el foco.", @@ -29,14 +32,11 @@ "sideBarLocation": "Controla la ubicación de la barra lateral. Puede mostrarse a la izquierda o a la derecha del área de trabajo.", "statusBarVisibility": "Controla la visibilidad de la barra de estado en la parte inferior del área de trabajo.", "activityBarVisibility": "Controla la visibilidad de la barra de actividades en el área de trabajo.", - "closeOnFileDelete": "Controla si los editores que muestran un archivo deben cerrarse automáticamente cuando otro proceso elimina el archivo o le cambia el nombre. Si se deshabilita esta opción y se da alguna de estas circunstancias, se mantiene el editor abierto con modificaciones. Tenga en cuenta que, cuando se eliminan archivos desde la aplicación, siempre se cierra el editor y que los archivos con modificaciones no se cierran nunca para preservar los datos.", - "enableNaturalLanguageSettingsSearch": "Controla si habilita el modo de búsqueda de lenguaje natural para la configuración.", "fontAliasing": "Controla el método de suavizado de fuentes en el área de trabajo.\n- default: suavizado de fuentes en subpíxeles. En la mayoría de las pantallas que no son Retina, esta opción muestra el texto más nítido.\n- antialiased: suaviza las fuentes en píxeles, en lugar de subpíxeles. Puede hacer que las fuentes se vean más claras en general\n- none: deshabilita el suavizado de fuentes. El texto se muestra con bordes nítidos irregulares.", "workbench.fontAliasing.default": "Suavizado de fuentes en subpíxeles. En la mayoría de las pantallas que no son Retina, esta opción muestra el texto más nítido.", "workbench.fontAliasing.antialiased": "Suaviza las fuentes en píxeles, en lugar de subpíxeles. Puede hacer que las fuentes se vean más claras en general.", "workbench.fontAliasing.none": "Deshabilita el suavizado de fuentes. El texto se muestra con bordes nítidos irregulares.", - "swipeToNavigate": "Navegar entre achivos abiertos utlizando la pulsación de tres dedos para deslizar horizontalmante.", - "workbenchConfigurationTitle": "Área de trabajo", + "enableNaturalLanguageSettingsSearch": "Controla si habilita el modo de búsqueda de lenguaje natural para la configuración.", "windowConfigurationTitle": "Ventana", "window.openFilesInNewWindow.on": "Los archivos se abrirán en una nueva ventana", "window.openFilesInNewWindow.off": "Los archivos se abrirán en la ventana con la carpeta de archivos abierta o en la última ventana activa", diff --git a/i18n/esn/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/esn/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 0f8291c0572..68ea94e5a20 100644 --- a/i18n/esn/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "depurado", - "debug.terminal.not.available.error": "Terminal integrado no disponible" + "debug.terminal.title": "depurado" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 1ba4ecd59bf..c01e0004e65 100644 --- a/i18n/esn/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "Abrir nuevo símbolo del sistema", "globalConsoleActionMacLinux": "Abrir nuevo terminal", "scopedConsoleActionWin": "Abrir en símbolo del sistema", - "scopedConsoleActionMacLinux": "Abrir en terminal", - "openFolderInIntegratedTerminal": "Abrir en terminal" + "scopedConsoleActionMacLinux": "Abrir en terminal" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index 3335907cc3e..90cb60f6caf 100644 --- a/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "Esta extensión se recomienda basado en los archivos que abrió recientemente.", + "neverShowAgain": "No volver a mostrar", + "close": "Cerrar", "workspaceRecommendation": "Esta extensión es recomendada por los usuarios del espacio de trabajo actual.", + "fileBasedRecommendation": "Esta extensión se recomienda basado en los archivos que abrió recientemente.", "exeBasedRecommendation": "Se recomienda esta extensión porque tiene instalado {0} . ", "reallyRecommended2": "La extension recomendada para este tipo de archivo es {0}", "reallyRecommendedExtensionPack": "Para este tipo de fichero, se recomienda el paquete de extensión '{0}'.", "showRecommendations": "Mostrar recomendaciones", "install": "Instalar", - "neverShowAgain": "No volver a mostrar", - "close": "Cerrar", "workspaceRecommended": "Esta área de trabajo tiene recomendaciones de extensión.", "installAll": "Instalar todo", "ignoreExtensionRecommendations": "¿Desea ignorar todas las recomendaciones de la extensión?", diff --git a/i18n/esn/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..eff0be207f1 --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "Área de trabajo" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/esn/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 5b4f1d9a867..a73d898f487 100644 --- a/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,25 @@ "filesCategory": "Archivo", "revealInSideBar": "Mostrar en barra lateral", "acceptLocalChanges": "Usar los cambios y sobrescribir el contenido del disco", - "revertLocalChanges": "Descartar los cambios y volver al contenido del disco" + "revertLocalChanges": "Descartar los cambios y volver al contenido del disco", + "copyPathOfActive": "Copiar ruta del archivo activo", + "saveAllInGroup": "Guardar todo en el grupo", + "saveFiles": "Guardar todos los archivos", + "revert": "Revertir archivo", + "compareActiveWithSaved": "Comparar el archivo activo con el guardado", + "closeEditor": "Cerrar editor", + "view": "Ver", + "openToSide": "Abrir en el lateral", + "revealInWindows": "Mostrar en el Explorador", + "revealInMac": "Mostrar en Finder", + "openContainer": "Abrir carpeta contenedora", + "copyPath": "Copiar ruta de acceso", + "saveAll": "Guardar todos", + "compareWithSaved": "Comparar con el guardado", + "compareSource": "Seleccionar para comparar", + "close": "Cerrar", + "closeOthers": "Cerrar otros", + "closeUnmodified": "Cerrar los que no se han modificado", + "closeAll": "Cerrar todo", + "deleteFile": "Eliminar permanentemente" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 849c94fa0c7..a96cb97676f 100644 --- a/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "Reintentar", - "rename": "Cambiar nombre", "newFile": "Nuevo archivo", "newFolder": "Nueva carpeta", + "rename": "Cambiar nombre", + "delete": "Eliminar", + "copyFile": "Copiar", + "pasteFile": "Pegar", + "retry": "Reintentar", "openFolderFirst": "Abra primero una carpeta para crear archivos o carpetas en ella.", "newUntitledFile": "Nuevo archivo sin título", "createNewFile": "Nuevo archivo", @@ -28,26 +31,14 @@ "confirmDeleteMessageFile": "¿Está seguro de que desea eliminar '{0}' de forma permanente?", "irreversible": "Esta acción es irreversible.", "permDelete": "Eliminar permanentemente", - "delete": "Eliminar", "importFiles": "Importar archivos", "confirmOverwrite": "Ya existe un archivo o carpeta con el mismo nombre en la carpeta de destino. ¿Quiere reemplazarlo?", "replaceButtonLabel": "&&Reemplazar", - "copyFile": "Copiar", - "pasteFile": "Pegar", "duplicateFile": "Duplicado", - "openToSide": "Abrir en el lateral", - "compareSource": "Seleccionar para comparar", "globalCompareFile": "Comparar archivo activo con...", "openFileToCompare": "Abrir un archivo antes para compararlo con otro archivo.", - "compareWith": "Comparar \"{0}\" con \"{1}\"", - "compareFiles": "Comparar archivos", "refresh": "Actualizar", - "save": "Guardar", - "saveAs": "Guardar como...", - "saveAll": "Guardar todos", "saveAllInGroup": "Guardar todo en el grupo", - "saveFiles": "Guardar todos los archivos", - "revert": "Revertir archivo", "focusOpenEditors": "Foco sobre la vista de editores abiertos", "focusFilesExplorer": "Enfocar Explorador de archivos", "showInExplorer": "Mostrar el archivo activo en la barra lateral", @@ -56,20 +47,11 @@ "refreshExplorer": "Actualizar Explorador", "openFileInNewWindow": "Abrir archivo activo en nueva ventana", "openFileToShowInNewWindow": "Abrir un archivo antes para abrirlo en una nueva ventana", - "revealInWindows": "Mostrar en el Explorador", - "revealInMac": "Mostrar en Finder", - "openContainer": "Abrir carpeta contenedora", - "revealActiveFileInWindows": "Mostrar archivo activo en el Explorador de Windows", - "revealActiveFileInMac": "Mostrar archivo activo en Finder", - "openActiveFileContainer": "Abrir carpeta contenedora del archivo activo", "copyPath": "Copiar ruta de acceso", - "copyPathOfActive": "Copiar ruta del archivo activo", "emptyFileNameError": "Debe especificarse un nombre de archivo o carpeta.", "fileNameExistsError": "Ya existe el archivo o carpeta **{0}** en esta ubicación. Elija un nombre diferente.", "invalidFileNameError": "El nombre **{0}** no es válido para el archivo o la carpeta. Elija un nombre diferente.", "filePathTooLongError": "El nombre **{0}** da como resultado una ruta de acceso demasiado larga. Elija un nombre más corto.", - "compareWithSaved": "Comparar el archivo activo con el guardado", - "modifiedLabel": "{0} (en el disco) ↔ {1}", "compareWithClipboard": "Comparar archivo activo con portapapeles", "clipboardComparisonLabel": "Clipboard ↔ {0}" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index f417c4b11aa..2228202fde4 100644 --- a/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "Abrir un archivo antes para copiar su ruta de acceso", - "openFileToReveal": "Abrir un archivo antes para mostrarlo" + "revealInWindows": "Mostrar en el Explorador", + "revealInMac": "Mostrar en Finder", + "openContainer": "Abrir carpeta contenedora", + "saveAs": "Guardar como...", + "save": "Guardar", + "saveAll": "Guardar todos", + "removeFolderFromWorkspace": "Quitar carpeta del área de trabajo", + "modifiedLabel": "{0} (en el disco) ↔ {1}", + "openFileToReveal": "Abrir un archivo antes para mostrarlo", + "openFileToCopy": "Abrir un archivo antes para copiar su ruta de acceso" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 6b7926d2bf7..34df999607b 100644 --- a/i18n/esn/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,6 @@ "editorConfigurationTitle": "Editor", "formatOnSave": "Formatea un archivo al guardarlo. Debe haber un formateador disponible, el archivo no debe guardarse automáticamente y el editor no debe estar cerrándose.", "explorerConfigurationTitle": "Explorador de archivos", - "openEditorsVisible": "Número de editores mostrados en el panel Editores abiertos. Establezca este valor en 0 para ocultar el panel.", - "dynamicHeight": "Controla si la altura de la sección de editores abiertos debería adaptarse o no de forma dinámica al número de elementos.", "autoReveal": "Controla si el explorador debe mostrar y seleccionar automáticamente los archivos al abrirlos.", "enableDragAndDrop": "Controla si el explorador debe permitir mover archivos y carpetas mediante la función arrastrar y colocar.", "confirmDragAndDrop": "Controla si el explorador debe pedir la confirmación al reubicar archivos o carpetas a través de arrastrar y soltar.", diff --git a/i18n/esn/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/esn/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 186f5cdaa42..85b5734142e 100644 --- a/i18n/esn/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,9 @@ // Do not edit this file. It is machine generated. { "userGuide": "Use las acciones de la barra de herramientas del editor situada a la derecha para **deshacer** los cambios o **sobrescribir** el contenido del disco con sus cambios", - "discard": "Descartar", "overwrite": "Sobrescribir", "retry": "Reintentar", - "readonlySaveError": "No se pudo guardar '{0}': El archivo está protegido contra escritura. Seleccione \"Sobrescribir\" para quitar la protección.", + "discard": "Descartar", "genericSaveError": "No se pudo guardar '{0}': {1}", "staleSaveError": "No se pudo guardar '{0}': El contenido del disco es más reciente. Haga clic en **Comparar** para comparar su versión con la que hay en el disco.", "compareChanges": "Comparar", diff --git a/i18n/esn/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/esn/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index b4bad361098..f5060aef05b 100644 --- a/i18n/esn/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "Editores abiertos", "openEditosrSection": "Sección Editores abiertos", - "dirtyCounter": "{0} sin guardar", - "saveAll": "Guardar todos", - "closeAllUnmodified": "Cerrar los que no se han modificado", - "closeAll": "Cerrar todo", - "compareWithSaved": "Comparar con el guardado", - "close": "Cerrar", - "closeOthers": "Cerrar otros" + "dirtyCounter": "{0} sin guardar" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..68e35e56b16 --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "developer": "Desarrollador" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/esn/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..80e723dfda2 --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "Abrir carpeta de registros", + "showLogs": "Mostrar registros...", + "mainProcess": "Principal", + "sharedProcess": "Compartido", + "rendererProcess": "Ventana", + "extensionHost": "Host de extensión", + "selectProcess": "Seleccionar proceso", + "setLogLevel": "Establecer nivel de registro", + "trace": "Seguimiento", + "debug": "Depurar", + "info": "Información", + "warn": "Advertencia", + "err": "Error", + "critical": "Crítico", + "off": "Apagado" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/esn/src/vs/workbench/parts/markers/common/messages.i18n.json index a028050eafb..b28c9ca3342 100644 --- a/i18n/esn/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "viewCategory": "Ver", - "problems.view.toggle.label": "Alternar Problemas ", - "problems.view.focus.label": "Problemas de enfoque", "problems.panel.configuration.title": "Vista Problemas", "problems.panel.configuration.autoreveal": "Controla si la vista Problemas debe revelar automáticamente los archivos cuando los abre", "markers.panel.title.problems": "Problemas", diff --git a/i18n/esn/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..c75638715f9 --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "Salida", + "viewCategory": "Ver", + "clearOutput.label": "Borrar salida" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/esn/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/esn/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index b720c2b8a57..7f4ed8494b7 100644 --- a/i18n/esn/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "¡Intentar la búsqueda del lenguaje natural!", "defaultSettings": "Colocar la configuración en el editor de lado de mano derecha para anular.", "noSettingsFound": "No se encontró ninguna configuración.", "settingsSwitcherBarAriaLabel": "Conmutador de configuración", "userSettings": "Configuración de usuario", "workspaceSettings": "Configuración de área de trabajo", - "folderSettings": "Configuración de Carpeta", - "enableFuzzySearch": "Habilitar búsqueda en lenguaje natural" + "folderSettings": "Configuración de Carpeta" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/esn/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index 575bc61fdb4..2ae85dc2ac1 100644 --- a/i18n/esn/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "Más utilizada", - "mostRelevant": "Más relevante", "defaultKeybindingsHeader": "Coloque los enlaces de teclado en el archivo de enlaces de teclado para sobrescribirlos." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index 3a50ec52260..6e19797b529 100644 --- a/i18n/esn/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "Ver", "commandsHandlerDescriptionDefault": "Mostrar y ejecutar comandos", "gotoLineDescriptionMac": "Ir a la línea", "gotoLineDescriptionWin": "Ir a la línea", diff --git a/i18n/esn/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index 2d44f58d514..c5061e853b0 100644 --- a/i18n/esn/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,6 @@ "toggleGitViewlet": "Mostrar GIT", "source control": "Control de código fuente", "toggleSCMViewlet": "Mostrar SCM", - "view": "Ver" + "view": "Ver", + "scmConfigurationTitle": "SCM" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/esn/src/vs/workbench/parts/search/browser/searchActions.i18n.json index bcfc62d1906..5357b8b610a 100644 --- a/i18n/esn/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "Mostrar anterior término de búsqueda", "showSearchViewlet": "Mostrar búsqueda", "findInFiles": "Buscar en archivos", - "findInFilesWithSelectedText": "Buscar en ficheros de texto seleccionado", "replaceInFiles": "Reemplazar en archivos", - "replaceInFilesWithSelectedText": "Reemplazar en archivos con el texto seleccionado", "RefreshAction.label": "Actualizar", "CollapseDeepestExpandedLevelAction.label": "Contraer todo", "ClearSearchResultsAction.label": "Borrar", diff --git a/i18n/esn/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index fe7e74dbe33..a0aba2b8419 100644 --- a/i18n/esn/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "Buscar en carpeta...", + "findInWorkspace": "Buscar en área de trabajo...", "showTriggerActions": "Ir al símbolo en el área de trabajo...", "name": "Buscar", "search": "Buscar", + "showSearchViewlet": "Mostrar búsqueda", "view": "Ver", + "findInFiles": "Buscar en archivos", "openAnythingHandlerDescription": "Ir al archivo", "openSymbolDescriptionNormal": "Ir al símbolo en el área de trabajo", "searchOutputChannelTitle": "Buscar", diff --git a/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..9675a4f182c --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.1": "({0})", + "preferences": "Preferencias" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index c49e1beb60b..5fb6638f35b 100644 --- a/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,10 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "Seleccione lenguaje para el fragmento", - "openSnippet.errorOnCreate": "No se puede crear {0}", - "openSnippet.label": "Abrir fragmentos de código del usuario", - "preferences": "Preferencias", "snippetSchema.json.default": "Fragmento de código vacío", "snippetSchema.json": "Configuración de fragmento de código del usuario", "snippetSchema.json.prefix": "El prefijo que se debe usar al seleccionar el fragmento de código en Intellisense", diff --git a/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..8c806f2935a --- /dev/null +++ b/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "Fragmento de código del usuario" +} \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index ecf3b81fb81..34d3cff577c 100644 --- a/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "Lenguaje desconocido en \"contributes.{0}.language\". Valor proporcionado: {1}", "invalid.path.0": "Se esperaba una cadena en \"contributes.{0}.path\". Valor proporcionado: {1}", + "invalid.language": "Lenguaje desconocido en \"contributes.{0}.language\". Valor proporcionado: {1}", "invalid.path.1": "Se esperaba que \"contributes.{0}.path\" ({1}) se incluyera en la carpeta de la extensión ({2}). Esto puede hacer que la extensión no sea portátil.", "vscode.extension.contributes.snippets": "Aporta fragmentos de código.", "vscode.extension.contributes.snippets-language": "Identificador del lenguaje al que se aporta este fragmento de código.", "vscode.extension.contributes.snippets-path": "Ruta de acceso del archivo de fragmentos de código. La ruta es relativa a la carpeta de extensión y normalmente empieza por \"./snippets/\".", "badVariableUse": "Uno o más fragmentos de la extensión '{0}' muy probable confunden variables de fragmento y fragmento-marcadores de posición (véase https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax para más detalles)", "badFile": "No se pudo leer el archivo del fragmento \"{0}\".", - "source.snippet": "Fragmento de código del usuario", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json b/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json index b41adfc8dd9..f8bbe6f41b9 100644 --- a/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json @@ -8,6 +8,5 @@ "terminal.foreground": "El color de primer plano del terminal.", "terminalCursor.foreground": "Color de primer plano del cursor del terminal.", "terminalCursor.background": "Color de fondo del cursor del terminal. Permite personalizar el color de un carácter solapado por un cursor de bloque.", - "terminal.selectionBackground": "Color de fondo de selección del terminal.", - "terminal.ansiColor": "Color ANSI \"{0}\" en el terminal." + "terminal.selectionBackground": "Color de fondo de selección del terminal." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index 1a5374df014..d5f5c068b5f 100644 --- a/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,6 @@ "terminal.integrated.chooseWindowsShellInfo": "Para cambiar el shell de terminal predeterminado, seleccione el botón Personalizar.", "customize": "Personalizar", "cancel": "Cancelar", - "never again": "De acuerdo, no volver a mostrar este mensaje", "terminal.integrated.chooseWindowsShell": "Seleccione el shell de terminal que desee, puede cambiarlo más adelante en la configuración", "terminalService.terminalCloseConfirmationSingular": "Hay una sesión de terminal activa, ¿quiere terminarla?", "terminalService.terminalCloseConfirmationPlural": "Hay {0} sesiones de terminal activas, ¿quiere terminarlas?" diff --git a/i18n/esn/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/esn/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 1d8632efe35..45b01f69897 100644 --- a/i18n/esn/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/esn/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileNotModifiedError": "Archivo no modificado desde", "fileBinaryError": "El archivo parece ser binario y no se puede abrir como texto" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/esn/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index e49927e3bdf..caa8ce6bf00 100644 --- a/i18n/esn/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/esn/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "¿Quiere guardar los cambios efectuados en {0}?", "saveChangesMessages": "¿Desea guardar los cambios en los siguientes {0} archivos?", - "moreFile": "...1 archivo más que no se muestra", - "moreFiles": "...{0} archivos más que no se muestran", "saveAll": "&&Guardar todo", "save": "Guardar", "dontSave": "&&No guardar", diff --git a/i18n/esn/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/esn/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index 302c7ed170b..410c2efcbcb 100644 --- a/i18n/esn/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/esn/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "No file icons", "iconThemeError": "File icon theme is unknown or not installed.", "workbenchColors": "Reemplaza los colores del tema de color actual", - "editorColors": "Reemplaza los colores y el estilo de fuente del editor del tema de color seleccionado.", "editorColors.comments": "Establece los colores y estilos para los comentarios", "editorColors.strings": "Establece los colores y estilos para los literales de cadena.", "editorColors.keywords": "Establece los colores y estilos para las palabras clave.", @@ -19,5 +18,6 @@ "editorColors.types": "Establece los colores y estilos para las declaraciones y referencias de tipos.", "editorColors.functions": "Establece los colores y estilos para las declaraciones y referencias de funciones.", "editorColors.variables": "Establece los colores y estilos para las declaraciones y referencias de variables.", - "editorColors.textMateRules": "Establece colores y estilos utilizando las reglas de la tematización de textmate (avanzadas)." + "editorColors.textMateRules": "Establece colores y estilos utilizando las reglas de la tematización de textmate (avanzadas).", + "editorColors": "Reemplaza los colores y el estilo de fuente del editor del tema de color seleccionado." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/esn/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 83604230ec4..e7f9d116f01 100644 --- a/i18n/esn/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/esn/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "No se puede escribir en el archivo de configuración del espacio de trabajo. Por favor, abra el archivo para corregir sus errores/advertencias e inténtelo de nuevo.", "errorWorkspaceConfigurationFileDirty": "No se puede escribir en el archivo de configuración de espacio de trabajo porque el archivo ha sido modificado. Por favor, guárdelo y vuelva a intentarlo.", "openWorkspaceConfigurationFile": "Abrir archivo de configuración del área de trabajo", - "close": "Cerrar", - "enterWorkspace.close": "Cerrar", - "enterWorkspace.dontShowAgain": "No volver a mostrar", - "enterWorkspace.moreInfo": "Más información", - "enterWorkspace.prompt": "Obtenga más información acerca de cómo trabajar con varias carpetas en VS Code. " + "close": "Cerrar" } \ No newline at end of file diff --git a/i18n/fra/extensions/git/out/autofetch.i18n.json b/i18n/fra/extensions/git/out/autofetch.i18n.json index c7e1b61f3ec..e5a3f00f716 100644 --- a/i18n/fra/extensions/git/out/autofetch.i18n.json +++ b/i18n/fra/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "Oui", + "read more": "Lire la suite", "no": "Non", - "not now": "Pas maintenant", - "suggest auto fetch": "Voulez-vous activer la rappatriement automatique des dépôts Git ?" + "not now": "Me demander plus tard", + "suggest auto fetch": "Voulez-vous que Code exécute périodiquement `git fetch` ?" } \ No newline at end of file diff --git a/i18n/fra/extensions/git/out/commands.i18n.json b/i18n/fra/extensions/git/out/commands.i18n.json index ec8efb3f0d7..0ab84d9bc6f 100644 --- a/i18n/fra/extensions/git/out/commands.i18n.json +++ b/i18n/fra/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\nCette opération est IRRÉVERSIBLE, votre plage de travail actuelle sera DÉFINITIVEMENT PERDUE.", "yes discard tracked": "Ignorer 1 fichier suivi", "yes discard tracked multiple": "Ignorer {0} fichiers suivis", + "unsaved files single": "Le fichier suivant n'est pas enregistré : {0}.\n\nVoulez-vous l'enregistrer avant d'effectuer le commit ?", + "unsaved files": "Il y a {0} fichiers non enregistrés.\n\nVoulez-vous l'enregistrer avant d'effectuer le commit ?", + "save and commit": "Tout enregistrer et Effectuer le commit", + "commit": "Effectuer le commit quand même", "no staged changes": "Aucune modification en attente à valider.\n\nVoulez-vous automatiquement mettre en attente toutes vos modifications et les valider directement ?", "always": "Toujours", "no changes": "Il n'existe aucun changement à valider.", @@ -64,12 +68,13 @@ "no remotes to pull": "Votre dépôt n'a aucun dépôt distant configuré pour un Pull.", "pick remote pull repo": "Choisir un dépôt distant duquel extraire la branche", "no remotes to push": "Votre dépôt n'a aucun dépôt distant configuré pour un Push.", - "push with tags success": "Envoyé (push) avec des balises.", "nobranch": "Vous devez extraire une branche dont vous souhaitez effectuer le Push vers un emplacement distant.", + "confirm publish branch": "La branche '{0}' n'a pas de branche en amont. Voulez-vous publier cette branche ?", + "ok": "OK", + "push with tags success": "Envoyé (push) avec des balises.", "pick remote": "Choisissez un dépôt distant où publier la branche '{0}' :", "sync is unpredictable": "Cette action effectue un transfert (Push) et un tirage (Pull) des validations à destination et en provenance de '{0}'.", - "ok": "OK", - "never again": "OK, ne plus afficher", + "never again": "OK, Ne plus afficher", "no remotes to publish": "Votre dépôt n'a aucun dépôt distant configuré pour une publication.", "no changes stash": "Aucune modification à remiser (stash).", "provide stash message": "Spécifier éventuellement un message pour la remise (stash)", diff --git a/i18n/fra/extensions/git/package.i18n.json b/i18n/fra/extensions/git/package.i18n.json index 188e2b5ba4a..a1ed0d37d5d 100644 --- a/i18n/fra/extensions/git/package.i18n.json +++ b/i18n/fra/extensions/git/package.i18n.json @@ -54,12 +54,13 @@ "command.stashPopLatest": "Appliquer et supprimer la dernière remise", "config.enabled": "Indique si git est activé", "config.path": "Chemin d'accès à l'exécutable git", + "config.autoRepositoryDetection": "Si les dépôts doivent être détectés automatiquement", "config.autorefresh": "Indique si l'actualisation automatique est activée", "config.autofetch": "Indique si la récupération automatique est activée", "config.enableLongCommitWarning": "Indique si les longs messages de validation doivent faire l'objet d'un avertissement", "config.confirmSync": "Confirmer avant de synchroniser des dépôts git", "config.countBadge": "Contrôle le compteur de badges Git. La valeur 'toutes' compte toutes les modifications. La valeur 'suivies' compte uniquement les modifications suivies. La valeur 'désactivé' désactive le compteur.", - "config.checkoutType": "Contrôle le type des branches répertoriées pendant l'exécution de 'Extraire vers...'. La valeur 'toutes' montre toutes les références, la valeur 'locales' montre uniquement les branches locales, la valeur 'balises' montre uniquement les balises et la valeur 'distantes' montre uniquement les branches distantes.", + "config.checkoutType": "Contrôle quel type de branches sont répertoriées pendant l'exécution de 'Extraire vers...'. `all` affiche toutes les références, `local` affiche uniquement les branches locales, `tags` affiche uniquement les balises et la valeur `remote` montre uniquement les branches distantes.", "config.ignoreLegacyWarning": "Ignore l'avertissement Git hérité", "config.ignoreMissingGitWarning": "Ignore l'avertissement quand Git est manquant", "config.ignoreLimitWarning": "Ignore l'avertissement quand il y a trop de modifications dans un dépôt", @@ -72,5 +73,6 @@ "colors.deleted": "Couleur pour les ressources supprimées.", "colors.untracked": "Couleur pour les ressources non tracées.", "colors.ignored": "Couleur des ressources ignorées.", - "colors.conflict": "Couleur pour les ressources avec des conflits." + "colors.conflict": "Couleur pour les ressources avec des conflits.", + "colors.submodule": "Couleur pour les ressources de sous-module." } \ No newline at end of file diff --git a/i18n/fra/extensions/typescript/out/commands.i18n.json b/i18n/fra/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..6c1e268636a --- /dev/null +++ b/i18n/fra/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "Ouvrez un dossier dans VS Code pour utiliser un projet TypeScript ou JavaScript", + "typescript.projectConfigUnsupportedFile": "Impossible de déterminer le projet TypeScript ou JavaScript. Type de fichier non pris en charge", + "typescript.projectConfigCouldNotGetInfo": "Impossible de déterminer le projet TypeScript ou JavaScript", + "typescript.noTypeScriptProjectConfig": "Le fichier ne fait pas partie d'un projet TypeScript", + "typescript.noJavaScriptProjectConfig": "Le fichier ne fait pas partie d'un projet JavaScript", + "typescript.configureTsconfigQuickPick": "Configurer tsconfig.json", + "typescript.configureJsconfigQuickPick": "Configurer jsconfig.json", + "typescript.projectConfigLearnMore": "En savoir plus" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/fra/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/fra/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/base/node/ps.i18n.json b/i18n/fra/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..a67aa7a91d1 --- /dev/null +++ b/i18n/fra/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "Récupération des informations processeur et mémoire. Cela peut prendre quelques secondes." +} \ No newline at end of file diff --git a/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json index dd19016cb45..4beaeedee28 100644 --- a/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "Les numéros de ligne sont affichés en nombre absolu.", "lineNumbers.relative": "Les numéros de ligne sont affichés sous la forme de distance en lignes à la position du curseur.", "lineNumbers.interval": "Les numéros de ligne sont affichés toutes les 10 lignes.", - "lineNumbers": "Contrôle l’affichage des numéros de ligne. Les valeurs possibles sont 'on', 'off', et 'relative'.", + "lineNumbers": "Contrôle l’affichage des numéros de ligne. Les valeurs possibles sont 'on', 'off', 'relative' et 'interval'.", "rulers": "Afficher les règles verticales après un certain nombre de caractères à espacement fixe. Utiliser plusieurs valeurs pour plusieurs règles. Aucune règle n'est dessinée si le tableau est vide", "wordSeparators": "Caractères utilisés comme séparateurs de mots durant la navigation ou les opérations basées sur les mots", "tabSize": "Le nombre d'espaces correspondant à une tabulation. Ce paramètre est remplacé en fonction du contenu du fichier quand 'editor.detectIndentation' est activé.", @@ -72,6 +72,7 @@ "cursorBlinking": "Contrôle le style d'animation du curseur. Valeurs possibles : 'blink', 'smooth', 'phase', 'expand' et 'solid'", "mouseWheelZoom": "Agrandir ou réduire la police de l'éditeur quand l'utilisateur fait tourner la roulette de la souris tout en maintenant la touche Ctrl enfoncée", "cursorStyle": "Contrôle le style du curseur. Les valeurs acceptées sont 'block', 'block-outline', 'line', 'line-thin', 'underline' et 'underline-thin'", + "lineCursorWidth": "Contrôle la largeur du curseur quand editor.cursorStyle est à 'line'", "fontLigatures": "Active les ligatures de police", "hideCursorInOverviewRuler": "Contrôle si le curseur doit être masqué dans la règle d'aperçu.", "renderWhitespace": "Contrôle la façon dont l'éditeur affiche les espaces blancs. Il existe trois options possibles : 'none', 'boundary' et 'all'. L'option 'boundary' n'affiche pas les espaces uniques qui séparent les mots.", diff --git a/i18n/fra/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/fra/src/vs/editor/common/view/editorColorRegistry.i18n.json index 4bea17a181e..aff67fd2a97 100644 --- a/i18n/fra/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/fra/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,7 @@ { "lineHighlight": "Couleur d'arrière-plan de la mise en surbrillance de la ligne à la position du curseur.", "lineHighlightBorderBox": "Couleur d'arrière-plan de la bordure autour de la ligne à la position du curseur.", - "rangeHighlight": "Couleur d'arrière-plan des plages mises en surbrillance, par exemple par les fonctionnalités de recherche et Quick Open.", + "rangeHighlight": "Couleur d'arrière-plan des plages mises en surbrillance, par exemple par les fonctionnalités d'ouverture rapide et de recherche. La couleur ne doit pas être opaque pour ne pas masquer les décorations sous-jacentes.", "caret": "Couleur du curseur de l'éditeur.", "editorCursorBackground": "La couleur de fond du curseur de l'éditeur. Permet de personnaliser la couleur d'un caractère survolé par un curseur de bloc.", "editorWhitespaces": "Couleur des espaces blancs dans l'éditeur.", diff --git a/i18n/fra/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/fra/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 2e7dbc5e1ee..fc4679bba93 100644 --- a/i18n/fra/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/fra/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "Accéder à l'erreur ou l'avertissement suivant", - "markerAction.previous.label": "Accéder à l'erreur ou l'avertissement précédent", + "markerAction.next.label": "Aller au problème suivant (Erreur, Avertissement, Info)", + "markerAction.previous.label": "Aller au problème précédent (Erreur, Avertissement, Info)", "editorMarkerNavigationError": "Couleur d'erreur du widget de navigation dans les marqueurs de l'éditeur.", "editorMarkerNavigationWarning": "Couleur d'avertissement du widget de navigation dans les marqueurs de l'éditeur.", "editorMarkerNavigationInfo": "Couleur d’information du widget de navigation du marqueur de l'éditeur.", diff --git a/i18n/fra/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/fra/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index 45974daea0a..8e43823c7ac 100644 --- a/i18n/fra/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/fra/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "Couleur d'arrière-plan d'un symbole durant l'accès en lecture, par exemple la lecture d'une variable.", - "wordHighlightStrong": "Couleur d'arrière-plan d'un symbole durant l'accès en écriture, par exemple l'écriture dans une variable.", + "wordHighlight": "Couleur d'arrière-plan d'un symbole durant l'accès en lecture, par exemple la lecture d'une variable. La couleur ne doit pas être opaque pour ne pas masquer les décorations sous-jacentes.", + "wordHighlightStrong": "Couleur d'arrière-plan d'un symbole durant l'accès en écriture, par exemple l'écriture dans une variable. La couleur ne doit pas être opaque pour ne pas masquer les décorations sous-jacentes.", "overviewRulerWordHighlightForeground": "Couleur du marqueur de la règle d'aperçu pour la mise en évidence de symbole.", "overviewRulerWordHighlightStrongForeground": "Couleur du marqueur de la règle d'aperçu la mise en évidence de symbole d’accès en écriture.", "wordHighlight.next.label": "Aller à la prochaine mise en évidence de symbole", diff --git a/i18n/fra/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/fra/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index ed0024d2710..f13a4bbc9e9 100644 --- a/i18n/fra/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/fra/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "'{0}' est un identificateur de menu non valide", "missing.command": "L'élément de menu fait référence à une commande '{0}' qui n'est pas définie dans la section 'commands'.", "missing.altCommand": "L'élément de menu fait référence à une commande alt '{0}' qui n'est pas définie dans la section 'commands'.", - "dupe.command": "L'élément de menu fait référence à la même commande que la commande par défaut et la commande alt", - "nosupport.altCommand": "Actuellement, seul le groupe 'navigation' du menu 'editor/title' prend en charge les commandes alt" + "dupe.command": "L'élément de menu fait référence à la même commande que la commande par défaut et la commande alt" } \ No newline at end of file diff --git a/i18n/fra/src/vs/platform/environment/node/argv.i18n.json b/i18n/fra/src/vs/platform/environment/node/argv.i18n.json index f676e6c787f..217c685dc72 100644 --- a/i18n/fra/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/fra/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,35 @@ "diff": "Comparez deux fichiers entre eux.", "add": "Ajoutez un ou plusieurs dossiers à la dernière fenêtre active.", "goto": "Ouvrez un fichier dans le chemin, à la ligne et la position de caractère spécifiées.", - "locale": "Paramètres régionaux à utiliser (exemple : fr-FR ou en-US).", "newWindow": "Forcez l'utilisation d'une nouvelle instance de Code.", - "performance": "Démarrez avec la commande 'Développeur : performance de démarrage' activée.", - "prof-startup": "Exécuter le profileur d'UC au démarrage", - "inspect-extensions": "Autorise le débogage et le profilage des extensions. Vérifier les outils de développements pour l'uri de connexion.", - "inspect-brk-extensions": "Autorise le débogage et le profilage des extensions avec l'hôte d'extensions en pause après le démarrage. Vérifier les outils de développement pour l'uri de connexion.", "reuseWindow": "Forcez l'ouverture d'un fichier ou dossier dans la dernière fenêtre active.", - "userDataDir": "Spécifie le répertoire où sont conservées les données des utilisateurs. S'avère utile pour une exécution en tant que root.", - "log": "Niveau de journalisation à utiliser. La valeur par défaut est 'info'. Les valeurs autorisées sont 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off.", - "verbose": "Affichez la sortie détaillée (implique --wait).", "wait": "Attendre que les fichiers soient fermés avant de retourner.", + "locale": "Paramètres régionaux à utiliser (exemple : fr-FR ou en-US).", + "userDataDir": "Spécifie le répertoire où sont conservées les données des utilisateurs. S'avère utile pour une exécution en tant que root.", + "version": "Affichez la version.", + "help": "Affichez le mode d'utilisation.", "extensionHomePath": "Définissez le chemin racine des extensions.", "listExtensions": "Listez les extensions installées.", "showVersions": "Affichez les versions des extensions installées, quand --list-extension est utilisé.", "installExtension": "Installe une extension.", "uninstallExtension": "Désinstalle une extension.", "experimentalApis": "Active les fonctionnalités d'API proposées pour une extension.", - "disableExtensions": "Désactivez toutes les extensions installées.", - "disableGPU": "Désactivez l'accélération matérielle du GPU.", + "verbose": "Affichez la sortie détaillée (implique --wait).", + "log": "Niveau de journalisation à utiliser. La valeur par défaut est 'info'. Les valeurs autorisées sont 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off.", "status": "Imprimer l'utilisation de processus et l'information des diagnostics.", - "version": "Affichez la version.", - "help": "Affichez le mode d'utilisation.", + "performance": "Démarrez avec la commande 'Développeur : performance de démarrage' activée.", + "prof-startup": "Exécuter le profileur d'UC au démarrage", + "disableExtensions": "Désactivez toutes les extensions installées.", + "inspect-extensions": "Autorise le débogage et le profilage des extensions. Vérifier les outils de développements pour l'uri de connexion.", + "inspect-brk-extensions": "Autorise le débogage et le profilage des extensions avec l'hôte d'extensions en pause après le démarrage. Vérifier les outils de développement pour l'uri de connexion.", + "disableGPU": "Désactivez l'accélération matérielle du GPU.", + "uploadLogs": "Upload les logs depuis la session actuelle vers le endpoint sécurisé.", "usage": "Utilisation", "options": "options", "paths": "chemins", - "optionsUpperCase": "Options" + "stdinWindows": "Pour lire la sortie d’un autre programme, ajouter '-' (ex. 'echo Bonjour tout le monde | {0} -')", + "stdinUnix": "Pour lire depuis stdin, ajouter '-' (ex. 'ps aux | grep code | {0} -')", + "optionsUpperCase": "Options", + "extensionsManagement": "Gestion des extensions", + "troubleshooting": "Dépannage" } \ No newline at end of file diff --git a/i18n/fra/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/fra/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index 620e2694e2a..ccd0c9dadfd 100644 --- a/i18n/fra/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/fra/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,15 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "Extension non valide : package.json n'est pas un fichier JSON.", - "restartCodeLocal": "Redémarrez Code avant de réinstaller {0}.", + "restartCode": "Redémarrez Code avant de réinstaller {0}.", "installingOutdatedExtension": "Une version plus récente de cette extension est déjà installée. Voulez-vous remplacer celle-ci avec l'ancienne version ?", "override": "Remplacer", "cancel": "Annuler", - "notFoundCompatible": "Installation impossible car l'extension '{0}' compatible avec la version actuelle '{1}' de VS Code est introuvable.", - "quitCode": "Installation impossible car une instance obsolète de l'extension est en cours d'exécution. Veuillez quitter et redémarrer VS Code avant de réinstaller.", - "exitCode": "Installation impossible car une instance obsolète de l'extension est en cours d'exécution. Veuillez sortir et redémarrer VS Code avant de réinstaller.", + "errorInstallingDependencies": "Erreur lors de l'installation des dépendances. {0}", + "notFoundCompatible": "Impossible d’installer '{0}'; Il n’y a pas de version disponible compatible avec VS Code '{1}'.", "notFoundCompatibleDependency": "Installation impossible car l'extension dépendante '{0}' compatible avec la version actuelle '{1}' de VS Code est introuvable.", + "quitCode": "Impossible d’installer l’extension. Veuillez s’il vous plaît quitter et redémarrer VS Code avant de le réinstaller.", + "exitCode": "Impossible d’installer l’extension. Veuillez s’il vous plaît sortir et redémarrer VS Code avant de le réinstaller.", "uninstallDependeciesConfirmation": "Voulez-vous désinstaller uniquement '{0}' ou également ses dépendances ?", "uninstallOnly": "Uniquement", "uninstallAll": "Tout", diff --git a/i18n/fra/src/vs/platform/message/common/message.i18n.json b/i18n/fra/src/vs/platform/message/common/message.i18n.json index 93ee2acf35b..227d6123d7a 100644 --- a/i18n/fra/src/vs/platform/message/common/message.i18n.json +++ b/i18n/fra/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "Fermer", "later": "Plus tard", - "cancel": "Annuler" + "cancel": "Annuler", + "moreFile": "...1 fichier supplémentaire non affiché", + "moreFiles": "...{0} fichiers supplémentaires non affichés" } \ No newline at end of file diff --git a/i18n/fra/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/fra/src/vs/platform/theme/common/colorRegistry.i18n.json index 64fc37335ec..125c9debbca 100644 --- a/i18n/fra/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/fra/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,12 @@ "editorWidgetBorder": "Couleur de bordure des widgets de l'éditeur. La couleur est utilisée uniquement si le widget choisit d'avoir une bordure et si la couleur n'est pas remplacée par un widget.", "editorSelectionBackground": "Couleur de la sélection de l'éditeur.", "editorSelectionForeground": "Couleur du texte sélectionné pour le contraste élevé.", - "editorInactiveSelection": "Couleur de la sélection dans un éditeur inactif.", - "editorSelectionHighlight": "Couleur des régions dont le contenu est identique à la sélection.", + "editorInactiveSelection": "Couleur de sélection dans un éditeur inactif. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", + "editorSelectionHighlight": "Couleur des régions avec le même contenu que la sélection. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", "editorFindMatch": "Couleur du résultat de recherche actif.", - "findMatchHighlight": "Couleur des autres résultats de recherche.", - "findRangeHighlight": "Couleur de la plage limitant la recherche.", - "hoverHighlight": "Mettez en surbrillance ci-dessous le mot pour lequel un pointage s'affiche.", + "findMatchHighlight": "Couleur des autres résultats de recherche correspondants. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", + "findRangeHighlight": "Couleur de la plage limitant la recherche. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", + "hoverHighlight": "Mettre en surbrillance ci-dessous le mot pour lequel un survol est affiché. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", "hoverBackground": "Couleur d'arrière-plan du pointage de l'éditeur.", "hoverBorder": "Couleur de bordure du pointage de l'éditeur.", "activeLinkForeground": "Couleur des liens actifs.", @@ -76,12 +76,12 @@ "diffEditorRemoved": "Couleur d'arrière-plan du texte supprimé.", "diffEditorInsertedOutline": "Couleur de contour du texte inséré.", "diffEditorRemovedOutline": "Couleur de contour du texte supprimé.", - "mergeCurrentHeaderBackground": "Arrière-plan de l'en-tête actuel dans les conflits de fusion inline.", - "mergeCurrentContentBackground": "Arrière-plan du contenu actuel dans les conflits de fusion inline.", - "mergeIncomingHeaderBackground": "Arrière-plan de l'en-tête entrant dans les conflits de fusion inline.", - "mergeIncomingContentBackground": "Arrière-plan du contenu entrant dans les conflits de fusion inline.", - "mergeCommonHeaderBackground": "Arrière-plan de l'en-tête de l'ancêtre commun dans les conflits de fusion inline.", - "mergeCommonContentBackground": "Arrière-plan du contenu de l'ancêtre commun dans les conflits de fusion inline.", + "mergeCurrentHeaderBackground": "Arrière-plan de l'en-tête en cours dans les conflits de fusion inline. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", + "mergeCurrentContentBackground": "Arrière-plan du contenu en cours dans les conflits de fusion inline. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", + "mergeIncomingHeaderBackground": "Arrière-plan de l'en-tête qui arrive dans les conflits de fusion inline. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", + "mergeIncomingContentBackground": "Arrière-plan du contenu qui arrive dans les conflits de fusion inline. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", + "mergeCommonHeaderBackground": "Arrière-plan de l'en-tête de l'ancêtre commun dans les conflits de fusion inline. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", + "mergeCommonContentBackground": "Arrière-plan du contenu de l'ancêtre commun dans les conflits de fusion inline. La couleur doit ne pas être opaque afin de ne pas masquer les décorations sous-jacentes.", "mergeBorder": "Couleur de bordure des en-têtes et du séparateur dans les conflits de fusion inline.", "overviewRulerCurrentContentForeground": "Premier plan de la règle d'aperçu actuelle pour les conflits de fusion inline.", "overviewRulerIncomingContentForeground": "Premier plan de la règle d'aperçu entrante pour les conflits de fusion inline.", diff --git a/i18n/fra/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/fra/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/fra/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/fra/src/vs/workbench/api/node/extHostTreeViews.i18n.json index 2c25d01eeb1..2475bc3e519 100644 --- a/i18n/fra/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/fra/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "treeView.notRegistered": "Aucune arborescence avec l'ID '{0}' n'est inscrite.", - "treeItem.notFound": "L'élément d'arborescence avec l'ID '{0}' est introuvable.", - "treeView.duplicateElement": "L'élément '{0}' est déjà inscrit" + "treeView.duplicateElement": "L'élément avec l'id {0} est déjà inscrit" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/fra/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index 0ea0c59d765..053ff77f9f9 100644 --- a/i18n/fra/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "Activer/désactiver l'emplacement de la barre latérale", + "toggleSidebarPosition": "Activer/désactiver la position de la barre latérale", "view": "Affichage" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/fra/src/vs/workbench/browser/actions/workspaceActions.i18n.json index 6158fd5950f..3bffd603d63 100644 --- a/i18n/fra/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "Ouvrir un fichier...", "openFolder": "Ouvrir un dossier...", "openFileFolder": "Ouvrir...", - "addFolderToWorkspace": "Ajouter un dossier à l'espace de travail...", - "add": "&&Ajouter", - "addFolderToWorkspaceTitle": "Ajouter un dossier à l'espace de travail", "globalRemoveFolderFromWorkspace": "Supprimer le dossier d’espace de travail...", - "removeFolderFromWorkspace": "Supprimer le dossier de l'espace de travail", - "openFolderSettings": "Ouvrir le dossier Paramètres", "saveWorkspaceAsAction": "Enregistrer l’espace de travail sous...", "save": "&&Enregistrer", "saveWorkspace": "Enregistrer l’espace de travail", "openWorkspaceAction": "Ouvrir un espace de travail...", "openWorkspaceConfigFile": "Ouvrir le Fichier de Configuration d’espace de travail", - "openFolderAsWorkspaceInNewWindow": "Ouvrir le dossier en tant qu'espace de travail dans une nouvelle fenêtre", - "workspaceFolderPickerPlaceholder": "Sélectionner le dossier de l’espace de travail" + "openFolderAsWorkspaceInNewWindow": "Ouvrir le dossier en tant qu'espace de travail dans une nouvelle fenêtre" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/fra/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..b644d1c9572 --- /dev/null +++ b/i18n/fra/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "Ajouter un dossier à l'espace de travail...", + "add": "&&Ajouter", + "addFolderToWorkspaceTitle": "Ajouter un dossier à l'espace de travail", + "workspaceFolderPickerPlaceholder": "Sélectionner le dossier de l’espace de travail" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/fra/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index 4326e29e9e4..22a325e3fa6 100644 --- a/i18n/fra/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,18 @@ "groupThreePicker": "Afficher les éditeurs du troisième groupe", "allEditorsPicker": "Afficher tous les éditeurs ouverts", "view": "Affichage", - "file": "Fichier" + "file": "Fichier", + "close": "Fermer", + "closeOthers": "Fermer les autres", + "closeRight": "Fermer à droite", + "closeAllUnmodified": "Fermer les éléments non modifiés", + "closeAll": "Tout fermer", + "keepOpen": "Garder ouvert", + "toggleInlineView": "Activer/désactiver l'affichage Inline", + "showOpenedEditors": "Afficher les éditeurs ouverts", + "keepEditor": "Conserver l'éditeur", + "closeEditorsInGroup": "Fermer tous les éditeurs du groupe", + "closeUnmodifiedEditors": "Fermer les éditeurs non modifiés du groupe", + "closeOtherEditors": "Fermer les autres éditeurs", + "closeRightEditors": "Fermer les éditeurs situés à droite" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/fra/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index 19586632ac8..a2562d91fe9 100644 --- a/i18n/fra/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "Fermer l'éditeur", "revertAndCloseActiveEditor": "Restaurer et fermer l'éditeur", "closeEditorsToTheLeft": "Fermer les éditeurs situés à gauche", - "closeEditorsToTheRight": "Fermer les éditeurs situés à droite", "closeAllEditors": "Fermer tous les éditeurs", - "closeUnmodifiedEditors": "Fermer les éditeurs non modifiés du groupe", "closeEditorsInOtherGroups": "Fermer les éditeurs des autres groupes", - "closeOtherEditorsInGroup": "Fermer les autres éditeurs", - "closeEditorsInGroup": "Fermer tous les éditeurs du groupe", "moveActiveGroupLeft": "Déplacer le groupe d'éditeurs vers la gauche", "moveActiveGroupRight": "Déplacer le groupe d'éditeurs vers la droite", "minimizeOtherEditorGroups": "Réduire les autres groupes d'éditeurs", "evenEditorGroups": "Même largeur pour le groupe d'éditeurs", "maximizeEditor": "Agrandir le groupe d'éditeurs et masquer la barre latérale", - "keepEditor": "Conserver l'éditeur", "openNextEditor": "Ouvrir l'éditeur suivant", "openPreviousEditor": "Ouvrir l'éditeur précédent", "nextEditorInGroup": "Ouvrir l'éditeur suivant du groupe", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "Afficher les éditeurs du premier groupe", "showEditorsInSecondGroup": "Afficher les éditeurs du deuxième groupe", "showEditorsInThirdGroup": "Afficher les éditeurs du troisième groupe", - "showEditorsInGroup": "Afficher les éditeurs du groupe", "showAllEditors": "Afficher tous les éditeurs", "openPreviousRecentlyUsedEditorInGroup": "Ouvrir l'éditeur précédent du groupe", "openNextRecentlyUsedEditorInGroup": "Ouvrir l'éditeur suivant du groupe", @@ -54,5 +48,8 @@ "moveEditorLeft": "Déplacer l'éditeur vers la gauche", "moveEditorRight": "Déplacer l'éditeur vers la droite", "moveEditorToPreviousGroup": "Déplacer l'éditeur vers le groupe précédent", - "moveEditorToNextGroup": "Déplacer l'éditeur vers le groupe suivant" + "moveEditorToNextGroup": "Déplacer l'éditeur vers le groupe suivant", + "moveEditorToFirstGroup": "Déplacer l'éditeur vers le premier groupe", + "moveEditorToSecondGroup": "Déplacer l'éditeur vers le second groupe", + "moveEditorToThirdGroup": "Déplacer l'éditeur vers le troisième groupe" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/fra/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index be96f08df0d..5dc335cf48b 100644 --- a/i18n/fra/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "Déplacer l'éditeur actif par onglets ou par groupes", "editorCommand.activeEditorMove.arg.name": "Argument de déplacement de l'éditeur actif", - "editorCommand.activeEditorMove.arg.description": "Propriétés d’argument : * 'to' : Valeur de chaîne spécifiant où aller.\n\t* 'by' : Valeur de chaîne spécifiant l'unité à déplacer. Par tabulation ou par groupe.\n\t* 'value' : Valeur numérique spécifiant combien de positions ou une position absolue à déplacer.", - "commandDeprecated": "La commande **{0}** a été supprimée. Vous pouvez utiliser **{1}** à la place", - "openKeybindings": "Configurer les raccourcis clavier" + "editorCommand.activeEditorMove.arg.description": "Propriétés d’argument : * 'to' : Valeur de chaîne spécifiant où aller.\n\t* 'by' : Valeur de chaîne spécifiant l'unité à déplacer. Par tabulation ou par groupe.\n\t* 'value' : Valeur numérique spécifiant combien de positions ou une position absolue à déplacer." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/fra/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index 92e9eaf8779..3a04eca1120 100644 --- a/i18n/fra/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "Éditeur de comparaison de fichier texte.", "navigate.next.label": "Modification suivante", "navigate.prev.label": "Modification précédente", - "inlineDiffLabel": "Passer au mode inline", - "sideBySideDiffLabel": "Passer au mode Côte à côte" + "toggleIgnoreTrimWhitespace.label": "Ignorer la suppression des espaces" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/fra/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index 99c0ec41f61..a0384c94b7a 100644 --- a/i18n/fra/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "Fermer", - "closeOthers": "Fermer les autres", - "closeRight": "Fermer à droite", - "closeAll": "Tout fermer", - "closeAllUnmodified": "Fermer les éléments non modifiés", - "keepOpen": "Garder ouvert", - "showOpenedEditors": "Afficher les éditeurs ouverts", "araLabelEditorActions": "Actions de l'éditeur" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/fra/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index d9f31d9c850..3d0b4541c12 100644 --- a/i18n/fra/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[Non prise en charge]", + "userIsAdmin": "[Administrator]", + "userIsSudo": "[Superuser]", "devExtensionWindowTitlePrefix": "[Hôte de développement d'extension]" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/fra/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index 3ed5e9fc685..dd1dfbd52dd 100644 --- a/i18n/fra/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/fra/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "hideView": "Masquer dans la barre latérale" + "hideView": "Masquer" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/common/theme.i18n.json b/i18n/fra/src/vs/workbench/common/theme.i18n.json index 0082e6d4ec1..42755eb915e 100644 --- a/i18n/fra/src/vs/workbench/common/theme.i18n.json +++ b/i18n/fra/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "Couleur d'arrière-plan de l'onglet actif. Les onglets sont les conteneurs des éditeurs dans la zone d'éditeurs. Vous pouvez ouvrir plusieurs onglets dans un groupe d'éditeurs. Il peut exister plusieurs groupes d'éditeurs.", "tabInactiveBackground": "Couleur d'arrière-plan de l'onglet inactif. Les onglets sont les conteneurs des éditeurs dans la zone d'éditeurs. Vous pouvez ouvrir plusieurs onglets dans un groupe d'éditeurs. Il peut exister plusieurs groupes d'éditeurs.", + "tabHoverBackground": "Couleur de l'onglet d’arrière-plan lors du survol. Les onglets sont les conteneurs pour les éditeurs dans la zone de l’éditeur. Plusieurs onglets peuvent être ouverts dans un groupe d'éditeur. Il peut y avoir plusieurs groupes d’éditeur.", + "tabUnfocusedHoverBackground": "Couleur de l'onglet d’arrière-plan dans un groupe n'ayant pas le focus lors du survol. Les onglets sont les conteneurs pour les éditeurs dans la zone de l’éditeur. Plusieurs onglets peuvent être ouverts dans un groupe d'éditeur. Il peut y avoir plusieurs groupes d’éditeur.", "tabBorder": "Bordure séparant les onglets les uns des autres. Les onglets sont les conteneurs des éditeurs dans la zone d'éditeurs. Vous pouvez ouvrir plusieurs onglets dans un groupe d'éditeurs. Il peut exister plusieurs groupes d'éditeurs.", "tabActiveBorder": "Bordure pour mettre en évidence les onglets actifs. Les onglets sont les conteneurs des éditeurs dans la zone d'édition. Vous pouvez ouvrir plusieurs onglets dans un groupe d'éditeurs. Il peut exister plusieurs groupes d'éditeurs.", "tabActiveUnfocusedBorder": "Bordure pour mettre en évidence les onglets actifs dans un groupe inactif. Les onglets sont les conteneurs des éditeurs dans la zone d'édition. Vous pouvez ouvrir plusieurs onglets dans un groupe d'éditeurs. Il peut exister plusieurs groupes d'éditeurs.", + "tabHoverBorder": "Bordure avec laquelle surligner les onglets lors du survol. Couleur de l'onglet d’arrière-plan dans un groupe n'ayant pas le focus lors du survol. Les onglets sont les conteneurs pour les éditeurs dans la zone de l’éditeur. Plusieurs onglets peuvent être ouverts dans un groupe d'éditeur. Il peut y avoir plusieurs groupes d’éditeur.", + "tabUnfocusedHoverBorder": "Bordure avec laquelle surligner les onglets lors du survol dans un groupe n'ayant pas le focus. Couleur de l'onglet d’arrière-plan dans un groupe n'ayant pas le focus lors du survol. Les onglets sont les conteneurs pour les éditeurs dans la zone de l’éditeur. Plusieurs onglets peuvent être ouverts dans un groupe d'éditeur. Il peut y avoir plusieurs groupes d’éditeur.", "tabActiveForeground": "Couleur de premier plan de l'onglet actif dans un groupe actif. Les onglets sont les conteneurs des éditeurs dans la zone d'éditeurs. Vous pouvez ouvrir plusieurs onglets dans un groupe d'éditeurs. Il peut exister plusieurs groupes d'éditeurs.", "tabInactiveForeground": "Couleur de premier plan de l'onglet inactif dans un groupe actif. Les onglets sont les conteneurs des éditeurs dans la zone d'éditeurs. Vous pouvez ouvrir plusieurs onglets dans un groupe d'éditeurs. Il peut exister plusieurs groupes d'éditeurs.", "tabUnfocusedActiveForeground": "Couleur de premier plan de l'onglet actif dans un groupe inactif. Les onglets sont les conteneurs des éditeurs dans la zone d'éditeurs. Vous pouvez ouvrir plusieurs onglets dans un groupe d'éditeurs. Il peut exister plusieurs groupes d'éditeurs.", @@ -16,7 +20,7 @@ "editorGroupBackground": "Couleur d'arrière-plan d'un groupe d'éditeurs. Les groupes d'éditeurs sont les conteneurs des éditeurs. La couleur d'arrière-plan s'affiche pendant le glissement de groupes d'éditeurs.", "tabsContainerBackground": "Couleur d'arrière-plan de l'en-tête du titre du groupe d'éditeurs quand les onglets sont activés. Les groupes d'éditeurs sont les conteneurs des éditeurs.", "tabsContainerBorder": "Couleur de bordure de l'en-tête du titre du groupe d'éditeurs quand les onglets sont activés. Les groupes d'éditeurs sont les conteneurs des éditeurs.", - "editorGroupHeaderBackground": "Couleur d'arrière-plan de l'en-tête du titre du groupe d'éditeurs quand les onglets sont désactivés. Les groupes d'éditeurs sont les conteneurs des éditeurs.", + "editorGroupHeaderBackground": "Couleur d'arrière-plan de l'en-tête du titre du groupe d'éditeurs quand les onglets sont désactivés (`\"workbench.editor.showTabs\": false`). Les groupes d'éditeurs sont les conteneurs des éditeurs.", "editorGroupBorder": "Couleur séparant plusieurs groupes d'éditeurs les uns des autres. Les groupes d'éditeurs sont les conteneurs des éditeurs.", "editorDragAndDropBackground": "Couleur d'arrière-plan lors du déplacement des éditeurs par glissement. La couleur doit avoir une transparence pour que le contenu de l'éditeur soit visible à travers.", "panelBackground": "Couleur d'arrière-plan du panneau. Les panneaux s'affichent sous la zone d'éditeurs et contiennent des affichages tels que la sortie et le terminal intégré.", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "Couleur de la bordure qui sépare la barre latérale et l’éditeur lorsque aucun dossier ne s’ouvre la barre d’état. La barre d’état s’affiche en bas de la fenêtre.", "statusBarItemActiveBackground": "Couleur d'arrière-plan de l'élément de la barre d'état durant un clic. La barre d'état est affichée en bas de la fenêtre.", "statusBarItemHoverBackground": "Couleur d'arrière-plan de l'élément de la barre d'état durant un pointage. La barre d'état est affichée en bas de la fenêtre.", - "statusBarProminentItemBackground": "Couleur d'arrière-plan des éléments importants de la barre d'état. Les éléments importants se différencient des autres entrées de la barre d'état pour indiquer l'importance. La barre d'état est affichée en bas de la fenêtre.", - "statusBarProminentItemHoverBackground": "Couleur d'arrière-plan des éléments importants de la barre d'état pendant le pointage. Les éléments importants se différencient des autres entrées de la barre d'état pour indiquer l'importance. La barre d'état est affichée en bas de la fenêtre.", + "statusBarProminentItemBackground": "Couleur d'arrière-plan des éléments importants de la barre d'état. Les éléments importants se différencient des autres entrées de la barre d'état pour indiquer l'importance. Changer le mode `Appuyer sur la touche tabulation déplace le focus` depuis la palette de commandes pour voir un exemple. La barre d'état est affichée en bas de la fenêtre.", + "statusBarProminentItemHoverBackground": "Couleur d'arrière-plan des éléments importants de la barre d'état lors du survol. Les éléments importants se différencient des autres entrées de la barre d'état pour indiquer l'importance. Changer le mode `Appuyer sur la touche tabulation déplace le focus` depuis la palette de commandes pour voir un exemple. La barre d'état est affichée en bas de la fenêtre.", "activityBarBackground": "Couleur d'arrière-plan de la barre d'activités. La barre d'activités s'affiche complètement à gauche ou à droite, et permet de naviguer entre les affichages de la barre latérale.", "activityBarForeground": "Couleur de premier plan de la barre d'activités (par ex., utilisée pour les icônes). La barre d'activités s'affiche complètement à gauche ou à droite, et permet de parcourir les vues de la barre latérale.", "activityBarBorder": "Couleur de bordure de la barre d'activités faisant la séparation avec la barre latérale. La barre d'activités, située à l'extrême droite ou gauche, permet de parcourir les vues de la barre latérale.", diff --git a/i18n/fra/src/vs/workbench/common/views.i18n.json b/i18n/fra/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..e7ba8e9e54b --- /dev/null +++ b/i18n/fra/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "Une vue avec l’id `{0}` est déjà enregistrée à l’emplacement `{1}`" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json index 541429a5408..93919d9a851 100644 --- a/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "Fermer l'éditeur", "closeWindow": "Fermer la fenêtre", "closeWorkspace": "Fermer l’espace de travail", "noWorkspaceOpened": "Il n’y a actuellement aucun espace de travail ouvert dans cette instance à fermer.", @@ -52,21 +51,5 @@ "displayLanguage": "Définit le langage affiché par VSCode.", "doc": "Consultez {0} pour connaître la liste des langues prises en charge.", "restart": "Le changement de la valeur nécessite le redémarrage de VS Code.", - "fail.createSettings": "Impossible de créer '{0}' ({1}).", - "openLogsFolder": "Ouvrir le dossier des journaux", - "showLogs": "Afficher les journaux...", - "mainProcess": "Principal", - "sharedProcess": "Partagé", - "rendererProcess": "Renderer", - "extensionHost": "Hôte de l’extension", - "selectProcess": "Sélectionner le processus", - "setLogLevel": "Définir le niveau de journalisation (log)", - "trace": "Trace", - "debug": "Déboguer", - "info": "Informations", - "warn": "Avertissement", - "err": "Erreur", - "critical": "Critique", - "off": "Désactivé", - "selectLogLevel": "Sélectionner le niveau de journalisation (log)" + "fail.createSettings": "Impossible de créer '{0}' ({1})." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/fra/src/vs/workbench/electron-browser/main.contribution.i18n.json index 7c7573087ca..d44b504894c 100644 --- a/i18n/fra/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "Affichage", "help": "Aide", "file": "Fichier", - "developer": "Développeur", "workspaces": "Espaces de travail", + "developer": "Développeur", + "workbenchConfigurationTitle": "Banc d'essai", "showEditorTabs": "Contrôle si les éditeurs ouverts doivent s'afficher ou non sous des onglets.", "workbench.editor.labelFormat.default": "Afficher le nom du fichier. Lorsque les onglets sont activés et que deux fichiers portent le même nom dans un groupe, les sections distinctes du chemin de chaque fichier sont ajoutées. Lorsque les onglets sont désactivées, le chemin d’accès relatif au dossier de l'espace de travail est affiché si l’éditeur est actif.", "workbench.editor.labelFormat.short": "Indiquer le nom du fichier suivi de son nom de répertoire.", @@ -20,23 +21,23 @@ "showIcons": "Contrôle si les éditeurs ouverts doivent s'afficher ou non avec une icône. Cela implique notamment l'activation d'un thème d'icône.", "enablePreview": "Contrôle si les éditeurs ouverts s'affichent en mode aperçu. Les éditeurs en mode aperçu sont réutilisés jusqu'à ce qu'ils soient conservés (par exemple, après un double-clic ou une modification) et apparaissent avec un style de police en italique.", "enablePreviewFromQuickOpen": "Contrôle si les éditeurs de Quick Open s'affichent en mode aperçu. Les éditeurs en mode aperçu sont réutilisés jusqu'à ce qu'ils soient conservés (par exemple, après un double-clic ou une modification).", + "closeOnFileDelete": "Contrôle si les éditeurs qui affichent un fichier doivent se fermer automatiquement quand ce fichier est supprimé ou renommé par un autre processus. Si vous désactivez cette option, l'éditeur reste ouvert dans un état indiquant une intégrité compromise. Notez que la suppression de fichiers à partir de l'application entraîne toujours la fermeture de l'éditeur, et que les fichiers à l'intégrité compromise ne sont jamais fermés pour permettre la conservation de vos données.", "editorOpenPositioning": "Permet de définir à quel endroit les éditeurs s'ouvrent. Sélectionnez 'left' ou 'right' pour ouvrir les éditeurs à gauche ou à droite de celui actuellement actif. Sélectionnez 'first' ou 'last' pour ouvrir les éditeurs indépendamment de celui actuellement actif.", "revealIfOpen": "Contrôle si un éditeur est affiché dans l'un des groupes visibles, s'il est ouvert. Si cette option est désactivée, l'éditeur s'ouvre de préférence dans le groupe d'éditeurs actif. Si cette option est activée, tout éditeur déjà ouvert est affiché au lieu d'être rouvert dans le groupe d'éditeurs actif. Notez que dans certains cas, ce paramètre est ignoré, par exemple quand vous forcez un éditeur à s'ouvrir dans un groupe spécifique ou à côté du groupe actif.", + "swipeToNavigate": "Parcourez les fichiers ouverts en faisant glisser trois doigts horizontalement. ", "commandHistory": "Contrôle le nombre de commandes récemment utilisées à retenir dans l’historique de la palette de commande. Spécifier la valeur 0 pour désactiver l’historique des commandes.", "preserveInput": "Contrôle si la dernière entrée tapée dans la palette de commandes doit être restaurée à la prochaine ouverture.", "closeOnFocusLost": "Contrôle si Quick Open doit se fermer automatiquement, une fois qu'il a perdu le focus.", "openDefaultSettings": "Contrôle si l'ouverture des paramètres entraîne également l'ouverture d'un éditeur qui affiche tous les paramètres par défaut.", "sideBarLocation": "Contrôle l'emplacement de la barre latérale. Elle peut s'afficher à gauche ou à droite du banc d'essai.", + "panelDefaultLocation": "Contrôle l’emplacement par défaut du panneau. Il peut être affiché soit en bas ou à droite du banc d'essai.", "statusBarVisibility": "Contrôle la visibilité de la barre d'état au bas du banc d'essai.", "activityBarVisibility": "Contrôle la visibilité de la barre d'activités dans le banc d'essai.", - "closeOnFileDelete": "Contrôle si les éditeurs qui affichent un fichier doivent se fermer automatiquement quand ce fichier est supprimé ou renommé par un autre processus. Si vous désactivez cette option, l'éditeur reste ouvert dans un état indiquant une intégrité compromise. Notez que la suppression de fichiers à partir de l'application entraîne toujours la fermeture de l'éditeur, et que les fichiers à l'intégrité compromise ne sont jamais fermés pour permettre la conservation de vos données.", - "enableNaturalLanguageSettingsSearch": "Contrôle s’il faut activer le mode de recherche en langage naturel pour les paramètres.", "fontAliasing": "Contrôle la méthode de font aliasing dans le workbench.\n- par défaut : Lissage des polices de sous-pixel. Sur la plupart des affichages non-ratina, cela vous donnera le texte le plus vif\n- crénelées : Lisse les polices au niveau du pixel, plutôt que les sous-pixels. Peut faire en sorte que la police apparaisse plus légère dans l’ensemble \n- none : désactive le lissage des polices. Le texte s'affichera avec des bordures dentelées", "workbench.fontAliasing.default": "Lissage de sous-pixel des polices. Sur la plupart des affichages non-retina, cela vous donnera le texte le plus vif.", "workbench.fontAliasing.antialiased": "Lisser les polices au niveau du pixel, plutôt que les sous-pixels. Peut faire en sorte que la police apparaisse plus légère dans l’ensemble.", "workbench.fontAliasing.none": "Désactive le lissage des polices. Le texte s'affichera avec des bordures dentelées.", - "swipeToNavigate": "Parcourez les fichiers ouverts en faisant glisser trois doigts horizontalement. ", - "workbenchConfigurationTitle": "Banc d'essai", + "enableNaturalLanguageSettingsSearch": "Contrôle s’il faut activer le mode de recherche en langage naturel pour les paramètres.", "windowConfigurationTitle": "Fenêtre", "window.openFilesInNewWindow.on": "Les fichiers s'ouvrent dans une nouvelle fenêtre", "window.openFilesInNewWindow.off": "Les fichiers s'ouvrent dans la fenêtre du dossier conteneur ouvert ou dans la dernière fenêtre active", diff --git a/i18n/fra/src/vs/workbench/electron-browser/window.i18n.json b/i18n/fra/src/vs/workbench/electron-browser/window.i18n.json index 96dc00191af..25e0b269de1 100644 --- a/i18n/fra/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/fra/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "Couper", "copy": "Copier", "paste": "Coller", - "selectAll": "Tout Sélectionner" + "selectAll": "Tout Sélectionner", + "runningAsRoot": "Il est déconseillé d’exécuter {0} en tant qu’utilisateur root." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/fra/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index 2cfe628ea39..07d9f8f5644 100644 --- a/i18n/fra/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "Couleur d'arrière-plan de la barre d'outils de débogage." + "debugToolBarBackground": "Couleur d'arrière-plan de la barre d'outils de débogage.", + "debugToolBarBorder": "Couleur de bordure de la barre d'outils de débogage." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/fra/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 6740cff8f8e..c08a897c7ff 100644 --- a/i18n/fra/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "élément débogué", - "debug.terminal.not.available.error": "Terminal intégré non disponible" + "debug.terminal.title": "élément débogué" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 8fadf8b958b..f5bf621cde9 100644 --- a/i18n/fra/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "Ouvrir une nouvelle invite de commandes", "globalConsoleActionMacLinux": "Ouvrir un nouveau Terminal", "scopedConsoleActionWin": "Ouvrir dans l'invite de commandes", - "scopedConsoleActionMacLinux": "Ouvrir dans Terminal", - "openFolderInIntegratedTerminal": "Ouvrir dans Terminal" + "scopedConsoleActionMacLinux": "Ouvrir dans Terminal" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index 32c0006fd67..01219f8b3f8 100644 --- a/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,17 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "Cette extension est recommandée basé sur les fichiers que vous avez ouverts récemment.", + "neverShowAgain": "Ne plus afficher", + "close": "Fermer", "workspaceRecommendation": "Cette extension est recommandée par les utilisateurs de l’espace de travail actuel.", + "fileBasedRecommendation": "Cette extension est recommandée basé sur les fichiers que vous avez ouverts récemment.", "exeBasedRecommendation": "Cette extension est recommandée parce que {0} est installé.", "reallyRecommended2": "L'extension '{0}' est recommandée pour ce type de fichier.", "reallyRecommendedExtensionPack": "Le pack d’extensions '{0}' est recommandé pour ce type de fichier.", "showRecommendations": "Afficher les recommandations", "install": "Installer", - "neverShowAgain": "Ne plus afficher", - "close": "Fermer", + "showLanguageExtensions": "Le Marketplace a des extensions qui peuvent aider avec les fichiers '.{0}'", + "searchMarketplace": "Rechercher dans le Marketplace", "workspaceRecommended": "Cet espace de travail a des recommandations d'extension.", "installAll": "Tout installer", "ignoreExtensionRecommendations": "Voulez-vous ignorer toutes les recommandations d’extensions ?", diff --git a/i18n/fra/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.i18n.json b/i18n/fra/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.i18n.json index 8ea9b909100..b3a917afeda 100644 --- a/i18n/fra/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.i18n.json @@ -4,6 +4,9 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "installingVSIXExtension": "Installation d'extension depuis un VSIX...", + "installingMarketPlaceExtension": "Installation d'extension depuis le Marketplace...", + "uninstallingExtension": "Désinstallation d'extension...", "enableDependeciesConfirmation": "L'activation de '{0}' entraîne également l'activation de ses dépendances. Voulez-vous continuer ?", "enable": "Oui", "doNotEnable": "Non", diff --git a/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..2cd1d40a124 --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "Banc d'essai", + "feedbackVisibility": "Contrôle la visibilité du feedback Twitter (smiley) dans la barre d'état au bas du banc d'essai." +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json b/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json index a7605d084cd..45a05b23cfe 100644 --- a/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json @@ -16,6 +16,7 @@ "request a missing feature": "Demander une fonctionnalité manquante", "tell us why?": "Pourquoi ?", "commentsHeader": "Commentaires", + "showFeedback": "Afficher le Smiley Feedback dans la barre d'état", "tweet": "Tweet", "character left": "caractère restant", "characters left": "caractères restants", diff --git a/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..16a5fa73cb2 --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "hide": "Masquer" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 54a25f75ec0..1b0804c3433 100644 --- a/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,27 @@ "filesCategory": "Fichier", "revealInSideBar": "Afficher dans la barre latérale", "acceptLocalChanges": "Utiliser vos modifications et écraser les contenus du disque", - "revertLocalChanges": "Ignorer les modifications locales et restaurer le contenu sur disque" + "revertLocalChanges": "Ignorer les modifications locales et restaurer le contenu sur disque", + "copyPathOfActive": "Copier le chemin du fichier actif", + "saveAllInGroup": "Enregistrer tout dans le groupe", + "saveFiles": "Enregistrer tous les fichiers", + "revert": "Rétablir le fichier", + "compareActiveWithSaved": "Compare le fichier actif avec celui enregistré", + "closeEditor": "Fermer l'éditeur", + "view": "Affichage", + "openToSide": "Ouvrir sur le côté", + "revealInWindows": "Révéler dans l'Explorateur", + "revealInMac": "Révéler dans le Finder", + "openContainer": "Ouvrir le dossier contenant", + "copyPath": "Copier le chemin", + "saveAll": "Enregistrer tout", + "compareWithSaved": "Comparer avec celui enregistré", + "compareWithSelected": "Comparer avec ce qui est sélectionné", + "compareSource": "Sélectionner pour comparer", + "compareSelected": "Comparer le sélectionné", + "close": "Fermer", + "closeOthers": "Fermer les autres", + "closeUnmodified": "Fermer les éléments non modifiés", + "closeAll": "Tout fermer", + "deleteFile": "Supprimer définitivement" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 002c86e7daa..90edc5bf9f2 100644 --- a/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "Réessayer", - "rename": "Renommer", "newFile": "Nouveau fichier", "newFolder": "Nouveau dossier", + "rename": "Renommer", + "delete": "Supprimer", + "copyFile": "Copier", + "pasteFile": "Coller", + "retry": "Réessayer", "openFolderFirst": "Ouvrez d'abord un dossier pour y créer des fichiers ou des dossiers.", "newUntitledFile": "Nouveau fichier sans titre", "createNewFile": "Nouveau fichier", @@ -15,39 +18,32 @@ "deleteButtonLabelRecycleBin": "&&Déplacer vers la Corbeille", "deleteButtonLabelTrash": "&&Déplacer vers la Poubelle", "deleteButtonLabel": "S&&upprimer", + "dirtyMessageFilesDelete": "Vous supprimez des fichiers dont les changements n'ont pas été enregistrés. Voulez-vous continuer ?", "dirtyMessageFolderOneDelete": "Vous supprimez un dossier contenant 1 fichier dont les changements n'ont pas été enregistrés. Voulez-vous continuer ?", "dirtyMessageFolderDelete": "Vous supprimez un dossier contenant {0} fichiers dont les changements n'ont pas été enregistrés. Voulez-vous continuer ?", "dirtyMessageFileDelete": "Vous supprimez un fichier dont les changements n'ont pas été enregistrés. Voulez-vous continuer ?", "dirtyWarning": "Vous perdrez vos modifications, si vous ne les enregistrez pas.", + "confirmMoveTrashMessageMultiple": "Êtes-vous sûr de vouloir supprimer les fichiers {0} suivants ?", "confirmMoveTrashMessageFolder": "Voulez-vous vraiment supprimer '{0}' et son contenu ?", "confirmMoveTrashMessageFile": "Voulez-vous vraiment supprimer '{0}' ?", "undoBin": "Vous pouvez effectuer une restauration à partir de la Corbeille.", "undoTrash": "Vous pouvez effectuer une restauration à partir de la Poubelle.", "doNotAskAgain": "Ne plus me demander", + "confirmDeleteMessageMultiple": "Êtes-vous sûr de vouloir supprimer définitivement les fichiers {0} suivants ?", "confirmDeleteMessageFolder": "Voulez-vous vraiment supprimer définitivement '{0}' et son contenu ?", "confirmDeleteMessageFile": "Voulez-vous vraiment supprimer définitivement '{0}' ?", "irreversible": "Cette action est irréversible !", "permDelete": "Supprimer définitivement", - "delete": "Supprimer", "importFiles": "Importer des fichiers", "confirmOverwrite": "Un fichier ou dossier portant le même nom existe déjà dans le dossier de destination. Voulez-vous le remplacer ?", "replaceButtonLabel": "&&Remplacer", - "copyFile": "Copier", - "pasteFile": "Coller", + "fileDeleted": "Le fichier a été supprimé ou déplacé pendant ce temps", + "fileIsAncestor": "Le fichier à copier est un ancêtre du dossier destination", "duplicateFile": "Doublon", - "openToSide": "Ouvrir sur le côté", - "compareSource": "Sélectionner pour comparer", "globalCompareFile": "Comparer le fichier actif à...", "openFileToCompare": "Ouvrez d'abord un fichier pour le comparer à un autre fichier.", - "compareWith": "Comparer '{0}' à '{1}'", - "compareFiles": "Comparer des fichiers", "refresh": "Actualiser", - "save": "Enregistrer", - "saveAs": "Enregistrer sous...", - "saveAll": "Enregistrer tout", "saveAllInGroup": "Enregistrer tout dans le groupe", - "saveFiles": "Enregistrer tous les fichiers", - "revert": "Rétablir le fichier", "focusOpenEditors": "Mettre le focus sur la vue des éditeurs ouverts", "focusFilesExplorer": "Focus sur l'Explorateur de fichiers", "showInExplorer": "Révéler le fichier actif dans la barre latérale", @@ -56,20 +52,11 @@ "refreshExplorer": "Actualiser l'explorateur", "openFileInNewWindow": "Ouvrir le fichier actif dans une nouvelle fenêtre", "openFileToShowInNewWindow": "Ouvrir d'abord un fichier à ouvrir dans une nouvelle fenêtre", - "revealInWindows": "Révéler dans l'Explorateur", - "revealInMac": "Révéler dans le Finder", - "openContainer": "Ouvrir le dossier contenant", - "revealActiveFileInWindows": "Révéler le fichier actif dans l'Explorateur Windows", - "revealActiveFileInMac": "Révéler le fichier actif dans le Finder", - "openActiveFileContainer": "Ouvrir le dossier contenant le fichier actif", "copyPath": "Copier le chemin", - "copyPathOfActive": "Copier le chemin du fichier actif", "emptyFileNameError": "Un nom de fichier ou de dossier doit être fourni.", "fileNameExistsError": "Un fichier ou dossier **{0}** existe déjà à cet emplacement. Choisissez un autre nom.", "invalidFileNameError": "Le nom **{0}** est non valide en tant que nom de fichier ou de dossier. Choisissez un autre nom.", "filePathTooLongError": "Le nom **{0}** correspond à un chemin d'accès trop long. Choisissez un nom plus court.", - "compareWithSaved": "Compare le fichier actif avec celui enregistré", - "modifiedLabel": "{0} (sur le disque) ↔ {1}", "compareWithClipboard": "Compare le fichier actif avec le presse-papiers", "clipboardComparisonLabel": "Presse-papier ↔ {0}" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index ee5d441071a..a8dcaebe5a2 100644 --- a/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "Ouvrir d'abord un fichier pour copier son chemin", - "openFileToReveal": "Ouvrir d'abord un fichier à révéler" + "revealInWindows": "Révéler dans l'Explorateur", + "revealInMac": "Révéler dans le Finder", + "openContainer": "Ouvrir le dossier contenant", + "saveAs": "Enregistrer sous...", + "save": "Enregistrer", + "saveAll": "Enregistrer tout", + "removeFolderFromWorkspace": "Supprimer le dossier de l'espace de travail", + "genericRevertError": "Échec pour faire revenir '{0}' : {1}", + "modifiedLabel": "{0} (sur le disque) ↔ {1}", + "openFileToReveal": "Ouvrir d'abord un fichier à révéler", + "openFileToCopy": "Ouvrir d'abord un fichier pour copier son chemin" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 9693ca31c50..9427b00fc2a 100644 --- a/i18n/fra/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,7 @@ "editorConfigurationTitle": "Éditeur", "formatOnSave": "Met en forme un fichier au moment de l'enregistrement. Un formateur doit être disponible, le fichier ne doit pas être enregistré automatiquement, et l'éditeur ne doit pas être en cours d'arrêt.", "explorerConfigurationTitle": "Explorateur de fichiers", - "openEditorsVisible": "Nombre d'éditeurs affichés dans le volet Éditeurs ouverts. Définissez la valeur 0 pour masquer le volet.", - "dynamicHeight": "Contrôle si la hauteur de la section des éditeurs ouverts doit s'adapter dynamiquement ou non au nombre d'éléments.", + "openEditorsVisible": "Nombre d'éditeurs affichés dans le volet Éditeurs ouverts.", "autoReveal": "Contrôle si l'Explorateur doit automatiquement afficher et sélectionner les fichiers à l'ouverture.", "enableDragAndDrop": "Contrôle si l'explorateur doit autoriser le déplacement de fichiers et de dossiers par glisser-déplacer.", "confirmDragAndDrop": "Contrôle si l’Explorateur doit demander confirmation lors du déplacement de fichiers ou de dossiers via glisser-déposer.", diff --git a/i18n/fra/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/fra/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index f944e7fc14f..0c4d859caa4 100644 --- a/i18n/fra/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,14 @@ // Do not edit this file. It is machine generated. { "userGuide": "Utiliser les actions dans la barre d’outils de l’éditeur vers la droite pour soit **annuler** vos modifications ou **écraser** le contenu sur le disque avec vos modifications", - "discard": "Abandonner", + "overwriteElevated": "Remplacer en tant qu'Admin...", + "saveElevated": "Réessayer en tant qu'Admin...", "overwrite": "Remplacer", "retry": "Réessayer", - "readonlySaveError": "Échec de l'enregistrement de '{0}' : le fichier est protégé en écriture. Sélectionnez 'Remplacer' pour supprimer la protection.", + "discard": "Abandonner", + "readonlySaveErrorAdmin": "Échec de l'enregistrement de '{0}' : le fichier est protégé en écriture. Sélectionnez 'Remplacer' pour réessayer en tant qu'administrateur.", + "readonlySaveError": "Échec de l'enregistrement de '{0}' : le fichier est protégé en écriture. Sélectionnez 'Remplacer' pour essayer de supprimer la protection.", + "permissionDeniedSaveError": "Échec de l'enregistrement de '{0}' : Permissions insuffisantes. Sélectionnez 'Remplacer en tant qu'Admin' pour réessayer en tant qu'administrator.", "genericSaveError": "Échec d'enregistrement de '{0}' ({1}).", "staleSaveError": "Échec de l'enregistrement de '{0}' : le contenu sur disque est plus récent. Cliquez sur **Comparer** pour comparer votre version à celle située sur le disque.", "compareChanges": "Comparer", diff --git a/i18n/fra/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json b/i18n/fra/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json index 631a14a1cef..64edc5f6461 100644 --- a/i18n/fra/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json @@ -10,6 +10,7 @@ "dropFolder": "Voulez-vous ajouter le dossier à l’espace de travail ?", "addFolders": "&&Ajouter les dossiers", "addFolder": "&&Ajouter le dossier", + "confirmMultiMove": "Êtes-vous sûr de vouloir déplacer les fichiers '{0}' suivants ?", "confirmMove": "Êtes-vous certain de vouloir déplacer '{0}' ?", "doNotAskAgain": "Ne plus me demander", "moveButtonLabel": "&&Déplacer", diff --git a/i18n/fra/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/fra/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index c536ea46a5d..620260dc73a 100644 --- a/i18n/fra/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "Éditeurs ouverts", "openEditosrSection": "Section des éditeurs ouverts", - "dirtyCounter": "{0} non enregistré(s)", - "saveAll": "Enregistrer tout", - "closeAllUnmodified": "Fermer les éléments non modifiés", - "closeAll": "Tout fermer", - "compareWithSaved": "Comparer avec celui enregistré", - "close": "Fermer", - "closeOthers": "Fermer les autres" + "dirtyCounter": "{0} non enregistré(s)" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..b5604efd4c8 --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "mainLog": "Journal (Principal)", + "sharedLog": "Journal (Partagé)", + "rendererLog": "Journal (Fenêtre)", + "extensionsLog": "Journal (Hôte d'extension)", + "developer": "Développeur" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/fra/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..6d8707bc4eb --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "Ouvrir le dossier des journaux", + "showLogs": "Afficher les journaux...", + "mainProcess": "Principal", + "sharedProcess": "Partagé", + "rendererProcess": "Fenêtre", + "extensionHost": "Hôte d'extension", + "selectProcess": "Sélectionner le processus", + "openLogFile": "Ouvrir le fichier de log...", + "setLogLevel": "Définir le niveau de journalisation (log)", + "trace": "Trace", + "debug": "Déboguer", + "info": "Informations", + "warn": "Avertissement", + "err": "Erreur", + "critical": "Critique", + "off": "Désactivé", + "selectLogLevel": "Sélectionner le niveau de journalisation (log)" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/fra/src/vs/workbench/parts/markers/common/messages.i18n.json index de7f944af49..2b60a006c26 100644 --- a/i18n/fra/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "viewCategory": "Affichage", - "problems.view.toggle.label": "Activer/désactiver les problèmes", - "problems.view.focus.label": "Problèmes de focus", "problems.panel.configuration.title": "Affichage des problèmes", "problems.panel.configuration.autoreveal": "Contrôle si l'affichage des problèmes doit automatiquement montrer les fichiers quand il les ouvre", "markers.panel.title.problems": "Problèmes", diff --git a/i18n/fra/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..7666fba29aa --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "Sortie", + "logViewer": "Visualiseur de journal", + "viewCategory": "Affichage", + "clearOutput.label": "Effacer la sortie" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/fra/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..2ae62f64fbe --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "{0} - Sortie", + "channel": "Canal de sortie pour '{0}'" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json b/i18n/fra/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json index c7b2dfd5e8a..a41e960d2e8 100644 --- a/i18n/fra/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json @@ -11,6 +11,8 @@ "oneSettingFound": "1 paramètre correspondant", "settingsFound": "{0} paramètres correspondants", "totalSettingsMessage": "Total de {0} paramètres", + "nlpResult": "Résultats en langage naturel", + "filterResult": "Résultats filtrés", "defaultSettings": "Paramètres par défaut", "defaultFolderSettings": "Paramètres de dossier par défaut", "defaultEditorReadonly": "Modifier dans l’éditeur du côté droit pour substituer les valeurs par défaut.", diff --git a/i18n/fra/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/fra/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index 89aaca94b7b..d5cd0fe71d7 100644 --- a/i18n/fra/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "Essayez la recherche en langage naturel !", "defaultSettings": "Placez vos paramètres dans l’éditeur du côté droit pour substituer.", "noSettingsFound": "Aucun paramètre.", "settingsSwitcherBarAriaLabel": "Sélecteur de paramètres", "userSettings": "Paramètres utilisateur", "workspaceSettings": "Paramètres de l'espace de travail", - "folderSettings": "Paramètres de dossier", - "enableFuzzySearch": "Activer la recherche en langage naturel" + "folderSettings": "Paramètres de dossier" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/fra/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index 42c1698dcd3..5800126a777 100644 --- a/i18n/fra/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "Utilisés le plus souvent", - "mostRelevant": "Plus pertinent", "defaultKeybindingsHeader": "Remplacez les combinaisons de touches dans votre fichier de combinaisons de touches." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index 923695e6fb4..561c8b8fcd3 100644 --- a/i18n/fra/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "Affichage", "commandsHandlerDescriptionDefault": "Commandes d'affichage et d'exécution", "gotoLineDescriptionMac": "Atteindre la ligne", "gotoLineDescriptionWin": "Atteindre la ligne", diff --git a/i18n/fra/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index 015c5898f64..2d2ad3ba485 100644 --- a/i18n/fra/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,9 @@ "toggleGitViewlet": "Afficher Git", "source control": "Contrôle de code source", "toggleSCMViewlet": "Afficher SCM", - "view": "Afficher" + "view": "Afficher", + "scmConfigurationTitle": "SCM", + "alwaysShowProviders": "S'il faut toujours afficher la section Fournisseur de contrôle de code source.", + "diffDecorations": "Contrôle les décorations diff dans l'éditeur", + "inputCounter": "Contrôle quand afficher le compteur de saisie" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json b/i18n/fra/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json index 4852691d7f0..e262a05e669 100644 --- a/i18n/fra/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json @@ -6,6 +6,9 @@ { "scm providers": "Fournisseurs de contrôle de code source", "hideRepository": "Masquer", + "commitMessageInfo": "{0} caractères sur la ligne actuelle", + "commitMessageCountdown": "{0} caractères restants sur la ligne actuelle", + "commitMessageWarning": "{0} caractères sur {1} sur la ligne actuelle", "installAdditionalSCMProviders": "Installer des fournisseurs SCM supplémentaires...", "no open repo": "Il n’y a aucun fournisseur de contrôle de code source actif.", "source control": "Contrôle de code source", diff --git a/i18n/fra/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/fra/src/vs/workbench/parts/search/browser/searchActions.i18n.json index 72ef3e89f83..c87f37c878c 100644 --- a/i18n/fra/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "Afficher le terme de recherche précédent", "showSearchViewlet": "Afficher la zone de recherche", "findInFiles": "Chercher dans les fichiers", - "findInFilesWithSelectedText": "Rechercher dans les fichiers avec le texte sélectionné", "replaceInFiles": "Remplacer dans les fichiers", - "replaceInFilesWithSelectedText": "Remplacer dans les fichiers avec le texte sélectionné", "RefreshAction.label": "Actualiser", "CollapseDeepestExpandedLevelAction.label": "Réduire tout", "ClearSearchResultsAction.label": "Effacer", diff --git a/i18n/fra/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index 727436ac8ed..f5dbbc47515 100644 --- a/i18n/fra/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "Rechercher dans le dossier...", + "findInWorkspace": "Trouver dans l’espace de travail...", "showTriggerActions": "Atteindre le symbole dans l'espace de travail...", "name": "Rechercher", "search": "Rechercher", + "showSearchViewlet": "Afficher la zone de recherche", "view": "Affichage", + "findInFiles": "Chercher dans les fichiers", "openAnythingHandlerDescription": "Accéder au fichier", "openSymbolDescriptionNormal": "Atteindre le symbole dans l'espace de travail", "searchOutputChannelTitle": "Rechercher", @@ -18,5 +22,6 @@ "useRipgrep": "Contrôle si ripgrep doit être utilisé dans la recherche de texte et de fichier", "useIgnoreFiles": "Contrôle s'il faut utiliser les fichiers .gitignore et .ignore par défaut pendant la recherche de fichiers.", "search.quickOpen.includeSymbols": "Configurez l'ajout des résultats d'une recherche de symboles globale dans le fichier de résultats pour Quick Open.", - "search.followSymlinks": "Contrôle s'il faut suivre les symlinks pendant la recherche." + "search.followSymlinks": "Contrôle s'il faut suivre les symlinks pendant la recherche.", + "search.smartCase": "Recherches de manière non case-sensitive si le modèle est entièrement en minuscules, dans le cas contraire, recherche de manière case-sensitive" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..4823418ee4d --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.1": "({0})", + "new.global": "Nouveau fichier d'extraits globaux...", + "group.global": "Extraits existants", + "openSnippet.pickLanguage": "Sélectionner le fichier d'extraits ou créer des extraits", + "openSnippet.label": "Configurer les extraits de l’utilisateur", + "preferences": "Préférences" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 96366bc3eb5..1917de0f41a 100644 --- a/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,13 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "Sélectionner le langage de l'extrait de code", - "openSnippet.errorOnCreate": "Impossible de créer {0}", - "openSnippet.label": "Ouvrir les extraits de code utilisateur", - "preferences": "Préférences", "snippetSchema.json.default": "Extrait de code vide", "snippetSchema.json": "Configuration de l'extrait de code utilisateur", "snippetSchema.json.prefix": "Préfixe à utiliser durant la sélection de l'extrait de code dans IntelliSense", "snippetSchema.json.body": "Contenu de l'extrait de code. Utilisez '$1', '${1:defaultText}' pour définir les positions du curseur, utilisez '$0' pour la position finale du curseur. Insérez les valeurs de variable avec '${varName}' et '${varName:defaultText}', par ex., 'Il s'agit du fichier : $TM_FILENAME'.", - "snippetSchema.json.description": "Description de l'extrait de code." + "snippetSchema.json.description": "Description de l'extrait de code.", + "snippetSchema.json.scope": "Une liste des noms de langages auxquels s’applique cet extrait de code, par exemple 'typescript,javascript'." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..c12c73b0de8 --- /dev/null +++ b/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "Extrait de code utilisateur" +} \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index 0c67783e02a..a21a67fed20 100644 --- a/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "Langage inconnu dans 'contributes.{0}.language'. Valeur fournie : {1}", "invalid.path.0": "Chaîne attendue dans 'contributes.{0}.path'. Valeur fournie : {1}", + "invalid.language.0": "Si le langage est omis, la valeur de 'contributes.{0}.path' doit être un fichier `.code-snippets`. Valeur fournie : {1}", + "invalid.language": "Langage inconnu dans 'contributes.{0}.language'. Valeur fournie : {1}", "invalid.path.1": "'contributes.{0}.path' ({1}) est censé être inclus dans le dossier ({2}) de l'extension. Cela risque de rendre l'extension non portable.", "vscode.extension.contributes.snippets": "Ajoute des extraits de code.", "vscode.extension.contributes.snippets-language": "Identificateur de langage pour lequel cet extrait de code est ajouté.", "vscode.extension.contributes.snippets-path": "Chemin du fichier d'extraits de code. Le chemin est relatif au dossier d'extensions et commence généralement par './snippets/'.", "badVariableUse": "Un ou plusieurs extraits de l’extension '{0}' confondent très probablement des snippet-variables et des snippet-placeholders (Voir https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax pour plus de détails)", "badFile": "Le fichier d’extrait \"{0}\" n’a pas pu être lu.", - "source.snippet": "Extrait de code utilisateur", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index 8e54d84198f..c372a7b1d75 100644 --- a/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -14,6 +14,7 @@ "terminal.integrated.shell.windows": "Le chemin du shell que le terminal utilise sous Windows. Lors de l’utilisation de shells fournies avec Windows (cmd, PowerShell ou Bash sur Ubuntu).", "terminal.integrated.shellArgs.windows": "Arguments de ligne de commande à utiliser sur le terminal Windows.", "terminal.integrated.rightClickCopyPaste": "Une fois le paramètre défini, le menu contextuel cesse de s'afficher quand l'utilisateur clique avec le bouton droit dans le terminal. À la place, une opération de copie est effectuée quand il existe une sélection, et une opération de collage est effectuée en l'absence de sélection.", + "terminal.integrated.copyOnSelection": "Une fois le paramètre défini, le texte sélectionné dans le terminal sera copié dans le presse-papiers.", "terminal.integrated.fontFamily": "Contrôle la famille de polices du terminal. La valeur par défaut est la valeur associée à editor.fontFamily.", "terminal.integrated.fontSize": "Contrôle la taille de police en pixels du terminal.", "terminal.integrated.lineHeight": "Contrôle la hauteur de ligne du terminal. La multiplication de ce nombre par la taille de police du terminal permet d'obtenir la hauteur de ligne réelle en pixels.", @@ -24,10 +25,12 @@ "terminal.integrated.setLocaleVariables": "Contrôle si les variables locales sont définies au démarrage du terminal. La valeur par défaut est true sur OS X, false sur les autres plateformes.", "terminal.integrated.cwd": "Chemin explicite de lancement du terminal. Il est utilisé comme répertoire de travail actif du processus d'interpréteur de commandes. Cela peut être particulièrement utile dans les paramètres d'espace de travail, si le répertoire racine n'est pas un répertoire de travail actif adéquat.", "terminal.integrated.confirmOnExit": "Indique s'il est nécessaire de confirmer l'existence de sessions de terminal actives au moment de quitter.", + "terminal.integrated.enableBell": "Si le terminal bell est activé ou non.", "terminal.integrated.commandsToSkipShell": "Ensemble d'ID de commandes dont les combinaisons de touches sont gérées par Code au lieu d'être envoyées à l'interpréteur de commandes. Cela permet d'utiliser des combinaisons de touches qui sont normalement consommées par l'interpréteur de commandes et d'obtenir le même résultat quand le terminal n'a pas le focus, par exemple Ctrl+P pour lancer Quick Open.", "terminal.integrated.env.osx": "Objet avec les variables d’environnement qui seront ajoutées au processus VS Code pour être utilisées par le terminal sous OS X", "terminal.integrated.env.linux": "Objet avec les variables d’environnement qui seront ajoutées au processus VS Code pour être utilisées par le terminal sous Linux", "terminal.integrated.env.windows": "Objet avec les variables d’environnement qui seront ajoutées au processus VS Code pour être utilisées par le terminal sous Windows", + "terminal.integrated.showExitAlert": "Afficher une alerte `Le processus terminal s’est arrêté avec le code de sortie` lorsque le code de sortie est différent de zéro.", "terminalCategory": "Terminal", "viewCategory": "Affichage" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json b/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json index b1d65f3e2d3..c4ad53ee08a 100644 --- a/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json @@ -12,8 +12,11 @@ "workbench.action.terminal.selectAll": "Tout Sélectionner", "workbench.action.terminal.deleteWordLeft": "Supprimer le mot à gauche", "workbench.action.terminal.deleteWordRight": "Supprimer le mot à droite", + "workbench.action.terminal.enterLineNavigationMode": "Saisir la ligne de mode de navigation", "workbench.action.terminal.new": "Créer un terminal intégré", "workbench.action.terminal.new.short": "Nouveau terminal", + "workbench.action.terminal.newWorkspacePlaceholder": "Sélectionner le répertoire de travail actuel pour le nouveau terminal", + "workbench.action.terminal.newInActiveWorkspace": "Créer un nouveau Terminal intégré (dans l'espace de travail actif)", "workbench.action.terminal.focus": "Focus sur le terminal", "workbench.action.terminal.focusNext": "Focus sur le terminal suivant", "workbench.action.terminal.focusPrevious": "Focus sur le terminal précédent", diff --git a/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index d636f6886f8..64dece8c292 100644 --- a/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,7 @@ "terminal.integrated.chooseWindowsShellInfo": "Vous pouvez changer l'interpréteur de commandes par défaut du terminal en sélectionnant le bouton Personnaliser.", "customize": "Personnaliser", "cancel": "Annuler", - "never again": "OK, ne plus afficher", + "never again": "OK, Ne plus afficher", "terminal.integrated.chooseWindowsShell": "Sélectionnez votre interpréteur de commandes de terminal favori. Vous pouvez le changer plus tard dans vos paramètres", "terminalService.terminalCloseConfirmationSingular": "Il existe une session de terminal active. Voulez-vous la tuer ?", "terminalService.terminalCloseConfirmationPlural": "Il existe {0} sessions de terminal actives. Voulez-vous les tuer ?" diff --git a/i18n/fra/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/fra/src/vs/workbench/parts/update/electron-browser/update.i18n.json index 12b4156b835..1e7c69d38aa 100644 --- a/i18n/fra/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -23,6 +23,7 @@ "commandPalette": "Palette de commandes...", "settings": "Paramètres", "keyboardShortcuts": "Raccourcis clavier", + "userSnippets": "Extraits de code de l'utilisateur", "selectTheme.label": "Thème de couleur", "themes.selectIconTheme.label": "Thème d'icône de fichier", "not available": "Mises à jour non disponibles", diff --git a/i18n/fra/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/fra/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 8ca568a2f40..865514aec03 100644 --- a/i18n/fra/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/fra/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "Le fichier est un répertoire", + "fileNotModifiedError": "Fichier non modifié depuis", "fileBinaryError": "Il semble que le fichier soit binaire. Impossible de l'ouvrir en tant que texte" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/services/files/node/fileService.i18n.json b/i18n/fra/src/vs/workbench/services/files/node/fileService.i18n.json index 6ba63445dd2..f83d0f45ec2 100644 --- a/i18n/fra/src/vs/workbench/services/files/node/fileService.i18n.json +++ b/i18n/fra/src/vs/workbench/services/files/node/fileService.i18n.json @@ -10,6 +10,7 @@ "fileTooLargeError": "Fichier trop volumineux pour être ouvert", "fileNotFoundError": "Fichier introuvable ({0})", "fileBinaryError": "Il semble que le fichier soit binaire. Impossible de l'ouvrir en tant que texte", + "filePermission": "Autorisation refusée en écrivant dans le fichier ({0})", "fileExists": "Le fichier à créer existe déjà ({0})", "fileMoveConflict": "Déplacement/copie impossible. Le fichier existe déjà dans la destination.", "unableToMoveCopyError": "Impossible de déplacer/copier. Le fichier remplace le dossier qui le contient.", diff --git a/i18n/fra/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json b/i18n/fra/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json index 232203467df..e217d8d597b 100644 --- a/i18n/fra/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json +++ b/i18n/fra/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json @@ -22,5 +22,6 @@ "keybindings.json.when": "Condition quand la touche est active.", "keybindings.json.args": "Arguments à passer à la commande à exécuter.", "keyboardConfigurationTitle": "Clavier", - "dispatch": "Contrôle la logique de distribution des appuis sur les touches pour utiliser soit 'code' (recommandé), soit 'keyCode'." + "dispatch": "Contrôle la logique de distribution des appuis sur les touches pour utiliser soit 'code' (recommandé), soit 'keyCode'.", + "touchbar.enabled": "Active les boutons de la touchbar macOS sur le clavier si disponible." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/fra/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index 4d90040dd20..a5d794a742e 100644 --- a/i18n/fra/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/fra/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "Voulez-vous enregistrer les modifications apportées à {0} ?", "saveChangesMessages": "Voulez-vous enregistrer les modifications apportées aux {0} fichiers suivants ?", - "moreFile": "...1 fichier supplémentaire non affiché", - "moreFiles": "...{0} fichiers supplémentaires non affichés", "saveAll": "&&Enregistrer tout", "save": "&&Enregistrer", "dontSave": "&&Ne pas enregistrer", diff --git a/i18n/fra/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/fra/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index 46a345fad2d..e40e5326149 100644 --- a/i18n/fra/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/fra/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "No file icons", "iconThemeError": "File icon theme is unknown or not installed.", "workbenchColors": "Remplace les couleurs du thème de couleur sélectionné.", - "editorColors": "Remplace les couleurs et le style de la police de l’éditeur du thème par la couleur actuellement sélectionnée.", "editorColors.comments": "Définit les couleurs et les styles des commentaires", "editorColors.strings": "Définit les couleurs et les styles des littéraux de chaînes.", "editorColors.keywords": "Définit les couleurs et les styles des mots clés.", @@ -19,5 +18,6 @@ "editorColors.types": "Définit les couleurs et les styles des déclarations et références de type.", "editorColors.functions": "Définit les couleurs et les styles des déclarations et références de fonctions.", "editorColors.variables": "Définit les couleurs et les styles des déclarations et références de variables.", - "editorColors.textMateRules": "Définit les couleurs et les styles à l’aide de règles de thème textmate (avancé)." + "editorColors.textMateRules": "Définit les couleurs et les styles à l’aide de règles de thème textmate (avancé).", + "editorColors": "Remplace les couleurs et le style de la police de l’éditeur du thème par la couleur actuellement sélectionnée." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/fra/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 079d530ab03..f4f2e499154 100644 --- a/i18n/fra/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/fra/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "Impossible d’écrire dans le fichier de configuration de l’espace de travail. Veuillez ouvrir le fichier pour y corriger les erreurs/avertissements et essayez à nouveau.", "errorWorkspaceConfigurationFileDirty": "Impossible d’écrire dans le fichier de configuration de l’espace de travail, car le fichier a été modifié. Veuillez, s’il vous plaît, l'enregistrez et réessayez.", "openWorkspaceConfigurationFile": "Ouvrir le Fichier de Configuration d’espace de travail", - "close": "Fermer", - "enterWorkspace.close": "Fermer", - "enterWorkspace.dontShowAgain": "Ne plus afficher", - "enterWorkspace.moreInfo": "Informations", - "enterWorkspace.prompt": "En savoir plus sur l’utilisation de dossiers multiples dans VS Code." + "close": "Fermer" } \ No newline at end of file diff --git a/i18n/hun/extensions/git/out/autofetch.i18n.json b/i18n/hun/extensions/git/out/autofetch.i18n.json index fe69406ef37..83092572a2a 100644 --- a/i18n/hun/extensions/git/out/autofetch.i18n.json +++ b/i18n/hun/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "Igen", + "read more": "További információk", "no": "Nem", - "not now": "Most nem", - "suggest auto fetch": "Szeretné engedélyezni a Git-forráskódtárhelyek automatikus lekérését (fetch)?" + "not now": "Kérdezzen rá később", + "suggest auto fetch": "Szeretné, hogy a Code időszakosan futtasson `git fetch`-t?" } \ No newline at end of file diff --git a/i18n/hun/extensions/git/out/commands.i18n.json b/i18n/hun/extensions/git/out/commands.i18n.json index d2dfa251e5d..80f41babc05 100644 --- a/i18n/hun/extensions/git/out/commands.i18n.json +++ b/i18n/hun/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\nA művelet NEM VONHATÓ VISSZA, az aktuális munka ÖRÖKRE EL FOG VESZNI.", "yes discard tracked": "Egy követett fájl elvetése", "yes discard tracked multiple": "{0} követett fájl elvetése", + "unsaved files single": "A következő fájl nincs elmentve: {0}.\n\nSzeretné menteni a beadás előtt?", + "unsaved files": "{0} nem mentett fájl található.\n\nSzeretné menteni őket a beadás előtt?", + "save and commit": "Összes mentése és beadás", + "commit": "Beadás mindenképp", "no staged changes": "Nincs beadáshoz (commithoz) előjegyzett módosítás. Szeretné automatikusan előjegyeztetni a módosításokat és közvetlenül beadni őket?", "always": "Mindig", "no changes": "Nincs beadandó módosítás.", @@ -64,12 +68,13 @@ "no remotes to pull": "A forráskódtárhoz nincsenek távoli szerverek konfigurálva, ahonnan pullozni lehetne.", "pick remote pull repo": "Válassza ki a távoli szervert, ahonnan pullozni szeretné az ágat", "no remotes to push": "A forráskódtárhoz nincsenek távoli szerverek konfigurálva, ahová pusholni lehetne.", - "push with tags success": "A címkékkel együtt történő pusholás sikeresen befejeződött.", "nobranch": "Válasszon egy ágat a távoli szerverre való pusholáshot!", + "confirm publish branch": "A(z) '{0}' ág nem létezik a távoli szerveren. Szeretné publikálni ezt az ágat?", + "ok": "OK", + "push with tags success": "A címkékkel együtt történő pusholás sikeresen befejeződött.", "pick remote": "Válassza ki a távoli szervert, ahová publikálni szeretné a(z) '{0}' ágat:", "sync is unpredictable": "Ez a művelet pusholja és pullozza a commitokat a következő helyről: '{0}'.", - "ok": "OK", - "never again": "Rendben, ne jelenítse meg újra", + "never again": "Rendben, ne jelenjen meg újra", "no remotes to publish": "A forráskódtárhoz nincsenek távoli szerverek konfigurálva, ahová publikálni lehetne.", "no changes stash": "Nincs elrakandó módosítás.", "provide stash message": "Adja meg a stash-hez tartozó üzenet (nem kötelező)", diff --git a/i18n/hun/extensions/git/out/main.i18n.json b/i18n/hun/extensions/git/out/main.i18n.json index ab59b50cfc7..19742ee7152 100644 --- a/i18n/hun/extensions/git/out/main.i18n.json +++ b/i18n/hun/extensions/git/out/main.i18n.json @@ -7,7 +7,7 @@ "looking": "Git keresése a következő helyen: {0}", "using git": "Git {0} használata a következő helyről: {1}", "downloadgit": "Git letöltése", - "neverShowAgain": "Ne jelenjen meg újra", + "neverShowAgain": "Ne jelenítse meg újra", "notfound": "A Git nem található. Telepítse vagy állítsa be az elérési útját a 'git.path' beállítással.", "updateGit": "Git frissítése", "git20": "Úgy tűnik, hogy a git {0} van telepítve. A Code a git >= 2 verzióival működik együtt a legjobban." diff --git a/i18n/hun/extensions/git/out/repository.i18n.json b/i18n/hun/extensions/git/out/repository.i18n.json index 234abfc4470..b2654e062b7 100644 --- a/i18n/hun/extensions/git/out/repository.i18n.json +++ b/i18n/hun/extensions/git/out/repository.i18n.json @@ -27,6 +27,6 @@ "staged changes": "Beadásra előjegyzett módosítások", "changes": "Módosítások", "ok": "OK", - "neveragain": "Soha ne jelenítse meg újra", + "neveragain": "Ne jelenítse meg újra", "huge": "A(z) '{0}' forráskódtárban túl sok aktív módosítás van. A Git-funkciók csak egy része lesz engedélyezve." } \ No newline at end of file diff --git a/i18n/hun/extensions/git/package.i18n.json b/i18n/hun/extensions/git/package.i18n.json index 150ac02318b..52f61e79d5d 100644 --- a/i18n/hun/extensions/git/package.i18n.json +++ b/i18n/hun/extensions/git/package.i18n.json @@ -54,12 +54,12 @@ "command.stashPopLatest": "Legutóbbi stash visszaállítása", "config.enabled": "Meghatározza, hogy a git engedélyezve van-e", "config.path": "A git végrehajtható fájl elérési útja", + "config.autoRepositoryDetection": "Meghatározza, hogy a forráskódtárak automatikusan fel legyenek-e derítve", "config.autorefresh": "Meghatározza, hogy engedélyezve van-e az automatikus frissítés", "config.autofetch": "Meghatározza, hogy engedélyezve van-e az automatikus lekérés", "config.enableLongCommitWarning": "Figyelmeztessen-e az alkalmazás hosszú beadási üzenet esetén", "config.confirmSync": "Megerősítés kérése git forráskódtárak szinkronizálása előtt", "config.countBadge": "Meghatározza a git jelvényen megjelenő számláló működését. Az `all` minden módosítást számol, a `tracked` csak a követkett változtatásokat. Az `off` kikapcsolja a jelvényt.", - "config.checkoutType": "Meghatározza, hogy milyen típusú ágak jelenjenek meg a `Checkout adott helyről... ` parancs futtatása esetén. Az `all` esetén az összes ref megjelenik, `local` esetén csak a helyi ágak, `tags` esetén csak a címkék, `remote` esetén pedig csak a távoli ágak.", "config.ignoreLegacyWarning": "Régi gittel kapcsolatos figyelmeztetés figyelmen kívül hagyása", "config.ignoreMissingGitWarning": "Figyelmeztetés figyelmen kívül hagyása, ha a Git hiányzik", "config.ignoreLimitWarning": "Túl sok módosítás esetén megjelenő figyelmeztetés figyelmen kívül hagyása", @@ -72,5 +72,6 @@ "colors.deleted": "A törölt erőforrások színe.", "colors.untracked": "A nem követett erőforrások színe.", "colors.ignored": "A figyelmen kívül hagyott erőforrások színe.", - "colors.conflict": "A konfliktusos erőforrások színe." + "colors.conflict": "A konfliktusos erőforrások színe.", + "colors.submodule": "Az almodulokhoz tartozó erőforrások színe" } \ No newline at end of file diff --git a/i18n/hun/extensions/typescript/out/commands.i18n.json b/i18n/hun/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..c521fb331a6 --- /dev/null +++ b/i18n/hun/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "Nyisson meg egy mappát a VS Code-ban typescriptes vagy javascriptes projekt használatához!", + "typescript.projectConfigUnsupportedFile": "Nem sikerült meghatározni a TypeScript- vagy JavaScript-projektet. Nem támogatott fájltípus", + "typescript.projectConfigCouldNotGetInfo": "Nem sikerült meghatározni a TypeScript- vagy JavaScript-projektet", + "typescript.noTypeScriptProjectConfig": "A fájl nem része egy TypeScript-projektnek", + "typescript.noJavaScriptProjectConfig": "A fájl nem része egy JavaScript-projektnek", + "typescript.configureTsconfigQuickPick": "tsconfig.json konfigurálása", + "typescript.configureJsconfigQuickPick": "jsconfig.json konfigurálása", + "typescript.projectConfigLearnMore": "További információ" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/hun/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/hun/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/base/node/ps.i18n.json b/i18n/hun/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..688e86b7228 --- /dev/null +++ b/i18n/hun/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "Processzor- és memóriahasználattal kapcsolatos információk gyűjtése. A folyamat eltarthat néhány másodpercig." +} \ No newline at end of file diff --git a/i18n/hun/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/hun/src/vs/editor/common/config/commonEditorConfig.i18n.json index 48b15939e90..7f137c6fbff 100644 --- a/i18n/hun/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/hun/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "A sorszámok abszolút értékként jelennek meg.", "lineNumbers.relative": "A sorszámok a kurzortól való távolságuk alapján jelennek meg.", "lineNumbers.interval": "A sorszámok minden 10. sorban jelennek meg.", - "lineNumbers": "Meghatározza a sorszámok megjelenését. A lehetséges értékek: 'on', 'off' és 'relative'.", + "lineNumbers": "Meghatározza a sorszámok megjelenését. A lehetséges értékek: 'on', 'off', 'relative' és 'interval'.", "rulers": "Függőleges vonalzók kirajzolása bizonyos számú fix szélességű karakter után. Több vonalzó használatához adjon meg több értéket. Nincs kirajzolva semmi, ha a tömb üres.", "wordSeparators": "Azon karakterek listája, amelyek szóelválasztónak vannak tekintve szavakkal kapcsolatos navigáció vagy műveletek során.", "tabSize": "Egy tabulátor hány szóköznek felel meg. Ez a beállítás felülírásra kerül a fájl tartalma alapján, ha az `editor.detectIndentation` beállítás aktív.", @@ -72,6 +72,7 @@ "cursorBlinking": "Meghatározza a kurzor animációjának stílusát. Lehetséges értékek: 'blink', 'smooth', 'phase', 'expand' vagy 'solid'", "mouseWheelZoom": "A szerkesztőablak betűtípusának nagyítása vagy kicsinyítése az egérgörgő Ctrl lenyomása mellett történő használata esetén", "cursorStyle": "Meghatározza a kurzor stílusát. Lehetséges értékek: 'block', 'block-outline', 'line', 'line-thin', 'underline' vagy 'underline-thin'", + "lineCursorWidth": "Meghatározza a kurzor szélességét, ha az editor.cursorStyle értéke 'line'.", "fontLigatures": "Engedélyezi a betűtípusban található ligatúrák használatát", "hideCursorInOverviewRuler": "Meghatározza, hogy a kurzor pozíciója el legyen-e rejtve az áttekintő sávon.", "renderWhitespace": "Meghatározza, hogy a szerkesztőablakban hogyan legyenek kirajzolva a szóköz karakterek. Lehetséges értékek: 'none', 'boundary', vagy 'all'. A 'boundary' beállítás esetén, ha szavak között egyetlen szóköz található, akkor az nem lesz kirajzolva.", diff --git a/i18n/hun/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/hun/src/vs/editor/common/view/editorColorRegistry.i18n.json index ca5c75eaa93..bcb0b0e54d5 100644 --- a/i18n/hun/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/hun/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,7 @@ { "lineHighlight": "A kurzor pozícióján található sor kiemelési háttérszíne.", "lineHighlightBorderBox": "A kurzor pozícióján található sor keretszíne.", - "rangeHighlight": "A kiemelt területek háttérszíne, pl. a gyors megnyitás és keresés funkcióknál.", + "rangeHighlight": "A kiemelt területek háttérszíne, pl. a gyors megnyitás és keresés funkcióknál. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", "caret": "A szerkesztőablak kurzorának színe.", "editorCursorBackground": "A szerkesztőablak kurzorának háttérszíne. Lehetővé teszik az olyan karakterek színének módosítását, amelyek fölött egy blokk-típusú kurzor áll.", "editorWhitespaces": "A szerkesztőablakban található szóköz karakterek színe.", diff --git a/i18n/hun/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/hun/src/vs/editor/contrib/gotoError/gotoError.i18n.json index e3ec625549e..657741e4ffd 100644 --- a/i18n/hun/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/hun/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "Következő hiba vagy figyelmeztetés", - "markerAction.previous.label": "Előző hiba vagy figyelmeztetés", + "markerAction.next.label": "Következő probléma (hiba, figyelmeztetés, információ)", + "markerAction.previous.label": "Előző probléma (hiba, figyelmeztetés, információ)", "editorMarkerNavigationError": "A szerkesztőablak jelzőnavigációs moduljának színe hiba esetén.", "editorMarkerNavigationWarning": "A szerkesztőablak jelzőnavigációs moduljának színe figyelmeztetés esetén.", "editorMarkerNavigationInfo": "A szerkesztőablak jelzőnavigációs moduljának színe információ esetén.", diff --git a/i18n/hun/src/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.i18n.json b/i18n/hun/src/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.i18n.json index dc4360652cb..96f61fa990d 100644 --- a/i18n/hun/src/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.i18n.json +++ b/i18n/hun/src/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggle.tabMovesFocus": "Tab billentyűvel mozgatott fókusz ki- és bekapcsolása" + "toggle.tabMovesFocus": "Tabulátor billentyűvel mozgatott fókusz ki- és bekapcsolása" } \ No newline at end of file diff --git a/i18n/hun/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/hun/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index fa7c3359075..d251158c987 100644 --- a/i18n/hun/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/hun/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "Szimbólumok háttérszíne olvasási hozzáférés, páldául változó olvasása esetén.", - "wordHighlightStrong": "Szimbólumok háttérszíne írási hozzáférés, páldául változó írása esetén.", + "wordHighlight": "Szimbólumok háttérszíne olvasási hozzáférés, páldául változó olvasása esetén. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "wordHighlightStrong": "Szimbólumok háttérszíne írási hozzáférés, páldául változó írása esetén. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", "overviewRulerWordHighlightForeground": "A kiemelt szimbólumokat jelölő jelzések színe az áttekintősávon.", "overviewRulerWordHighlightStrongForeground": "A kiemelt, írási hozzáférésű szimbólumokat jelölő jelzések színe az áttekintősávon.", "wordHighlight.next.label": "Ugrás a következő kiemelt szimbólumhoz", diff --git a/i18n/hun/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/hun/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index 27181140f4b..9ef8de88790 100644 --- a/i18n/hun/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/hun/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "A(z) `{0}` nem érvényes menüazonosító", "missing.command": "A menüpont a(z) `{0}` parancsra hivatkozik, ami nincs deklarálva a 'commands'-szakaszban.", "missing.altCommand": "A menüpont a(z) `{0}` alternatív parancsra hivatkozik, ami nincs deklarálva a 'commands'-szakaszban.", - "dupe.command": "A menüpont ugyanazt a parancsot hivatkozza alapértelmezett és alternatív parancsként", - "nosupport.altCommand": "Jelenleg csak az 'editor/title' menü 'navigation' csoportja támogatja az alternatív parancsokat" + "dupe.command": "A menüpont ugyanazt a parancsot hivatkozza alapértelmezett és alternatív parancsként" } \ No newline at end of file diff --git a/i18n/hun/src/vs/platform/environment/node/argv.i18n.json b/i18n/hun/src/vs/platform/environment/node/argv.i18n.json index acbe400a835..f2b86a65d34 100644 --- a/i18n/hun/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/hun/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,35 @@ "diff": "Két fájl összehasonlítása egymással.", "add": "Mappá(k) hozzáadása a legutolsó aktív ablakhoz.", "goto": "Megnyitja a megadott elérési úton található fájlt a megadott sornál és oszlopnál.", - "locale": "A használt lokalizáció (pl. en-US vagy zh-TW)", "newWindow": "Mindenképp induljon új példány a Code-ból.", - "performance": "Indítás a 'Developer: Startup Performance' parancs engedélyezésével.", - "prof-startup": "Processzorhasználat profilozása induláskor", - "inspect-extensions": "Hibakeresés és profilozás engedélyezése a kiegészítőkben. Ellenőrizze a fejlesztői eszközöket a csatlakozási URI-hoz.", - "inspect-brk-extensions": "Hibakeresés és profilozás engedélyezése a kiegészítőkben, úgy, hogy a kiegészítő gazdafolyamata szüneteltetve lesz az indítás után. Ellenőrizze a fejlesztői eszközöket a csatlakozási URI-hoz. ", "reuseWindow": "Fájl vagy mappa megnyitása a legutoljára aktív ablakban.", - "userDataDir": "Meghatározza a könyvtárat, ahol a felhasználói adatok vannak tárolva. Hasznás, ha rootként van futtatva.", - "log": "A naplózott események szintje.Az 'info' az alapértelmezett értéke. Lehetséges értékek: 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'.", - "verbose": "Részletes kimenet kiírása (magába foglalja a --wait kapcsolót)", "wait": "Várjon a fájlok bezárására a visszatérés előtt.", + "locale": "A használt lokalizáció (pl. en-US vagy zh-TW)", + "userDataDir": "Meghatározza a könyvtárat, ahol a felhasználói adatok vannak tárolva. Hasznás, ha rootként van futtatva.", + "version": "Verzió kiírása.", + "help": "Használati útmutató kiírása.", "extensionHomePath": "A kiegészítők gyökérkönyvtárának beállítása.", "listExtensions": "Telepített kiegészítők listázása.", "showVersions": "Telepített kiegészítők verziójának megjelenítése a --list-extension kapcsoló használata esetén.", "installExtension": "Kiegészítő telepítése.", "uninstallExtension": "Kiegészítő eltávolítása.", "experimentalApis": "Tervezett API-funkciók engedélyezése egy kiegészítő számára.", - "disableExtensions": "Összes telepített kiegészítő letiltása.", - "disableGPU": "Hardveres gyorsítás letiltása.", + "verbose": "Részletes kimenet kiírása (magába foglalja a --wait kapcsolót)", + "log": "A naplózott események szintje.Az 'info' az alapértelmezett értéke. Lehetséges értékek: 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'.", "status": "Folyamatok erőforrás-használati és diagnosztikai adatinak kiíratása.", - "version": "Verzió kiírása.", - "help": "Használati útmutató kiírása.", + "performance": "Indítás a 'Developer: Startup Performance' parancs engedélyezésével.", + "prof-startup": "Processzorhasználat profilozása induláskor", + "disableExtensions": "Összes telepített kiegészítő letiltása.", + "inspect-extensions": "Hibakeresés és profilozás engedélyezése a kiegészítőkben. Ellenőrizze a fejlesztői eszközöket a csatlakozási URI-hoz.", + "inspect-brk-extensions": "Hibakeresés és profilozás engedélyezése a kiegészítőkben, úgy, hogy a kiegészítő gazdafolyamata szüneteltetve lesz az indítás után. Ellenőrizze a fejlesztői eszközöket a csatlakozási URI-hoz. ", + "disableGPU": "Hardveres gyorsítás letiltása.", + "uploadLogs": "Az aktuális munkamenet naplóinak feltöltése egy biztonságos végpontra.", "usage": "Használat", "options": "beállítások", "paths": "elérési utak", - "optionsUpperCase": "Beálítások" + "stdinWindows": "Más program bemenetének olvasásához fűzze a '-' karaktert a parancshoz (pl.: 'echo Hello World | {0} -')", + "stdinUnix": "Az stdin-ről történő olvasásához fűzze a '-' karaktert a parancshoz (pl.: 'ps aux | grep code | {0} -')", + "optionsUpperCase": "Beálítások", + "extensionsManagement": "Kiegészítők kezelése", + "troubleshooting": "Hibaelhárítás" } \ No newline at end of file diff --git a/i18n/hun/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/hun/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index 8788d40a469..b5c8c712977 100644 --- a/i18n/hun/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/hun/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,15 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "A kiegészítő érvénytelen: a package.json nem egy JSON-fájl.", - "restartCodeLocal": "Indítsa újra a Code-ot a(z) {0} újratelepítése előtt.", + "restartCode": "Indítsa újra a Code-ot a(z) {0} újratelepítése előtt.", "installingOutdatedExtension": "A kiegészítő egy újabb verziója már telepítve van. Szeretné felülírni a régebbi verzióval?", "override": "Felülírás", "cancel": "Mégse", - "notFoundCompatible": "A telepítés nem sikerült, mert a(z) '{0}' kiegészítő VS Code '{1}' verziójával kompatibilis változata nem található.", - "quitCode": "A telepítés nem sikerült, mert a kiegészítő elavult példánya még mindig fut. Lépjen ki a VS Code-ból, és indítsa újra az újratelepítés előtt.", - "exitCode": "A telepítés nem sikerült, mert a kiegészítő elavult példánya még mindig fut. Lépjen ki a VS Code-ból, és indítsa újra az újratelepítés előtt.", + "errorInstallingDependencies": "Hiba a függőségek telepítése közben. {0}", + "notFoundCompatible": "A(z) '{0}' nem telepíthető: nincs a VS Code '{1}' verziójával kompatibilis változat.", "notFoundCompatibleDependency": "A telepítés nem sikerült, mert a(z) '{0}' kiegészítő függőség VS Code '{1}' verziójával kompatibilis változata nem található. ", + "quitCode": "A kiegészítő telepítése nem sikerült. Lépjen ki és indítsa el a VS Code-ot az újratelepítés előtt!", + "exitCode": "A kiegészítő telepítése nem sikerült. Lépjen ki és indítsa el a VS Code-ot az újratelepítés előtt!", "uninstallDependeciesConfirmation": "Csak a(z) '{0}' kiegészítőt szeretné eltávolítani vagy annak függőségeit is?", "uninstallOnly": "Csak ezt", "uninstallAll": "Mindent", diff --git a/i18n/hun/src/vs/platform/message/common/message.i18n.json b/i18n/hun/src/vs/platform/message/common/message.i18n.json index a4f556eb01c..ee6d194b8dd 100644 --- a/i18n/hun/src/vs/platform/message/common/message.i18n.json +++ b/i18n/hun/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "Bezárás", "later": "Később", - "cancel": "Mégse" + "cancel": "Mégse", + "moreFile": "...1 további fájl nincs megjelenítve", + "moreFiles": "...{0} további fájl nincs megjelenítve" } \ No newline at end of file diff --git a/i18n/hun/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/hun/src/vs/platform/theme/common/colorRegistry.i18n.json index a024837c583..e489cf247bf 100644 --- a/i18n/hun/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/hun/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,12 @@ "editorWidgetBorder": "A szerkesztőablak-modulok keretszíne. A szín csak akkor van használva, ha a modul beállítása alapján rendelkezik kerettel, és a színt nem írja felül a modul.", "editorSelectionBackground": "A szerkesztőablak-szakasz színe.", "editorSelectionForeground": "A kijelölt szöveg színe nagy kontrasztú téma esetén.", - "editorInactiveSelection": "Az inaktív szerkesztőablakban található kijelölések színe.", - "editorSelectionHighlight": "A kijelöléssel megegyező tartalmú területek színe.", + "editorInactiveSelection": "Az inaktív szerkesztőablakban található kijelölések színe. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "editorSelectionHighlight": "A kijelöléssel megegyező tartalmú területek színe. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", "editorFindMatch": "A keresés jelenlegi találatának színe.", - "findMatchHighlight": "A keresés további találatainak színe.", - "findRangeHighlight": "A keresést korlátozó terület színe.", - "hoverHighlight": "Kiemelés azon szó alatt, amely fölött lebegő elem jelenik meg.", + "findMatchHighlight": "A keresés további találatainak színe. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "findRangeHighlight": "A keresést korlátozó terület színe. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "hoverHighlight": "Kiemelés azon szó alatt, amely fölött lebegő elem jelenik meg. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", "hoverBackground": "A szerkesztőablakban lebegő elemek háttérszíne.", "hoverBorder": "A szerkesztőablakban lebegő elemek keretszíne.", "activeLinkForeground": "Az aktív hivatkozások háttérszíne.", @@ -76,12 +76,12 @@ "diffEditorRemoved": "Az eltávolított szövegek háttérszíne.", "diffEditorInsertedOutline": "A beillesztett szövegek körvonalának színe.", "diffEditorRemovedOutline": "Az eltávolított szövegek körvonalának színe.", - "mergeCurrentHeaderBackground": "A helyi tartalom fejlécének háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén.", - "mergeCurrentContentBackground": "A helyi tartalom háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén.", - "mergeIncomingHeaderBackground": "A beérkező tartalom fejlécének háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén.", - "mergeIncomingContentBackground": "A beérkező tartalom háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén.", - "mergeCommonHeaderBackground": "A közös ős tartalom fejlécének háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén. ", - "mergeCommonContentBackground": "A közös ős tartalom háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén. ", + "mergeCurrentHeaderBackground": "A helyi tartalom fejlécének háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "mergeCurrentContentBackground": "A helyi tartalom háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "mergeIncomingHeaderBackground": "A beérkező tartalom fejlécének háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "mergeIncomingContentBackground": "A beérkező tartalom háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "mergeCommonHeaderBackground": "A közös ős tartalom fejlécének háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", + "mergeCommonContentBackground": "A közös ős tartalmának háttérszíne sorok között megjelenített összeolvasztási konfliktusok esetén. A színnek áttetszőnek kell lennie, hogy ne fedje el az alatta lévő dekorátorokat.", "mergeBorder": "A fejlécek és az elválasztó sáv keretszíne a sorok között megjelenített összeolvasztási konfliktusok esetén.", "overviewRulerCurrentContentForeground": "A helyi tartalom előtérszíne az áttekintő sávon összeolvasztási konfliktusok esetén.", "overviewRulerIncomingContentForeground": "A beérkező tartalom előtérszíne az áttekintő sávon összeolvasztási konfliktusok esetén.", diff --git a/i18n/hun/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/hun/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..753cc84e856 --- /dev/null +++ b/i18n/hun/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "saveParticipants": "Mentési események futtatása..." +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/hun/src/vs/workbench/api/node/extHostTreeViews.i18n.json index ad630367cba..d46c5a08986 100644 --- a/i18n/hun/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/hun/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "treeView.notRegistered": "Nincs '{0}' azonosítóval regisztrált fanézet.", - "treeItem.notFound": "Nincs '{0}' azonosítójú elem a fában.", - "treeView.duplicateElement": "A(z) {0} elem már regisztrálva van" + "treeView.duplicateElement": "Már van {0} azonosítójú elem regisztrálva" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/hun/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index b5b22901d6a..8846afdbff9 100644 --- a/i18n/hun/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "Oldalsáv helyének váltása", + "toggleSidebarPosition": "Oldalsáv helyzetének váltása", "view": "Nézet" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/hun/src/vs/workbench/browser/actions/workspaceActions.i18n.json index 586bbb9d5a1..5b05c77fb5d 100644 --- a/i18n/hun/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "Fájl megnyitása...", "openFolder": "Mappa megnyitása...", "openFileFolder": "Megnyitás...", - "addFolderToWorkspace": "Mappa hozzáadása a munkaterülethez...", - "add": "&&Hozzáadás", - "addFolderToWorkspaceTitle": "Mappa hozzáadása a munkaterülethez", "globalRemoveFolderFromWorkspace": "Mappa eltávolítása a munkaterületről...", - "removeFolderFromWorkspace": "Mappa eltávolítása a munkaterületről", - "openFolderSettings": "Mappa beállításainak megnyitása", "saveWorkspaceAsAction": "Munkaterület mentése másként...", "save": "Menté&&s", "saveWorkspace": "Munkaterület mentése", "openWorkspaceAction": "Munkaterület megnyitása...", "openWorkspaceConfigFile": "Munkaterület konfigurációs fájljának megnyitása", - "openFolderAsWorkspaceInNewWindow": "Mappa megnyitása munkaterületként egy új ablakban", - "workspaceFolderPickerPlaceholder": "Válasszon munkaterület-mappát!" + "openFolderAsWorkspaceInNewWindow": "Mappa megnyitása munkaterületként egy új ablakban" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/hun/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..080898a7ed6 --- /dev/null +++ b/i18n/hun/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "Mappa hozzáadása a munkaterülethez...", + "add": "&&Hozzáadás", + "addFolderToWorkspaceTitle": "Mappa hozzáadása a munkaterülethez", + "workspaceFolderPickerPlaceholder": "Válasszon munkaterület-mappát!" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/hun/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index 05a3be82161..5d48accc6b6 100644 --- a/i18n/hun/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,18 @@ "groupThreePicker": "A harmadik csoportban található szerkesztőablakok megjelenítése", "allEditorsPicker": "Összes megnyitott szerkesztőablak megjelenítése", "view": "Nézet", - "file": "Fájl" + "file": "Fájl", + "close": "Bezárás", + "closeOthers": "Többi bezárása", + "closeRight": "Jobbra lévők bezárása", + "closeAllUnmodified": "Nem módosultak bezárása", + "closeAll": "Összes bezárása", + "keepOpen": "Maradjon nyitva", + "toggleInlineView": "Sorok közötti nézet be- és kikapcsolása", + "showOpenedEditors": "Megnyitott szerkesztőablak megjelenítése", + "keepEditor": "Szerkesztőablak nyitva tartása", + "closeEditorsInGroup": "A csoportban lévő összes szerkesztőablak bezárása", + "closeUnmodifiedEditors": "Nem módosult szerkesztőablakok bezárása a csoportban", + "closeOtherEditors": "Többi szerkesztőablak bezárása", + "closeRightEditors": "Jobbra lévő szerkesztőablakok bezárása" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/hun/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index c82ab6ff2a2..52fa76d91e7 100644 --- a/i18n/hun/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "Szerkesztőablak bezárása", "revertAndCloseActiveEditor": "Visszaállítás és szerkesztőablak bezárása", "closeEditorsToTheLeft": "Balra lévő szerkesztőablakok bezárása", - "closeEditorsToTheRight": "Jobbra lévő szerkesztőablakok bezárása", "closeAllEditors": "Összes szerkesztőablak bezárása", - "closeUnmodifiedEditors": "Nem módosult szerkesztőablakok bezárása a csoportban", "closeEditorsInOtherGroups": "A többi csoport szerkesztőablakainak bezárása", - "closeOtherEditorsInGroup": "Többi szerkesztőablak bezárása", - "closeEditorsInGroup": "A csoportban lévő összes szerkesztőablak bezárása", "moveActiveGroupLeft": "Szerkesztőablak-csoport mozgatása balra", "moveActiveGroupRight": "Szerkesztőablak-csoport mozgatása jobbra", "minimizeOtherEditorGroups": "Többi szerkesztőablak-csoport kis méretűvé tétele", "evenEditorGroups": "Szerkesztőablak-csoportok egyenlő méretűvé tétele", "maximizeEditor": "Szerkesztőablak-csoport nagy méretűvé tétele és oldalsáv elrejtése", - "keepEditor": "Szerkesztőablak nyitva tartása", "openNextEditor": "Következő szerkesztőablak megnyitása", "openPreviousEditor": "Előző szerkesztőablak megnyitása", "nextEditorInGroup": "A csoport következő szerkesztőablakának megnyitása", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "Az első csoportban található szerkesztőablakok megjelenítése", "showEditorsInSecondGroup": "A második csoportban található szerkesztőablakok megjelenítése", "showEditorsInThirdGroup": "A harmadik csoportban található szerkesztőablakok megjelenítése", - "showEditorsInGroup": "A csoportban található szerkesztőablakok megjelenítése", "showAllEditors": "Összes szerkesztőablak megjelenítése", "openPreviousRecentlyUsedEditorInGroup": "A csoportban előző legutoljára használt szerksztőablak megnyitása", "openNextRecentlyUsedEditorInGroup": "A csoportban következő legutoljára használt szerksztőablak megnyitása", @@ -54,5 +48,8 @@ "moveEditorLeft": "Szerkesztőablak mozgatása balra", "moveEditorRight": "Szerkesztőablak mozgatása jobbra", "moveEditorToPreviousGroup": "Szerkesztőablak mozgatása az előző csoportba", - "moveEditorToNextGroup": "Szerkesztőablak mozgatása a következő csoportba" + "moveEditorToNextGroup": "Szerkesztőablak mozgatása a következő csoportba", + "moveEditorToFirstGroup": "Szerkesztőablak mozgatása az első csoportba", + "moveEditorToSecondGroup": "Szerkesztőablak mozgatása a második csoportba", + "moveEditorToThirdGroup": "Szerkesztőablak mozgatása a harmadik csoportba" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/hun/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index b15ee093f22..37f4933240b 100644 --- a/i18n/hun/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "Aktív szerkesztőablak mozgatása fülek vagy csoportok között", "editorCommand.activeEditorMove.arg.name": "Aktív szerkesztőablak mozgatási argumentum", - "editorCommand.activeEditorMove.arg.description": "Argumentumtulajdonságok:\n\t* 'to': karakterlánc, a mozgatás célpontja.\n\t* 'by': karakterlánc, a mozgatás egysége. Fülek (tab) vagy csoportok (group) alapján.\n\t* 'value': szám, ami meghatározza, hogy hány pozíciót kell mozgatni, vagy egy abszolút pozíciót, ahová mozgatni kell.", - "commandDeprecated": "A(z) **{0}** parancs el lett távolítva. A(z) **{1}** használható helyette", - "openKeybindings": "Billentyűparancsok beállítása" + "editorCommand.activeEditorMove.arg.description": "Argumentumtulajdonságok:\n\t* 'to': karakterlánc, a mozgatás célpontja.\n\t* 'by': karakterlánc, a mozgatás egysége. Fülek (tab) vagy csoportok (group) alapján.\n\t* 'value': szám, ami meghatározza, hogy hány pozíciót kell mozgatni, vagy egy abszolút pozíciót, ahová mozgatni kell." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/hun/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index 0cb7c46cb05..5d020bd339d 100644 --- a/i18n/hun/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "Szövegfájl-összehasonlító.", "navigate.next.label": "Következő módosítás", "navigate.prev.label": "Előző módosítás", - "inlineDiffLabel": "Váltás inline nézetre", - "sideBySideDiffLabel": "Váltás párhuzamos nézetre" + "toggleIgnoreTrimWhitespace.label": "Térközlevágás mellőzése" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/hun/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index 0ef6405cab2..11d4a655ad1 100644 --- a/i18n/hun/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "Bezárás", - "closeOthers": "Többi bezárása", - "closeRight": "Jobbra lévők bezárása", - "closeAll": "Összes bezárása", - "closeAllUnmodified": "Nem módosultak bezárása", - "keepOpen": "Maradjon nyitva", - "showOpenedEditors": "Megnyitott szerkesztőablak megjelenítése", "araLabelEditorActions": "Szerkesztőablak-műveletek" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/hun/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index 6ed546539cf..9fd111df3c0 100644 --- a/i18n/hun/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[Nem támogatott]", + "userIsAdmin": "(Rendszergazda)", + "userIsSudo": "(Superuser)", "devExtensionWindowTitlePrefix": "[Kiegészítő fejlesztői példány]" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/hun/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index b21a79bc546..b88b3f6c04e 100644 --- a/i18n/hun/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/hun/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "hideView": "Elrejtés az oldalsávról" + "hideView": "Elrejtés" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/common/theme.i18n.json b/i18n/hun/src/vs/workbench/common/theme.i18n.json index b30bec0d245..634a2ddeccc 100644 --- a/i18n/hun/src/vs/workbench/common/theme.i18n.json +++ b/i18n/hun/src/vs/workbench/common/theme.i18n.json @@ -6,17 +6,21 @@ { "tabActiveBackground": "Az aktív fül háttérszíne. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", "tabInactiveBackground": "Az inaktív fülek háttérszíne. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", - "tabBorder": "A füleket egymástól elválasztó keret színe. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", - "tabActiveBorder": "Az aktív fülek kiemelésére használt keretszín. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", - "tabActiveUnfocusedBorder": "Az aktív fülek kiemelésére használt keretszín egy fókusz nélküli csoportban. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni. ", - "tabActiveForeground": "Az aktív fül előtérszíne az aktív csoportban. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", - "tabInactiveForeground": "Az inaktív fülek előtérszíne az aktív csoportban. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", - "tabUnfocusedActiveForeground": "Az aktív fül előtérszíne egy fókusz nélküli csoportban. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", - "tabUnfocusedInactiveForeground": "Az inaktív fülek előtérszíne egy fókusz nélküli csoportban. A fülek tartalmazzák a szerkesztőablakokat a szerkesztőterületen. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabHoverBackground": "A fülek háttérszíne amikor az egérkurzor fölöttük van. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabUnfocusedHoverBackground": "A fülek háttérszíne egy fókusz nélküli csoportban, amikor az egérkurzor fölötte van. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabBorder": "A füleket egymástól elválasztó keret színe. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabActiveBorder": "Az aktív fülek kiemelésére használt keret színe. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabActiveUnfocusedBorder": "Az aktív fülek kiemelésére használt keret színe egy fókusz nélküli csoportban. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabHoverBorder": "A fülek kiemelésére használt keret színe amikor az egérkurzor fölöttük van. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabUnfocusedHoverBorder": "A fülek kiemelésére használt keret színe egy fókusz nélküli csoportban, amikor az egérkurzor fölöttük van. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabActiveForeground": "Az aktív fül előtérszíne az aktív csoportban. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabInactiveForeground": "Az inaktív fülek előtérszíne az aktív csoportban. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabUnfocusedActiveForeground": "Az aktív fül előtérszíne egy fókusz nélküli csoportban. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", + "tabUnfocusedInactiveForeground": "Az inaktív fülek előtérszíne egy fókusz nélküli csoportban. A fülek tartalmazzák a szerkesztőterületen lévő szerkesztőablakokat. Egy szerkesztőablak-csoportban több fül is megnyitható. Több szerkesztőablak-csoportot is létre lehet hozni.", "editorGroupBackground": "A szerkesztőcsoportok háttérszíne. A szerkesztőcsoportok szerkesztőablakokat tartalmaznak. A háttérszín akkor jelenik meg, ha a szerkesztőcsoportok mozgatva vannak.", "tabsContainerBackground": "A szerkesztőcsoport címsorának háttérszíne, ha a fülek engedélyezve vannak. A szerkesztőcsoportok szerkesztőablakokat tartalmaznak.", "tabsContainerBorder": "A szerkesztőcsoport címsorának keretszíne, ha a fülek engedélyezve vannak. A szerkesztőcsoportok szerkesztőablakokat tartalmaznak.", - "editorGroupHeaderBackground": "A szerkesztőcsoport címsorának keretszíne, ha a fülek le vannak tiltva. A szerkesztőcsoportok szerkesztőablakokat tartalmaznak.", + "editorGroupHeaderBackground": "A szerkesztőcsoportok címsorának keretszíne, ha a fülek le vannak tiltva (`\"workbench.editor.showTabs\": false`). A szerkesztőcsoportok szerkesztőablakokat tartalmaznak.", "editorGroupBorder": "A szerkesztőcsoportokat elválasztó vonal színe. A szerkesztőcsoportok szerkesztőablakokat tartalmaznak.", "editorDragAndDropBackground": "A szerkesztőablakok mozgatásánál használt háttérszín. Érdemes átlátszó színt választani, hogy a szerkesztőablak tartalma továbbra is látszódjon.", "panelBackground": "A panelek háttérszíne. A panelek a szerkesztőterület alatt jelennek meg, és pl. itt található a kimenet és az integrált terminál.", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "Az állapotsort az oldalsávtól és a szerkesztőablakoktól elválasztó keret színe, ha nincs mappa megnyitva. Az állapotsor az ablak alján jelenik meg. ", "statusBarItemActiveBackground": "Az állapotsor elemének háttérszíne kattintás esetén. Az állapotsor az ablak alján jelenik meg.", "statusBarItemHoverBackground": "Az állapotsor elemének háttérszíne, ha az egérkurzor fölötte van. Az állapotsor az ablak alján jelenik meg.", - "statusBarProminentItemBackground": "Az állapotsor kiemelt elemeinek háttérszíne. A kiemelt elemek kitűnnek az állapotsor többi eleme közül, így jelezve a fontosságukat. Az állapotsor az ablak alján jelenik meg.", - "statusBarProminentItemHoverBackground": "Az állapotsor kiemelt elemeinek háttérszíne, ha az egérkurzor fölöttük van. A kiemelt elemek kitűnnek az állapotsor többi eleme közül, így jelezve a fontosságukat. Az állapotsor az ablak alján jelenik meg.", + "statusBarProminentItemBackground": "Az állapotsor kiemelt elemeinek háttérszíne. A kiemelt elemek kitűnnek az állapotsor többi eleme közül, így jelezve a fontosságukat. Kapcsolja be a `Tabulátor billentyűvel mozgatott fókusz` módot a parancskatalógusban egy példa megtekintéséhez! Az állapotsor az ablak alján jelenik meg.", + "statusBarProminentItemHoverBackground": "Az állapotsor kiemelt elemeinek háttérszíne, ha az egérkurzor fölöttük van. A kiemelt elemek kitűnnek az állapotsor többi eleme közül, így jelezve a fontosságukat. Kapcsolja be a `Tabulátor billentyűvel mozgatott fókusz` módot a parancskatalógusban egy példa megtekintéséhez! Az állapotsor az ablak alján jelenik meg.", "activityBarBackground": "A tevékenységsáv háttérszíne. A tevékenységsáv az ablak legszélén jelenik meg bal vagy jobb oldalon, segítségével lehet váltani az oldalsáv nézetei között.", "activityBarForeground": "A tevékenységsáv előtérszíne (pl. az ikonok színe). A tevékenységsáv az ablak legszélén jelenik meg bal vagy jobb oldalon, segítségével lehet váltani az oldalsáv nézetei között.", "activityBarBorder": "A tevékenyésgsáv keretszíne, ami elválasztja az oldalsávtól. A tevékenységsáv az ablak legszélén jelenik meg bal vagy jobb oldalon, segítségével lehet váltani az oldalsáv nézetei között.", diff --git a/i18n/hun/src/vs/workbench/common/views.i18n.json b/i18n/hun/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..52cc050953f --- /dev/null +++ b/i18n/hun/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "Már van `{0}` azonosítójú nézet regisztrálva a következő helyen: `{1}`" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/hun/src/vs/workbench/electron-browser/actions.i18n.json index 8fa88c8859b..2e7a5636a3d 100644 --- a/i18n/hun/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/hun/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "Szerkesztőablak bezárása", "closeWindow": "Ablak bezárása", "closeWorkspace": "Munkaterület bezárása", "noWorkspaceOpened": "Az aktuális példányban nincs egyetlen munkaterület sem nyitva, amit be lehetne zárni.", @@ -52,21 +51,5 @@ "displayLanguage": "Meghatározza a VSCode felületének nyelvét.", "doc": "Az elérhető nyelvek listája a következő címen tekinthető meg: {0}", "restart": "Az érték módosítása után újra kell indítani a VSCode-ot.", - "fail.createSettings": "Nem sikerült a(z) '{0}' létrehozás ({1}).", - "openLogsFolder": "Naplómappa megnyitása", - "showLogs": "Naplók megjelenítése...", - "mainProcess": "Fő", - "sharedProcess": "Megosztott", - "rendererProcess": "Megjelenítő", - "extensionHost": "Kiegészítő gazdafolyamata", - "selectProcess": "Válasszon folyamatot!", - "setLogLevel": "Naplózási szint beállítása", - "trace": "Nyomkövetés", - "debug": "Hibakeresés", - "info": "Információ", - "warn": "Figyelmeztetés", - "err": "Hiba", - "critical": "Kritikus", - "off": "Kikapcsolva", - "selectLogLevel": "Naplózási szint beállítása" + "fail.createSettings": "Nem sikerült a(z) '{0}' létrehozás ({1})." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/hun/src/vs/workbench/electron-browser/main.contribution.i18n.json index ffdce8089b5..e6f6299231e 100644 --- a/i18n/hun/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "Nézet", "help": "Súgó", "file": "Fájl", - "developer": "Fejlesztői", "workspaces": "Munkaterületek", + "developer": "Fejlesztői", + "workbenchConfigurationTitle": "Munkaterület", "showEditorTabs": "Meghatározza, hogy a megnyitott szerkesztőablakok telején megjelenjenek-e a fülek", "workbench.editor.labelFormat.default": "Fájl nevének megjelenítése. Ha a fülek engedélyezve vannak, és két egyező nevű fájl van egy csoportban, az elérési útjuk eltérő része lesz hozzáfűzve a névhez. Ha a fülek le vannak tiltva, a fájl munkaterület könyvtárához képest relatív elérési útja jelenik meg, ha a szerkesztőablak aktív.", "workbench.editor.labelFormat.short": "A fájl nevének megjelenítése a könyvtár nevével együtt.", @@ -20,23 +21,23 @@ "showIcons": "Meghatározza, hogy a megnyitott szerkesztőablakok ikonnal együtt jelenjenek-e meg. A működéshez szükséges egy ikontéma engedélyezése is.", "enablePreview": "Meghatározza, hogy a megnyitott szerkesztőablakok előnézetként jelenjenek-e meg. Az előnézetként használt szerkesztőablakok újra vannak hasznosítva, amíg meg nem tartja őket a felhasználó (pl. dupla kattintás vagy szerkesztés esetén), és dőlt betűvel jelenik meg a címsoruk.", "enablePreviewFromQuickOpen": "Meghatározza, hogy a gyors megnyitás során megnyitott szerkesztőablakok előnézetként jelenjenek-e meg. Az előnézetként használt szerkesztőablakok újra vannak hasznosítva, amíg meg nem tartja őket a felhasználó (pl. dupla kattintás vagy szerkesztés esetén).", + "closeOnFileDelete": "Meghatározza, hogy bezáródjanak-e azok a szerkesztőablakok, melyekben olyan fájl van megnyitva, amelyet töröl vagy átnevez egy másik folyamat. A beállítás letiltása esetén a szerkesztőablak nyitva marad módosított állapotban ilyen esemény után. Megjegyzés: az alkalmazáson belüli törlések esetén mindig bezáródik a szerkesztőablakok, a módosított fájlok pedig soha nem záródnak be, hogy az adatok megmaradjanak.", "editorOpenPositioning": "Meghatározza, hogy hol nyíljanak meg a szerkesztőablakok. A 'left' vagy 'right' használata esetén az aktív szerkesztőablaktól jobbra vagy balra nyílnak meg az újak. 'first' vagy 'last' esetén a szerkesztőablakok a jelenleg aktív ablaktól függetlenül nyílnak meg.", "revealIfOpen": "Meghatározza, hogy egy szerkesztőablak fel legyen-e fedve, ha már meg van nyitva a látható csoportok bármelyiképben. Ha le van tiltva, akkor egy új szerkesztőablak nyílik az aktív szerkesztőablak-csoportban. Ha engedélyezve van, akkor a már megnyitott szerkesztőablak lesz felfedve egy új megnyitása helyett. Megjegyzés: vannak esetek, amikor ez a beállítás figyelmen kívül van hagyva, pl. ha egy adott szerkesztőablak egy konkrét csoportban vagy a jelenleg aktív csoport mellett van menyitva.", + "swipeToNavigate": "Navigálás a nyitott fájlok között háromujjas, vízszintes húzással.", "commandHistory": "Meghatározza, hogy hány legutóbb használt parancs jelenjen meg a parancskatalógus előzményeinek listájában. Az előzmények kikapcsolásához állítsa az értéket nullára.", "preserveInput": "Meghatározza, hogy a legutóbb beírt parancs automatikusan helyre legyen-e állítva a parancskatalógus következő megnyitása során.", "closeOnFocusLost": "Meghatározza, hogy a gyors megnyitás automatikusan bezáródjon-e amint elveszíti a fókuszt.", "openDefaultSettings": "Meghatározza, hogy a beállítások megnyitásakor megnyíljon-e egy szerkesztő az összes alapértelmezett beállítással.", "sideBarLocation": "Meghatározza az oldalsáv helyét. Az oldalsáv megjelenhet a munkaterület bal vagy jobb oldalán.", + "panelDefaultLocation": "Meghatározza a panel alapértelmezett pozícióját. A panel a munkaterület alján vagy jobb oldalán jelenhet meg.", "statusBarVisibility": "Meghatározza, hogy megjelenjen-e az állapotsor a munkaterület alján.", "activityBarVisibility": "Meghatározza, hogy megjelenjen-e a tevékenységsáv a munkaterületen.", - "closeOnFileDelete": "Meghatározza, hogy bezáródjanak-e azok a szerkesztőablakok, melyekben olyan fájl van megnyitva, amelyet töröl vagy átnevez egy másik folyamat. A beállítás letiltása esetén a szerkesztőablak nyitva marad módosított állapotban ilyen esemény után. Megjegyzés: az alkalmazáson belüli törlések esetén mindig bezáródik a szerkesztőablakok, a módosított fájlok pedig soha nem záródnak be, hogy az adatok megmaradjanak.", - "enableNaturalLanguageSettingsSearch": "Meghatározza, hogy engedélyezve van-e a természetes nyelvi keresési mód a beállításoknál.", "fontAliasing": "Meghatározza a munkaterületen megjelenő betűtípusok élsimítási módszerét.\n- default: Szubpixeles betűsimítás. A legtöbb nem-retina típusú kijelzőn ez adja a legélesebb szöveget.\n- antialiased: A betűket pixelek, és nem szubpixelek szintjén simítja. A betűtípus vékonyabbnak tűnhet összességében.\n- none: Letiltja a betűtípusok élsimítését. A szövegek egyenetlen, éles szélekkel jelennek meg.", "workbench.fontAliasing.default": "Szubpixeles betűsimítás. A legtöbb nem-retina típusú kijelzőn ez adja a legélesebb szöveget.", "workbench.fontAliasing.antialiased": "A betűket pixelek, és nem szubpixelek szintjén simítja. A betűtípus vékonyabbnak tűnhet összességében.", "workbench.fontAliasing.none": "Letiltja a betűtípusok élsimítését. A szövegek egyenetlen, éles szélekkel jelennek meg.", - "swipeToNavigate": "Navigálás a nyitott fájlok között háromujjas, vízszintes húzással.", - "workbenchConfigurationTitle": "Munkaterület", + "enableNaturalLanguageSettingsSearch": "Meghatározza, hogy engedélyezve van-e a természetes nyelvi keresési mód a beállításoknál.", "windowConfigurationTitle": "Ablak", "window.openFilesInNewWindow.on": "A fájlok új ablakban nyílnak meg", "window.openFilesInNewWindow.off": "A fájlok abban az ablakban nyílnak meg, ahol a mappájuk meg van nyitva vagy a legutoljára aktív ablakban", diff --git a/i18n/hun/src/vs/workbench/electron-browser/window.i18n.json b/i18n/hun/src/vs/workbench/electron-browser/window.i18n.json index 3f8ae5cf9dd..59e05312870 100644 --- a/i18n/hun/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/hun/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "Kivágás", "copy": "Másolás", "paste": "Beillesztés", - "selectAll": "Összes kijelölése" + "selectAll": "Összes kijelölése", + "runningAsRoot": "Nem ajánlott a {0} 'root'-két futtatása." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.i18n.json b/i18n/hun/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.i18n.json index 1631851aee5..ef8b1ac13eb 100644 --- a/i18n/hun/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "wordWrapMigration.ok": "OK", - "wordWrapMigration.dontShowAgain": "Ne jelenjen meg újra", + "wordWrapMigration.dontShowAgain": "Ne jelenítse meg újra", "wordWrapMigration.openSettings": "Beállítások megnyitása", "wordWrapMigration.prompt": "Az `editor.wrappingColumn` beállítás elavult az `editor.wordWrap` bevezetése miatt." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/hun/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index fa1bc4e164b..c02cc939c66 100644 --- a/i18n/hun/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "A hibakeresési eszköztár háttérszíne." + "debugToolBarBackground": "A hibakeresési eszköztár háttérszíne.", + "debugToolBarBorder": "A hibakeresési eszköztár keretszíne." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/hun/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 8e82d560ff0..9708ac70e9b 100644 --- a/i18n/hun/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "hibakereső", - "debug.terminal.not.available.error": "Az integrált terminál nem elérhető" + "debug.terminal.title": "hibakereső" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index a33718b8e73..b8ed67afeb5 100644 --- a/i18n/hun/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "Új parancssor megnyitása", "globalConsoleActionMacLinux": "Új terminál megnyitása", "scopedConsoleActionWin": "Megnyitás a parancssorban", - "scopedConsoleActionMacLinux": "Megnyitás a terminálban", - "openFolderInIntegratedTerminal": "Megnyitás a terminálban" + "scopedConsoleActionMacLinux": "Megnyitás a terminálban" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/hun/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index a03a32613a6..27e3da174c1 100644 --- a/i18n/hun/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "Ez a kiegészítő a közelmúltban megnyitott fájlok alapján ajánlott.", + "neverShowAgain": "Ne jelenjen meg újra", + "close": "Bezárás", "workspaceRecommendation": "Ez a kiegészítő az aktuális munkaterület felhasználói által ajánlott.", + "fileBasedRecommendation": "Ez a kiegészítő a közelmúltban megnyitott fájlok alapján ajánlott.", "exeBasedRecommendation": "Ez a kiegészítő azért ajánlott, mert a következő telepítve van: {0}.", "reallyRecommended2": "Ehhez a fájltípushoz a(z) '{0}' kiegészítő ajánlott.", "reallyRecommendedExtensionPack": "Ehhez a fájltípushoz a(z) '{0}' kiegészítőcsomag ajánlott.", "showRecommendations": "Ajánlatok megjelenítése", "install": "Telepítés", - "neverShowAgain": "Ne jelenítse meg újra", - "close": "Bezárás", "workspaceRecommended": "A munkaterülethez vannak javasolt kiegészítők", "installAll": "Összes telepítése", "ignoreExtensionRecommendations": "Figyelmen kívül akarja hagyni az összes javasolt kiegészítőt?", diff --git a/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..652267823c8 --- /dev/null +++ b/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "Munkaterület", + "feedbackVisibility": "Meghatározza az állapotsoron megjelenő, visszajelzés tweetelése (mosoly) gomb láthatóságát." +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json b/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json index d2b7c3c88fa..5bf2f90ef1e 100644 --- a/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json @@ -16,6 +16,7 @@ "request a missing feature": "Hiányzó funkció kérése", "tell us why?": "Mondja el, hogy miért", "commentsHeader": "Visszajelzés", + "showFeedback": "Visszajelzésre szolgáló mosoly gomb megjelenítése az állapotsoron", "tweet": "Tweer", "character left": "karakter maradt", "characters left": "karakter maradt", diff --git a/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..d2ae286b72e --- /dev/null +++ b/i18n/hun/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "hide": "Elrejtés" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index d032a29e684..d115d415af9 100644 --- a/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,27 @@ "filesCategory": "Fájl", "revealInSideBar": "Megjelenítés az oldalsávon", "acceptLocalChanges": "A lemezen lévő tartalom felülírása a saját módosításokkal", - "revertLocalChanges": "Saját módosítások elvetése és a lemezen lévő tartalom visszaállítása" + "revertLocalChanges": "Saját módosítások elvetése és a lemezen lévő tartalom visszaállítása", + "copyPathOfActive": "Aktív fájl elérési útjának másolása", + "saveAllInGroup": "Összes mentése a csoportban", + "saveFiles": "Összes fájl mentése", + "revert": "Fájl visszaállítása", + "compareActiveWithSaved": "Aktív fájl összehasonlítása a mentett változattal", + "closeEditor": "Szerkesztőablak bezárása", + "view": "Nézet", + "openToSide": "Megnyitás oldalt", + "revealInWindows": "Megjelenítés a fájlkezelőben", + "revealInMac": "Megjelenítés a Finderben", + "openContainer": "Tartalmazó mappa megnyitása", + "copyPath": "Elérési út másolása", + "saveAll": "Összes mentése", + "compareWithSaved": "Összehasonlítás a mentett változattal", + "compareWithSelected": "Összehasonlítás a kiválasztottal", + "compareSource": "Kijelölés összehasonlításhoz", + "compareSelected": "Kiválasztottak összehasonlítása", + "close": "Bezárás", + "closeOthers": "Többi bezárása", + "closeUnmodified": "Nem módosultak bezárása", + "closeAll": "Összes bezárása", + "deleteFile": "Végleges törlés" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 559fe056a7d..7c5ad91feba 100644 --- a/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "Újrapróbálkozás", - "rename": "Átnevezés", "newFile": "Új fájl", "newFolder": "Új mappa", + "rename": "Átnevezés", + "delete": "Törlés", + "copyFile": "Másolás", + "pasteFile": "Beillesztés", + "retry": "Újrapróbálkozás", "openFolderFirst": "Mappák vagy fájlok létrehozásához először nyisson meg egy mappát!", "newUntitledFile": "Új, névtelen fájl", "createNewFile": "Új fájl", @@ -15,39 +18,32 @@ "deleteButtonLabelRecycleBin": "Áthelyezés a lo&&mtárba", "deleteButtonLabelTrash": "Áthelyezés a &&kukába", "deleteButtonLabel": "&&Törlés", + "dirtyMessageFilesDelete": "Olyan fájlokat készül törölni, amelyek nem mentett változtatásokat tartalmaznak. Folytatja?", "dirtyMessageFolderOneDelete": "Törölni készül egy olyan mappát, melyben egy nem mentett változtatásokat tartalmazó fájl van. Folytatja?", "dirtyMessageFolderDelete": "Törölni készül egy olyan mappát, melyben {0} nem mentett változtatásokat tartalmazó fájl van. Folytatja?", "dirtyMessageFileDelete": "Törölni készül egy olyan fájlt, amely nem mentett változtatásokat tartalmaz. Folytatja?", "dirtyWarning": "A módosítások elvesznek, ha nem menti őket.", + "confirmMoveTrashMessageMultiple": "Törli a következő {0} fájlt?", "confirmMoveTrashMessageFolder": "Törli a(z) '{0}' nevű mappát és a teljes tartalmát?", "confirmMoveTrashMessageFile": "Törli a(z) '{0}' nevű fájlt?", "undoBin": "Helyreállíthatja a lomtárból.", "undoTrash": "Helyreállíthatja a kukából.", "doNotAskAgain": "Ne kérdezze meg újra", - "confirmDeleteMessageFolder": "Törli a(z) {0} mappát és a teljes tartalmát?", - "confirmDeleteMessageFile": "Véglegesen törli a következőt: {0}?", + "confirmDeleteMessageMultiple": "Véglegesen törli a következő {0} fájlt?", + "confirmDeleteMessageFolder": "Törli a(z) '{0}' nevű mappát és annak teljes tartalmát? ", + "confirmDeleteMessageFile": "Véglegesen törli a(z) '{0}' nevű fájlt?", "irreversible": "A művelet nem vonható vissza!", "permDelete": "Végleges törlés", - "delete": "Törlés", "importFiles": "Fájlok importálása", "confirmOverwrite": "A célmappában már van ilyen nevű mappa vagy fájl. Le szeretné cserélni?", "replaceButtonLabel": "&&Csere", - "copyFile": "Másolás", - "pasteFile": "Beillesztés", + "fileDeleted": "A fájl időközben törölve lett vagy át lett helyezve", + "fileIsAncestor": "A másolandó fájl a célmappa szülője", "duplicateFile": "Duplikálás", - "openToSide": "Megnyitás oldalt", - "compareSource": "Kijelölés összehasonlításhoz", "globalCompareFile": "Aktív fájl összehasonlítása...", "openFileToCompare": "Fájlok összehasonlításához elősször nyisson meg egy fájlt.", - "compareWith": "'{0}' összehasonlítása a következővel: '{1}'", - "compareFiles": "Fájlok összehasonlítása", "refresh": "Frissítés", - "save": "Mentés", - "saveAs": "Mentés másként...", - "saveAll": "Összes mentése", "saveAllInGroup": "Összes mentése a csoportban", - "saveFiles": "Összes fájl mentése", - "revert": "Fájl visszaállítása", "focusOpenEditors": "Váltás a megnyitott szerkesztőablakok nézetre", "focusFilesExplorer": "Váltás a fájlkezelőre", "showInExplorer": "Aktív fájl megjelenítése az oldalsávon", @@ -56,20 +52,11 @@ "refreshExplorer": "Fájlkezelő frissítése", "openFileInNewWindow": "Aktív fájl megnyitása új ablakban", "openFileToShowInNewWindow": "Fájl új ablakban történő megnyitásához először nyisson meg egy fájlt", - "revealInWindows": "Megjelenítés a fájlkezelőben", - "revealInMac": "Megjelenítés a Finderben", - "openContainer": "Tartalmazó mappa megnyitása", - "revealActiveFileInWindows": "Aktív fájl megjelenítése a Windows Intézőben", - "revealActiveFileInMac": "Aktív fájl megjelenítése a Finderben", - "openActiveFileContainer": "Aktív fájlt tartalmazó mappa megnyitása", "copyPath": "Elérési út másolása", - "copyPathOfActive": "Aktív fájl elérési útjának másolása", "emptyFileNameError": "Meg kell adni egy fájl vagy mappa nevét.", "fileNameExistsError": "Már létezik **{0}** nevű fájl vagy mappa ezen a helyszínen. Adjon meg egy másik nevet!", "invalidFileNameError": "A(z) **{0}** név nem érvényes fájl- vagy mappanév. Adjon meg egy másik nevet!", "filePathTooLongError": "A(z) **{0}** név egy olyan elérési utat eredményez, ami túl hosszú. Adjon meg egy másik nevet!", - "compareWithSaved": "Aktív fájl összehasonlítása a mentett változattal", - "modifiedLabel": "{0} (a lemezen) ↔ {1}", "compareWithClipboard": "Aktív fájl összehasonlítása a vágólap tartalmával", "clipboardComparisonLabel": "Vágólap ↔ {0}" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index dd9057b1fa4..57192b1bc98 100644 --- a/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "Fájlok elérési útjának másolásához elősször nyisson meg egy fájlt", - "openFileToReveal": "Fájlok felfedéséhez elősször nyisson meg egy fájlt" + "revealInWindows": "Megjelenítés a fájlkezelőben", + "revealInMac": "Megjelenítés a Finderben", + "openContainer": "Tartalmazó mappa megnyitása", + "saveAs": "Mentés másként...", + "save": "Mentés", + "saveAll": "Összes mentése", + "removeFolderFromWorkspace": "Mappa eltávolítása a munkaterületről", + "genericRevertError": "Nem sikerült a(z) '{0}' visszaállítása: {1}", + "modifiedLabel": "{0} (a lemezen) ↔ {1}", + "openFileToReveal": "Fájlok felfedéséhez elősször nyisson meg egy fájlt", + "openFileToCopy": "Fájlok elérési útjának másolásához elősször nyisson meg egy fájlt" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 22341f239a2..c8272df7913 100644 --- a/i18n/hun/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,7 @@ "editorConfigurationTitle": "Szerkesztőablak", "formatOnSave": "Fájlok formázása mentéskor. Az adott nyelvhez rendelkezésre kell állni formázónak, nem lehet beállítva automatikus mentés, és a szerkesztő nem állhat éppen lefelé.", "explorerConfigurationTitle": "Fájlkezelő", - "openEditorsVisible": "A megnyitott szerkesztőablakok panelen megjelenített szerkesztőablakok száma. Állítsa 0-ra, ha el szeretné rejteni a panelt.", - "dynamicHeight": "Meghatározza, hogy a megnyitott szerkesztőablakok szakasz magassága automatikusan illeszkedjen a megnyitott elemek számához vagy sem.", + "openEditorsVisible": "A megnyitott szerkesztőablakok panelen megjelenített szerkesztőablakok száma.", "autoReveal": "Meghatározza, hogy a fájlkezelőben automatikusan fel legyenek fedve és ki legyenek jelölve a fájlok, amikor megnyitják őket.", "enableDragAndDrop": "Meghatározza, hogy a fájlkezelőben áthelyezhetők-e a fájlok és mappák húzással.", "confirmDragAndDrop": "Meghatározza, hogy a fájlkezelő kérjen-e megerősítést fájlok és mappák húzással történő áthelyezése esetén.", diff --git a/i18n/hun/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/hun/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 0bb33fdc628..da61a7106fd 100644 --- a/i18n/hun/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,14 @@ // Do not edit this file. It is machine generated. { "userGuide": "Használja a jobbra lévő szerkesztői eszköztáron található műveleteket a saját módosítások **visszavonására** vagy **írja felül** a lemezen lévő tartalmat a változtatásokkal", - "discard": "Elvetés", + "overwriteElevated": "Felülírás rendszergazdaként...", + "saveElevated": "Újrapróbálkozás rendszergazdaként...", "overwrite": "Felülírás", "retry": "Újrapróbálkozás", - "readonlySaveError": "Nem sikerült menteni a(z) '{0}' fájlt: a fájl írásvédett. Válassza a 'Felülírás' lehetőséget a védelem eltávolításához.", + "discard": "Elvetés", + "readonlySaveErrorAdmin": "Nem sikerült menteni a(z) '{0}' fájlt: a fájl írásvédett. Válassza a 'Felülírás rendszergazdaként' lehetőséget a védelem eltávolításához!", + "readonlySaveError": "Nem sikerült menteni a(z) '{0}' fájlt: a fájl írásvédett. Válassza a 'Felülírás' lehetőséget a védelem eltávolításának megkísérléséhez!", + "permissionDeniedSaveError": "Nem sikerült menteni a(z) '{0}' fájlt: nincs megfelelő jogosultság. Válassza az 'Újrapróbálkozás rendszergazdaként' lehetőséget az újrapróbálkozáshoz adminisztrátorként!", "genericSaveError": "Hiba a(z) '{0}' mentése közben: {1}", "staleSaveError": "Nem sikerült menteni a(z) '{0}' fájlt: a lemezen lévő tartalom újabb. Kattintson az **Összehasonlítás*** gombra a helyi és a lemezen lévő változat összehasonlításához.", "compareChanges": "Összehasonlítás", diff --git a/i18n/hun/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json b/i18n/hun/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json index e00a7141ecf..a171c2f9995 100644 --- a/i18n/hun/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json @@ -10,7 +10,8 @@ "dropFolder": "Szeretné hozzáadni a mappát a munkaterülethez?", "addFolders": "Mappák hozzá&&adása", "addFolder": "Mappa hozzá&&adása", - "confirmMove": "Biztosan át szeretné helyezni a következőt: '{0}'?", + "confirmMultiMove": "Át szeretné helyezni a következő {0} fájlt?", + "confirmMove": "Át szeretné helyezni a(z) '{0}' nevű fájlt?", "doNotAskAgain": "Ne kérdezze meg újra", "moveButtonLabel": "&&Áthelyezés", "confirmOverwriteMessage": "A célmappában már létezik '{0}' nevű elem. Le szeretné cserélni?", diff --git a/i18n/hun/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/hun/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index 99cf9cb13e7..4e9c224f2c9 100644 --- a/i18n/hun/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "Megnyitott szerkesztőablakok", "openEditosrSection": "Megnyitott szerkesztőablakok szakasz", - "dirtyCounter": "{0} nincs mentve", - "saveAll": "Összes mentése", - "closeAllUnmodified": "Nem módosultak bezárása", - "closeAll": "Összes bezárása", - "compareWithSaved": "Összehasonlítás a mentett változattal", - "close": "Bezárás", - "closeOthers": "Többi bezárása" + "dirtyCounter": "{0} nincs mentve" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..a647b02e9cb --- /dev/null +++ b/i18n/hun/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "mainLog": "Napló (elsődleges)", + "sharedLog": "Napló (megosztott)", + "rendererLog": "Napló (ablak)", + "extensionsLog": "Napló (kiegészítő gazdafolyamata)", + "developer": "Fejlesztői" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/hun/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..fde9c01e66f --- /dev/null +++ b/i18n/hun/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "Naplómappa megnyitása", + "showLogs": "Naplók megjelenítése...", + "mainProcess": "Elsődleges", + "sharedProcess": "Megosztott", + "rendererProcess": "Ablak", + "extensionHost": "Kiegészítő gazdafolyamata", + "selectProcess": "Válasszon folyamatot!", + "openLogFile": "Naplófájl megnyitása...", + "setLogLevel": "Naplózási szint beállítása", + "trace": "Nyomkövetés", + "debug": "Hibakeresés", + "info": "Információ", + "warn": "Figyelmeztetés", + "err": "Hiba", + "critical": "Kritikus", + "off": "Kikapcsolva", + "selectLogLevel": "Naplózási szint beállítása" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/hun/src/vs/workbench/parts/markers/common/messages.i18n.json index 1ecd95e356c..12347f91b9e 100644 --- a/i18n/hun/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "viewCategory": "Nézet", - "problems.view.toggle.label": "Problémák be- és kikapcsolása", - "problems.view.focus.label": "Váltás a problémákra", + "problems.view.toggle.label": "Problémák be- és kikapcsolása (hiba, figyelmeztetés, információ)", + "problems.view.focus.label": "Váltás a problémákra (hiba, figyelmeztetés, információ)", "problems.panel.configuration.title": "Problémák-nézet", "problems.panel.configuration.autoreveal": "Meghatározza, hogy a problémák nézet automatikusan felfedje-e a fájlokat, amikor megnyitja őket.", "markers.panel.title.problems": "Problémák", diff --git a/i18n/hun/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..5cbaa37bf16 --- /dev/null +++ b/i18n/hun/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "Kimenet", + "logViewer": "Naplófájl-megjelenítő", + "viewCategory": "Nézet", + "clearOutput.label": "Kimenet törlése" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/hun/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..c164d86f883 --- /dev/null +++ b/i18n/hun/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "{0} – Kimenet", + "channel": "A(z) '{0}' kimeneti csatornája" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json b/i18n/hun/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json index 5f23e1e85aa..878fe224656 100644 --- a/i18n/hun/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json @@ -17,6 +17,7 @@ "resetLabel": "Billentyűparancs visszaállítása", "showConflictsLabel": "Konfliktusok megjelenítése", "copyLabel": "Másolás", + "copyCommandLabel": "Parancs másolása", "error": "'{0}' hiba a billentyűparancsok szerkesztése közben. Nyissa meg a 'keybindings.json' fájlt, és ellenőrizze!", "command": "Parancs", "keybinding": "Billentyűparancs", diff --git a/i18n/hun/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json b/i18n/hun/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json index 9b9670df23c..dd151493ad8 100644 --- a/i18n/hun/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json @@ -11,6 +11,8 @@ "oneSettingFound": "1 illeszkedő beállítás", "settingsFound": "{0} illeszkedő beállítás", "totalSettingsMessage": "Összesen {0} beállítás", + "nlpResult": "Természetes nyelvi keresés eredményei", + "filterResult": "Szűrt találatok", "defaultSettings": "Alapértelmezett beállítások", "defaultFolderSettings": "Alapértelmezett mappabeállítások", "defaultEditorReadonly": "A jobb oldalon lévő szerkesztőablak tartalmának módosításával írhatja felül az alapértelmezett beállításokat.", diff --git a/i18n/hun/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/hun/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index ef9a96afe7b..3a1caa89fed 100644 --- a/i18n/hun/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "Próbálja ki a természetes nyelvi keresést!", "defaultSettings": "A jobb oldalon lévő szerkesztőablakban elhelyezett beállítások felülírják az alapértelmezett beállításokat.", "noSettingsFound": "Beállítás nem található.", "settingsSwitcherBarAriaLabel": "Beállításkapcsoló", "userSettings": "Felhasználói beállítások", "workspaceSettings": "Munkaterület-beállítások", - "folderSettings": "Mappabeálíltások", - "enableFuzzySearch": "Természetes nyelvi keresés engedélyezése" + "folderSettings": "Mappabeálíltások" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/hun/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index 1fd4f23c9d2..35cc39622d0 100644 --- a/i18n/hun/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "Gyakran használt", - "mostRelevant": "Legfontosabb", "defaultKeybindingsHeader": "A billentyűparancsok fájlban elhelyezett billentyűparancsok felülírják az alapértelmezett beállításokat" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index 7e61210cdf7..cd538504f47 100644 --- a/i18n/hun/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "Nézet", "commandsHandlerDescriptionDefault": "Parancsok megjelenítése és futtatása", "gotoLineDescriptionMac": "Sor megkeresése", "gotoLineDescriptionWin": "Sor megkeresése", diff --git a/i18n/hun/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index 4f8b481dc00..39ce0536498 100644 --- a/i18n/hun/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,9 @@ "toggleGitViewlet": "Git megjelenítése", "source control": "Verziókezelő rendszer", "toggleSCMViewlet": "Verziókezelő megjelenítése", - "view": "Nézet" + "view": "Nézet", + "scmConfigurationTitle": "VKR (SCM)", + "alwaysShowProviders": "Mindig megjelenjen-e a verziókezelő rendszerek szakasz.", + "diffDecorations": "Vezérli a szerkesztőablakban megjelenő, változásokat jelölő dekorátorokat.", + "inputCounter": "Meghatározza, hogy mikor jelenjen meg a bemeneti karakterszámláló." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json b/i18n/hun/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json index 821a91e9b57..aa865d6ba59 100644 --- a/i18n/hun/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json @@ -6,6 +6,9 @@ { "scm providers": "Verziókezelő rendszerek", "hideRepository": "Elrejtés", + "commitMessageInfo": "{0} karakter a jelenlegi sorban", + "commitMessageCountdown": "{0} karakter maradt az aktuális sorban", + "commitMessageWarning": " {0} karakterrel több, mint {1} az aktuális sorban", "installAdditionalSCMProviders": "További verziókezelő rendszerek telepítése...", "no open repo": "Nincs aktív verziókezelő rendszer.", "source control": "Verziókezelő rendszer", diff --git a/i18n/hun/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/hun/src/vs/workbench/parts/search/browser/searchActions.i18n.json index 9f5f0bf4d8b..ce4480e2eb9 100644 --- a/i18n/hun/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "Előző keresőkifejezés megjelenítése", "showSearchViewlet": "Keresés megjelenítése", "findInFiles": "Keresés a fájlokban", - "findInFilesWithSelectedText": "Keresés a fájlokban a kijelölt szöveg alapján", "replaceInFiles": "Csere a fájlokban", - "replaceInFilesWithSelectedText": "Csere a fájlokban a kijelölt szöveg alapján", "RefreshAction.label": "Frissítés", "CollapseDeepestExpandedLevelAction.label": "Összes bezárása", "ClearSearchResultsAction.label": "Törlés", diff --git a/i18n/hun/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index e1fb57e6aa6..9cd24f4c872 100644 --- a/i18n/hun/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "Keresés mappában...", + "findInWorkspace": "Keresés a munkaterületen...", "showTriggerActions": "Szimbólum megkeresése a munkaterületen...", "name": "Keresés", "search": "Keresés", + "showSearchViewlet": "Keresés megjelenítése", "view": "Nézet", + "findInFiles": "Keresés a fájlokban", "openAnythingHandlerDescription": "Fájl megkeresése", "openSymbolDescriptionNormal": "Szimbólum megkeresése a munkaterületen", "searchOutputChannelTitle": "Keresés", @@ -18,5 +22,6 @@ "useRipgrep": "Meghatározza, hogy a szövegben és fájlokban való kereséshez a ripgrep van-e használva.", "useIgnoreFiles": "Meghatározza, hogy a .gitignore és .ignore fájlok használva legyenek-e a kereséshez.", "search.quickOpen.includeSymbols": "Meghatározza, hogy a fájlok gyors megnyitásánál megjelenjenek-e a globális szimbólumkereső találatai.", - "search.followSymlinks": "Meghatározza, hogy keresés során követve legyenek-e a szimbolikus linkek." + "search.followSymlinks": "Meghatározza, hogy keresés során követve legyenek-e a szimbolikus linkek.", + "search.smartCase": "Figyelmen kívül hagyja a kis- és nagybetűket, ha a minta csak kisbetűkből áll, ellenkező esetben kis- és nagybetűérzékenyen keres" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..4d54491cc1e --- /dev/null +++ b/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.scope": "(globális)", + "global.1": "(({0})", + "new.global": "Új globális kódrészlet-fájl...", + "group.global": "Létező kódrészletek", + "new.global.sep": "Új kódrészletek", + "openSnippet.pickLanguage": "Válasszon hozzon létre egy kódrészlet-fájlt!", + "openSnippet.label": "Felhasználói kódrészletek konfigurálása", + "preferences": "Beállítások" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 12f3a6365e8..61cbea48eca 100644 --- a/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,13 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "Kódrészlet nyelvének kiválasztása", - "openSnippet.errorOnCreate": "A(z) {0} nem hozható létre", - "openSnippet.label": "Felhasználói kódrészletek megnyitása", - "preferences": "Beállítások", "snippetSchema.json.default": "Üres kódrészlet", "snippetSchema.json": "Felhasználói kódrészlet-konfiguráció", "snippetSchema.json.prefix": "A kódrészlet IntelliSense-ben történő kiválasztásánál használt előtag", "snippetSchema.json.body": "A kódrészlet tartalma. Kurzorpozíciók definiálásához használja a '$1' és '${1:defaultText}' jelölőket, a '$0' pedig a végső kurzorpozíció. Változónevek a '${varName}' és '${varName:defaultText}' formában definiálhatók, pl.: 'Ez a fájl: $TM_FILENAME'.", - "snippetSchema.json.description": "A kódrészlet leírása" + "snippetSchema.json.description": "A kódrészlet leírása", + "snippetSchema.json.scope": "Azok nyelvek nevei, amelyekhez a kódrészlet tartozik, pl. 'typescript,javascript'." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..ac8bcd025bd --- /dev/null +++ b/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "Felhasználói kódrészlet" +} \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index b86aeaf6994..3931f7acd24 100644 --- a/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "Ismeretlen nyelv található a következőben: `contributes.{0}.language`. A megadott érték: {1}", "invalid.path.0": "Hiányzó karakterlánc a `contributes.{0}.path`-ban. A megadott érték: {1}", + "invalid.language.0": "Nyelv elhagyása esetén a `contributes.{0}.path` értékének egy `.code-snippets`-fájlnak kell lennie. A megadott érték: {1}", + "invalid.language": "Ismeretlen nyelv található a következőben: `contributes.{0}.language`. A megadott érték: {1}", "invalid.path.1": "A `contributes.{0}.path` ({1}) nem a kiegészítő mappáján belül található ({2}). Emiatt előfordulhat, hogy a kiegészítő nem lesz hordozható.", "vscode.extension.contributes.snippets": "Kódrészleteket szolgáltat.", "vscode.extension.contributes.snippets-language": "Azon nyelv azonosítója, amely számára szolgáltatva van ez a kódrészlet.", "vscode.extension.contributes.snippets-path": "A kódrészlet-fájl elérési útja. Az elérési út relatív a kiegészítő mappájához, és általában a következővel kezdődik: './snippets/',", "badVariableUse": "A(z) '{0}' kiegészítőben egy vagy több kódrészlet nagy valószínűséggel keveri a kódrészletváltozók és a kódrészlet-helyjelölők fogalmát (további információ a következő oldalon található: https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax)", "badFile": "A(z) \"{0}\" kódrészletet tartalmazó fájlt nem sikerült beolvasni.", - "source.snippet": "Felhasználói kódrészlet", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index 4d4b7d5d7cf..525d9caef57 100644 --- a/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -13,7 +13,8 @@ "terminal.integrated.shellArgs.osx": "OS X-terminál esetén használt parancssori argumentumok.", "terminal.integrated.shell.windows": "A terminál által használt shell elérési útja Windowson. A Windows beépített shelljei (cmd, PowerShell vagy Bash on Ubuntu) használata esetén kell megadni.", "terminal.integrated.shellArgs.windows": "Windows-terminál esetén használt parancssori argumentumok.", - "terminal.integrated.rightClickCopyPaste": "Ha be van állítva, megakadályozza a helyi menü megjelenését a terminálon történő jobb kattintás esetén. Helyette másol, ha van kijelölés, és beilleszt, ha nincs.", + "terminal.integrated.rightClickCopyPaste": "Ha be van kapcsolva, megakadályozza, hogy megjelenjen a helyi menü a terminálon történő jobb kattintás esetén. Ehelyett másol, ha van kijelölés, és beilleszt, ha nincs.", + "terminal.integrated.copyOnSelection": "Ha be van kapcsolva, a terminálban kijelölt szöveg a vágólapra lesz másolva.", "terminal.integrated.fontFamily": "Meghatározza a terminál betűtípusát. Alapértelmezett értéke az editor.fontFamily értéke.", "terminal.integrated.fontSize": "Meghatározza a terminálban használt betű méretét, pixelekben.", "terminal.integrated.lineHeight": "Meghatározza a terminál sormagasságát. A tényleges méret a megadott szám és a terminál betűméretének szorzatából jön ki.", @@ -24,10 +25,12 @@ "terminal.integrated.setLocaleVariables": "Meghatározza, hogy a lokálváltozók be vannak-e állítva a terminál indításánál. Alapértelmezett értéke igaz OS X-en, hamis más platformokon.", "terminal.integrated.cwd": "Explicit elérési út, ahol a terminál indítva lesz. Ez a shellfolyamat munkakönyvtára (cwd) lesz. Ez a beállítás nagyon hasznos olyan munkaterületeken, ahol a gyökérkönyvtár nem felel meg munkakönyvtárnak.", "terminal.integrated.confirmOnExit": "Meghatározza, hogy megerősítést kér-e az alkalamzás, ha van aktív terminál-munkafolyamat.", + "terminal.integrated.enableBell": "Meghatározza, hogy engedélyezve van-e a csengő a terminálba.", "terminal.integrated.commandsToSkipShell": "Olyan parancsazonosítók listája, melyek nem lesznek elküldve a shellnek, és ehelyett mindig a Code kezeli le őket. Ez lehetővé teszi, hogy az olyan billentyűparancsok, melyeket normál esetben a shell dolgozna fel, ugyanúgy működjenek, mint mikor a terminálon nincs fókusz. Például ilyen a gyorsmegnyitás indításához használt Ctrl+P.", "terminal.integrated.env.osx": "A VS Code folyamatához hozzáadott környezeti változókat tartalmazó objektum, amit az OS X-es terminál használ.", "terminal.integrated.env.linux": "A VS Code folyamatához hozzáadott környezeti változókat tartalmazó objektum, amit a linuxos terminál használ.", "terminal.integrated.env.windows": "A VS Code folyamatához hozzáadott környezeti változókat tartalmazó objektum, amit a windowsos terminál használ.", + "terminal.integrated.showExitAlert": "A `A terminálfolyamat a következő kilépési kóddal állt le` üzenet megjelenítése, ha a kilépési kód nem nulla.", "terminalCategory": "Terminál", "viewCategory": "Nézet" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json b/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json index c671a91c989..8f1350c0d3c 100644 --- a/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json @@ -14,6 +14,8 @@ "workbench.action.terminal.deleteWordRight": "Jobbra lévő szó törlése", "workbench.action.terminal.new": "Új integrált terminál létrehozása", "workbench.action.terminal.new.short": "Új terminál", + "workbench.action.terminal.newWorkspacePlaceholder": "Az aktuális munkakönyvtár kiválasztása az új terminálhoz", + "workbench.action.terminal.newInActiveWorkspace": "Új integrált terminál létrehozása (az aktív munkaterületen)", "workbench.action.terminal.focus": "Váltás a terminálra", "workbench.action.terminal.focusNext": "Váltás a következő terminálra", "workbench.action.terminal.focusPrevious": "Váltás az előző terminálra", diff --git a/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json b/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json index 3471cfec5dc..ff1983f42c6 100644 --- a/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json @@ -9,5 +9,5 @@ "terminalCursor.foreground": "A terminál kurzorának előtérszíne.", "terminalCursor.background": "A terminál kurzorának háttérszíne. Lehetővé teszik az olyan karakterek színének módosítását, amelyek fölött egy blokk-típusú kurzor áll.", "terminal.selectionBackground": "A terminálban kijelölt tartalom háttérszíne.", - "terminal.ansiColor": "A(z) '{0}' ANSI-szín a terminálban." + "terminal.ansiColor": "'{0}' ANSI-szín a terminálban." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index 45f5c16180a..1a4fb7a15a1 100644 --- a/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,7 @@ "terminal.integrated.chooseWindowsShellInfo": "Megváltoztathatja az alapértelmezett terminált a testreszabás gomb választásával.", "customize": "Testreszabás", "cancel": "Mégse", - "never again": "Rendben, ne jelenítse meg újra", + "never again": "Rendben, ne jelenjen meg újra", "terminal.integrated.chooseWindowsShell": "Válassza ki a preferált terminál shellt! Ez később módosítható a beállításokban.", "terminalService.terminalCloseConfirmationSingular": "Van egy aktív terminálmunkamenet. Szeretné megszakítani?", "terminalService.terminalCloseConfirmationPlural": "{0} aktív terminálmunkamenet van. Szeretné megszakítani?" diff --git a/i18n/hun/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/hun/src/vs/workbench/parts/update/electron-browser/update.i18n.json index 79c64944348..6315a5d17bd 100644 --- a/i18n/hun/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/hun/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -13,7 +13,7 @@ "read the release notes": "Üdvözöljük a {0} v{1} verziójában. Szeretné megtekinteni a kiadási jegyzéket?", "licenseChanged": "A licencfeltételek változtak. Olvassa végig!", "license": "Licenc elolvasása", - "neveragain": "Soha ne jelenítse meg újra", + "neveragain": "Ne jelenítse meg újra", "64bitisavailable": "Elérhető a {0} 64-bites Windowsra készült változata!", "learn more": "További információ", "updateIsReady": "Új {0}-frissítés érhető el.", @@ -23,6 +23,7 @@ "commandPalette": "Parancskatalógus...", "settings": "Beállítások", "keyboardShortcuts": "Billentyűparancsok", + "userSnippets": "Felhasználói kódrészletek", "selectTheme.label": "Színtéma", "themes.selectIconTheme.label": "Fájlikontéma", "not available": "A frissítések nem érhetők el", diff --git a/i18n/hun/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/hun/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index f77948f5276..e2deab2db4e 100644 --- a/i18n/hun/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/hun/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "A fájl egy könyvtár", + "fileNotModifiedError": "A fájl azóta nem módosult", "fileBinaryError": "A fájl binárisnak tűnik és nem nyitható meg szövegként" } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/services/files/node/fileService.i18n.json b/i18n/hun/src/vs/workbench/services/files/node/fileService.i18n.json index 91ce4d8f750..fcbe399cbac 100644 --- a/i18n/hun/src/vs/workbench/services/files/node/fileService.i18n.json +++ b/i18n/hun/src/vs/workbench/services/files/node/fileService.i18n.json @@ -10,6 +10,7 @@ "fileTooLargeError": "A fájl túl nagy a megnyitáshoz", "fileNotFoundError": "Fájl nem található ({0})", "fileBinaryError": "A fájl binárisnak tűnik és nem nyitható meg szövegként", + "filePermission": "Engedély megtagadva a fájl írására ({0})", "fileExists": "A létrehozandó fájl már létezik ({0})", "fileMoveConflict": "Nem lehet áthelyezni vagy másolni. A fájl már létezik a célhelyen.", "unableToMoveCopyError": "Nem lehet áthelyezni vagy másolni. A fájl felülírná a mappát, amiben található.", diff --git a/i18n/hun/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json b/i18n/hun/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json index 6928f2f1935..38b057d0682 100644 --- a/i18n/hun/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json +++ b/i18n/hun/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json @@ -22,5 +22,6 @@ "keybindings.json.when": "A billentyűparancs aktiválási feltétele.", "keybindings.json.args": "A végrehajtandó parancs számára átadott argumentumok", "keyboardConfigurationTitle": "Billentyűzet", - "dispatch": "Meghatározza, hogy a billentyűleütések észleléséhez a `code` (ajánlott) vagy `keyCode` esemény legyen használva." + "dispatch": "Meghatározza, hogy a billentyűleütések észleléséhez a `code` (ajánlott) vagy `keyCode` esemény legyen használva.", + "touchbar.enabled": "Ha elérhető, engedélyezi a macOS érintősávgombokat a billentyűzeten." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/hun/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index a411a51ba59..5a0ddc8c042 100644 --- a/i18n/hun/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/hun/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "Szeretné menteni a(z) {0} fájlban elvégzett módosításokat?", "saveChangesMessages": "Szeretné menteni a következő {0} fájlban elvégzett módosításokat?", - "moreFile": "...1 további fájl nincs megjelenítve", - "moreFiles": "...{0} további fájl nincs megjelenítve", "saveAll": "Ö&&sszes mentése", "save": "Menté&&s", "dontSave": "&&Ne mentse", diff --git a/i18n/hun/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/hun/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index d67776bc433..afe4cf7833a 100644 --- a/i18n/hun/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/hun/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "Nincsenek fájlikonok", "iconThemeError": "A fájlikontéma ismeretlen vagy nincs telepítve.", "workbenchColors": "Felülírja az aktuális színtémában definiált színeket.", - "editorColors": "Felülírja az aktuális színtémában definiált, szerkesztőablakhoz kapcsolódó színeket és betűstílusokat.", "editorColors.comments": "Meghatározza a megjegyzések színét és stílusát.", "editorColors.strings": "Meghatározza a sztringliterálok színét és stílusát.", "editorColors.keywords": "Meghatározza a kulcsszavak színét és stílusát.", @@ -19,5 +18,6 @@ "editorColors.types": "Meghatározza a típusdeklarációk és -referenciák színét és stílusát.", "editorColors.functions": "Meghatározza a függvénydeklarációk és -referenciák színét és stílusát.", "editorColors.variables": "Meghatározza a változódeklarációk és -referenciák színét és stílusát.", - "editorColors.textMateRules": "Színek és stílusok beállítása textmate témázási szabályok alapján (haladó)." + "editorColors.textMateRules": "Színek és stílusok beállítása textmate témázási szabályok alapján (haladó).", + "editorColors": "Felülírja az aktuális színtémában definiált, szerkesztőablakhoz kapcsolódó színeket és betűstílusokat." } \ No newline at end of file diff --git a/i18n/hun/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/hun/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 068445ae82b..3c7eb68f49e 100644 --- a/i18n/hun/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/hun/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "Nem sikerült írni a munkaterület konfigurációs fájljába. Nyissa meg a fájlt, javítsa a benne található hibákat és figyelmeztetéseket, majd próbálja újra!", "errorWorkspaceConfigurationFileDirty": "Nem sikerült írni a munkaterület konfigurációs fájljába, mert módosítva lett. Mentse, majd próbálja újra!", "openWorkspaceConfigurationFile": "Munkaterület konfigurációs fájljának megnyitása", - "close": "Bezárás", - "enterWorkspace.close": "Bezárás", - "enterWorkspace.dontShowAgain": "Ne jelenítse meg újra", - "enterWorkspace.moreInfo": "További információ", - "enterWorkspace.prompt": "Tudjon meg többet arról, hogyan dolgozhat egyszerre több mappával a VS Code-ban!" + "close": "Bezárás" } \ No newline at end of file diff --git a/i18n/ita/extensions/git/out/autofetch.i18n.json b/i18n/ita/extensions/git/out/autofetch.i18n.json index b51df7e140d..96f76ecafff 100644 --- a/i18n/ita/extensions/git/out/autofetch.i18n.json +++ b/i18n/ita/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "Sì", + "read more": "Altre informazioni", "no": "No", - "not now": "Non ora", - "suggest auto fetch": "Vorresti attivare il fetching automatico di repository Git?" + "not now": "Chiedimelo in seguito", + "suggest auto fetch": "Desideri che Code esegua `git fetch` periodicamente?" } \ No newline at end of file diff --git a/i18n/ita/extensions/git/out/commands.i18n.json b/i18n/ita/extensions/git/out/commands.i18n.json index b544cb5ca24..167af56bf54 100644 --- a/i18n/ita/extensions/git/out/commands.i18n.json +++ b/i18n/ita/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\nQuesta operazione è IRREVERSIBILE. Il working set corrente andrà PERSO PER SEMPRE.", "yes discard tracked": "Rimuovi 1 file di cui viene tenuta traccia", "yes discard tracked multiple": "Rimuovi {0} file di cui viene tenuta traccia", + "unsaved files single": "Il seguente file non è stato salvato: {0}\n\nVuoi salvarlo prima di eseguirne il commit? ", + "unsaved files": "Ci sono {0} file non ancora salvati.\n\nVuoi salvarli prima di eseguirne il commit? ", + "save and commit": "Salva tutto & esegui Commit", + "commit": "Esegui il Commit comunque", "no staged changes": "Non ci sono modifiche in stage di cui eseguire il commit.\n\nSI desidera mettere in stage automaticamente tutte le modifiche ed eseguirne il commit direttamente?", "always": "Sempre", "no changes": "Non ci sono modifiche di cui eseguire il commit.", @@ -64,12 +68,12 @@ "no remotes to pull": "Il repository non contiene elementi remoti configurati come origini del pull.", "pick remote pull repo": "Selezionare un repository remoto da cui effettuare il pull del ramo", "no remotes to push": "Il repository non contiene elementi remoti configurati come destinazione del push.", - "push with tags success": "Il push con tag è riuscito.", "nobranch": "Estrarre un ramo per eseguire il push in un elemento remoto.", + "confirm publish branch": "La branch '{0}' non ha una branch corrispondente a monte. Desideri pubblicarla?", + "ok": "OK", + "push with tags success": "Il push con tag è riuscito.", "pick remote": "Selezionare un repository remoto in cui pubblicare il ramo '{0}':", "sync is unpredictable": "Questa azione consentirà di effettuare il push e il pull di commit da e verso '{0}'.", - "ok": "OK", - "never again": "OK, non visualizzare più", "no remotes to publish": "Il repository non contiene elementi remoti configurati come destinazione della pubblicazione.", "no changes stash": "Non ci sono modifiche da accantonare.", "provide stash message": "Specificare un messaggio di accantonamento (facoltativo)", diff --git a/i18n/ita/extensions/git/package.i18n.json b/i18n/ita/extensions/git/package.i18n.json index 9e6cd77fdcb..5d58b8449e0 100644 --- a/i18n/ita/extensions/git/package.i18n.json +++ b/i18n/ita/extensions/git/package.i18n.json @@ -54,12 +54,12 @@ "command.stashPopLatest": "Preleva accantonamento più recente", "config.enabled": "Indica se GIT è abilitato", "config.path": "Percorso dell'eseguibile di GIT", + "config.autoRepositoryDetection": "Se i repository devono essere rilevati automaticamente", "config.autorefresh": "Indica se l'aggiornamento automatico è abilitato", "config.autofetch": "Indica se il recupero automatico è abilitato", "config.enableLongCommitWarning": "Indica se visualizzare un avviso in caso di messaggi di commit lunghi", "config.confirmSync": "Conferma prima di sincronizzare i repository GIT", "config.countBadge": "Controlla il contatore delle notifiche git. Con `all` vengono conteggiate tutte le modifiche. Con `tracked` vengono conteggiate solo le revisioni. Con `off` il contatore è disattivato.", - "config.checkoutType": "Controlla il tipo di branch mostrati eseguendo il comando `Checkout in...`. `all` mostra tutti i refs, `local` mostra solamente i branch locali, `tags` mostra solamente i tag e `remote` mostra solamente i branch remoti.", "config.ignoreLegacyWarning": "Ignora l'avvertimento legacy di Git", "config.ignoreMissingGitWarning": "Ignora il messaggio di avviso quando manca Git", "config.ignoreLimitWarning": "Ignora il messaggio di avviso quando ci sono troppi cambiamenti in un repository", diff --git a/i18n/ita/extensions/typescript/out/commands.i18n.json b/i18n/ita/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..e771e7a4a9e --- /dev/null +++ b/i18n/ita/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "Aprire una cartella in Visual Studio Code per usare un progetto TypeScript o JavaScript", + "typescript.projectConfigUnsupportedFile": "Non è stato possibile determinare il progetto TypeScript o JavaScript. Il tipo di file non è supportato", + "typescript.projectConfigCouldNotGetInfo": "Non è stato possibile determinare il progetto TypeScript o JavaScript", + "typescript.noTypeScriptProjectConfig": "Il file non fa parte di un progetto TypeScript", + "typescript.noJavaScriptProjectConfig": "Il file non fa parte di un progetto JavaScript", + "typescript.configureTsconfigQuickPick": "Configura tsconfig.json", + "typescript.configureJsconfigQuickPick": "Configura jsconfig.json", + "typescript.projectConfigLearnMore": "Altre informazioni" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/base/browser/ui/resourceviewer/resourceViewer.i18n.json b/i18n/ita/src/vs/base/browser/ui/resourceviewer/resourceViewer.i18n.json index 6e295ef1e2c..8baf1308a26 100644 --- a/i18n/ita/src/vs/base/browser/ui/resourceviewer/resourceViewer.i18n.json +++ b/i18n/ita/src/vs/base/browser/ui/resourceviewer/resourceViewer.i18n.json @@ -6,7 +6,7 @@ { "imgMeta": "{0}x{1} {2}", "largeImageError": "L'immagine è troppo grande per essere visualizzata nell'editor", - "resourceOpenExternalButton": "Aprire immagine utilizzando un programma esterno?", + "resourceOpenExternalButton": "Aprire l'immagine utilizzando un programma esterno?", "nativeBinaryError": "Il file non verrà visualizzato nell'editor perché è binario, è molto grande o usa una codifica testo non supportata.", "sizeB": "{0} B", "sizeKB": "{0} KB", diff --git a/i18n/ita/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/ita/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/ita/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/base/node/ps.i18n.json b/i18n/ita/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/ita/src/vs/base/node/ps.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/ita/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/ita/src/vs/editor/common/config/commonEditorConfig.i18n.json index 99d10858e07..71aff162568 100644 --- a/i18n/ita/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/ita/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "I numeri di riga vengono visualizzati come numeri assoluti.", "lineNumbers.relative": "I numeri di riga vengono visualizzati come distanza in linee alla posizione del cursore.", "lineNumbers.interval": "I numeri di riga vengono visualizzati ogni 10 righe.", - "lineNumbers": "Controlla la visualizzazione dei numeri di riga. I valori possibili sono 'on', 'off' e 'relativi'.", + "lineNumbers": "Controlla la visualizzazione dei numeri di riga. I valori possibili sono 'on', 'off', 'relativi' ed 'intervallo'.", "rulers": "Mostra righelli verticali dopo un certo numero di caratteri a spaziatura fissa. Utilizza più valori per più righelli. Nessun righello viene disegnati se la matrice è vuota", "wordSeparators": "Caratteri che verranno usati come separatori di parola quando si eseguono operazioni o spostamenti correlati a parole", "tabSize": "Il numero di spazi corrispondenti ad un carattere Tab. Questa impostazione viene sottoposta a override in base al contenuto dei file quando 'editor.detectIndentation' è 'on'.", diff --git a/i18n/ita/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/ita/src/vs/editor/common/view/editorColorRegistry.i18n.json index bd8958bdf97..81909087f69 100644 --- a/i18n/ita/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/ita/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,6 @@ { "lineHighlight": "Colore di sfondo per l'evidenziazione della riga alla posizione del cursore.", "lineHighlightBorderBox": "Colore di sfondo per il bordo intorno alla riga alla posizione del cursore.", - "rangeHighlight": "Colore di sfondo degli intervalli evidenziati, ad esempio dalle funzionalità Quick Open e Trova.", "caret": "Colore del cursore dell'editor.", "editorCursorBackground": "Colore di sfondo del cursore editor. Permette di personalizzare il colore di un carattere quando sovrapposto da un blocco cursore.", "editorWhitespaces": "Colore dei caratteri di spazio vuoto nell'editor.", diff --git a/i18n/ita/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/ita/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 2d24c4f96ea..505e8cba014 100644 --- a/i18n/ita/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/ita/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "Vai a errore o avviso successivo", - "markerAction.previous.label": "Vai a errore o avviso precedente", "editorMarkerNavigationError": "Colore per gli errori del widget di spostamento tra marcatori dell'editor.", "editorMarkerNavigationWarning": "Colore per gli avvisi del widget di spostamento tra marcatori dell'editor.", "editorMarkerNavigationInfo": "Colore delle informazioni del widget di navigazione marcatori dell'editor.", diff --git a/i18n/ita/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/ita/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index d57627a559a..b355190a13b 100644 --- a/i18n/ita/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/ita/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "Colore di sfondo di un simbolo durante l'accesso in lettura, ad esempio durante la lettura di una variabile.", - "wordHighlightStrong": "Colore di sfondo di un simbolo durante l'accesso in scrittura, ad esempio durante la scrittura in una variabile.", "overviewRulerWordHighlightForeground": "Colore del marcatore del righello delle annotazioni per le evidenziazioni dei simboli.", "overviewRulerWordHighlightStrongForeground": "Colore del marcatore del righello delle annotazioni per le evidenziazioni dei simboli di accesso in scrittura.", "wordHighlight.next.label": "Vai al prossimo simbolo evidenziato", diff --git a/i18n/ita/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/ita/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index 32a58ae4a61..f8e28e396b6 100644 --- a/i18n/ita/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/ita/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "`{0}` non è un identificatore di menu valido", "missing.command": "La voce di menu fa riferimento a un comando `{0}` che non è definito nella sezione 'commands'.", "missing.altCommand": "La voce di menu fa riferimento a un comando alternativo `{0}` che non è definito nella sezione 'commands'.", - "dupe.command": "La voce di menu fa riferimento allo stesso comando come comando predefinito e come comando alternativo", - "nosupport.altCommand": "I comandi alternativi sono attualmente supportati solo nel gruppo 'navigation' del menu 'editor/title'" + "dupe.command": "La voce di menu fa riferimento allo stesso comando come comando predefinito e come comando alternativo" } \ No newline at end of file diff --git a/i18n/ita/src/vs/platform/environment/node/argv.i18n.json b/i18n/ita/src/vs/platform/environment/node/argv.i18n.json index 194dc9d937c..c1d35df0230 100644 --- a/i18n/ita/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/ita/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,32 @@ "diff": "Confronta due file tra loro.", "add": "Aggiunge la cartella o le cartelle all'ultima finestra attiva.", "goto": "Apre un file nel percorso alla posizione specificata di riga e carattere.", - "locale": "Impostazioni locali da usare, ad esempio en-US o it-IT.", "newWindow": "Forza una nuova istanza di Code.", - "performance": "Eseguire l'avvio con il comando 'Developer: Startup Performance' abilitato.", - "prof-startup": "Esegui il profiler della CPU durante l'avvio", - "inspect-extensions": "Consentire il debug e profiling delle estensioni. Controllare gli strumenti di sviluppo per l'uri di connessione.", - "inspect-brk-extensions": "Consentire il debug e profiling delle estensioni con l'host di estensione in pausa dopo inizio. Controllare gli strumenti di sviluppo per l'uri di connessione.", "reuseWindow": "Forza l'apertura di un file o di una cartella nell'ultima finestra attiva.", - "userDataDir": "Consente di specificare la directory in cui si trovano i dati utente. Utile quando viene eseguito come root.", - "log": "Livello di logging da utilizzare. Il valore predefinito è 'info'. I valori consentiti sono 'critical, 'error', 'warn', 'info', 'debug', 'trace', 'off'.", - "verbose": "Visualizza l'output dettagliato (implica --wait).", "wait": "Attendere la chiusura dei file prima della restituzione.", + "locale": "Impostazioni locali da usare, ad esempio en-US o it-IT.", + "userDataDir": "Consente di specificare la directory in cui si trovano i dati utente. Utile quando viene eseguito come root.", + "version": "Visualizza la versione.", + "help": "Visualizza la sintassi.", "extensionHomePath": "Impostare il percorso radice per le estensioni.", "listExtensions": "Elenca le estensioni installate.", "showVersions": "Mostra le versioni delle estensioni installate, quando si usa --list-extension.", "installExtension": "Installa un'estensione.", "uninstallExtension": "Disinstalla un'estensione.", "experimentalApis": "Abilita funzionalità di API proposte per un'estensione specifica.", - "disableExtensions": "Disabilita tutte le estensioni installate.", - "disableGPU": "Disabilita l'accelerazione hardware della GPU.", + "verbose": "Visualizza l'output dettagliato (implica --wait).", + "log": "Livello di logging da utilizzare. Il valore predefinito è 'info'. I valori consentiti sono 'critical, 'error', 'warn', 'info', 'debug', 'trace', 'off'.", "status": "Stampare le informazioni di utilizzo e diagnostica di processo.", - "version": "Visualizza la versione.", - "help": "Visualizza la sintassi.", + "performance": "Eseguire l'avvio con il comando 'Developer: Startup Performance' abilitato.", + "prof-startup": "Esegui il profiler della CPU durante l'avvio", + "disableExtensions": "Disabilita tutte le estensioni installate.", + "inspect-extensions": "Consentire il debug e profiling delle estensioni. Controllare gli strumenti di sviluppo per l'uri di connessione.", + "inspect-brk-extensions": "Consentire il debug e profiling delle estensioni con l'host di estensione in pausa dopo inizio. Controllare gli strumenti di sviluppo per l'uri di connessione.", + "disableGPU": "Disabilita l'accelerazione hardware della GPU.", "usage": "Utilizzo", "options": "opzioni", "paths": "percorsi", + "stdinWindows": "Per leggere l'output da un altro programma, aggiungere alla fine '-' (ad esempio 'echo Hello World | {0} -')", + "stdinUnix": "Per leggere da stdin, aggiungere alla fine '-' (ad esempio 'ps aux | grep code | {0} -')", "optionsUpperCase": "Opzioni" } \ No newline at end of file diff --git a/i18n/ita/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/ita/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index f8230336461..d13d2b8b626 100644 --- a/i18n/ita/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/ita/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,14 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "Estensione non valida: package.json non è un file JSON.", - "restartCodeLocal": "Riavviare Code prima di reinstallare {0}.", + "restartCode": "Riavviare Code prima di reinstallare {0}.", "installingOutdatedExtension": "Una versione più recente di questa estensione è già installata. Vuoi eseguire l'override di questa con la versione precedente?", "override": "Eseguire l'override", "cancel": "Annulla", - "notFoundCompatible": "Impossibile installare perché non è stata trovata l'estensione '{0}' compatibile con la versione corrente '{1}' di VS Code.", - "quitCode": "Impossibile installare perché un'istanza obsoleta dell'estensione è ancora in esecuzione. Si prega di uscire e riavviare VS Code prima di reinstallare.", - "exitCode": "Impossibile installare perché un'istanza obsoleta dell'estensione è ancora in esecuzione. Si prega di uscire e riavviare VS Code prima di reinstallare.", + "notFoundCompatible": "Impossibile installare '{0}'; non è presente alcuna versione compatibile con VS Code '{1}'.", "notFoundCompatibleDependency": "Impossibile installare perché non è stata trovata l'estensione dipendente '{0}' compatibile con la versione corrente '{1}' di VS Code.", + "quitCode": "Impossibile installare l'estensione. Riavviare VS Code prima di procedere ad un nuovo setup.", + "exitCode": "Impossibile installare l'estensione. Riavviare VS Code prima di procedere ad un nuovo setup.", "uninstallDependeciesConfirmation": "Disinstallare solo '{0}' o anche le relative dipendenze?", "uninstallOnly": "Solo", "uninstallAll": "Tutto", diff --git a/i18n/ita/src/vs/platform/message/common/message.i18n.json b/i18n/ita/src/vs/platform/message/common/message.i18n.json index c623cd2a9bb..2822182506c 100644 --- a/i18n/ita/src/vs/platform/message/common/message.i18n.json +++ b/i18n/ita/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "Chiudi", "later": "In seguito", - "cancel": "Annulla" + "cancel": "Annulla", + "moreFile": "...1 altro file non visualizzato", + "moreFiles": "...{0} altri file non visualizzati" } \ No newline at end of file diff --git a/i18n/ita/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/ita/src/vs/platform/theme/common/colorRegistry.i18n.json index 6505e976a25..5375e34f3cb 100644 --- a/i18n/ita/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/ita/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,7 @@ "editorWidgetBorder": "Colore bordo dei widget dell'editor. Il colore viene utilizzato solo se il widget sceglie di avere un bordo e se il colore non è sottoposto a override da un widget.", "editorSelectionBackground": "Colore della selezione dell'editor.", "editorSelectionForeground": "Colore del testo selezionato per il contrasto elevato.", - "editorInactiveSelection": "Colore della selezione in un editor inattivo.", - "editorSelectionHighlight": "Colore delle aree con lo stesso contenuto della selezione.", "editorFindMatch": "Colore della corrispondenza di ricerca corrente.", - "findMatchHighlight": "Colore delle altre corrispondenze di ricerca.", - "findRangeHighlight": "Colore dell'intervallo di ricerca.", - "hoverHighlight": "Evidenziazione sotto la parola per cui è visualizzata un'area sensibile al passaggio del mouse.", "hoverBackground": "Colore di sfondo dell'area sensibile al passaggio del mouse dell'editor.", "hoverBorder": "Colore del bordo dell'area sensibile al passaggio del mouse dell'editor.", "activeLinkForeground": "Colore dei collegamenti attivi.", @@ -76,12 +71,6 @@ "diffEditorRemoved": "Colore di sfondo del testo che è stato rimosso.", "diffEditorInsertedOutline": "Colore del contorno del testo che è stato inserito.", "diffEditorRemovedOutline": "Colore del contorno del testo che è stato rimosso.", - "mergeCurrentHeaderBackground": "Sfondo intestazione corrente in conflitti di merge in linea.", - "mergeCurrentContentBackground": "Sfondo contenuto corrente in conflitti di merge in linea.", - "mergeIncomingHeaderBackground": "Sfondo intestazione modifica in ingresso in conflitti di merge in linea.", - "mergeIncomingContentBackground": "Sfondo contenuto modifica in ingresso in conflitti di merge in linea.", - "mergeCommonHeaderBackground": "Sfondo dell'intestazione dell'antenato comune nei conflitti di merge in linea.", - "mergeCommonContentBackground": "Sfondo del contenuto dell'antenato comune nei conflitti di merge in linea.", "mergeBorder": "Colore bordo su intestazioni e sulla barra di divisione di conflitti di merge in linea.", "overviewRulerCurrentContentForeground": "Colore primo piano righello panoramica attuale per i conflitti di merge in linea.", "overviewRulerIncomingContentForeground": "Colore primo piano del righello panoramica modifiche in arrivo per i conflitti di merge in linea.", diff --git a/i18n/ita/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/ita/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..4bc65098ea9 --- /dev/null +++ b/i18n/ita/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "saveParticipants": "Esecuzione del salvataggio partecipanti..." +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/ita/src/vs/workbench/api/node/extHostTreeViews.i18n.json index 04c4b11db8c..aac2c8ae46e 100644 --- a/i18n/ita/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/ita/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -4,7 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "treeView.notRegistered": "Nessuna visualizzazione di struttura ad albero con ID '{0}' registrata.", - "treeItem.notFound": "Nessun elemento di struttura ad albero con id '{0}' trovato.", - "treeView.duplicateElement": "L'elemento {0} è già registrato" + "treeView.notRegistered": "Nessuna visualizzazione di struttura ad albero con ID '{0}' registrata." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/ita/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index 4f3f7993c31..e851ba0b17e 100644 --- a/i18n/ita/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "Attiva/Disattiva posizione della barra laterale", "view": "Visualizza" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/ita/src/vs/workbench/browser/actions/workspaceActions.i18n.json index 0a58dca9eaa..b30eb5b862d 100644 --- a/i18n/ita/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "Apri file...", "openFolder": "Apri cartella...", "openFileFolder": "Apri...", - "addFolderToWorkspace": "Aggiungi cartella all'area di lavoro...", - "add": "&&Aggiungi", - "addFolderToWorkspaceTitle": "Aggiungi cartella all'area di lavoro", "globalRemoveFolderFromWorkspace": "Rimuovi cartella dall'area di lavoro...", - "removeFolderFromWorkspace": "Rimuovi cartella dall'area di lavoro", - "openFolderSettings": "Apri impostazioni cartella", "saveWorkspaceAsAction": "Salva area di lavoro come...", "save": "&&Salva", "saveWorkspace": "Salva area di lavoro", "openWorkspaceAction": "Apri area di lavoro...", "openWorkspaceConfigFile": "Apri file di configurazione dell'area di lavoro", - "openFolderAsWorkspaceInNewWindow": "Apre la cartella come area di lavoro in una nuova finestra", - "workspaceFolderPickerPlaceholder": "Selezionare la cartella dell'area di lavoro" + "openFolderAsWorkspaceInNewWindow": "Apre la cartella come area di lavoro in una nuova finestra" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/ita/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..e07a448e23d --- /dev/null +++ b/i18n/ita/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "Aggiungi cartella all'area di lavoro...", + "add": "&&Aggiungi", + "addFolderToWorkspaceTitle": "Aggiungi cartella all'area di lavoro" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/ita/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index aa914d12c1d..8430880ec80 100644 --- a/i18n/ita/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,17 @@ "groupThreePicker": "Mostra editor nel terzo gruppo", "allEditorsPicker": "Mostra tutti gli editor aperti", "view": "Visualizza", - "file": "File" + "file": "File", + "close": "Chiudi", + "closeOthers": "Chiudi altri", + "closeRight": "Chiudi a destra", + "closeAllUnmodified": "Chiudi non modificati", + "closeAll": "Chiudi tutto", + "keepOpen": "Mantieni aperto", + "showOpenedEditors": "Mostra editor aperti", + "keepEditor": "Mantieni editor", + "closeEditorsInGroup": "Chiudi tutti gli editor del gruppo", + "closeUnmodifiedEditors": "Chiudi editor non modificati del gruppo", + "closeOtherEditors": "Chiudi gli altri editor", + "closeRightEditors": "Chiudi editor a destra" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/ita/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index 00de0aab7d6..5ff06b5baf6 100644 --- a/i18n/ita/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "Chiudi editor", "revertAndCloseActiveEditor": "Ripristina e chiudi editor", "closeEditorsToTheLeft": "Chiudi editor a sinistra", - "closeEditorsToTheRight": "Chiudi editor a destra", "closeAllEditors": "Chiudi tutti gli editor", - "closeUnmodifiedEditors": "Chiudi editor non modificati del gruppo", "closeEditorsInOtherGroups": "Chiudi editor in altri gruppi", - "closeOtherEditorsInGroup": "Chiudi gli altri editor", - "closeEditorsInGroup": "Chiudi tutti gli editor del gruppo", "moveActiveGroupLeft": "Sposta gruppo di editor a sinistra", "moveActiveGroupRight": "Sposta gruppo di editor a destra", "minimizeOtherEditorGroups": "Riduci a icona gli altri gruppi di editor", "evenEditorGroups": "Imposta stessa larghezza per gruppo di editor", "maximizeEditor": "Ingrandisci gruppo di editor e nascondi barra laterale", - "keepEditor": "Mantieni editor", "openNextEditor": "Apri editor successivo", "openPreviousEditor": "Apri editor precedente", "nextEditorInGroup": "Apri editor successivo del gruppo", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "Mostra editor nel primo gruppo", "showEditorsInSecondGroup": "Mostra editor nel secondo gruppo", "showEditorsInThirdGroup": "Mostra editor nel terzo gruppo", - "showEditorsInGroup": "Mostra editor nel gruppo", "showAllEditors": "Mostra tutti gli editor", "openPreviousRecentlyUsedEditorInGroup": "Apri editor precedente usato di recente nel gruppo", "openNextRecentlyUsedEditorInGroup": "Apri editor successivo usato di recente nel gruppo", diff --git a/i18n/ita/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/ita/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 0e49511fa54..023619e8620 100644 --- a/i18n/ita/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "Consente di spostare l'editor attivo per schede o gruppi", "editorCommand.activeEditorMove.arg.name": "Argomento per spostamento editor attivo", - "editorCommand.activeEditorMove.arg.description": "Proprietà degli argomenti:\n\t* 'to': valore stringa che specifica dove eseguire lo spostamento.\n\t* 'by': valore stringa che specifica l'unità per lo spostamento, ovvero per scheda o per gruppo.\n\t* 'value': valore numerico che specifica il numero di posizioni o una posizione assoluta per lo spostamento.", - "commandDeprecated": "Il comando **{0}** è stato rimosso. In alternativa, usare **{1}**", - "openKeybindings": "Configura tasti di scelta rapida" + "editorCommand.activeEditorMove.arg.description": "Proprietà degli argomenti:\n\t* 'to': valore stringa che specifica dove eseguire lo spostamento.\n\t* 'by': valore stringa che specifica l'unità per lo spostamento, ovvero per scheda o per gruppo.\n\t* 'value': valore numerico che specifica il numero di posizioni o una posizione assoluta per lo spostamento." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/ita/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index 1efc298b02c..4476182db18 100644 --- a/i18n/ita/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -10,7 +10,5 @@ "editableEditorWithInputAriaLabel": "{0}. Editor di confronto file di testo", "editableEditorAriaLabel": "Editor di confronto file di testo.", "navigate.next.label": "Revisione successiva", - "navigate.prev.label": "Revisione precedente", - "inlineDiffLabel": "Passa alla visualizzazione inline", - "sideBySideDiffLabel": "Passa alla visualizzazione affiancata" + "navigate.prev.label": "Revisione precedente" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/ita/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index db72fb32688..12d1b76075f 100644 --- a/i18n/ita/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "Chiudi", - "closeOthers": "Chiudi altri", - "closeRight": "Chiudi a destra", - "closeAll": "Chiudi tutto", - "closeAllUnmodified": "Chiudi non modificati", - "keepOpen": "Mantieni aperto", - "showOpenedEditors": "Mostra editor aperti", "araLabelEditorActions": "Azioni editor" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/ita/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index 5a69f46955d..d4f0af0c2c3 100644 --- a/i18n/ita/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[Non supportata]", + "userIsAdmin": "[Amministratore]", + "userIsSudo": "[Superutente]", "devExtensionWindowTitlePrefix": "[Host di sviluppo estensione]" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/ita/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index f5ecae5746b..8b6ad71cd4e 100644 --- a/i18n/ita/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/ita/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -3,6 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{ - "hideView": "Nascondi da barra laterale" -} \ No newline at end of file +{} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/common/theme.i18n.json b/i18n/ita/src/vs/workbench/common/theme.i18n.json index c2344ccce6a..fb8298647d6 100644 --- a/i18n/ita/src/vs/workbench/common/theme.i18n.json +++ b/i18n/ita/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "Colore di sfondo delle schede attive. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", "tabInactiveBackground": "Colore di sfondo delle schede inattive. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", + "tabHoverBackground": "Colore di sfondo al passaggio del mouse sulle schede. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", + "tabUnfocusedHoverBackground": "Colore di sfondo al passaggio del mouse sulle schede in un gruppo non attivo. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", "tabBorder": "Bordo per separare le schede l'una dall'altra. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", "tabActiveBorder": "Bordo per evidenziare le schede attive. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", "tabActiveUnfocusedBorder": "Bordo per evidenziare le schede attive in un gruppo con stato non attivo. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", + "tabHoverBorder": "Bordo da utilizzare per evidenziare la scheda al passaggio del mouse. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", + "tabUnfocusedHoverBorder": "Bordo da utilizzare per evidenziare la scheda non attiva al passaggio del mouse. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", "tabActiveForeground": "Colore di primo piano delle schede attive in un gruppo attivo. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", "tabInactiveForeground": "Colore di primo piano delle schede inattive in un gruppo attivo. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", "tabUnfocusedActiveForeground": "Colore primo piano delle schede attive in un gruppo con stato non attivo. Le schede sono i contenitori degli editor nell'area degli editor. È possibile aprire più schede in un gruppo di editor e possono esistere più gruppi di editor.", @@ -16,7 +20,7 @@ "editorGroupBackground": "Colore di sfondo di un gruppo di editor. I gruppi di editor sono contenitori di editor. Il colore di sfondo viene visualizzato quando si trascinano i gruppi di editor in un'altra posizione.", "tabsContainerBackground": "Colore di sfondo dell'intestazione del titolo di gruppo di editor, quando le schede sono abilitate. I gruppi di editor sono i contenitori degli editor.", "tabsContainerBorder": "Colore del bordo dell'intestazione del titolo di gruppo di editor, quando le schede sono abilitate. I gruppi di editor sono i contenitori degli editor.", - "editorGroupHeaderBackground": "Colore di sfondo dell'intestazione del titolo dell'editor quando le schede sono disabilitate. I gruppi di editor sono contenitori di editor.", + "editorGroupHeaderBackground": "Colore di sfondo dell'intestazione del titolo dell'editor quando le schede sono disabilitate (`\"workbench.editor.showTabs\": false`). I gruppi di editor sono contenitori di editor.", "editorGroupBorder": "Colore per separare più gruppi di editor l'uno dall'altro. I gruppi di editor sono i contenitori degli editor.", "editorDragAndDropBackground": "Colore di sfondo quando si trascinano gli editor. Il colore dovrebbe avere una trasparenza impostata in modo che il contenuto dell'editor sia ancora visibile.", "panelBackground": "Colore di sfondo dei pannelli. I pannelli sono visualizzati sotto l'area degli editor e contengono visualizzazioni quali quella di output e del terminale integrato.", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "Colore del bordo della barra di stato che la separa dalla barra laterale e dall'editor quando non ci sono cartelle aperte. La barra di stato è visualizzata nella parte inferiore della finestra.", "statusBarItemActiveBackground": "Colore di sfondo degli elementi della barra di stato quando si fa clic. La barra di stato è visualizzata nella parte inferiore della finestra.", "statusBarItemHoverBackground": "Colore di sfondo degli elementi della barra di stato al passaggio del mouse. La barra di stato è visualizzata nella parte inferiore della finestra.", - "statusBarProminentItemBackground": "Colore di sfondo degli elementi rilevanti della barra di stato. Gli elementi rilevanti spiccano rispetto ad altre voci della barra di stato. La barra di stato è visualizzata nella parte inferiore della finestra.", - "statusBarProminentItemHoverBackground": "Colore di sfondo degli elementi rilevanti della barra di stato al passaggio del mouse. Gli elementi rilevanti spiccano rispetto ad altre voci della barra di stato. La barra di stato è visualizzata nella parte inferiore della finestra.", + "statusBarProminentItemBackground": "Colore di sfondo degli elementi rilevanti della barra di stato. Gli elementi rilevanti spiccano rispetto ad altre voci della barra di stato. Per vedere un esempio, cambiare la modalità `Toggle Tab Key Moves Focus` nella barra dei comandi. La barra di stato è visualizzata nella parte inferiore della finestra.", + "statusBarProminentItemHoverBackground": "Colore di sfondo degli elementi rilevanti della barra di stato al passaggio del mouse. Gli elementi rilevanti spiccano rispetto ad altre voci della barra di stato. Per vedere un esempio, cambiare la modalità `Toggle Tab Key Moves Focus` nella barra dei comandi. La barra di stato è visualizzata nella parte inferiore della finestra.", "activityBarBackground": "Colore di sfondo della barra attività. La barra attività viene visualizzata nella parte inferiore sinistra/destra e consente il passaggio tra diverse visualizzazioni della barra laterale", "activityBarForeground": "Colore primo piano della barra attività (ad es. quello utilizzato per le icone). La barra attività viene mostrata all'estrema sinistra o destra e permette di alternare le visualizzazioni della barra laterale.", "activityBarBorder": "Colore del bordo della barra attività che la separa dalla barra laterale. La barra di attività viene mostrata all'estrema sinistra o destra e permette di alternare le visualizzazioni della barra laterale.", diff --git a/i18n/ita/src/vs/workbench/common/views.i18n.json b/i18n/ita/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..ed1c7bde950 --- /dev/null +++ b/i18n/ita/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "Nel percorso `{1}` è già registrata una visualizzazione con ID `{0}` " +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/ita/src/vs/workbench/electron-browser/actions.i18n.json index ac85b55822e..9ae1266d1f0 100644 --- a/i18n/ita/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/ita/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "Chiudi editor", "closeWindow": "Chiudi finestra", "closeWorkspace": "Chiudi area di lavoro", "noWorkspaceOpened": "In questa istanza non ci sono attualmente aree di lavoro aperte da chiudere.", @@ -52,21 +51,5 @@ "displayLanguage": "Definisce la lingua visualizzata di VSCode.", "doc": "Per un elenco delle lingue supportate, vedere {0}.", "restart": "Se si modifica il valore, è necessario riavviare VSCode.", - "fail.createSettings": "Non è possibile creare '{0}' ({1}).", - "openLogsFolder": "Apri cartella dei log", - "showLogs": "Mostra log...", - "mainProcess": "Principale", - "sharedProcess": "Condiviso", - "rendererProcess": "Renderer", - "extensionHost": "Host dell'estensione", - "selectProcess": "Seleziona il processo", - "setLogLevel": "Imposta livello log", - "trace": "Analisi", - "debug": "Debug", - "info": "Informazioni", - "warn": "Avviso", - "err": "Errore", - "critical": "Errori critici", - "off": "Disattivato", - "selectLogLevel": "Seleziona il livello log" + "fail.createSettings": "Non è possibile creare '{0}' ({1})." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/ita/src/vs/workbench/electron-browser/main.contribution.i18n.json index 14e407b8a5d..103d383af16 100644 --- a/i18n/ita/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "Visualizza", "help": "Guida", "file": "File", - "developer": "Sviluppatore", "workspaces": "Aree di lavoro", + "developer": "Sviluppatore", + "workbenchConfigurationTitle": "Area di lavoro", "showEditorTabs": "Controlla se visualizzare o meno gli editor aperti in schede.", "workbench.editor.labelFormat.default": "Visualizza il nome del file. Quando le schede sono abilitate e due file hanno lo stesso nome in un unico gruppo, vengono aggiunte le sezioni distintive del percorso di ciascun file. Quando le schede sono disabilitate, se l'editor è attivo, viene visualizzato il percorso relativo alla radice dell'area di lavoro.", "workbench.editor.labelFormat.short": "Visualizza il nome del file seguito dal relativo nome di directory.", @@ -20,8 +21,10 @@ "showIcons": "Controlla se visualizzare o meno un'icona per gli editor aperti. Richiede l'abilitazione anche di un tema dell'icona.", "enablePreview": "Controlla se gli editor aperti vengono visualizzati come anteprima. Le anteprime editor vengono riutilizzate finché vengono mantenute (ad esempio tramite doppio clic o modifica) e vengono visualizzate in corsivo.", "enablePreviewFromQuickOpen": "Controlla se gli editor aperti da Quick Open vengono visualizzati come anteprima. Le anteprime editor vengono riutilizzate finché vengono mantenute, ad esempio tramite doppio clic o modifica.", + "closeOnFileDelete": "Controlla se gli editor che visualizzano un file devono chiudersi automaticamente quando il file viene eliminato o rinominato da un altro processo. Se si disabilita questa opzione, in una simile circostanza l'editor verrà aperto e i file risulteranno modificati ma non salvati. Nota: se si elimina il file dall'interno dell'applicazione, l'editor verrà sempre chiuso e i file modificati ma non salvati non verranno mai chiusi allo scopo di salvaguardare i dati.", "editorOpenPositioning": "Controlla la posizione in cui vengono aperti gli editor. Selezionare 'sinistra' o 'destra' per aprire gli editor a sinistra o a destra di quello attualmente attivo. Selezionare 'primo' o 'ultimo' per aprire gli editor indipendentemente da quello attualmente attivo.", "revealIfOpen": "Controlla se un editor viene visualizzato in uno qualsiasi dei gruppi visibili se viene aperto. Se l'opzione è disabilitata, un editor verrà aperto preferibilmente nel gruppo di editor attualmente attivo. Se è abilitata, un editor già aperto verrà visualizzato e non aperto di nuovo nel gruppo di editor attualmente attivo. Nota: in alcuni casi questa impostazione viene ignorata, ad esempio quando si forza l'apertura di un editor in un gruppo specifico oppure a lato del gruppo attualmente attivo.", + "swipeToNavigate": "Scorrere orizzontalmente con tre dita per spostarsi tra i file aperti.", "commandHistory": "Controlla il numero di comandi utilizzati di recente da mantenere nella cronologia. Impostare a 0 per disabilitare la cronologia dei comandi.", "preserveInput": "Controlla se l'ultimo input digitato nel riquadro comandi deve essere ripristinato alla successiva riapertura del riquadro.", "closeOnFocusLost": "Controlla se Quick Open deve essere chiuso automaticamente quando perde lo stato attivo.", @@ -29,14 +32,11 @@ "sideBarLocation": "Controlla la posizione della barra laterale. Può essere visualizzata a sinistra o a destra del workbench.", "statusBarVisibility": "Controlla la visibilità della barra di stato nella parte inferiore del workbench.", "activityBarVisibility": "Controlla la visibilità della barra attività nel workbench.", - "closeOnFileDelete": "Controlla se gli editor che visualizzano un file devono chiudersi automaticamente quando il file viene eliminato o rinominato da un altro processo. Se si disabilita questa opzione, in una simile circostanza l'editor verrà aperto e i file risulteranno modificati ma non salvati. Nota: se si elimina il file dall'interno dell'applicazione, l'editor verrà sempre chiuso e i file modificati ma non salvati non verranno mai chiusi allo scopo di salvaguardare i dati.", - "enableNaturalLanguageSettingsSearch": "Controlla se abilitare la modalità di ricerca in linguaggio naturale per le impostazioni.", "fontAliasing": "Controlla il metodo di aliasing dei caratteri nell'area di lavoro.\n- impostazione predefinita: anti-aliasing dei caratteri a livello di sub-pixel. Nella maggior parte delle visualizzazioni non retina consentirà di ottenere un testo con il massimo contrasto.\n- anti-aliasing: anti-aliasing dei caratteri a livello di pixel, invece che a livello di sub-pixel. Consente di visualizzare i caratteri più chiari.\n- nessuno: disabilita l'anti-aliasing dei caratteri. Il testo verrà visualizzato con contorni irregolari.", "workbench.fontAliasing.default": "Anti-aliasing dei caratteri a livello di sub-pixel. Nella maggior parte delle visualizzazioni non retina consentirà di ottenere un testo con il massimo contrasto.", "workbench.fontAliasing.antialiased": "Anti-aliasing dei caratteri a livello di pixel, invece che a livello di sub-pixel. Consente di visualizzare i caratteri più chiari.", "workbench.fontAliasing.none": "Disabilita l'anti-aliasing dei caratteri. Il testo verrà visualizzato con contorni irregolari. ", - "swipeToNavigate": "Scorrere orizzontalmente con tre dita per spostarsi tra i file aperti.", - "workbenchConfigurationTitle": "Area di lavoro", + "enableNaturalLanguageSettingsSearch": "Controlla se abilitare la modalità di ricerca in linguaggio naturale per le impostazioni.", "windowConfigurationTitle": "Finestra", "window.openFilesInNewWindow.on": "I file verranno aperti in una nuova finestra", "window.openFilesInNewWindow.off": "I file verranno aperti nella finestra con la cartella dei file aperta o nell'ultima finestra attiva", diff --git a/i18n/ita/src/vs/workbench/electron-browser/window.i18n.json b/i18n/ita/src/vs/workbench/electron-browser/window.i18n.json index 8c2277fae11..a589565cc73 100644 --- a/i18n/ita/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/ita/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "Taglia", "copy": "Copia", "paste": "Incolla", - "selectAll": "Seleziona tutto" + "selectAll": "Seleziona tutto", + "runningAsRoot": "Non è consigliabile eseguire {0} come utente root." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/ita/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index 2e0a0d42956..dad36665ecd 100644 --- a/i18n/ita/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "Colore di sfondo della barra degli strumenti di debug." + "debugToolBarBackground": "Colore di sfondo della barra degli strumenti di debug.", + "debugToolBarBorder": "Colore del bordo della barra degli strumenti di debug." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/ita/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 7e90f64d82a..94d7c45f7eb 100644 --- a/i18n/ita/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "oggetto del debug", - "debug.terminal.not.available.error": "Il terminale integrato non è disponibile" + "debug.terminal.title": "oggetto del debug" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 1b150a45b5f..5f819964e72 100644 --- a/i18n/ita/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "Apri nuovo prompt dei comandi", "globalConsoleActionMacLinux": "Apri nuovo terminale", "scopedConsoleActionWin": "Apri nel prompt dei comandi", - "scopedConsoleActionMacLinux": "Apri nel terminale", - "openFolderInIntegratedTerminal": "Apri nel terminale" + "scopedConsoleActionMacLinux": "Apri nel terminale" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index ec5fd33a3b1..fbdc3b5e322 100644 --- a/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "Questa estensione è raccomandata in base ai file aperti di recente.", + "neverShowAgain": "Non visualizzare più questo messaggio", + "close": "Chiudi", "workspaceRecommendation": "Questa estensione è consigliata dagli utenti dell'area di lavoro corrente.", + "fileBasedRecommendation": "Questa estensione è raccomandata in base ai file aperti di recente.", "exeBasedRecommendation": "Questa estensione è consigliata perché avete installato {0}.", "reallyRecommended2": "Per questo tipo di file è consigliabile utilizzare l'estensione '{0}'.", "reallyRecommendedExtensionPack": "Per questo tipo di file è consigliabile usare il pacchetto di estensione '{0}'.", "showRecommendations": "Mostra gli elementi consigliati", "install": "Installa", - "neverShowAgain": "Non visualizzare più questo messaggio", - "close": "Chiudi", "workspaceRecommended": "Per questa area di lavoro sono disponibili estensioni consigliate.", "installAll": "Installa tutto", "ignoreExtensionRecommendations": "Ignorare tutti i suggerimenti per le estensioni?", diff --git a/i18n/ita/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..1866903b33e --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "Area di lavoro" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/ita/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 979ee1896bb..a1c5eca5548 100644 --- a/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,25 @@ "filesCategory": "File", "revealInSideBar": "Visualizza nella barra laterale", "acceptLocalChanges": "Utilizzare le modifiche e sovrascrivere il contenuto del disco", - "revertLocalChanges": "Annullare le modifiche e tornare al contenuto sul disco" + "revertLocalChanges": "Annullare le modifiche e tornare al contenuto sul disco", + "copyPathOfActive": "Copia percorso del file attivo", + "saveAllInGroup": "Salva tutto nel gruppo", + "saveFiles": "Salva tutti i file", + "revert": "Ripristina file", + "compareActiveWithSaved": "Confronta file attivo con file salvato", + "closeEditor": "Chiudi editor", + "view": "Visualizza", + "openToSide": "Apri lateralmente", + "revealInWindows": "Visualizza in Esplora risorse", + "revealInMac": "Visualizza in Finder", + "openContainer": "Apri cartella superiore", + "copyPath": "Copia percorso", + "saveAll": "Salva tutto", + "compareWithSaved": "Confronta con file salvato", + "compareSource": "Seleziona per il confronto", + "close": "Chiudi", + "closeOthers": "Chiudi altri", + "closeUnmodified": "Chiudi non modificati", + "closeAll": "Chiudi tutto", + "deleteFile": "Elimina definitivamente" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 7d23a38e703..14358d0abb2 100644 --- a/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "Riprova", - "rename": "Rinomina", "newFile": "Nuovo file", "newFolder": "Nuova cartella", + "rename": "Rinomina", + "delete": "Elimina", + "copyFile": "Copia", + "pasteFile": "Incolla", + "retry": "Riprova", "openFolderFirst": "Aprire prima di tutto una cartella per creare file o cartelle al suo interno.", "newUntitledFile": "Nuovo file senza nome", "createNewFile": "Nuovo file", @@ -28,26 +31,14 @@ "confirmDeleteMessageFile": "Eliminare definitivamente '{0}'?", "irreversible": "Questa azione è irreversibile.", "permDelete": "Elimina definitivamente", - "delete": "Elimina", "importFiles": "Importa file", "confirmOverwrite": "Nella cartella di destinazione esiste già un file o una cartella con lo stesso nome. Sovrascrivere?", "replaceButtonLabel": "&&Sostituisci", - "copyFile": "Copia", - "pasteFile": "Incolla", "duplicateFile": "Duplicato", - "openToSide": "Apri lateralmente", - "compareSource": "Seleziona per il confronto", "globalCompareFile": "Confronta file attivo con...", "openFileToCompare": "Aprire prima un file per confrontarlo con un altro file.", - "compareWith": "Confronta '{0}' con '{1}'", - "compareFiles": "Confronta file", "refresh": "Aggiorna", - "save": "Salva", - "saveAs": "Salva con nome...", - "saveAll": "Salva tutto", "saveAllInGroup": "Salva tutto nel gruppo", - "saveFiles": "Salva tutti i file", - "revert": "Ripristina file", "focusOpenEditors": "Stato attivo su visualizzazione editor aperti", "focusFilesExplorer": "Stato attivo su Esplora file", "showInExplorer": "Visualizza file attivo nella barra laterale", @@ -56,20 +47,11 @@ "refreshExplorer": "Aggiorna Explorer", "openFileInNewWindow": "Apri file attivo in un'altra finestra", "openFileToShowInNewWindow": "Aprire prima un file per visualizzarlo in un'altra finestra", - "revealInWindows": "Visualizza in Esplora risorse", - "revealInMac": "Visualizza in Finder", - "openContainer": "Apri cartella superiore", - "revealActiveFileInWindows": "Visualizza file attivo in Esplora risorse", - "revealActiveFileInMac": "Visualizza file attivo in Finder", - "openActiveFileContainer": "Apri cartella che contiene il file attivo", "copyPath": "Copia percorso", - "copyPathOfActive": "Copia percorso del file attivo", "emptyFileNameError": "È necessario specificare un nome file o un nome di cartella.", "fileNameExistsError": "In questo percorso esiste già un file o una cartella **{0}**. Scegliere un nome diverso.", "invalidFileNameError": "Il nome **{0}** non è valido per un nome file o un nome di cartella. Scegliere un nome diverso.", "filePathTooLongError": "Con il nome **{0}** il percorso diventa troppo lungo. Scegliere un nome più breve.", - "compareWithSaved": "Confronta file attivo con file salvato", - "modifiedLabel": "{0} (su disco) ↔ {1}", "compareWithClipboard": "Confronta il file attivo con gli appunti", "clipboardComparisonLabel": "Appunti ↔ {0}" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index a02c62cce4f..4e2f71fcbb4 100644 --- a/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "Aprire prima un file per copiarne il percorso", - "openFileToReveal": "Aprire prima un file per visualizzarlo" + "revealInWindows": "Visualizza in Esplora risorse", + "revealInMac": "Visualizza in Finder", + "openContainer": "Apri cartella superiore", + "saveAs": "Salva con nome...", + "save": "Salva", + "saveAll": "Salva tutto", + "removeFolderFromWorkspace": "Rimuovi cartella dall'area di lavoro", + "openFileToReveal": "Aprire prima un file per visualizzarlo", + "openFileToCopy": "Aprire prima un file per copiarne il percorso" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 6fb07e8966e..bf53e0bc960 100644 --- a/i18n/ita/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,6 @@ "editorConfigurationTitle": "Editor", "formatOnSave": "Formatta un file durante il salvataggio. Deve essere disponibile un formattatore, il file non deve essere salvato automaticamente e l'editor non deve essere in fase di chiusura.", "explorerConfigurationTitle": "Esplora file", - "openEditorsVisible": "Numero di editor visualizzati nel riquadro degli editor aperti. Impostarlo su 0 per nascondere il riquadro.", - "dynamicHeight": "Controlla se l'altezza della sezione degli editor aperti deve essere adattata o meno dinamicamente al numero di elementi.", "autoReveal": "Controlla se Esplora risorse deve rivelare automaticamente e selezionare i file durante l'apertura.", "enableDragAndDrop": "Controlla se Esplora risorse deve consentire lo spostamento di file e cartelle tramite trascinamento della selezione.", "confirmDragAndDrop": "Controlla se Esplora risorse deve chiedere conferma prima di spostare file e cartelle tramite trascinamento della selezione.", diff --git a/i18n/ita/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/ita/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 49ebceb9611..8052e44e9f3 100644 --- a/i18n/ita/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,9 @@ // Do not edit this file. It is machine generated. { "userGuide": "Usare le azioni della barra degli strumenti dell'editor a destra per **annullare** le modifiche o per **sovrascrivere** il contenuto su disco con le modifiche", - "discard": "Rimuovi", "overwrite": "Sovrascrivi", "retry": "Riprova", - "readonlySaveError": "Non è stato possibile salvare '{0}': il file è protetto da scrittura. Selezionare 'Sovrascrivi' per rimuovere la protezione.", + "discard": "Rimuovi", "genericSaveError": "Non è stato possibile salvare '{0}': {1}", "staleSaveError": "Non è stato possibile salvare '{0}': il contenuto sul disco è più recente. Fare clic su **Confronta** per confrontare la versione corrente con quella sul disco.", "compareChanges": "Confronta", diff --git a/i18n/ita/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/ita/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index 5627c56823f..f7d56641c92 100644 --- a/i18n/ita/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "Editor aperti", "openEditosrSection": "Sezione Editor aperti", - "dirtyCounter": "{0} non salvati", - "saveAll": "Salva tutto", - "closeAllUnmodified": "Chiudi non modificati", - "closeAll": "Chiudi tutto", - "compareWithSaved": "Confronta con file salvato", - "close": "Chiudi", - "closeOthers": "Chiudi altri" + "dirtyCounter": "{0} non salvati" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..458e7226595 --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "developer": "Sviluppatore" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/ita/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..88a2d7b7487 --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "Apri cartella dei log", + "showLogs": "Mostra log...", + "mainProcess": "Principale", + "sharedProcess": "Condiviso", + "rendererProcess": "Finestra", + "extensionHost": "Host dell'estensione", + "selectProcess": "Seleziona il processo", + "setLogLevel": "Imposta livello log", + "trace": "Analisi", + "debug": "Debug", + "info": "Informazioni", + "warn": "Avviso", + "err": "Errore", + "critical": "Errori critici", + "off": "Disattivato", + "selectLogLevel": "Seleziona il livello log" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/ita/src/vs/workbench/parts/markers/common/messages.i18n.json index 5e585c6ea40..0337b4edbb1 100644 --- a/i18n/ita/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "viewCategory": "Visualizza", - "problems.view.toggle.label": "Attiva/disattiva problemi", - "problems.view.focus.label": "Problemi di Focus", "problems.panel.configuration.title": "Visualizzazione Problemi", "problems.panel.configuration.autoreveal": "Controlla se la visualizzazione Problemi deve visualizzare automaticamente i file durante l'apertura", "markers.panel.title.problems": "Problemi", diff --git a/i18n/ita/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..99ba0e6815c --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "Output", + "viewCategory": "Visualizza", + "clearOutput.label": "Cancella output" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/ita/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/ita/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index 7c1a3a7d309..4669fa3cd56 100644 --- a/i18n/ita/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "Prova la ricerca in linguaggio naturale.", "defaultSettings": "Inserire le impostazioni nell'editor di lato destro per eseguire l'override.", "noSettingsFound": "Non sono state trovate impostazioni.", "settingsSwitcherBarAriaLabel": "Selezione impostazioni", "userSettings": "Impostazioni utente", "workspaceSettings": "Impostazioni area di lavoro", - "folderSettings": "Impostazioni cartella", - "enableFuzzySearch": "Abilita la ricerca in linguaggio naturale" + "folderSettings": "Impostazioni cartella" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/ita/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index c4cdd4ead33..7149b64d24f 100644 --- a/i18n/ita/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "Più usate", - "mostRelevant": "Più rilevanti", "defaultKeybindingsHeader": "Per sovrascrivere i tasti di scelta rapida, inserirli nel file dei tasti di scelta rapida." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index 13929c1fa4b..9d39d9c9b41 100644 --- a/i18n/ita/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "Visualizza", "commandsHandlerDescriptionDefault": "Mostra ed esegui comandi", "gotoLineDescriptionMac": "Vai alla riga", "gotoLineDescriptionWin": "Vai alla riga", diff --git a/i18n/ita/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index 44389863a65..7bc3bea7022 100644 --- a/i18n/ita/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,6 @@ "toggleGitViewlet": "Mostra GIT", "source control": "Controllo del codice sorgente", "toggleSCMViewlet": "Mostra Gestione controllo servizi", - "view": "Visualizza" + "view": "Visualizza", + "scmConfigurationTitle": "Gestione controllo servizi" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/ita/src/vs/workbench/parts/search/browser/searchActions.i18n.json index ebff6e3002a..406201bbecb 100644 --- a/i18n/ita/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "Mostra il termine di ricerca precedente", "showSearchViewlet": "Mostra Cerca", "findInFiles": "Cerca nei file", - "findInFilesWithSelectedText": "Cerca nei file con il testo selezionato", "replaceInFiles": "Sostituisci nei file", - "replaceInFilesWithSelectedText": "Sostituisci nei file con il testo selezionato", "RefreshAction.label": "Aggiorna", "CollapseDeepestExpandedLevelAction.label": "Comprimi tutto", "ClearSearchResultsAction.label": "Cancella", diff --git a/i18n/ita/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index 25315a7f99e..b29d6b897b6 100644 --- a/i18n/ita/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "Trova nella cartella...", + "findInWorkspace": "Trova nell'area di lavoro...", "showTriggerActions": "Vai al simbolo nell'area di lavoro...", "name": "Cerca", "search": "Cerca", + "showSearchViewlet": "Mostra Cerca", "view": "Visualizza", + "findInFiles": "Cerca nei file", "openAnythingHandlerDescription": "Vai al file", "openSymbolDescriptionNormal": "Vai al simbolo nell'area di lavoro", "searchOutputChannelTitle": "Cerca", diff --git a/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..32dc45ab7fd --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.1": "({0})", + "preferences": "Preferenze" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 7cea9caafc3..356ac5c6fe2 100644 --- a/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,10 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "Seleziona il linguaggio per il frammento", - "openSnippet.errorOnCreate": "Non è possibile creare {0}", - "openSnippet.label": "Apri frammenti di codice utente", - "preferences": "Preferenze", "snippetSchema.json.default": "Frammento vuoto", "snippetSchema.json": "Configurazione del frammento utente", "snippetSchema.json.prefix": "Prefisso da usare quando si seleziona il frammento in IntelliSense", diff --git a/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..fee95f06a2c --- /dev/null +++ b/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "Frammento utente" +} \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index d130ea84c16..02cfa9b88ab 100644 --- a/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "Il linguaggio in `contributes.{0}.language` è sconosciuto. Valore specificato: {1}", "invalid.path.0": "È previsto un valore stringa in `contributes.{0}.path`. Valore specificato: {1}", + "invalid.language": "Il linguaggio in `contributes.{0}.language` è sconosciuto. Valore specificato: {1}", "invalid.path.1": "Valore previsto di `contributes.{0}.path` ({1}) da includere nella cartella dell'estensione ({2}). L'estensione potrebbe non essere più portatile.", "vscode.extension.contributes.snippets": "Frammenti per contributes.", "vscode.extension.contributes.snippets-language": "Identificatore di linguaggio per cui si aggiunge come contributo questo frammento.", "vscode.extension.contributes.snippets-path": "Percorso del file snippets. È relativo alla cartella delle estensioni e in genere inizia con './snippets/'.", "badVariableUse": "Uno o più frammenti dall'estensione '{0}' confondono molto probabilmente variabili-frammento e segnaposto-frammento (Vedere https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax per maggiori dettagli)", "badFile": "Non è stato possibile leggere il file di frammento \"{0}\".", - "source.snippet": "Frammento utente", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json b/i18n/ita/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json index 6d85a595027..2d53dad9156 100644 --- a/i18n/ita/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json @@ -8,6 +8,5 @@ "terminal.foreground": "Il colore di primo piano del terminale.", "terminalCursor.foreground": "Colore di primo piano del cursore del terminale.", "terminalCursor.background": "Colore di sfondo del cursore del terminale. Permette di personalizzare il colore di un carattere quando sovrapposto da un blocco cursore.", - "terminal.selectionBackground": "Colore di sfondo di selezione del terminale.", - "terminal.ansiColor": "Colore ANSI '{0}' nel terminale." + "terminal.selectionBackground": "Colore di sfondo di selezione del terminale." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/ita/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index 6055f7da096..f695d8b57b2 100644 --- a/i18n/ita/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,6 @@ "terminal.integrated.chooseWindowsShellInfo": "È possibile modificare la shell di terminale di default selezionando il pulsante Personalizza.", "customize": "Personalizza", "cancel": "Annulla", - "never again": "OK, non visualizzare più", "terminal.integrated.chooseWindowsShell": "Seleziona la shell di terminale preferita - è possibile modificare questa impostazione dopo", "terminalService.terminalCloseConfirmationSingular": "C'è una sessione di terminale attiva. Terminarla?", "terminalService.terminalCloseConfirmationPlural": "Ci sono {0} sessioni di terminale attive. Terminarle?" diff --git a/i18n/ita/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/ita/src/vs/workbench/parts/update/electron-browser/update.i18n.json index 46c966a637e..7d586fdfcf4 100644 --- a/i18n/ita/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -23,6 +23,7 @@ "commandPalette": "Riquadro comandi...", "settings": "Impostazioni", "keyboardShortcuts": "Scelte rapide da tastiera", + "userSnippets": "Frammenti utente", "selectTheme.label": "Tema colori", "themes.selectIconTheme.label": "Tema icona file", "not available": "Aggiornamenti non disponibili", diff --git a/i18n/ita/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/ita/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 6952c245dd7..fb6e0553811 100644 --- a/i18n/ita/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/ita/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "Il File è una Directory", + "fileNotModifiedError": "File non modificato dal giorno", "fileBinaryError": "Il file sembra essere binario e non può essere aperto come file di testo" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/ita/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index c6f9ca63862..11826e9bcfb 100644 --- a/i18n/ita/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/ita/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "Salvare le modifiche apportate a {0}?", "saveChangesMessages": "Salvare le modifiche apportate ai file seguenti di {0}?", - "moreFile": "...1 altro file non visualizzato", - "moreFiles": "...{0} altri file non visualizzati", "saveAll": "&&Salva tutto", "save": "&&Salva", "dontSave": "&&Non salvare", diff --git a/i18n/ita/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/ita/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index c8e3f4e44d8..7ff89ea80bd 100644 --- a/i18n/ita/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/ita/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "No file icons", "iconThemeError": "File icon theme is unknown or not installed.", "workbenchColors": "Sostituisce i colori del tema colori attualmente selezionato.", - "editorColors": "Sostituisce i colori dell'editor e lo stile dei font nel tema colori attualmente selezionato.", "editorColors.comments": "Imposta i colori e gli stili per i commenti", "editorColors.strings": "Imposta i colori e gli stili per i valori letterali stringa.", "editorColors.keywords": "Imposta i colori e gli stili per le parole chiave.", @@ -19,5 +18,6 @@ "editorColors.types": "Imposta i colori e gli stili per i riferimenti e le dichiarazioni di tipo.", "editorColors.functions": "Imposta i colori e gli stili per i riferimenti e le dichiarazioni di funzioni.", "editorColors.variables": "Imposta i colori e gli stili per i riferimenti e le dichiarazioni di variabili.", - "editorColors.textMateRules": "Imposta i colori e gli stili usando le regole di creazione temi di TextMate (impostazione avanzata)." + "editorColors.textMateRules": "Imposta i colori e gli stili usando le regole di creazione temi di TextMate (impostazione avanzata).", + "editorColors": "Sostituisce i colori dell'editor e lo stile dei font nel tema colori attualmente selezionato." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/ita/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 83c0f4d81a8..af0e885e44b 100644 --- a/i18n/ita/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/ita/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "Impossibile scrivere nel file di configurazione dell'area di lavoro. Si prega di aprire il file per correggere eventuali errori/avvisi e riprovare.", "errorWorkspaceConfigurationFileDirty": "Impossibile scrivere nel file di configurazione dell'area di lavoro, perché il file è sporco. Si prega di salvarlo e riprovare.", "openWorkspaceConfigurationFile": "Apri file di configurazione dell'area di lavoro", - "close": "Chiudi", - "enterWorkspace.close": "Chiudi", - "enterWorkspace.dontShowAgain": "Non visualizzare più questo messaggio", - "enterWorkspace.moreInfo": "Altre informazioni", - "enterWorkspace.prompt": "Ulteriori informazioni su come lavorare con più cartelle in VS Code." + "close": "Chiudi" } \ No newline at end of file diff --git a/i18n/jpn/extensions/configuration-editing/out/settingsDocumentHelper.i18n.json b/i18n/jpn/extensions/configuration-editing/out/settingsDocumentHelper.i18n.json index f8b65e69685..905556c139c 100644 --- a/i18n/jpn/extensions/configuration-editing/out/settingsDocumentHelper.i18n.json +++ b/i18n/jpn/extensions/configuration-editing/out/settingsDocumentHelper.i18n.json @@ -22,7 +22,7 @@ "fileDescription": "特定のファイル拡張子を持つすべてのファイルと一致します。", "filesLabel": "複数の拡張子のファイル", "filesDescription": "いずれかのファイル拡張子を持つすべてのファイルと一致します。", - "derivedLabel": "同じ名前の兄弟があるファイル", + "derivedLabel": "同じ名前の同種のファイル", "derivedDescription": "名前が同じで拡張子が異なる兄弟を持つファイルと一致します。", "topFolderLabel": "特定の名前のフォルダー (最上位)", "topFolderDescription": "特定の名前の最上位にあるフォルダーと一致します。", @@ -32,7 +32,7 @@ "folderDescription": "任意の場所にある特定の名前のフォルダーと一致します。", "falseDescription": "パターンを無効にします。", "trueDescription": "パターンを有効にします。", - "siblingsDescription": "名前が同じで拡張子が異なる兄弟を持つファイルと一致します。", + "siblingsDescription": "名前が同じで異なる拡張子を持つ同種のファイルと一致します。", "languageSpecificEditorSettings": "言語固有のエディター設定", "languageSpecificEditorSettingsDescription": "言語に対するエディター設定を上書きします" } \ No newline at end of file diff --git a/i18n/jpn/extensions/css/package.i18n.json b/i18n/jpn/extensions/css/package.i18n.json index 5ff9ba2550a..4716b3c9ee1 100644 --- a/i18n/jpn/extensions/css/package.i18n.json +++ b/i18n/jpn/extensions/css/package.i18n.json @@ -5,24 +5,24 @@ // Do not edit this file. It is machine generated. { "css.title": "CSS", - "css.lint.argumentsInColorFunction.desc": "正しくないパラメーターの数", - "css.lint.boxModel.desc": "パディングまたは枠線を使用する場合は幅または高さを使用しないでください", - "css.lint.compatibleVendorPrefixes.desc": "ベンダー固有のプレフィックスを使用する場合は、他のすべてのベンダー固有のプロパティも必ず含めてください", + "css.lint.argumentsInColorFunction.desc": "無効なパラメーター数値", + "css.lint.boxModel.desc": "padding や border を使用するときに width や height を使用しないでください", + "css.lint.compatibleVendorPrefixes.desc": "ベンダー プレフィックス を使用するときは、他すべてのベンダー プレフィックスも必ず含めてください", "css.lint.duplicateProperties.desc": "重複するスタイル定義を使用しないでください", "css.lint.emptyRules.desc": "空の規則セットを使用しないでください", - "css.lint.float.desc": "'float' は使用しないでください。float を使用すると、レイアウトの一部が変更されたときに CSS が破損しやすくなります。", + "css.lint.float.desc": "'float' の使用を避けてください。float は脆弱な CSS につながり、レイアウトの一部が変更されたときに CSS が破損しやすくなります。", "css.lint.fontFaceProperties.desc": "@font-face 規則で 'src' プロパティと 'font-family' プロパティを定義する必要があります", - "css.lint.hexColorLength.desc": "16 進数の色には、3 つまたは 6 つの 16 進数が含まれる必要があります", + "css.lint.hexColorLength.desc": "Hex には 3 つまたは 6 つの 16 進数が含まれる必要があります", "css.lint.idSelector.desc": "セレクターには ID を含めないでください。これらの規則と HTML の結合が密接すぎます。", "css.lint.ieHack.desc": "IE ハックは、IE7 以前をサポートする場合にのみ必要です", "css.lint.important.desc": "!important は使用しないでください。これは CSS 全体の特定性が制御不能になり、リファクタリングが必要なことを示しています。", "css.lint.importStatement.desc": "複数の Import ステートメントを同時に読み込むことはできません", - "css.lint.propertyIgnoredDueToDisplay.desc": "表示によりプロパティが無視されます。たとえば、'display: inline' の場合、width、height、margin-top、margin-bottom、および float のプロパティには効果がありません", + "css.lint.propertyIgnoredDueToDisplay.desc": "display によってプロパティを無視します。例: 'display: inline' の場合、width、height、margin-top、margin-bottom、float プロパティには効果がありません。", "css.lint.universalSelector.desc": "ユニバーサル セレクター (*) を使用すると処理速度が低下することが分かっています", "css.lint.unknownProperties.desc": "不明なプロパティ。", "css.lint.unknownVendorSpecificProperties.desc": "不明なベンダー固有のプロパティ。", "css.lint.vendorPrefix.desc": "ベンダー固有のプレフィックスを使用する場合は、標準のプロパティも含めます", - "css.lint.zeroUnits.desc": "0 の単位は必要ありません", + "css.lint.zeroUnits.desc": "0 に単位は必要ありません", "css.trace.server.desc": "VS Code と CSS 言語サーバー間の通信をトレースします。", "css.validate.title": "CSS の検証と問題の重大度を制御します。", "css.validate.desc": "すべての検証を有効または無効にします", diff --git a/i18n/jpn/extensions/git/out/autofetch.i18n.json b/i18n/jpn/extensions/git/out/autofetch.i18n.json index a4b33109cea..4dcee36f0c2 100644 --- a/i18n/jpn/extensions/git/out/autofetch.i18n.json +++ b/i18n/jpn/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "はい", + "read more": "詳細を参照", "no": "いいえ", - "not now": "あとで", - "suggest auto fetch": "Git リポジトリの自動フェッチを有効にしますか?" + "not now": "後で通知する", + "suggest auto fetch": "Code が定期的に `git fetch` を実行してもよろしいですか?" } \ No newline at end of file diff --git a/i18n/jpn/extensions/git/out/commands.i18n.json b/i18n/jpn/extensions/git/out/commands.i18n.json index e73b6d879f2..5411af2ba63 100644 --- a/i18n/jpn/extensions/git/out/commands.i18n.json +++ b/i18n/jpn/extensions/git/out/commands.i18n.json @@ -13,7 +13,7 @@ "cancel tooltip": "クローンのキャンセル", "cloning": "Git リポジトリを複製しています...", "openrepo": "リポジトリを開く", - "proposeopen": "複製したリポジトリを開きますか?", + "proposeopen": "クローンしたリポジトリを開きますか?", "init": "Git リポジトリを初期化するワークスペース フォルダーを選択してください", "init repo": "リポジトリの初期化", "create repo": "リポジトリの初期化", @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\nこの変更は元に戻すことはできません。現在のワーキング セットは永久に失われます。", "yes discard tracked": "1 つの追跡ファイルを破棄", "yes discard tracked multiple": "{0} 個の追跡ファイルを破棄", + "unsaved files single": "次のファイルが保存されていません: {0}。\n\nコミット前に保存しますか?", + "unsaved files": "{0} 個の保存されていないファイルがあります。\n\nコミット前に保存しますか?", + "save and commit": "すべて保存してコミットする", + "commit": "とにかくコミットする", "no staged changes": "コミットするステージされた変更がありません。\n\nすべての変更を自動的にステージして、直接コミットしますか?", "always": "常に行う", "no changes": "コミットする必要のある変更はありません。", @@ -64,11 +68,12 @@ "no remotes to pull": "リポジトリには、プル元として構成されているリモートがありません。", "pick remote pull repo": "リモートを選んで、ブランチを次からプルします:", "no remotes to push": "リポジトリには、プッシュ先として構成されているリモートがありません。", - "push with tags success": "タグが正常にプッシュされました。", "nobranch": "リモートにプッシュするブランチをチェックアウトしてください。", + "confirm publish branch": "'{0}' ブランチに上流ブランチはありません。このブランチを公開しますか?", + "ok": "OK", + "push with tags success": "タグが正常にプッシュされました。", "pick remote": "リモートを選んで、ブランチ '{0}' を次に公開します:", "sync is unpredictable": "このアクションはコミットを '{0}' との間でプッシュしたりプルしたりします。", - "ok": "OK", "never again": "OK、今後は表示しない", "no remotes to publish": "リポジトリには、発行先として構成されているリモートがありません。", "no changes stash": "スタッシュする変更がありません。", diff --git a/i18n/jpn/extensions/git/package.i18n.json b/i18n/jpn/extensions/git/package.i18n.json index 1574014e89e..bdc7a5612ed 100644 --- a/i18n/jpn/extensions/git/package.i18n.json +++ b/i18n/jpn/extensions/git/package.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "command.clone": "複製", + "command.clone": "クローン", "command.init": "リポジトリの初期化", "command.close": "リポジトリを閉じる", "command.refresh": "最新の情報に更新", @@ -52,8 +52,9 @@ "command.stash": "スタッシュ", "command.stashPop": "スタッシュを適用して削除...", "command.stashPopLatest": "最新のスタッシュを適用して削除", - "config.enabled": "Git が有効になっているかどうか", + "config.enabled": "Git を有効にするかどうか", "config.path": "Git 実行可能ファイルのパス", + "config.autoRepositoryDetection": "レポジトリを自動的に検出するかどうか", "config.autorefresh": "自動更新が有効かどうか", "config.autofetch": "自動フェッチが有効かどうか", "config.enableLongCommitWarning": "長いコミット メッセージについて警告するかどうか", @@ -72,5 +73,6 @@ "colors.deleted": "リソースを検出した場合の配色", "colors.untracked": "リソースを追跡しない場合の配色", "colors.ignored": "リソースを無視する場合の配色", - "colors.conflict": "リソースが競合する場合の配色" + "colors.conflict": "リソースが競合する場合の配色", + "colors.submodule": "サブモジュールの配色。" } \ No newline at end of file diff --git a/i18n/jpn/extensions/markdown/package.i18n.json b/i18n/jpn/extensions/markdown/package.i18n.json index 9c09de2d69a..5f1c24f35e0 100644 --- a/i18n/jpn/extensions/markdown/package.i18n.json +++ b/i18n/jpn/extensions/markdown/package.i18n.json @@ -19,6 +19,6 @@ "markdown.showSource.title": "ソースの表示", "markdown.styles.dec": "マークダウン プレビューから使用する CSS スタイル シートの URL またはローカル パスの一覧。相対パスは、エクスプローラーで開かれているフォルダーへの絶対パスと解釈されます。開かれているフォルダーがない場合、マークダウン ファイルの場所を基準としていると解釈されます。'\\' はすべて '\\\\' と入力する必要があります。", "markdown.showPreviewSecuritySelector.title": "プレビュー のセキュリティ設定を変更", - "markdown.trace.desc": "マークダウン拡張機能のデバッグログを有効にします。", + "markdown.trace.desc": "マークダウン拡張機能のデバッグ ログを有効にします。", "markdown.refreshPreview.title": "プレビューを更新" } \ No newline at end of file diff --git a/i18n/jpn/extensions/php/package.i18n.json b/i18n/jpn/extensions/php/package.i18n.json index 1e7a986fcec..77aae3a85d1 100644 --- a/i18n/jpn/extensions/php/package.i18n.json +++ b/i18n/jpn/extensions/php/package.i18n.json @@ -6,7 +6,7 @@ { "configuration.suggest.basic": "組み込みの PHP 言語候補機能を有効にするかどうかを設定します。このサポートによって、PHP グローバルと変数の候補が示されます。", "configuration.validate.enable": "組み込みの PHP 検証を有効/無効にします。", - "configuration.validate.executablePath": "PHP 実行可能ファイルを指します。", + "configuration.validate.executablePath": "PHP 実行可能ファイルを指定します。", "configuration.validate.run": "リンターを保存時に実行するか、入力時に実行するか。", "configuration.title": "PHP", "commands.categroy.php": "PHP", diff --git a/i18n/jpn/extensions/typescript/out/commands.i18n.json b/i18n/jpn/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..e996cf2c1a9 --- /dev/null +++ b/i18n/jpn/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "TypeScript または JavaScript プロジェクトを使用するには、VS Code でフォルダーを開いてください", + "typescript.projectConfigUnsupportedFile": "TypeScript または JavaScript のプロジェクトを判別できませんでした。サポートされていないファイルの種類です", + "typescript.projectConfigCouldNotGetInfo": "TypeScript または JavaScript のプロジェクトを判別できませんでした", + "typescript.noTypeScriptProjectConfig": "ファイルは TypeScript プロジェクトの一部ではない", + "typescript.noJavaScriptProjectConfig": "ファイルは JavaScript プロジェクトの一部ではない", + "typescript.configureTsconfigQuickPick": "tsconfig.json を構成する", + "typescript.configureJsconfigQuickPick": "jsconfig.json を構成する", + "typescript.projectConfigLearnMore": "詳細情報" +} \ No newline at end of file diff --git a/i18n/jpn/extensions/typescript/package.i18n.json b/i18n/jpn/extensions/typescript/package.i18n.json index 837e11b2972..0b964b94699 100644 --- a/i18n/jpn/extensions/typescript/package.i18n.json +++ b/i18n/jpn/extensions/typescript/package.i18n.json @@ -37,7 +37,7 @@ "typescript.referencesCodeLens.enabled": "TypeScript ファイル内で CodeLens の参照を有効/無効にします。TypeScript 2.0.6 以上が必要です。", "typescript.implementationsCodeLens.enabled": "CodeLens の実装を有効/無効にします。TypeScript 2.2.0 以上が必要です。", "typescript.openTsServerLog.title": "TS サーバーのログを開く", - "typescript.restartTsServer": "TS サーバーを再起動する", + "typescript.restartTsServer": "TS サーバーを再起動", "typescript.selectTypeScriptVersion.title": "TypeScript のバージョンの選択", "typescript.reportStyleChecksAsWarnings": "スタイルチェックレポートを警告扱いとする", "jsDocCompletion.enabled": " 自動 JSDoc コメントを有効/無効にします", diff --git a/i18n/jpn/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/jpn/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/jpn/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/base/node/ps.i18n.json b/i18n/jpn/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..94b9be48727 --- /dev/null +++ b/i18n/jpn/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "CPU とメモリーの情報を収集しています。これには数秒かかる場合があります。" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/code/electron-main/menus.i18n.json b/i18n/jpn/src/vs/code/electron-main/menus.i18n.json index 8a7dad6df22..3de2dd195d0 100644 --- a/i18n/jpn/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/jpn/src/vs/code/electron-main/menus.i18n.json @@ -97,7 +97,7 @@ "miMoveSidebarRight": "サイド バーを右へ移動(&&M)", "miMoveSidebarLeft": "サイド バーを左へ移動(&&M)", "miTogglePanel": "パネルの切り替え(&&P)", - "miHideStatusbar": "ステータス バーを非表示にする(&&H)", + "miHideStatusbar": "ステータス バーを非表示(&&H)", "miShowStatusbar": "ステータス バーの表示(&&S)", "miHideActivityBar": "アクティビティ バーを非表示にする(&&A)", "miShowActivityBar": "アクティビティ バーを表示する(&&A)", @@ -146,7 +146,7 @@ "miEnableAllBreakpoints": "すべてのブレークポイントを有効にする", "miDisableAllBreakpoints": "すべてのブレークポイントを無効にする(&&L)", "miRemoveAllBreakpoints": "すべてのブレークポイントを削除する(&&R)", - "miInstallAdditionalDebuggers": "その他のデバッガーをインストールします(&&I)...", + "miInstallAdditionalDebuggers": "追加のデバッガーをインストール(&&I)...", "mMinimize": "最小化", "mZoom": "ズーム", "mBringToFront": "すべてを前面に配置", diff --git a/i18n/jpn/src/vs/code/node/cliProcessMain.i18n.json b/i18n/jpn/src/vs/code/node/cliProcessMain.i18n.json index 17e8239c8b5..36f86e4b3e5 100644 --- a/i18n/jpn/src/vs/code/node/cliProcessMain.i18n.json +++ b/i18n/jpn/src/vs/code/node/cliProcessMain.i18n.json @@ -10,7 +10,7 @@ "successVsixInstall": "拡張機能 '{0}' が正常にインストールされました。", "cancelVsixInstall": "拡張機能 '{0}' のインストールをキャンセルしました。", "alreadyInstalled": "拡張機能 '{0}' は既にインストールされています。", - "foundExtension": "マーケットプレースで '{0}' が見つかりました。", + "foundExtension": "Marketplace で '{0}' が見つかりました。", "installing": "インストールしています...", "successInstall": "拡張機能 '{0}' v{1} が正常にインストールされました!", "uninstalling": "{0} をアンインストールしています...", diff --git a/i18n/jpn/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/jpn/src/vs/editor/common/config/commonEditorConfig.i18n.json index ccf74d0af32..6d5f2ea1582 100644 --- a/i18n/jpn/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/jpn/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "行番号は、絶対数として表示されます。", "lineNumbers.relative": "行番号は、カーソル位置までの行数として表示されます。", "lineNumbers.interval": "行番号は 10 行ごとに表示されます。", - "lineNumbers": "行番号の表示を制御します。使用可能な値は、'on'、'off'、および 'relative' です。", + "lineNumbers": "行番号の表示を制御します。使用可能な値は、'on'、'off'、'relative'、'interval' です。", "rulers": "等幅フォントの特定番号の後ろに垂直ルーラーを表示します。複数のルーラーには複数の値を使用します。配列が空の場合はルーラーを表示しません。", "wordSeparators": "単語に関連したナビゲーションまたは操作を実行するときに、単語の区切り文字として使用される文字", "tabSize": "1 つのタブに相当するスペースの数。`editor.detectIndentation` がオンの場合、この設定はファイル コンテンツに基づいて上書きされます。", @@ -72,6 +72,7 @@ "cursorBlinking": "カーソルのアニメーション スタイルを制御します。指定できる値は 'blink'、'smooth'、'phase'、'expand'、'solid' です", "mouseWheelZoom": "Ctrl キーを押しながらマウス ホイールを使用してエディターのフォントをズームします", "cursorStyle": "カーソルのスタイルを制御します。指定できる値は 'block'、'block-outline'、'line'、'line-thin'、'underline'、'underline-thin' です", + "lineCursorWidth": "editor.cursorStyle が 'line' に設定されている場合、カーソルの幅を制御する", "fontLigatures": "フォントの合字を使用します", "hideCursorInOverviewRuler": "概要ルーラーでカーソルを非表示にするかどうかを制御します。", "renderWhitespace": "エディターで空白文字を表示する方法を制御します。'none'、'boundary' および 'all' が使用可能です。'boundary' オプションでは、単語間の単一スペースは表示されません。", diff --git a/i18n/jpn/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/jpn/src/vs/editor/common/view/editorColorRegistry.i18n.json index ccbe80f4d39..89993cc3618 100644 --- a/i18n/jpn/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/jpn/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,7 @@ { "lineHighlight": "カーソル位置の行を強調表示する背景色。", "lineHighlightBorderBox": "カーソル位置の行の境界線を強調表示する背景色。", - "rangeHighlight": "Quick Open 機能や検索機能などによって強調表示された範囲の背景色。", + "rangeHighlight": "Quick Open 機能や検索機能などによって強調表示された範囲の背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", "caret": "エディターのカーソルの色。", "editorCursorBackground": "選択された文字列の背景色です。選択された文字列の背景色をカスタマイズ出来ます。", "editorWhitespaces": "エディターのスペース文字の色。", diff --git a/i18n/jpn/src/vs/editor/contrib/folding/folding.i18n.json b/i18n/jpn/src/vs/editor/contrib/folding/folding.i18n.json index c6a310be421..1c780e8f0a3 100644 --- a/i18n/jpn/src/vs/editor/contrib/folding/folding.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/folding/folding.i18n.json @@ -13,5 +13,5 @@ "unfoldAllMarkerRegions.label": "すべての領域を展開", "foldAllAction.label": "すべて折りたたみ", "unfoldAllAction.label": "すべて展開", - "foldLevelAction.label": "折りたたみレベル {0}" + "foldLevelAction.label": "レベル {0} で折りたたむ" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/jpn/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 53ea71a9d4e..37cec91d1cd 100644 --- a/i18n/jpn/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "次のエラーまたは警告へ移動", - "markerAction.previous.label": "前のエラーまたは警告へ移動", + "markerAction.next.label": "次の問題 (エラー、警告、情報) へ移動", + "markerAction.previous.label": "前の問題 (エラー、警告、情報) へ移動", "editorMarkerNavigationError": "エディターのマーカー ナビゲーション ウィジェットのエラーの色。", "editorMarkerNavigationWarning": "エディターのマーカー ナビゲーション ウィジェットの警告の色。", "editorMarkerNavigationInfo": "エディターのマーカー ナビゲーション ウィジェットの情報の色。", diff --git a/i18n/jpn/src/vs/editor/contrib/multicursor/multicursor.i18n.json b/i18n/jpn/src/vs/editor/contrib/multicursor/multicursor.i18n.json index 0df6dca88c6..22250151607 100644 --- a/i18n/jpn/src/vs/editor/contrib/multicursor/multicursor.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/multicursor/multicursor.i18n.json @@ -7,10 +7,10 @@ "mutlicursor.insertAbove": "カーソルを上に挿入", "mutlicursor.insertBelow": "カーソルを下に挿入", "mutlicursor.insertAtEndOfEachLineSelected": "カーソルを行末に挿入", - "addSelectionToNextFindMatch": "選択した項目を次の一致項目に追加", - "addSelectionToPreviousFindMatch": "選んだ項目を前の一致項目に追加する", + "addSelectionToNextFindMatch": "選択項目を次の一致項目に追加", + "addSelectionToPreviousFindMatch": "選択項目を次の一致項目に追加", "moveSelectionToNextFindMatch": "最後に選択した項目を次の一致項目に移動", - "moveSelectionToPreviousFindMatch": "最後に選んだ項目を前の一致項目に移動する", - "selectAllOccurrencesOfFindMatch": "一致するすべての出現箇所を選択します", + "moveSelectionToPreviousFindMatch": "最後に選択した項目を前の一致項目に移動", + "selectAllOccurrencesOfFindMatch": "一致するすべての出現箇所を選択", "changeAll.label": "すべての出現箇所を変更" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.i18n.json b/i18n/jpn/src/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.i18n.json index 63cb6013496..6b75d7b1bbe 100644 --- a/i18n/jpn/src/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggle.tabMovesFocus": "Tab キーを切り替えるとフォーカスが移動します" + "toggle.tabMovesFocus": "TAB キーのフォーカス移動を切り替え" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/jpn/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index 8eac21c6979..9ecf4479aa8 100644 --- a/i18n/jpn/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "変数の読み取りなど読み取りアクセス中のシンボルの背景色。", - "wordHighlightStrong": "変数への書き込みなど書き込みアクセス中のシンボルの背景色。", + "wordHighlight": "変数の読み取りなど読み取りアクセス中のシンボルの背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "wordHighlightStrong": "変数への書き込みなど書き込みアクセス中のシンボルの背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", "overviewRulerWordHighlightForeground": "シンボルを強調表示するときの概要ルーラーのマーカー色。", "overviewRulerWordHighlightStrongForeground": "書き込みアクセス シンボルを強調表示するときの概要ルーラーのマーカー色。", "wordHighlight.next.label": "次のシンボル ハイライトに移動", diff --git a/i18n/jpn/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/jpn/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index 981e3bb87da..2a2b18aa6b8 100644 --- a/i18n/jpn/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/jpn/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "`{0}` は有効なメニュー識別子ではありません", "missing.command": "メニュー項目が、'commands' セクションで定義されていないコマンド `{0}` を参照しています。", "missing.altCommand": "メニュー項目が、'commands' セクションで定義されていない alt コマンド `{0}` を参照しています。", - "dupe.command": "メニュー項目において、既定と alt コマンドが同じコマンドを参照しています", - "nosupport.altCommand": "申し訳ございません。現在、alt コマンドをサポートしているのは 'editor/title' メニューの 'navigation' グループのみです" + "dupe.command": "メニュー項目において、既定と alt コマンドが同じコマンドを参照しています" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/platform/environment/node/argv.i18n.json b/i18n/jpn/src/vs/platform/environment/node/argv.i18n.json index e5dd71eb7e2..41c3e146387 100644 --- a/i18n/jpn/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/jpn/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,35 @@ "diff": "2 つのファイルを比較します。", "add": "最後にアクティブだったウィンドウにフォルダーを追加します。", "goto": "指定した行と文字の位置にあるパスでファイルを開きます。", - "locale": "使用する国と地域 (例:en-US や zh-TW など)。", "newWindow": "新しい Code のインスタンスを強制します。", - "performance": "'Developer: Startup Performance' コマンドを有効にして開始します。", - "prof-startup": "起動中に CPU プロファイラーを実行する", - "inspect-extensions": "拡張機能のデバッグとプロファイリングを許可します。接続 URI を開発者ツールでチェックします。", - "inspect-brk-extensions": "起動後に一時停止されている拡張ホストとの拡張機能のデバッグとプロファイリングを許可します。接続 URI を開発者ツールでチェックします。", "reuseWindow": "最後のアクティブ ウィンドウにファイルまたはフォルダーを強制的に開きます。", - "userDataDir": "ユーザー データを保持するディレクトリを指定します。ルートで実行している場合に役立ちます。", - "log": "使用するログレベル。既定値は 'info' です。利用可能な値は 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off' です。", - "verbose": "詳細出力を表示します (--wait を含みます)。", "wait": "現在のファイルが閉じられるまで待機します。", + "locale": "使用する国と地域 (例:en-US や zh-TW など)。", + "userDataDir": "ユーザー データを保持するディレクトリを指定します。ルートで実行している場合に役立ちます。", + "version": "バージョンを表示します。", + "help": "使用法を表示します。", "extensionHomePath": "拡張機能のルート パスを設定します。", "listExtensions": "インストールされている拡張機能を一覧表示します。", "showVersions": "--list-extension と使用するとき、インストールされている拡張機能のバージョンを表示します。", "installExtension": "拡張機能をインストールします。", "uninstallExtension": "拡張機能をアンインストールします。", "experimentalApis": "拡張機能に対して Proposed API 機能を有効にします。", - "disableExtensions": "インストールされたすべての拡張機能を無効にします。", - "disableGPU": "GPU ハードウェア アクセラレータを無効にします。", + "verbose": "詳細出力を表示します (--wait を含みます)。", + "log": "使用するログレベル。既定値は 'info' です。利用可能な値は 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off' です。", "status": "プロセスの使用状況や診断情報を印刷します。", - "version": "バージョンを表示します。", - "help": "使用法を表示します。", + "performance": "'Developer: Startup Performance' コマンドを有効にして開始します。", + "prof-startup": "起動中に CPU プロファイラーを実行する", + "disableExtensions": "インストールされたすべての拡張機能を無効にします。", + "inspect-extensions": "拡張機能のデバッグとプロファイリングを許可します。接続 URI を開発者ツールでチェックします。", + "inspect-brk-extensions": "起動後に一時停止されている拡張ホストとの拡張機能のデバッグとプロファイリングを許可します。接続 URI を開発者ツールでチェックします。", + "disableGPU": "GPU ハードウェア アクセラレータを無効にします。", + "uploadLogs": "現在のセッションから安全なエンドポイントにログをアップロードします。", "usage": "使用法", "options": "オプション", "paths": "パス", - "optionsUpperCase": "オプション" + "stdinWindows": "別のプログラムから出力を読み取るには、'-' を付け足してください (例: 'echo Hello World | {0} -')", + "stdinUnix": "stdin から読み取るには、'-' を付け足してください (例: 'ps aux | grep code | {0} -')", + "optionsUpperCase": "オプション", + "extensionsManagement": "拡張機能の管理", + "troubleshooting": "トラブルシューティング" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/jpn/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index 9901a3c82e4..9b169d44885 100644 --- a/i18n/jpn/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/jpn/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,15 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "正しくない拡張機能: package.json は JSON ファイルではありません。", - "restartCodeLocal": "{0} を再インストールする前に、Code を再起動してください。", + "restartCode": "{0} を再インストールする前に、Code を再起動してください。", "installingOutdatedExtension": "この拡張機能の新しいバージョンが既にインストールされています。古いバージョンでこれを上書きしますか?", "override": "上書き", "cancel": "キャンセル", - "notFoundCompatible": "VS Code の現在のバージョン '{1}' と互換性を持つ拡張機能 '{0}' が見つからないため、インストールできません。", - "quitCode": "拡張機能の古いインスタンスがまだ実行中であるため、インストールできません。再インストール前に VS Code の終了と起動を実施してください。", - "exitCode": "拡張機能の古いインスタンスがまだ実行中であるため、インストールできません。再インストール前に VS Code の終了と起動を実施してください。", + "errorInstallingDependencies": "依存関係のインストール中にエラーが発生しました。{0}", + "notFoundCompatible": "'{0}' をインストールできません。VS Code '{1}' と互換性がある利用可能なバージョンがありません。", "notFoundCompatibleDependency": "VS Code の現在のバージョン '{1}' と互換性を持つ、依存関係がある拡張機能 '{0}' が見つからないため、インストールできません。", + "quitCode": "拡張機能をインストールできません。再インストールの前に VS Code の終了と起動を実施してください。", + "exitCode": "拡張機能をインストールできません。再インストールの前に VS Code の終了と起動を実施してください。", "uninstallDependeciesConfirmation": "'{0}' のみをアンインストールしますか、または依存関係もアンインストールしますか?", "uninstallOnly": "限定", "uninstallAll": "すべて", diff --git a/i18n/jpn/src/vs/platform/message/common/message.i18n.json b/i18n/jpn/src/vs/platform/message/common/message.i18n.json index 85415e2c95f..15eee72cd0d 100644 --- a/i18n/jpn/src/vs/platform/message/common/message.i18n.json +++ b/i18n/jpn/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "閉じる", "later": "後続", - "cancel": "キャンセル" + "cancel": "キャンセル", + "moreFile": "...1 つの追加ファイルが表示されていません", + "moreFiles": "...{0} 個の追加ファイルが表示されていません" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/jpn/src/vs/platform/theme/common/colorRegistry.i18n.json index 24c492550e3..46bb9caa152 100644 --- a/i18n/jpn/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/jpn/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,12 @@ "editorWidgetBorder": "エディター ウィジェットの境界線色。ウィジェットに境界線があり、ウィジェットによって配色を上書きされていない場合でのみこの配色は使用されます。", "editorSelectionBackground": "エディターの選択範囲の色。", "editorSelectionForeground": "ハイ コントラストの選択済みテキストの色。", - "editorInactiveSelection": "非アクティブなエディターの選択範囲の色。", - "editorSelectionHighlight": "選択範囲と同じコンテンツの領域の色。", + "editorInactiveSelection": "非アクティブなエディターの選択範囲の色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "editorSelectionHighlight": "選択範囲と同じコンテンツの領域の色。下にある装飾を隠さないために、色は不透過であってはなりません。", "editorFindMatch": "現在の検索一致項目の色。", - "findMatchHighlight": "他の検索一致項目の色。", - "findRangeHighlight": "検索を制限する範囲の色。", - "hoverHighlight": "ホバーが表示されているワードの下を強調表示します。", + "findMatchHighlight": "他の検索一致項目の色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "findRangeHighlight": "検索を制限する範囲の色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "hoverHighlight": "ホバーが表示されているワードの下を強調表示します。下にある装飾を隠さないために、色は不透過であってはなりません。", "hoverBackground": "エディター ホバーの背景色。", "hoverBorder": "エディター ホバーの境界線の色。", "activeLinkForeground": "アクティブなリンクの色。", @@ -76,12 +76,12 @@ "diffEditorRemoved": "削除されたテキストの背景色。", "diffEditorInsertedOutline": "挿入されたテキストの輪郭の色。", "diffEditorRemovedOutline": "削除されたテキストの輪郭の色。", - "mergeCurrentHeaderBackground": "行内マージ競合の現在のヘッダー背景色。", - "mergeCurrentContentBackground": "行内マージ競合の現在のコンテンツ背景色。", - "mergeIncomingHeaderBackground": "行内マージ競合の入力側ヘッダー背景色。", - "mergeIncomingContentBackground": "行内マージ競合の入力側コンテンツ背景色。", - "mergeCommonHeaderBackground": "行内マージ競合の共通の祖先ヘッダー背景色。", - "mergeCommonContentBackground": "行内マージ競合の共通の祖先コンテンツ背景色。", + "mergeCurrentHeaderBackground": "行内マージ競合の現在のヘッダー背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "mergeCurrentContentBackground": "行内マージ競合の現在のコンテンツ背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "mergeIncomingHeaderBackground": "行内マージ競合の入力側ヘッダー背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "mergeIncomingContentBackground": "行内マージ競合の入力側コンテンツ背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "mergeCommonHeaderBackground": "行内マージ競合の共通の祖先ヘッダー背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", + "mergeCommonContentBackground": "行内マージ競合の共通の祖先コンテンツ背景色。下にある装飾を隠さないために、色は不透過であってはなりません。", "mergeBorder": "行内マージ競合のヘッダーとスプリッターの境界線の色。", "overviewRulerCurrentContentForeground": "行内マージ競合の現在の概要ルーラー前景色。", "overviewRulerIncomingContentForeground": "行内マージ競合の入力側の概要ルーラー前景色。", diff --git a/i18n/jpn/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/jpn/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..e4fd63e4462 --- /dev/null +++ b/i18n/jpn/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "saveParticipants": "Save Participants が実行中です..." +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/jpn/src/vs/workbench/api/node/extHostTreeViews.i18n.json index 74c5f0eabd7..ee062e8f6d2 100644 --- a/i18n/jpn/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/jpn/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "treeView.notRegistered": "ID '{0}' のツリー ビューは登録されていません。", - "treeItem.notFound": "ID '{0}' のツリー項目は見つかりませんでした。", - "treeView.duplicateElement": " {0} 要素は既に登録されています。" + "treeView.duplicateElement": "id [0] の要素はすでに登録されています。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/jpn/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index 4faa6069b27..9196d2adf6f 100644 --- a/i18n/jpn/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "サイド バーの位置の切り替え", + "toggleSidebarPosition": "サイド バーの位置の切り替え", "view": "表示" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/jpn/src/vs/workbench/browser/actions/workspaceActions.i18n.json index 60ed1228f04..69c30877972 100644 --- a/i18n/jpn/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "ファイルを開く...", "openFolder": "フォルダーを開く...", "openFileFolder": "開く...", - "addFolderToWorkspace": "ワークスペースにフォルダーを追加...", - "add": "追加(&&A)", - "addFolderToWorkspaceTitle": "ワークスペースにフォルダーを追加", "globalRemoveFolderFromWorkspace": "ワークスペースからフォルダーを削除...", - "removeFolderFromWorkspace": "ワークスペースからフォルダーを削除", - "openFolderSettings": "フォルダーの設定を開く", "saveWorkspaceAsAction": "名前を付けてワークスペースを保存...", "save": "保存(&&S)", "saveWorkspace": "ワークスペースを保存", "openWorkspaceAction": "ワークスペースを開く...", "openWorkspaceConfigFile": "ワークスペースの構成ファイルを開く", - "openFolderAsWorkspaceInNewWindow": "新しいウィンドウでワークスペースとしてフォルダーを開く", - "workspaceFolderPickerPlaceholder": "ワークスペース フォルダーを選択" + "openFolderAsWorkspaceInNewWindow": "新しいウィンドウでワークスペースとしてフォルダーを開く" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/jpn/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..d1d72afcab9 --- /dev/null +++ b/i18n/jpn/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "ワークスペースにフォルダーを追加...", + "add": "追加(&&A)", + "addFolderToWorkspaceTitle": "ワークスペースにフォルダーを追加", + "workspaceFolderPickerPlaceholder": "ワークスペース フォルダーを選択" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/jpn/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index 86cc5cdfa14..ef30ff122d1 100644 --- a/i18n/jpn/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,18 @@ "groupThreePicker": "3 番目のグループのエディターを表示する", "allEditorsPicker": "開いているエディターをすべて表示する", "view": "表示", - "file": "ファイル" + "file": "ファイル", + "close": "閉じる", + "closeOthers": "その他を閉じる", + "closeRight": "右側を閉じる", + "closeAllUnmodified": "未変更を閉じる", + "closeAll": "すべて閉じる", + "keepOpen": "開いたままにする", + "toggleInlineView": "インライン表示に切り替え", + "showOpenedEditors": "開いているエディターを表示", + "keepEditor": "エディターを保持", + "closeEditorsInGroup": "グループ内のすべてのエディターを閉じる", + "closeUnmodifiedEditors": "グループ内の未変更のエディターを閉じる", + "closeOtherEditors": "その他のエディターを閉じる", + "closeRightEditors": "右側のエディターを閉じる" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/jpn/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index 9e1f0ccd5c3..3d1749e2a39 100644 --- a/i18n/jpn/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "エディターを閉じる", "revertAndCloseActiveEditor": "元に戻してエディターを閉じる", "closeEditorsToTheLeft": "左側のエディターを閉じる", - "closeEditorsToTheRight": "右側のエディターを閉じる", "closeAllEditors": "すべてのエディターを閉じる", - "closeUnmodifiedEditors": "グループ内の未変更のエディターを閉じる", "closeEditorsInOtherGroups": "他のグループ内のエディターを閉じる", - "closeOtherEditorsInGroup": "その他のエディターを閉じる", - "closeEditorsInGroup": "グループ内のすべてのエディターを閉じる", "moveActiveGroupLeft": "エディター グループを左側に移動する", "moveActiveGroupRight": "エディター グループを右側に移動する", "minimizeOtherEditorGroups": "他のエディター グループを最小化する", "evenEditorGroups": "エディター グループの幅を等間隔に設定する", "maximizeEditor": "エディター グループを最大化してサイドバーを非表示にする", - "keepEditor": "エディターを保持", "openNextEditor": "次のエディターを開く", "openPreviousEditor": "以前のエディターを開く", "nextEditorInGroup": "グループ内で次のエディターを開く", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "最初のグループのエディターを表示する", "showEditorsInSecondGroup": "2 番目のグループでエディターを表示する", "showEditorsInThirdGroup": "3 番目のグループのエディターを表示する", - "showEditorsInGroup": "エディターをグループに表示する", "showAllEditors": "すべてのエディターを表示する", "openPreviousRecentlyUsedEditorInGroup": "グループ内の最近使用したエディターのうち前のエディターを開く", "openNextRecentlyUsedEditorInGroup": "グループ内の最近使用したエディターのうち次のエディターを開く", @@ -54,5 +48,8 @@ "moveEditorLeft": "エディターを左へ移動", "moveEditorRight": "エディターを右へ移動", "moveEditorToPreviousGroup": "エディターを前のグループに移動", - "moveEditorToNextGroup": "エディターを次のグループに移動" + "moveEditorToNextGroup": "エディターを次のグループに移動", + "moveEditorToFirstGroup": "エディターを 1 番目のグループに移動", + "moveEditorToSecondGroup": "エディターを 2 番目のグループに移動", + "moveEditorToThirdGroup": "エディターを 3 番目のグループに移動" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/jpn/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 31949627cfd..faa2938621c 100644 --- a/i18n/jpn/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "タブまたはグループ別にアクティブ エディターを移動する", "editorCommand.activeEditorMove.arg.name": "アクティブ エディターの Move 引数", - "editorCommand.activeEditorMove.arg.description": "引数プロパティ:\n\t* 'to': 移動先を指定する文字列値。\n\t* 'by': 移動の単位を指定する文字列値。タブ別またはグループ別。\n\t* 'value': 移動の位置数もしくは絶対位置を指定する数値。", - "commandDeprecated": "コマンド **{0}** は削除されました。代わりに **{1}** を使用できます", - "openKeybindings": "ショートカット キーの構成" + "editorCommand.activeEditorMove.arg.description": "引数プロパティ:\n\t* 'to': 移動先を指定する文字列値。\n\t* 'by': 移動の単位を指定する文字列値。タブ別またはグループ別。\n\t* 'value': 移動の位置数もしくは絶対位置を指定する数値。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/jpn/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index e5581c64d21..17ddb4365e0 100644 --- a/i18n/jpn/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "テキスト ファイル比較エディター。", "navigate.next.label": "次の変更箇所", "navigate.prev.label": "前の変更箇所", - "inlineDiffLabel": "インライン表示に切り替え", - "sideBySideDiffLabel": "並べて表示に切り替え" + "toggleIgnoreTrimWhitespace.label": "末尾の空白文字のトリミングを無視する" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/jpn/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index c10bd2e7b60..f0f64f4f3ad 100644 --- a/i18n/jpn/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "閉じる", - "closeOthers": "その他を閉じる", - "closeRight": "右側を閉じる", - "closeAll": "すべて閉じる", - "closeAllUnmodified": "未変更を閉じる", - "keepOpen": "開いたままにする", - "showOpenedEditors": "開いているエディターを表示", "araLabelEditorActions": "エディター操作" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/jpn/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index 5c96f185104..2ac16cc30bc 100644 --- a/i18n/jpn/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[サポート対象外]", + "userIsAdmin": "[管理者]", + "userIsSudo": "[スーパー ユーザー]", "devExtensionWindowTitlePrefix": "[拡張機能開発ホスト]" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/jpn/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index 39d2dcfed3e..2c65d714079 100644 --- a/i18n/jpn/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/jpn/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "hideView": "サイド バーから非表示" + "hideView": "非表示" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/common/theme.i18n.json b/i18n/jpn/src/vs/workbench/common/theme.i18n.json index a296fd913c1..61bc140d9d3 100644 --- a/i18n/jpn/src/vs/workbench/common/theme.i18n.json +++ b/i18n/jpn/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "アクティブ タブの背景色。タブはエディター領域におけるエディターのコンテナーです。1 つのエディター グループで複数のタブを開くことができます。エディター グループを複数にすることもできます。", "tabInactiveBackground": "非アクティブ タブの背景色。タブはエディター領域におけるエディターのコンテナーです。1 つのエディター グループで複数のタブを開くことができます。エディター グループを複数にすることもできます。", + "tabHoverBackground": "ホバー時のタブの背景色。タブはエディター領域におけるエディターのコンテナです。1 つのエディター グループで複数のタブを開くことができます。エディター グループを複数にすることもできます。", + "tabUnfocusedHoverBackground": "ホバー時のフォーカスされていないグループ内のタブの背景色。タブはエディター領域におけるエディターのコンテナです。1 つのエディター グループで複数のタブを開くことができます。エディター グループを複数にすることもできます。", "tabBorder": "タブ同士を分けるための境界線。タブはエディター領域内にあるエディターのコンテナーです。複数のタブを 1 つのエディター グループで開くことができます。複数のエディター グループがある可能性があります。", "tabActiveBorder": "アクティブなタブを強調表示するための境界線。タブはエディター領域内にあるエディターのコンテナーです。複数のタブを 1 つのエディター グループで開くことができます。複数のエディター グループがある可能性があります。", "tabActiveUnfocusedBorder": "フォーカスされていないグループ内のアクティブ タブを強調表示するための境界線。タブはエディター領域内にあるエディターのコンテナーです。複数のタブを 1 つのエディター グループで開くことができます。複数のエディター グループがある可能性があります。", + "tabHoverBorder": "ホバー時のタブを強調表示するための境界線。タブはエディター領域内にあるエディターのコンテナーです。複数のタブを 1 つのエディター グループで開くことができます。複数のエディター グループがある可能性があります。", + "tabUnfocusedHoverBorder": "ホバー時のフォーカスされていないグループ内のタブを強調表示するための境界線。タブはエディター領域内にあるエディターのコンテナーです。複数のタブを 1 つのエディター グループで開くことができます。複数のエディター グループがある可能性があります。", "tabActiveForeground": "アクティブ グループ内のアクティブ タブの前景色。タブはエディター領域におけるエディターのコンテナーです。1 つのエディター グループで複数のタブを開くことができます。エディター グループを複数にすることもできます。", "tabInactiveForeground": "アクティブ グループ内の非アクティブ タブの前景色。タブはエディター領域におけるエディターのコンテナーです。1 つのエディター グループで複数のタブを開くことができます。エディター グループを複数にすることもできます。", "tabUnfocusedActiveForeground": "フォーカスされていないグループ内のアクティブ タブの前景色。タブはエディター領域におけるエディターのコンテナーです。1 つのエディター グループで複数のタブを開くことができます。エディター グループを複数にすることもできます。", @@ -16,7 +20,7 @@ "editorGroupBackground": "エディター グループの背景色。エディター グループはエディターのコンテナーです。背景色はエディター グループをドラッグすると表示されます。", "tabsContainerBackground": "タブが有効な場合の エディター グループ タイトル ヘッダーの背景色。エディター グループはエディターのコンテナーです。", "tabsContainerBorder": "タブが有効な場合の エディター グループ タイトル ヘッダーの境界線色。エディター グループはエディターのコンテナーです。", - "editorGroupHeaderBackground": "タブが無効な場合の エディター グループ タイトル ヘッダーの背景色。エディター グループはエディターのコンテナーです。", + "editorGroupHeaderBackground": "タブが無効な場合 (`\"workbench.editor.showTabs\": false`) のエディター グループ タイトル ヘッダーの背景色。エディター グループはエディターのコンテナーです。", "editorGroupBorder": "複数のエディター グループを互いに分離するための色。エディター グループはエディターのコンテナーです。", "editorDragAndDropBackground": "エディターの周囲をドラッグしているときの背景色。エディターのコンテンツが最後まで輝くために、色は透過である必要があります。", "panelBackground": "パネルの背景色。パネルはエディター領域の下に表示され、出力や統合ターミナルなどのビューを含みます。", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "フォルダーを開いていないときにサイドバーとエディターを隔てるワークスペースのステータス バーの境界線の色。ステータス バーはウィンドウの下部に表示されます。 ", "statusBarItemActiveBackground": "クリック時のステータス バーの項目の背景色。ステータス バーはウィンドウの下部に表示されます。", "statusBarItemHoverBackground": "ホバーしたときのステータス バーの項目の背景色。ステータス バーはウィンドウの下部に表示されます。", - "statusBarProminentItemBackground": "ステータス バーの重要な項目の背景色。重要な項目は、重要性を示すために他のステータスバーの項目から際立っています。 ステータス バーはウィンドウの下部に表示されます。", - "statusBarProminentItemHoverBackground": "ホバーしたときのステータス バーの重要な項目の背景色。重要な項目は、重要性を示すために他のステータスバーの項目から際立っています。 ステータス バーはウィンドウの下部に表示されます。", + "statusBarProminentItemBackground": "ステータスバーで目立たせる項目の背景色。この項目は、重要性を示すために他のエントリーより目立って表示されます。コマンドパレットから `Toggle Tab Key Moves Focus` に切り替えると例を見ることができます。ステータスバーはウィンドウの下部に表示されます。", + "statusBarProminentItemHoverBackground": "ホバー中のステータスバーで目立たせる項目の背景色。この項目は、重要性を示すために他のエントリーより目立って表示されます。コマンドパレットから `Toggle Tab Key Moves Focus` に切り替えると例を見ることができます。ステータスバーはウィンドウの下部に表示されます。", "activityBarBackground": "アクティビティ バーの背景色。アクティビティ バーは左端または右端に表示され、サイド バーのビューを切り替えることができます。", "activityBarForeground": "アクティビティ バーの前景色 (例: アイコンの色)。アクティビティ バーは左端または右端に表示され、サイド バーのビューを切り替えることができます。", "activityBarBorder": "サイド バーと隔てるアクティビティ バーの境界線色。アクティビティ バーは左端または右端に表示され、サイド バーのビューを切り替えることができます。", diff --git a/i18n/jpn/src/vs/workbench/common/views.i18n.json b/i18n/jpn/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..3607a9f498a --- /dev/null +++ b/i18n/jpn/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "location `{1}` で id `{0}` のビューが既に登録されています" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/jpn/src/vs/workbench/electron-browser/actions.i18n.json index e4698109a33..68ba00974f3 100644 --- a/i18n/jpn/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/jpn/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "エディターを閉じる", "closeWindow": "ウィンドウを閉じる", "closeWorkspace": "ワークスペースを閉じる", "noWorkspaceOpened": "このインスタンスで現在開いているワークスペースがないので、閉じられません。", @@ -52,21 +51,5 @@ "displayLanguage": "VSCode の表示言語を定義します。", "doc": "サポートされている言語の一覧については、{0} をご覧ください。", "restart": "値を変更するには VS Code の再起動が必要です。", - "fail.createSettings": "'{0}' ({1}) を作成できません。", - "openLogsFolder": "ログ フォルダーを開く", - "showLogs": "ログの表示...", - "mainProcess": "メイン", - "sharedProcess": "共有", - "rendererProcess": "レンダラー", - "extensionHost": "拡張機能ホスト", - "selectProcess": "プロセスの選択", - "setLogLevel": "ログ レベルの設定", - "trace": "トレース", - "debug": "デバッグ", - "info": "情報", - "warn": "警告", - "err": "エラー", - "critical": "重大", - "off": "オフ", - "selectLogLevel": "ログ レベルを選択" + "fail.createSettings": "'{0}' ({1}) を作成できません。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/jpn/src/vs/workbench/electron-browser/main.contribution.i18n.json index 2f2b510b284..c0540ea9122 100644 --- a/i18n/jpn/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "表示", "help": "ヘルプ", "file": "ファイル", - "developer": "開発者", "workspaces": "ワークスペース", + "developer": "開発者", + "workbenchConfigurationTitle": "ワークベンチ", "showEditorTabs": "開いているエディターをタブに表示するかどうかを制御します。", "workbench.editor.labelFormat.default": "ファイルの名前を表示します。タブが有効かつ 1 つのグループ内の 2 つの同名ファイルがあるときに各ファイルのパスの区切り記号が追加されます。タブを無効にすると、エディターがアクティブな時にワークスペース フォルダーの相対パスが表示されます。", "workbench.editor.labelFormat.short": "ディレクトリ名に続けてファイル名を表示します。", @@ -20,23 +21,23 @@ "showIcons": "開いているエディターをアイコンで表示するかどうかを制御します。これには、アイコンのテーマを有効にする必要もあります。", "enablePreview": "開かれるエディターをプレビューとして表示するかどうかを制御します。プレビュー エディターは (例: ダブル クリックまたは編集などによって) 変更される時まで再利用し、斜体で表示します。", "enablePreviewFromQuickOpen": "Quick Open で開いたエディターをプレビューとして表示するかどうかを制御します。プレビュー エディターは、保持されている間、再利用されます (ダブルクリックまたは編集などによって)。", + "closeOnFileDelete": "ファイルを表示しているエディターを、ファイルが削除されるかその他のプロセスによって名前を変更された場合に、自動的に閉じるかどうかを制御します。これを無効にすると、このような場合にエディターはダーティで開かれたままになります。アプリケーション内で削除すると、必ずエディターは閉じられ、ダーティ ファイルは閉じられることがなく、データは保存されませんのでご注意ください。", "editorOpenPositioning": "エディターを開く場所を制御します。'left' または 'right' を選択すると現在アクティブになっているエディターの左または右にエディターを開きます。'first' または 'last' を選択すると現在アクティブになっているエディターとは別個にエディターを開きます。", "revealIfOpen": "任意の表示グループが開かれた場合に、そこにエディターを表示するかどうかを制御します。無効にした場合、エディターは現在のアクティブなエディター グループに優先して開かれます。有効にした場合は、現在のアクティブなエディター グループにもう一度開くのではなく、既に開いているエディターが表示されます。特定のグループ内や現在アクティブなグループの横に強制的にエディターを開いた場合などに、この設定が無視される場合もあることにご注意ください。", + "swipeToNavigate": "3 本の指で横方向にスワイプすると、開いているファイル間を移動できます。", "commandHistory": "コマンド パレットで最近使用したコマンド履歴を保持する数を制御します。0 に設定するとコマンド履歴を無効にします。", "preserveInput": "次回開いたとき、コマンド パレットの最後の入力を復元するかどうかを制御します。", "closeOnFocusLost": "フォーカスを失ったときに Quick Open を自動的に閉じるかどうかを制御します。", "openDefaultSettings": "設定を開くとすべての既定の設定を表示するエディターも開くかどうかを制御します。", "sideBarLocation": "サイド バーの位置を制御します。ワークベンチの左右のいずれかに表示できます。", + "panelDefaultLocation": "パネルの既定の位置を制御します。ワークベンチの下部または右のいずれかに表示できます。", "statusBarVisibility": "ワークベンチの下部にステータス バーを表示するかどうかを制御します。", "activityBarVisibility": "ワークベンチでのアクティビティ バーの表示をコントロールします。", - "closeOnFileDelete": "ファイルを表示しているエディターを、ファイルが削除されるかその他のプロセスによって名前を変更された場合に、自動的に閉じるかどうかを制御します。これを無効にすると、このような場合にエディターはダーティで開かれたままになります。アプリケーション内で削除すると、必ずエディターは閉じられ、ダーティ ファイルは閉じられることがなく、データは保存されませんのでご注意ください。", - "enableNaturalLanguageSettingsSearch": "設定で自然文検索モードを有効にするかどうかを制御します。", "fontAliasing": "ワークベンチのフォント エイリアシング方法を制御します。\n- default: サブピクセル方式でフォントを滑らかにします。ほとんどの非 Retina ディスプレイでもっとも鮮明なテキストを提供します\n- antialiased: サブピクセルとは対照的に、ピクセルのレベルでフォントを滑らかにします。フォント全体がより細く見えます\n- none: フォントのスムージングを無効にします。テキストをぎざぎざな尖ったエッジで表示します", "workbench.fontAliasing.default": "サブピクセル方式でフォントを滑らかにします。ほとんどの非 Retina ディスプレイでもっとも鮮明なテキストを提供します。", "workbench.fontAliasing.antialiased": "サブピクセルとは対照的に、ピクセルのレベルでフォントを滑らかにします。フォント全体がより細く見えるようになります。", "workbench.fontAliasing.none": "フォントのスムージングを無効にします。テキストをぎざぎざな尖ったエッジで表示します。", - "swipeToNavigate": "3 本の指で横方向にスワイプすると、開いているファイル間を移動できます。", - "workbenchConfigurationTitle": "ワークベンチ", + "enableNaturalLanguageSettingsSearch": "設定で自然文検索モードを有効にするかどうかを制御します。", "windowConfigurationTitle": "ウィンドウ", "window.openFilesInNewWindow.on": "新しいウィンドウでファイルを開きます", "window.openFilesInNewWindow.off": "ファイルのフォルダーが開かれていたウィンドウまたは最後のアクティブ ウィンドウでファイルを開きます", diff --git a/i18n/jpn/src/vs/workbench/electron-browser/window.i18n.json b/i18n/jpn/src/vs/workbench/electron-browser/window.i18n.json index 0813ed28598..b9e99cd4528 100644 --- a/i18n/jpn/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/jpn/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "切り取り", "copy": "コピー", "paste": "貼り付け", - "selectAll": "すべて選択" + "selectAll": "すべて選択", + "runningAsRoot": "{0} をルート ユーザーとして実行しないことを推奨します。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/codeEditor/electron-browser/accessibility.i18n.json b/i18n/jpn/src/vs/workbench/parts/codeEditor/electron-browser/accessibility.i18n.json index 1c53dd86bdd..f1f6fe1ec7d 100644 --- a/i18n/jpn/src/vs/workbench/parts/codeEditor/electron-browser/accessibility.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/codeEditor/electron-browser/accessibility.i18n.json @@ -22,5 +22,5 @@ "openDocMac": "command + H キーを押して、ブラウザー ウィンドウを今すぐ開き、アクセシビリティに関連する他の VS Code 情報を確認します。", "openDocWinLinux": "Ctrl + H キーを押して、ブラウザー ウィンドウを今すぐ開き、アクセシビリティに関連する他の VS Code 情報を確認します。", "outroMsg": "Esc キー か Shift+Esc を押すと、ヒントを消してエディターに戻ることができます。", - "ShowAccessibilityHelpAction": "アクセシビリティのヘルプを表示します" + "ShowAccessibilityHelpAction": "アクセシビリティのヘルプを表示" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.i18n.json b/i18n/jpn/src/vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.i18n.json index 3b84ee3fdb4..ec3d813e1dc 100644 --- a/i18n/jpn/src/vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/codeEditor/electron-browser/toggleMultiCursorModifier.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "マルチ カーソルの修飾キーを切り替える" + "toggleLocation": "マルチカーソル修飾子の切り替え" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/debug/browser/debugActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/browser/debugActions.i18n.json index 57ba460378d..bf61b86ff83 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/browser/debugActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/browser/debugActions.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "openLaunchJson": "{0} を開く", - "launchJsonNeedsConfigurtion": "'launch.json' を構成または修正してください", + "launchJsonNeedsConfigurtion": "'launch.json' の構成や修正", "noFolderDebugConfig": "高度なデバッグ構成を行うには、最初にフォルダーを開いてください。", "startDebug": "デバッグの開始", "startWithoutDebugging": "デバッグなしで開始", diff --git a/i18n/jpn/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index 8876044c17e..00d3b5a76c0 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "デバッグ ツール バーの背景色。" + "debugToolBarBackground": "デバッグ ツール バーの背景色。", + "debugToolBarBorder": "デバッグ ツール バーの境界線色。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/debug/browser/debugQuickOpen.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/browser/debugQuickOpen.i18n.json index f9530ecfb90..76d3254c4eb 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/browser/debugQuickOpen.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/browser/debugQuickOpen.i18n.json @@ -6,7 +6,7 @@ { "entryAriaLabel": "{0}、デバッグ", "debugAriaLabel": "実行する起動構成の名前を入力してください。", - "addConfigTo": "設定 ({0}) の追加 ...", + "addConfigTo": "構成 ({0}) の追加...", "addConfiguration": "構成の追加...", "noConfigurationsMatching": "一致するデバッグ構成はありません", "noConfigurationsFound": "デバッグ構成が見つかりません。'launch.json' ファイルを作成してください。" diff --git a/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/repl.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/repl.i18n.json index 3b2b57ca85d..010c65f0dc8 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/repl.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/repl.i18n.json @@ -8,5 +8,5 @@ "actions.repl.historyPrevious": "前の履歴", "actions.repl.historyNext": "次の履歴", "actions.repl.acceptInput": "REPL での入力を反映", - "actions.repl.copyAll": "デバッグ: コンソールをすべてコピーする" + "actions.repl.copyAll": "デバッグ: コンソールをすべてコピー" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 248289a591a..af2aec81915 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "デバッグ対象", - "debug.terminal.not.available.error": "統合ターミナルを使用できません" + "debug.terminal.title": "デバッグ対象" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 2a9f118d084..ecb730ce4d3 100644 --- a/i18n/jpn/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "新しいコマンド プロンプトを開く", "globalConsoleActionMacLinux": "新しいターミナルを開く", "scopedConsoleActionWin": "コマンド プロンプトで開く", - "scopedConsoleActionMacLinux": "ターミナルで開く", - "openFolderInIntegratedTerminal": "ターミナルで開く" + "scopedConsoleActionMacLinux": "ターミナルで開く" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index c381b702335..66ecd5fbfca 100644 --- a/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,17 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "最近開いたファイルに基づいてこの拡張機能が推奨されます。", + "neverShowAgain": "今後は表示しない", + "close": "閉じる", "workspaceRecommendation": "現在のワークスペースのユーザーによってこの拡張機能が推奨されています。", + "fileBasedRecommendation": "最近開いたファイルに基づいてこの拡張機能が推奨されます。", "exeBasedRecommendation": "{0} がインストールされているため、この拡張機能を推奨します。", "reallyRecommended2": "このファイルの種類には拡張機能 '{0}' が推奨されます。", "reallyRecommendedExtensionPack": "このファイルの種類には拡張機能パック '{0}' が推奨されます。", "showRecommendations": "推奨事項を表示", "install": "インストール", - "neverShowAgain": "今後は表示しない", - "close": "閉じる", + "showLanguageExtensions": "'.{0}' ファイルに役立つ拡張機能が Marketplace にあります", + "searchMarketplace": "Marketplace を検索", "workspaceRecommended": "このワークスペースには拡張機能の推奨事項があります。", "installAll": "すべてインストール", "ignoreExtensionRecommendations": "すべての拡張機能の推奨事項を無視しますか?", diff --git a/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..78d76e265f4 --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "ワークベンチ", + "feedbackVisibility": "ワークベンチ下部にあるステータス バーで Twitter のフィードバック (スマイル) を表示するかどうかを制御します。" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json b/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json index ba6b165a86a..8f7ff5b2b6f 100644 --- a/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json @@ -16,6 +16,7 @@ "request a missing feature": "欠落している機能を要求する", "tell us why?": "理由をお知らせください", "commentsHeader": "コメント", + "showFeedback": "ステータス バーにフィードバックの笑顔文字を表示", "tweet": "ツイートする", "character left": "文字入力可", "characters left": "文字入力可", diff --git a/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..e31810d983c --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "hide": "非表示" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 76306159955..cea92a2d16e 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,27 @@ "filesCategory": "ファイル", "revealInSideBar": "サイド バーに表示", "acceptLocalChanges": "変更を使用してディスクの内容を上書き", - "revertLocalChanges": "変更を破棄してディスク上の内容に戻る" + "revertLocalChanges": "変更を破棄してディスク上の内容に戻る", + "copyPathOfActive": "アクティブ ファイルのパスのコピー", + "saveAllInGroup": "グループ内のすべてを保存する", + "saveFiles": "すべてのファイルを保存", + "revert": "ファイルを元に戻す", + "compareActiveWithSaved": "保存済みファイルと作業中のファイルを比較", + "closeEditor": "エディターを閉じる", + "view": "表示", + "openToSide": "横に並べて開く", + "revealInWindows": "エクスプローラーで表示", + "revealInMac": "Finder で表示します", + "openContainer": "このアイテムのフォルダーを開く", + "copyPath": "パスのコピー", + "saveAll": "すべて保存", + "compareWithSaved": "保存済みと比較", + "compareWithSelected": "選択項目と比較", + "compareSource": "比較対象の選択", + "compareSelected": "選択項目の比較", + "close": "閉じる", + "closeOthers": "その他を閉じる", + "closeUnmodified": "未変更を閉じる", + "closeAll": "すべて閉じる", + "deleteFile": "完全に削除" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 2ef009f9c59..7754a978dc6 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "再試行", - "rename": "名前変更", "newFile": "新しいファイル", "newFolder": "新しいフォルダー", + "rename": "名前変更", + "delete": "削除", + "copyFile": "コピー", + "pasteFile": "貼り付け", + "retry": "再試行", "openFolderFirst": "フォルダー内にファイルやフォルダーを作成するには、フォルダーをまず開く必要があります。", "newUntitledFile": "無題の新規ファイル", "createNewFile": "新しいファイル", @@ -15,39 +18,32 @@ "deleteButtonLabelRecycleBin": "ごみ箱に移動(&&M)", "deleteButtonLabelTrash": "ゴミ箱に移動(&&M)", "deleteButtonLabel": "削除(&&D)", + "dirtyMessageFilesDelete": "保存されていない変更があるファイルを削除します。続行しますか?", "dirtyMessageFolderOneDelete": "保存されていない変更がある 1 個のファイルを含むフォルダーを削除します。続行しますか?", "dirtyMessageFolderDelete": "保存されていない変更があるファイルを {0} 個含むフォルダーを削除します。続行しますか?", "dirtyMessageFileDelete": "保存されていない変更があるファイルを削除します。続行しますか?", "dirtyWarning": "保存しないと変更内容が失われます。", + "confirmMoveTrashMessageMultiple": "次の {0} 個のファイルを削除してもよろしいですか?", "confirmMoveTrashMessageFolder": "'{0}' とその内容を削除しますか?", "confirmMoveTrashMessageFile": "'{0}' を削除しますか?", "undoBin": "ごみ箱から復元できます。", "undoTrash": "ゴミ箱から復元できます。", "doNotAskAgain": "再度表示しない", + "confirmDeleteMessageMultiple": "次の {0} 個のファイルを完全に削除してもよろしいですか?", "confirmDeleteMessageFolder": "'{0}' とその内容を完全に削除してもよろしいですか?", "confirmDeleteMessageFile": "'{0}' を完全に削除してもよろしいですか?", "irreversible": "このアクションは元に戻すことができません。", "permDelete": "完全に削除", - "delete": "削除", "importFiles": "ファイルのインポート", "confirmOverwrite": "保存先のフォルダーに同じ名前のファイルまたはフォルダーが既に存在します。置き換えてもよろしいですか?", "replaceButtonLabel": "置換(&&R)", - "copyFile": "コピー", - "pasteFile": "貼り付け", + "fileDeleted": "ファイルは削除されたか移動されています", + "fileIsAncestor": "コピーするファイルがコピー先フォルダの上位にあります", "duplicateFile": "重複", - "openToSide": "横に並べて開く", - "compareSource": "比較対象の選択", "globalCompareFile": "アクティブ ファイルを比較しています...", "openFileToCompare": "まずファイルを開いてから別のファイルと比較してください", - "compareWith": "'{0}' と '{1}' を比較", - "compareFiles": "ファイルの比較", "refresh": "最新の情報に更新", - "save": "保存", - "saveAs": "名前を付けて保存...", - "saveAll": "すべて保存", "saveAllInGroup": "グループ内のすべてを保存する", - "saveFiles": "すべてのファイルを保存", - "revert": "ファイルを元に戻す", "focusOpenEditors": "開いているエディターのビューにフォーカスする", "focusFilesExplorer": "ファイル エクスプローラーにフォーカスを置く", "showInExplorer": "アクティブ ファイルをサイド バーに表示", @@ -56,20 +52,11 @@ "refreshExplorer": "エクスプローラーを最新表示する", "openFileInNewWindow": "新しいウィンドウでアクティブ ファイルを開く", "openFileToShowInNewWindow": "まずファイルを開いてから新しいウィンドウで開きます", - "revealInWindows": "エクスプローラーで表示", - "revealInMac": "Finder で表示します", - "openContainer": "このアイテムのフォルダーを開く", - "revealActiveFileInWindows": "Windows エクスプローラーでアクティブ ファイルを表示する", - "revealActiveFileInMac": "Finder でアクティブ ファイルを表示する", - "openActiveFileContainer": "アクティブ ファイルを含んでいるフォルダーを開く", "copyPath": "パスのコピー", - "copyPathOfActive": "アクティブ ファイルのパスのコピー", "emptyFileNameError": "ファイルまたはフォルダーの名前を指定する必要があります。", "fileNameExistsError": "**{0}** というファイルまたはフォルダーはこの場所に既に存在します。別の名前を指定してください。", "invalidFileNameError": "名前 **{0}** がファイル名またはフォルダー名として無効です。別の名前を指定してください。", "filePathTooLongError": "名前 **{0}** のパスが長すぎます。名前を短くしてください。", - "compareWithSaved": "保存済みファイルと作業中のファイルを比較", - "modifiedLabel": "{0} (ローカル) ↔ {1}", "compareWithClipboard": "クリップボードとアクティブ ファイルを比較", "clipboardComparisonLabel": "クリップボード ↔ {0}" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index 4f2a963e359..108a656a68a 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "まずファイルを開いてからそのパスをコピーします", - "openFileToReveal": "まずファイルを開いてから表示します" + "revealInWindows": "エクスプローラーで表示", + "revealInMac": "Finder で表示します", + "openContainer": "このアイテムのフォルダーを開く", + "saveAs": "名前を付けて保存...", + "save": "保存", + "saveAll": "すべて保存", + "removeFolderFromWorkspace": "ワークスペースからフォルダーを削除", + "genericRevertError": "元へ戻すことに失敗しました '{0}': {1}", + "modifiedLabel": "{0} (ローカル) ↔ {1}", + "openFileToReveal": "まずファイルを開いてから表示します", + "openFileToCopy": "まずファイルを開いてからそのパスをコピーします" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 5461c0b3fa9..811c013e55b 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,7 @@ "editorConfigurationTitle": "エディター", "formatOnSave": "ファイルを保存するときにフォーマットしてください。フォーマッタを使用可能にして、ファイルを自動保存せず、エディターをシャットダウンしないでください。", "explorerConfigurationTitle": "エクスプローラー", - "openEditorsVisible": "[開いているエディター] ウィンドウに表示されているエディターの数。0 に設定するとウィンドウが非表示になります。", - "dynamicHeight": "開いているエディターのセクションの高さを要素の数に合わせて動的に調整するかどうかを制御します。", + "openEditorsVisible": "[開いているエディター] ウィンドウに表示するエディターの数。", "autoReveal": "エクスプローラーでファイルを開くとき、自動的にファイルの内容を表示して選択するかどうかを制御します。", "enableDragAndDrop": "ドラッグ アンド ドロップを使用したファイルとフォルダーの移動をエクスプローラーが許可するかどうかを制御します。", "confirmDragAndDrop": "ドラッグ アンド ドロップを使用したファイルやフォルダーの移動時にエクスプローラーが確認を求めるかどうかを制御します。", diff --git a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index a11f1cb6ffc..e3aeaafe4e7 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,14 @@ // Do not edit this file. It is machine generated. { "userGuide": "右側のエディター ツール バーの操作で、変更を [元に戻す] か、ディスクの内容を変更内容で [上書き] します", - "discard": "破棄", + "overwriteElevated": "管理者権限で上書き...", + "saveElevated": "管理者権限で再試行...", "overwrite": "上書き", "retry": "再試行", - "readonlySaveError": "'{0}' の保存に失敗しました。ファイルが書き込み禁止になっています。[上書き] を選択して保護を解除してください。", + "discard": "破棄", + "readonlySaveErrorAdmin": "'{0}' の保存に失敗しました。ファイルが書き込み禁止になっています。[管理者権限で上書き] を選択して管理者として再試行してください。", + "readonlySaveError": "'{0}' の保存に失敗しました。ファイルが書き込み禁止になっています。[上書き] を選択して保護の解除を試してください。", + "permissionDeniedSaveError": "'{0}' の保存に失敗しました。十分な権限がありません。[管理者権限で再試行] を選択して管理者として再試行してください。", "genericSaveError": "'{0}' の保存に失敗しました: {1}", "staleSaveError": "'{0} の保存に失敗しました。ディスクの内容の方が新しくなっています。[比較] をクリックしてご使用のバージョンをディスク上のバージョンと比較してください。", "compareChanges": "比較", diff --git a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json index f9c3565a125..3b5ce0838f3 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json @@ -10,6 +10,7 @@ "dropFolder": "ワークスペースにフォルダーを追加しますか?", "addFolders": "フォルダーの追加(&&A)", "addFolder": "フォルダーの追加(&&A)", + "confirmMultiMove": "次の {0} 個のファイルを移動してもよろしいですか?", "confirmMove": "'{0}' を移動しますか?", "doNotAskAgain": "再度表示しない", "moveButtonLabel": "移動(&&M)", diff --git a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index b798b662ed0..95dfcf4fae9 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "開いているエディター", "openEditosrSection": "[開いているエディター] セクション", - "dirtyCounter": "未保存 ({0})", - "saveAll": "すべて保存", - "closeAllUnmodified": "未変更を閉じる", - "closeAll": "すべて閉じる", - "compareWithSaved": "保存済みと比較", - "close": "閉じる", - "closeOthers": "その他を閉じる" + "dirtyCounter": "未保存 ({0})" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..f95880fcc36 --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "mainLog": "ログ (メイン)", + "sharedLog": "ログ (共有)", + "rendererLog": "ログ (ウィンドウ)", + "extensionsLog": "ログ (拡張機能ホスト)", + "developer": "開発者" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..861a564f2de --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "ログ フォルダーを開く", + "showLogs": "ログの表示...", + "mainProcess": "メイン", + "sharedProcess": "共有", + "rendererProcess": "ウィンドウ", + "extensionHost": "拡張機能ホスト", + "selectProcess": "プロセスの選択", + "openLogFile": "ログ ファイルを開く...", + "setLogLevel": "ログ レベルの設定", + "trace": "トレース", + "debug": "デバッグ", + "info": "情報", + "warn": "警告", + "err": "エラー", + "critical": "重大", + "off": "オフ", + "selectLogLevel": "ログ レベルを選択" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/jpn/src/vs/workbench/parts/markers/common/messages.i18n.json index efe22d017f6..0c951e42e75 100644 --- a/i18n/jpn/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,13 +5,13 @@ // Do not edit this file. It is machine generated. { "viewCategory": "表示", - "problems.view.toggle.label": "問題の切り替え", - "problems.view.focus.label": "問題にフォーカス", + "problems.view.toggle.label": "問題 (エラー、警告、情報) の切り替え", + "problems.view.focus.label": "問題 (エラー、警告、情報) にフォーカス", "problems.panel.configuration.title": "問題ビュー", "problems.panel.configuration.autoreveal": "ファイルを開くときに問題ビューに自動的にそのファイルを表示するかどうかを制御します", "markers.panel.title.problems": "問題", "markers.panel.aria.label.problems.tree": "ファイル別にグループ化した問題", - "markers.panel.no.problems.build": "現時点で問題はワークスペースで検出されていません。", + "markers.panel.no.problems.build": "現時点でワークスペースの問題は検出されていません。", "markers.panel.no.problems.filters": "指定されたフィルター条件による結果はありません", "markers.panel.action.filter": "問題のフィルター処理", "markers.panel.filter.placeholder": "種類またはテキストでフィルター処理", diff --git a/i18n/jpn/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..57deadb1a55 --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "出力", + "logViewer": "ログ ビューアー", + "viewCategory": "表示", + "clearOutput.label": "出力のクリア" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/jpn/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..8f00064048d --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "{0} - 出力", + "channel": "'{0}' の出力チャネル" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/preferences/browser/keybindingWidgets.i18n.json b/i18n/jpn/src/vs/workbench/parts/preferences/browser/keybindingWidgets.i18n.json index efdc6c41cac..99ba1fc8808 100644 --- a/i18n/jpn/src/vs/workbench/parts/preferences/browser/keybindingWidgets.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/preferences/browser/keybindingWidgets.i18n.json @@ -5,5 +5,5 @@ // Do not edit this file. It is machine generated. { "defineKeybinding.initial": "任意のキーの組み合わせを押し、ENTER キーを押します。", - "defineKeybinding.chordsTo": "次へのコード:" + "defineKeybinding.chordsTo": "の次に" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json b/i18n/jpn/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json index d963a2915fe..c440e97085d 100644 --- a/i18n/jpn/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json @@ -17,6 +17,7 @@ "resetLabel": "キー バインドのリセット", "showConflictsLabel": "競合の表示", "copyLabel": "コピー", + "copyCommandLabel": "コピー コマンド", "error": "キー バインドの編集中にエラー '{0}' が発生しました。'keybindings.json' ファイルを開いてご確認ください。", "command": "コマンド", "keybinding": "キー バインド", @@ -31,6 +32,6 @@ "keybindingAriaLabel": "キー バインドは {0} です。", "noKeybinding": "キー バインドが割り当てられていません。", "sourceAriaLabel": "ソースは {0} です。", - "whenAriaLabel": "時間は {0} です。", - "noWhen": "時間コンテキストがありません。" + "whenAriaLabel": "タイミングは {0} です。", + "noWhen": "タイミングのコンテキストがありません。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json b/i18n/jpn/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json index dacdf6ccd9d..00efa778c91 100644 --- a/i18n/jpn/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json @@ -11,6 +11,8 @@ "oneSettingFound": "1 つの設定が一致します", "settingsFound": "{0} 個の設定が一致します", "totalSettingsMessage": "合計 {0} 個の設定", + "nlpResult": "自然文 (natural language) の結果", + "filterResult": "フィルター後の結果", "defaultSettings": "既定の設定", "defaultFolderSettings": "既定のフォルダー設定", "defaultEditorReadonly": "既定値を上書きするには、右側のエディターを編集します。", diff --git a/i18n/jpn/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/jpn/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index dbb463d1324..05635b7c0f4 100644 --- a/i18n/jpn/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "自然文検索 (natural language search) を試し下さい!", "defaultSettings": "上書きするには、右側のエディターに設定を入力します。", "noSettingsFound": "設定が見つかりません。", "settingsSwitcherBarAriaLabel": "設定切り替え", "userSettings": "ユーザー設定", "workspaceSettings": "ワークスペースの設定", - "folderSettings": "フォルダーの設定", - "enableFuzzySearch": "自然文検索を有効にする" + "folderSettings": "フォルダーの設定" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/jpn/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index a99b14b8dd8..f28c0310389 100644 --- a/i18n/jpn/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "よく使用するもの", - "mostRelevant": "最も関連性の高い", "defaultKeybindingsHeader": "キー バインド ファイル内にキー バインドを挿入して、キー バインドを上書きします。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index 63217f20e3e..932be0b6bfa 100644 --- a/i18n/jpn/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "表示", "commandsHandlerDescriptionDefault": "コマンドの表示と実行", "gotoLineDescriptionMac": "行へ移動", "gotoLineDescriptionWin": "行へ移動", diff --git a/i18n/jpn/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index b650b0b0eb3..84c7c41eb09 100644 --- a/i18n/jpn/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,9 @@ "toggleGitViewlet": "Git を表示", "source control": "ソース管理", "toggleSCMViewlet": "SCM を表示", - "view": "表示" + "view": "表示", + "scmConfigurationTitle": "SCM", + "alwaysShowProviders": "ソース管理プロバイダーのセクションを常に表示するかどうか。", + "diffDecorations": "エディターの差分デコレーターを制御します。", + "inputCounter": "入力文字のカウントをいつ表示するかを制御します。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json b/i18n/jpn/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json index 2cd7ee76d8f..58ba9f785fc 100644 --- a/i18n/jpn/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json @@ -6,6 +6,9 @@ { "scm providers": "ソース管理プロバイダー", "hideRepository": "非表示", + "commitMessageInfo": "現在の行に {0}  文字", + "commitMessageCountdown": "現在の行で残り {0} 文字", + "commitMessageWarning": "現在の行で {1} から {0} 文字オーバー", "installAdditionalSCMProviders": "その他の SCM プロバイダーをインストール...", "no open repo": "有効なソース管理プロバイダーがありません。", "source control": "ソース管理", diff --git a/i18n/jpn/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/search/browser/searchActions.i18n.json index d07e4c94a3f..eeb352c7ca2 100644 --- a/i18n/jpn/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "前の検索語句を表示", "showSearchViewlet": "検索の表示", "findInFiles": "フォルダーを指定して検索", - "findInFilesWithSelectedText": "選択したテキストを含むファイルを検索", "replaceInFiles": "複数のファイルで置換", - "replaceInFilesWithSelectedText": "選択したテキストを含むファイルの置換", "RefreshAction.label": "最新の情報に更新", "CollapseDeepestExpandedLevelAction.label": "すべて折りたたむ", "ClearSearchResultsAction.label": "クリア", diff --git a/i18n/jpn/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index e266c4b0298..5253824e4bd 100644 --- a/i18n/jpn/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "フォルダー内を検索...", + "findInWorkspace": "ワークスペース内を検索...", "showTriggerActions": "ワークスペース内のシンボルへ移動...", "name": "検索", "search": "検索", + "showSearchViewlet": "検索の表示", "view": "表示", + "findInFiles": "フォルダーを指定して検索", "openAnythingHandlerDescription": "ファイルに移動する", "openSymbolDescriptionNormal": "ワークスペース内のシンボルへ移動", "searchOutputChannelTitle": "検索", @@ -18,5 +22,6 @@ "useRipgrep": "テキストとファイル検索で ripgrep を使用するかどうかを制御します", "useIgnoreFiles": "ファイルを検索するときに、.gitignore ファイルを使用するか .ignore ファイルを使用するかを制御します。", "search.quickOpen.includeSymbols": "グローバル シンボル検索の結果を、Quick Open の結果ファイルに含めるように構成します。", - "search.followSymlinks": "検索中にシンボリック リンクをたどるかどうかを制御します。" + "search.followSymlinks": "検索中にシンボリック リンクをたどるかどうかを制御します。", + "search.smartCase": "すべて小文字のパターンの場合、大文字と小文字を区別しないで検索し、そうでない場合は大文字と小文字を区別して検索する" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..9f9a7171140 --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.scope": "(グローバル)", + "global.1": "({0})", + "new.global": "新しいグローバル スニペット ファイル...", + "group.global": "既存のスニペット", + "new.global.sep": "新しいスニペット", + "openSnippet.pickLanguage": "スニペット ファイルの選択もしくはスニペットの作成", + "openSnippet.label": "ユーザー スニペットの構成", + "preferences": "基本設定" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 72cf35b045c..f4559520bc0 100644 --- a/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,13 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "スニペットの言語を選択", - "openSnippet.errorOnCreate": "{0} を作成できません", - "openSnippet.label": "ユーザー スニペットを開く", - "preferences": "基本設定", "snippetSchema.json.default": "空のスニペット", "snippetSchema.json": "ユーザー スニペット構成", "snippetSchema.json.prefix": "intellisense でスニペットを選択するときに使用するプレフィックス", "snippetSchema.json.body": "スニペットのコンテンツです。カーソルの位置を定義するには '$1', '${1:defaultText}' を使用し、最後のカーソルの位置には '$0' を使用します。'${varName}' と '${varName:defaultText}' を使用すると変数値を挿入します。例: 'This is file: $TM_FILENAME'.", - "snippetSchema.json.description": "スニペットについての記述。" + "snippetSchema.json.description": "スニペットについての記述。", + "snippetSchema.json.scope": "このスニペットを適用する言語名のリスト。例: 'typescript,javascript'。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..6528c4a5c72 --- /dev/null +++ b/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "ユーザー スニペット" +} \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index 247f01f3cea..8d9acf90cf1 100644 --- a/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "`contributes.{0}.language` で不明な言語です。提供された値: {1}", "invalid.path.0": "`contributes.{0}.path` に文字列が必要です。提供された値: {1}", + "invalid.language.0": "言語を省略するとき、`contributes.{0}.path` の値は `.code-snippets`-file にする必要があります。提供された値: {1}", + "invalid.language": "`contributes.{0}.language` で不明な言語です。提供された値: {1}", "invalid.path.1": "拡張機能のフォルダー ({2}) の中に `contributes.{0}.path` ({1}) が含まれている必要があります。これにより拡張を移植できなくなる可能性があります。", "vscode.extension.contributes.snippets": "スニペットを提供します。", "vscode.extension.contributes.snippets-language": "このスニペットの提供先の言語識別子です。", "vscode.extension.contributes.snippets-path": "スニペット ファイルのパス。拡張機能フォルダーの相対パスであり、通常 './snippets/' で始まります。", "badVariableUse": "拡張機能 '{0}' の 1 つまたは複数のスニペットは、スニペット変数とスニペット プレース ホルダーを混乱させる可能性が非常にあります。 (詳細については、 https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax を参照してください)", "badFile": "スニペット ファイル \"{0}\" を読み込むことができませんでした。", - "source.snippet": "ユーザー スニペット", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index 76dbf9d84f0..189e87c799d 100644 --- a/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -14,6 +14,7 @@ "terminal.integrated.shell.windows": "Windows でターミナルが使用するシェルのパス。 Windows に同梱されているシェルを使用する場合 (cmd、PowerShell、または Bash on Ubuntu) 。", "terminal.integrated.shellArgs.windows": "Windows ターミナル上の場合に使用されるコマンド ライン引数。", "terminal.integrated.rightClickCopyPaste": "設定している場合、ターミナル内で右クリックしたときにコンテキスト メニューを表示させず、選択範囲がある場合はコピー、選択範囲がない場合は貼り付けの操作を行います。", + "terminal.integrated.copyOnSelection": "設定した場合、ターミナルで選択しているテキストはクリップボードにコピーされます。", "terminal.integrated.fontFamily": "端末のフォント ファミリを制御します。既定値は editor.fontFamily になります。", "terminal.integrated.fontSize": "ターミナルのフォント サイズをピクセル単位で制御します。", "terminal.integrated.lineHeight": "ターミナルの行の高さを制御します。この数値にターミナルのフォント サイズを乗算すると、実際の行の高さ (ピクセル単位) になります。", @@ -24,10 +25,12 @@ "terminal.integrated.setLocaleVariables": "ターミナルの開始時にロケール変数を設定するかどうかを制御します。OS X では既定で true になり、その他のプラットフォームでは false です。", "terminal.integrated.cwd": "端末を起動する明示的な開始パスです。これはシェル プロセスの現在の作業ディレクトリ (cwd) として使用されます。特にルート ディレクトリが cwd に適していない場合に、ワークスペースの設定で役立ちます。", "terminal.integrated.confirmOnExit": "アクティブなターミナル セッションがある場合に終了の確認をするかどうか。", + "terminal.integrated.enableBell": "ターミナルのベルが有効かどうか。", "terminal.integrated.commandsToSkipShell": "キーバインドがシェルに送信されず、代わりに常に Code で処理されるコマンド ID のセット。これにより、ターミナルがフォーカスされていない場合と同じ動作をするシェルによって通常使用されるキーバインドを使用できるようになります。例: Ctrl+p で Quick Open を起動します。", "terminal.integrated.env.osx": "OS X のターミナルで使用される VS Code のプロセスに追加される環境変数を持つオブジェクト", "terminal.integrated.env.linux": "Linux のターミナルで使用される VS Code のプロセスに追加される環境変数を持つオブジェクト", "terminal.integrated.env.windows": "Windows のターミナルで使用される VS Code のプロセスに追加される環境変数を持つオブジェクト", + "terminal.integrated.showExitAlert": "0 以外の終了コードのとき `終了コードを伴ってターミナルの処理が終了しました` と警告を表示します。", "terminalCategory": "ターミナル", "viewCategory": "表示" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json index 6015fb400ae..96aa73cab67 100644 --- a/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json @@ -14,6 +14,8 @@ "workbench.action.terminal.deleteWordRight": "右の文字を削除", "workbench.action.terminal.new": "新しい統合ターミナルの作成", "workbench.action.terminal.new.short": "新しいターミナル", + "workbench.action.terminal.newWorkspacePlaceholder": "新しいターミナルの作業ディレクトリを選択してください", + "workbench.action.terminal.newInActiveWorkspace": "新しい統合ターミナルを作成 (アクティブなワークスペースに)", "workbench.action.terminal.focus": "端末にフォーカス", "workbench.action.terminal.focusNext": "次の端末にフォーカス", "workbench.action.terminal.focusPrevious": "前のターミナルにフォーカス", diff --git a/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index 42ec3aff619..37aa8bbba38 100644 --- a/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,7 @@ "terminal.integrated.chooseWindowsShellInfo": "カスタマイズ ボタンを選択して、既定のターミナル シェルを変更できます。", "customize": "カスタマイズする", "cancel": "キャンセル", - "never again": "OK、今後は表示しない", + "never again": "今後は表示しない", "terminal.integrated.chooseWindowsShell": "優先するターミナル シェルを選択します。これは後で設定から変更できます", "terminalService.terminalCloseConfirmationSingular": "アクティブなターミナル セッションが 1 つあります。中止しますか?", "terminalService.terminalCloseConfirmationPlural": "アクティブなターミナル セッションが {0} 個あります。中止しますか?" diff --git a/i18n/jpn/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/jpn/src/vs/workbench/parts/update/electron-browser/update.i18n.json index 5007e4d58ae..6df9478e8ba 100644 --- a/i18n/jpn/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -23,11 +23,12 @@ "commandPalette": "コマンド パレット...", "settings": "設定", "keyboardShortcuts": "キーボード ショートカット", + "userSnippets": "ユーザー スニペット", "selectTheme.label": "配色テーマ", "themes.selectIconTheme.label": "ファイル アイコンのテーマ", "not available": "更新は利用できません", "checkingForUpdates": "更新を確認しています...", - "DownloadUpdate": "利用可能な更新プログラムをダウンロードします", + "DownloadUpdate": "利用可能な更新プログラムをダウンロード", "DownloadingUpdate": "更新をダウンロードしています...", "InstallingUpdate": "更新プログラムをインストールしています...", "restartToUpdate": "再起動して更新...", diff --git a/i18n/jpn/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.i18n.json b/i18n/jpn/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.i18n.json index fbd940c7d47..39c4fd74ba4 100644 --- a/i18n/jpn/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.i18n.json @@ -21,7 +21,7 @@ "welcomePage.gitHubRepository": "GitHub リポジトリ", "welcomePage.stackOverflow": "Stack Overflow", "welcomePage.showOnStartup": "起動時にウェルカム ページを表示", - "welcomePage.customize": "カスタマイズする", + "welcomePage.customize": "カスタマイズ", "welcomePage.installExtensionPacks": "ツールと言語", "welcomePage.installExtensionPacksDescription": "{0} と {1} のサポートをインストールする ", "welcomePage.moreExtensions": "その他", diff --git a/i18n/jpn/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/jpn/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 26fc5404882..6384721117f 100644 --- a/i18n/jpn/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/jpn/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "ファイルはディレクトリです", + "fileNotModifiedError": "ファイルは次の時点以後に変更されていません:", "fileBinaryError": "ファイルはバイナリのようなので、テキストとして開くことができません" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/services/files/node/fileService.i18n.json b/i18n/jpn/src/vs/workbench/services/files/node/fileService.i18n.json index 104db33f633..95c0a8bffc2 100644 --- a/i18n/jpn/src/vs/workbench/services/files/node/fileService.i18n.json +++ b/i18n/jpn/src/vs/workbench/services/files/node/fileService.i18n.json @@ -10,6 +10,7 @@ "fileTooLargeError": "開くファイルが大きすぎます", "fileNotFoundError": "ファイルが見つかりません ({0})", "fileBinaryError": "ファイルはバイナリのようなので、テキストとして開くことができません", + "filePermission": "ファイルへの書き込み許可が拒否されました ({0})", "fileExists": "生成しようとしているファイル ({0}) は既に存在しています", "fileMoveConflict": "移動/コピーできません。移動/コピー先にファイルが既に存在します。", "unableToMoveCopyError": "移動/コピーできません。ファイルが含まれるフォルダーが置き換わることになります。", diff --git a/i18n/jpn/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json b/i18n/jpn/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json index 4845e670df1..5d95483dfac 100644 --- a/i18n/jpn/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json +++ b/i18n/jpn/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json @@ -8,19 +8,20 @@ "requirestring": "`{0}` プロパティは必須で、`string` 型でなければなりません", "optstring": "`{0}` プロパティは省略するか、`string` 型にする必要があります", "vscode.extension.contributes.keybindings.command": "キー バインドのトリガー時に実行するコマンドの識別子。", - "vscode.extension.contributes.keybindings.key": "キーまたはキー シーケンス (キーは + で区切り、シーケンスはスペースで区切る。例: Ctrl+O や Ctrl+L L のようにキーを同時に押す)。", + "vscode.extension.contributes.keybindings.key": "キーまたはキー シーケンス (キーは + で区切り、シーケンスはスペースで区切ります。例: Ctrl+O、Ctrl+L L)。", "vscode.extension.contributes.keybindings.mac": "Mac 固有のキーまたはキー シーケンス。", "vscode.extension.contributes.keybindings.linux": "Linux 固有のキーまたはキー シーケンス。", "vscode.extension.contributes.keybindings.win": "Windows 固有のキーまたはキー シーケンス。", - "vscode.extension.contributes.keybindings.when": "キーがアクティブの場合の条件。", + "vscode.extension.contributes.keybindings.when": "キーがアクティブになるときの条件。", "vscode.extension.contributes.keybindings": "キー バインドを提供します。", "invalid.keybindings": "正しくない `contributes.{0}`: {1}", "unboundCommands": "他に使用できるコマンドは次のとおりです: ", "keybindings.json.title": "キー バインドの構成", - "keybindings.json.key": "キーまたはキー シーケンス (スペースで区切る) を押します", + "keybindings.json.key": "キーまたはキー シーケンス (スペースで区切る)", "keybindings.json.command": "実行するコマンドの名前", - "keybindings.json.when": "キーがアクティブの場合の条件。", + "keybindings.json.when": "キーがアクティブになるときの条件。", "keybindings.json.args": "実行するコマンドに渡す引数。", "keyboardConfigurationTitle": "キーボード", - "dispatch": "`code` (推奨) または `keyCode` のいずれかを使用するキー操作のディスパッチ ロジックを制御します。" + "dispatch": "`code` (推奨) または `keyCode` のいずれかを使用するキー操作のディスパッチ ロジックを制御します。", + "touchbar.enabled": "利用可能であれば macOS の Touch Bar ボタンを有効にします。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/jpn/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index 2b4d38667bc..a570e254df8 100644 --- a/i18n/jpn/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/jpn/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "{0} に加えた変更を保存しますか?", "saveChangesMessages": "次の {0} ファイルに対する変更を保存しますか?", - "moreFile": "...1 つの追加ファイルが表示されていません", - "moreFiles": "...{0} 個の追加ファイルが表示されていません", "saveAll": "すべて保存(&&S)", "save": "保存(&&S)", "dontSave": "保存しない(&&N)", diff --git a/i18n/jpn/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/jpn/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index b1fd1a9b69e..3430db60129 100644 --- a/i18n/jpn/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/jpn/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "ファイル アイコンがありません", "iconThemeError": "ファイル アイコンのテーマが不明、またはインストールされていません。", "workbenchColors": "現在選択している配色テーマで配色を上書きします。", - "editorColors": "現在選択している配色テーマで配色とフォント スタイルを上書きします。", "editorColors.comments": "コメントの色とスタイルを設定します", "editorColors.strings": "文字列リテラルの色とスタイルを設定します。", "editorColors.keywords": "キーワードの色とスタイルを設定します。", @@ -19,5 +18,6 @@ "editorColors.types": "型定義と参照の色とスタイルを設定します。", "editorColors.functions": "関数定義と参照の色とスタイルを設定します。", "editorColors.variables": "変数定義と参照の色とスタイルを設定します。", - "editorColors.textMateRules": "textmate テーマ規則 (高度) を使っての色とスタイルを設定します。" + "editorColors.textMateRules": "textmate テーマ規則 (高度) を使っての色とスタイルを設定します。", + "editorColors": "現在選択している配色テーマで配色とフォント スタイルを上書きします。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/jpn/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index ec391b0543b..132852e62ff 100644 --- a/i18n/jpn/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/jpn/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "ワークスペース構成ファイルに書き込めません。ファイルを開いて、ファイル内のエラー/警告を修正してからもう一度お試しください。", "errorWorkspaceConfigurationFileDirty": "ファイルが変更されているため、ワークスペース構成ファイルに書き込めません。ファイルを保存してから、もう一度お試しください。", "openWorkspaceConfigurationFile": "ワークスペースの構成ファイルを開く", - "close": "閉じる", - "enterWorkspace.close": "閉じる", - "enterWorkspace.dontShowAgain": "今後は表示しない", - "enterWorkspace.moreInfo": "詳細情報", - "enterWorkspace.prompt": "VS Code での複数フォルダーの操作の詳細。" + "close": "閉じる" } \ No newline at end of file diff --git a/i18n/kor/extensions/git/out/autofetch.i18n.json b/i18n/kor/extensions/git/out/autofetch.i18n.json index a02c668eb9d..1a491bc8a6d 100644 --- a/i18n/kor/extensions/git/out/autofetch.i18n.json +++ b/i18n/kor/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "예", + "read more": "자세히 알아보기", "no": "아니요", - "not now": "나중에", - "suggest auto fetch": "Git 리포지토리 자동 페치하기를 사용하도록 설정하시겠습니까?" + "not now": "나중에 물어보기", + "suggest auto fetch": "Code가 주기적으로 `git fetch`를 실행할까요?" } \ No newline at end of file diff --git a/i18n/kor/extensions/git/out/commands.i18n.json b/i18n/kor/extensions/git/out/commands.i18n.json index 15fcc99ffbe..97749e34962 100644 --- a/i18n/kor/extensions/git/out/commands.i18n.json +++ b/i18n/kor/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\n이 작업은 되돌릴 수 없으며, 현재 작업 설정이 영구적으로 손실됩니다.", "yes discard tracked": "1개의 추적된 파일 취소", "yes discard tracked multiple": "{0}개의 추적된 파일 취소", + "unsaved files single": "다음 파일이 저장되지 않았습니다: {0}.\n\n제출하기 전에 저장할까요?", + "unsaved files": "저장되지 않은 {0}개의 파일들이 있습니다.\n\n제출하기 전에 저장할까요?", + "save and commit": "모두 저장하고 제출", + "commit": "그냥 제출", "no staged changes": "저장할 단계적 변경 사항이 없습니다.\n\n모든 변경 사항을 자동으로 스테이징하고 직접 저장하시겠습니까?", "always": "항상", "no changes": "커밋할 변경 내용이 없습니다.", @@ -64,12 +68,12 @@ "no remotes to pull": "리포지토리에 풀하도록 구성된 원격 항목이 없습니다.", "pick remote pull repo": "분기를 가져올 원격 선택", "no remotes to push": "리포지토리에 푸시하도록 구성된 원격이 없습니다.", - "push with tags success": "태그와 함께 푸시되었습니다.", "nobranch": "원격에 푸시할 분기를 체크 아웃하세요.", + "confirm publish branch": "'{0}' 분기에는 상향 분기가 없습니다. 이 분기를 게시하시겠습니까?", + "ok": "확인", + "push with tags success": "태그와 함께 푸시되었습니다.", "pick remote": "'{0}' 분기를 다음에 게시하려면 원격을 선택하세요.", "sync is unpredictable": "이 작업은 '{0}' 간에 커밋을 푸시하고 풀합니다.", - "ok": "확인", - "never again": "다시 표시 안 함", "no remotes to publish": "리포지토리에 게시하도록 구성된 원격이 없습니다.", "no changes stash": "스태시할 변경 내용이 없습니다.", "provide stash message": "필요한 경우 스태시 메시지를 입력하세요.", diff --git a/i18n/kor/extensions/git/package.i18n.json b/i18n/kor/extensions/git/package.i18n.json index 33448449d9e..8e38cc88df5 100644 --- a/i18n/kor/extensions/git/package.i18n.json +++ b/i18n/kor/extensions/git/package.i18n.json @@ -54,12 +54,12 @@ "command.stashPopLatest": "최신 슬래시 표시", "config.enabled": "Git 사용 여부", "config.path": "Git 실행 파일의 경로", + "config.autoRepositoryDetection": "리포지토리가 자동 감지되어야 하는지 여부", "config.autorefresh": "자동 새로 고침 사용 여부", "config.autofetch": "자동 가져오기 사용 여부", "config.enableLongCommitWarning": "긴 커밋 메시지에 대해 경고할지 여부입니다.", "config.confirmSync": "Git 리포지토리를 동기화하기 전에 확인합니다.", "config.countBadge": "Git 배지 카운터를 제어합니다. `all`이면 변경 내용을 모두 계산하고, `tracked`이면 추적된 변경 내용만 계산하고, `off`이면 해제합니다.", - "config.checkoutType": "`다음으로 체크 아웃...`을 실행할 때 나열되는 분기 유형을 제어합니다. `all`이면 모든 참조를 표시하고, `local`이면 로컬 분기만 표시하고, `tags`이면 태그만 표시하고, `remote`이면 원격 분기만 표시합니다.", "config.ignoreLegacyWarning": "레거시 Git 경고를 무시합니다.", "config.ignoreMissingGitWarning": "Git이 없으면 경고를 무시합니다.", "config.ignoreLimitWarning": "리포지토리에 변경 내용이 너무 많으면 경고를 무시합니다.", @@ -72,5 +72,6 @@ "colors.deleted": "삭제된 리소스의 색상입니다.", "colors.untracked": "추적되지 않은 리소스의 색상입니다.", "colors.ignored": "무시된 리소스의 색상입니다.", - "colors.conflict": "충돌이 발생한 리소스의 색상입니다." + "colors.conflict": "충돌이 발생한 리소스의 색상입니다.", + "colors.submodule": "서브모듈 자원의 색상" } \ No newline at end of file diff --git a/i18n/kor/extensions/typescript/out/commands.i18n.json b/i18n/kor/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..70c3246796b --- /dev/null +++ b/i18n/kor/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "TypeScript 또는 JavaScript 프로젝트를 사용하려면 VS Code의 폴더를 여세요.", + "typescript.projectConfigUnsupportedFile": "TypeScript 또는 JavaScript 프로젝트를 확인할 수 없습니다. 지원되지 않는 파일 형식", + "typescript.projectConfigCouldNotGetInfo": "TypeScript 또는 JavaScript 프로젝트를 확인할 수 없습니다.", + "typescript.noTypeScriptProjectConfig": "파일이 TypeScript 프로젝트의 일부가 아닙니다.", + "typescript.noJavaScriptProjectConfig": "파일이 JavaScript 프로젝트의 일부가 아닙니다.", + "typescript.configureTsconfigQuickPick": "tsconfig.json 구성", + "typescript.configureJsconfigQuickPick": "jsconfig.json 구성", + "typescript.projectConfigLearnMore": "자세한 정보" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/kor/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/kor/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/base/node/ps.i18n.json b/i18n/kor/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/kor/src/vs/base/node/ps.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json index 1fe9d415d3a..15922e98314 100644 --- a/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "줄 번호는 절대값으로 렌더링 됩니다.", "lineNumbers.relative": "줄 번호는 커서 위치에서 줄 간격 거리로 렌더링 됩니다.", "lineNumbers.interval": "줄 번호는 매 10 줄마다 렌더링이 이루어집니다.", - "lineNumbers": "줄 번호의 표시 여부를 제어합니다. 가능한 값은 'on', 'off', 'relative'입니다.", + "lineNumbers": "줄 번호의 표시 방식을 제어합니다. 가능한 값은 'on', 'off', 'relative', 'interval' 입니다.", "rulers": "특정 수의 고정 폭 문자 뒤에 세로 눈금자를 렌더링합니다. 여러 눈금자의 경우 여러 값을 사용합니다. 배열이 비어 있는 경우 눈금자가 그려져 있지 않습니다.", "wordSeparators": "단어 관련 탐색 또는 작업을 수행할 때 단어 구분 기호로 사용되는 문자입니다.", "tabSize": "탭 한 개에 해당하는 공백 수입니다. `editor.detectIndentation`이 켜져 있는 경우 이 설정은 파일 콘텐츠에 따라 재정의됩니다.", diff --git a/i18n/kor/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/kor/src/vs/editor/common/view/editorColorRegistry.i18n.json index a8423dd155b..90813fe32fb 100644 --- a/i18n/kor/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/kor/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,6 @@ { "lineHighlight": "커서 위치의 줄 강조 표시에 대한 배경색입니다.", "lineHighlightBorderBox": "커서 위치의 줄 테두리에 대한 배경색입니다.", - "rangeHighlight": "빠른 열기 및 찾기 기능 등을 통해 강조 표시된 영역의 배경색입니다.", "caret": "편집기 커서 색입니다.", "editorCursorBackground": "편집기 커서의 배경색입니다. 블록 커서와 겹치는 글자의 색상을 사용자 정의할 수 있습니다.", "editorWhitespaces": "편집기의 공백 문자 색입니다.", diff --git a/i18n/kor/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/kor/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 58029e4cfcd..73b79e44721 100644 --- a/i18n/kor/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/kor/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "다음 오류 또는 경고로 이동", - "markerAction.previous.label": "이전 오류 또는 경고로 이동", "editorMarkerNavigationError": "편집기 표식 탐색 위젯 오류 색입니다.", "editorMarkerNavigationWarning": "편집기 표식 탐색 위젯 경고 색입니다.", "editorMarkerNavigationInfo": "편집기 표식 탐색 위젯 정보 색입니다.", diff --git a/i18n/kor/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/kor/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index ab340d73f19..8dd1a533f72 100644 --- a/i18n/kor/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/kor/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "변수 읽기와 같은 읽기 액세스 중 기호의 배경색입니다.", - "wordHighlightStrong": "변수에 쓰기와 같은 쓰기 액세스 중 기호의 배경색입니다.", "overviewRulerWordHighlightForeground": "기호 강조 표시의 개요 눈금자 마커 색입니다.", "overviewRulerWordHighlightStrongForeground": "쓰기 권한 기호 강조 표시의 개요 눈금자 마커 색입니다.", "wordHighlight.next.label": "다음 강조 기호로 이동", diff --git a/i18n/kor/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/kor/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index ee9870e16a1..8a92234e152 100644 --- a/i18n/kor/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/kor/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "`{0}`은(는) 유효한 메뉴 식별자가 아닙니다.", "missing.command": "메뉴 항목이 '명령' 섹션에 정의되지 않은 `{0}` 명령을 참조합니다.", "missing.altCommand": "메뉴 항목이 '명령' 섹션에 정의되지 않은 alt 명령 `{0}`을(를) 참조합니다.", - "dupe.command": "메뉴 항목이 동일한 명령을 기본값과 alt 명령으로 참조합니다.", - "nosupport.altCommand": "죄송합니다. 현재 '편집기/제목' 메뉴의 '탐색' 그룹만 alt 명령을 지원합니다." + "dupe.command": "메뉴 항목이 동일한 명령을 기본값과 alt 명령으로 참조합니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/platform/environment/node/argv.i18n.json b/i18n/kor/src/vs/platform/environment/node/argv.i18n.json index 43b38b984db..afaf41e4aa2 100644 --- a/i18n/kor/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/kor/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,34 @@ "diff": "두 파일을 서로 비교합니다.", "add": "마지막 활성 창에 폴더를 추가합니다.", "goto": "지정된 줄과 문자 위치에 있는 경로의 파일을 엽니다.", - "locale": "사용할 로캘(예: en-US 또는 zh-TW)입니다.", "newWindow": "Code의 새 인스턴스를 강제 적용합니다.", - "performance": "'Developer: Startup Performance' 명령을 사용하여 시작합니다.", - "prof-startup": "시작하는 동안 CPU 프로파일러 실행", - "inspect-extensions": "디버깅 및 확장 프로파일링을 허용합니다. 연결 uri에 대한 개발자 도구를 확인하십시오.", - "inspect-brk-extensions": "시작 후 일시 중시된 확장 호스트에서 디버깅 및 확장 프로파일링을 허용합니다. 연결 URL은 개발자 도구를 확인하세요.", "reuseWindow": "마지막 활성 창에서 파일 또는 폴더를 강제로 엽니다.", - "userDataDir": "사용자 데이터가 저장되는 디렉터리를 지정합니다(루트로 실행할 경우 유용함).", - "log": "사용할 로그 수준이며 기본값은 'info'입니다. 허용되는 값은 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'입니다.", - "verbose": "자세한 정보 표시를 출력합니다(--wait를 의미).", "wait": "파일이 닫힐 때 까지 기다린 후 돌아갑니다.", + "locale": "사용할 로캘(예: en-US 또는 zh-TW)입니다.", + "userDataDir": "사용자 데이터가 저장되는 디렉터리를 지정합니다(루트로 실행할 경우 유용함).", + "version": "버전을 출력합니다.", + "help": "사용법을 출력합니다.", "extensionHomePath": "확장의 루트 경로를 설정합니다.", "listExtensions": "설치된 확장을 나열합니다.", "showVersions": "#NAME?", "installExtension": "확장을 설치합니다.", "uninstallExtension": "확장을 제거합니다.", "experimentalApis": "확장에 대해 제안된 API 기능을 사용하도록 설정합니다.", - "disableExtensions": "설치된 모든 확장을 사용하지 않도록 설정합니다.", - "disableGPU": "GPU 하드웨어 가속을 사용하지 않도록 설정합니다.", + "verbose": "자세한 정보 표시를 출력합니다(--wait를 의미).", + "log": "사용할 로그 수준이며 기본값은 'info'입니다. 허용되는 값은 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'입니다.", "status": "프로세스 사용 및 진단 정보를 인쇄합니다.", - "version": "버전을 출력합니다.", - "help": "사용법을 출력합니다.", + "performance": "'Developer: Startup Performance' 명령을 사용하여 시작합니다.", + "prof-startup": "시작하는 동안 CPU 프로파일러 실행", + "disableExtensions": "설치된 모든 확장을 사용하지 않도록 설정합니다.", + "inspect-extensions": "디버깅 및 확장 프로파일링을 허용합니다. 연결 uri에 대한 개발자 도구를 확인하십시오.", + "inspect-brk-extensions": "시작 후 일시 중시된 확장 호스트에서 디버깅 및 확장 프로파일링을 허용합니다. 연결 URL은 개발자 도구를 확인하세요.", + "disableGPU": "GPU 하드웨어 가속을 사용하지 않도록 설정합니다.", "usage": "사용법", "options": "옵션", "paths": "경로", - "optionsUpperCase": "옵션" + "stdinWindows": "다른 프로그램의 출력을 읽으려면, '-'를 추가하십시오. (예: 'echo Hello World | {0} -')", + "stdinUnix": "stdin에서 읽어오려면, '-'를 추가하십시오.(예. 'ps aux | grep code | {0} -')", + "optionsUpperCase": "옵션", + "extensionsManagement": "확장 관리", + "troubleshooting": "문제 해결" } \ No newline at end of file diff --git a/i18n/kor/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/kor/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index 64578b6f8a5..01c78cf0a53 100644 --- a/i18n/kor/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/kor/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,14 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "잘못된 확장: package.json이 JSON 파일이 아닙니다.", - "restartCodeLocal": "{0}을(를) 다시 설치하기 전에 Code를 다시 시작하세요.", + "restartCode": "{0}을(를) 다시 설치하기 전에 Code를 다시 시작하세요.", "installingOutdatedExtension": "이 확장의 최신 버전이 이미 설치되어 있습니다. 이 버전을 이전 버전으로 재정의하시겠습니까?", "override": "재정의", "cancel": "취소", - "notFoundCompatible": "VS Code의 현재 버전 '{1}'과(와) 호환되는 '{0}' 확장을 찾을 수 없으므로 설치할 수 없습니다.", - "quitCode": "확장의 사용되지 않는 인스턴스가 계속 실행 중이므로 설치할 수 없습니다. 다시 설치하기 전에 VS Code를 종료했다가 다시 시작하세요.", - "exitCode": "확장의 사용되지 않는 인스턴스가 계속 실행 중이므로 설치할 수 없습니다. 다시 설치하기 전에 VS Code를 종료했다가 다시 시작하세요.", + "notFoundCompatible": "'{0}'을(를) 설치할 수 없습니다; VS Code '{1}'과 호환되는 버전이 없습니다.", "notFoundCompatibleDependency": "VS Code의 현재 버전 '{1}'과(와) 호환되는 종속된 확장 '{0}'을(를) 찾을 수 없으므로 설치할 수 없습니다.", + "quitCode": "확장을 설치할 수 없습니다. 다시 설치하기 위해 VS Code를 종료하고 다시 시작하십시오.", + "exitCode": "확장을 설치할 수 없습니다. 다시 설치하기 전에 VS 코드를 종료한 후 다시 시작하십시오. ", "uninstallDependeciesConfirmation": "'{0}'만 제거할까요, 아니면 종속성도 제거할까요?", "uninstallOnly": "만", "uninstallAll": "모두", diff --git a/i18n/kor/src/vs/platform/message/common/message.i18n.json b/i18n/kor/src/vs/platform/message/common/message.i18n.json index 8194d2b9b95..7cec53dd19a 100644 --- a/i18n/kor/src/vs/platform/message/common/message.i18n.json +++ b/i18n/kor/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "닫기", "later": "나중에", - "cancel": "취소" + "cancel": "취소", + "moreFile": "...1개의 추가 파일이 표시되지 않음", + "moreFiles": "...{0}개의 추가 파일이 표시되지 않음" } \ No newline at end of file diff --git a/i18n/kor/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/kor/src/vs/platform/theme/common/colorRegistry.i18n.json index 8f111cba06f..ac7b14b24ea 100644 --- a/i18n/kor/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/kor/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,7 @@ "editorWidgetBorder": "편집기 위젯의 테두리 색입니다. 위젯에 테두리가 있고 위젯이 색상을 무시하지 않을 때만 사용됩니다.", "editorSelectionBackground": "편집기 선택 영역의 색입니다.", "editorSelectionForeground": "고대비를 위한 선택 텍스트의 색입니다.", - "editorInactiveSelection": "비활성 편집기 선택 영역의 색입니다.", - "editorSelectionHighlight": "선택 영역과 동일한 콘텐츠가 있는 영역의 색입니다.", "editorFindMatch": "현재 검색 일치 항목의 색입니다.", - "findMatchHighlight": "기타 검색 일치 항목의 색입니다.", - "findRangeHighlight": "검색을 제한하는 영역의 색을 지정합니다.", - "hoverHighlight": "호버가 표시된 단어 아래를 강조 표시합니다.", "hoverBackground": "편집기 호버의 배경색.", "hoverBorder": "편집기 호버의 테두리 색입니다.", "activeLinkForeground": "활성 링크의 색입니다.", @@ -76,12 +71,6 @@ "diffEditorRemoved": "제거된 텍스트의 배경색입니다.", "diffEditorInsertedOutline": "삽입된 텍스트의 윤곽선 색입니다.", "diffEditorRemovedOutline": "제거된 텍스트의 윤곽선 색입니다.", - "mergeCurrentHeaderBackground": "인라인 병합 충돌의 현재 헤더 배경입니다.", - "mergeCurrentContentBackground": "인라인 병합 충돌의 현재 콘텐츠 배경입니다.", - "mergeIncomingHeaderBackground": "인라인 병합 충돌에서 수신 헤더 배경입니다.", - "mergeIncomingContentBackground": "인라인 병합 충돌에서 수신 콘텐츠 배경입니다.", - "mergeCommonHeaderBackground": "인라인 병합 충돌의 공통 과거 헤더 배경입니다.", - "mergeCommonContentBackground": "인라인 병합 충돌의 공통 과거 콘텐츠 배경입니다.", "mergeBorder": "인라인 병합 충돌에서 헤더 및 스플리터의 테두리 색입니다.", "overviewRulerCurrentContentForeground": "인라인 병합 충돌에서 현재 개요 눈금 전경색입니다.", "overviewRulerIncomingContentForeground": "인라인 병합 충돌에서 수신 개요 눈금 전경색입니다.", diff --git a/i18n/kor/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/kor/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..9f96e3885f7 --- /dev/null +++ b/i18n/kor/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "saveParticipants": "실행중인 저장 관계자..." +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/kor/src/vs/workbench/api/node/extHostTreeViews.i18n.json index 4dfa6a6e897..80def44cc85 100644 --- a/i18n/kor/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/kor/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -4,7 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "treeView.notRegistered": "ID가 '{0}'인 등록된 트리 뷰가 없습니다.", - "treeItem.notFound": "ID가 '{0}'인 트리 항목을 찾을 수 없습니다.", - "treeView.duplicateElement": "{0} 요소가 이미 등록되어 있습니다." + "treeView.notRegistered": "ID가 '{0}'인 등록된 트리 뷰가 없습니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/kor/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index 2ad17264baf..091e1d88413 100644 --- a/i18n/kor/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "사이드바 위치 설정/해제", "view": "보기" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/kor/src/vs/workbench/browser/actions/workspaceActions.i18n.json index d99bcba35ef..646be54e188 100644 --- a/i18n/kor/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "파일 열기...", "openFolder": "폴더 열기...", "openFileFolder": "열기...", - "addFolderToWorkspace": "작업 영역에 폴더 추가...", - "add": "추가(&&A)", - "addFolderToWorkspaceTitle": "작업 영역에 폴더 추가", "globalRemoveFolderFromWorkspace": "작업 영역에서 폴더 제거...", - "removeFolderFromWorkspace": "작업 영역에서 폴더 삭제", - "openFolderSettings": "폴더 설정 열기", "saveWorkspaceAsAction": "작업 영역을 다른 이름으로 저장", "save": "저장(&&S)", "saveWorkspace": "작업 영역 저장", "openWorkspaceAction": "작업 영역 열기...", "openWorkspaceConfigFile": "작업 영역 구성 파일 열기", - "openFolderAsWorkspaceInNewWindow": "새 창에서 작업 영역으로 폴더 열기", - "workspaceFolderPickerPlaceholder": "작업 영역 폴더 선택" + "openFolderAsWorkspaceInNewWindow": "새 창에서 작업 영역으로 폴더 열기" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/kor/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..4aff2c19344 --- /dev/null +++ b/i18n/kor/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "작업 영역에 폴더 추가...", + "add": "추가(&&A)", + "addFolderToWorkspaceTitle": "작업 영역에 폴더 추가" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index 32f439e8de1..57c83a5d7c5 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,17 @@ "groupThreePicker": "세 번째 그룹에 편집기 표시", "allEditorsPicker": "열려 있는 모든 편집기 표시", "view": "보기", - "file": "파일" + "file": "파일", + "close": "닫기", + "closeOthers": "기타 항목 닫기", + "closeRight": "오른쪽에 있는 항목 닫기", + "closeAllUnmodified": "미수정 항목 닫기", + "closeAll": "모두 닫기", + "keepOpen": "열린 상태 유지", + "showOpenedEditors": "열려 있는 편집기 표시", + "keepEditor": "편집기 유지", + "closeEditorsInGroup": "그룹의 모든 편집기 닫기", + "closeUnmodifiedEditors": "그룹의 수정되지 않은 편집기 닫기", + "closeOtherEditors": "다른 편집기 닫기", + "closeRightEditors": "오른쪽에 있는 편집기 닫기" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index ed6d0f43e21..92ac30a939f 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "편집기 닫기", "revertAndCloseActiveEditor": "편집기 되돌리기 및 닫기", "closeEditorsToTheLeft": "왼쪽에 있는 편집기 닫기", - "closeEditorsToTheRight": "오른쪽에 있는 편집기 닫기", "closeAllEditors": "모든 편집기 닫기", - "closeUnmodifiedEditors": "그룹의 수정되지 않은 편집기 닫기", "closeEditorsInOtherGroups": "다른 그룹의 편집기 닫기", - "closeOtherEditorsInGroup": "다른 편집기 닫기", - "closeEditorsInGroup": "그룹의 모든 편집기 닫기", "moveActiveGroupLeft": "편집기 그룹을 왼쪽으로 이동", "moveActiveGroupRight": "편집기 그룹을 오른쪽으로 이동", "minimizeOtherEditorGroups": "다른 편집기 그룹 최소화", "evenEditorGroups": "균등한 편집기 그룹 너비", "maximizeEditor": "편집기 그룹 최대화 및 사이드바 숨기기", - "keepEditor": "편집기 유지", "openNextEditor": "다음 편집기 열기", "openPreviousEditor": "이전 편집기 열기", "nextEditorInGroup": "그룹에서 다음 편집기 열기", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "첫 번째 그룹에 편집기 표시", "showEditorsInSecondGroup": "두 번째 그룹에 편집기 표시", "showEditorsInThirdGroup": "세 번째 그룹에 편집기 표시", - "showEditorsInGroup": "그룹의 편집기 표시", "showAllEditors": "모든 편집기 표시", "openPreviousRecentlyUsedEditorInGroup": "그룹에서 최근에 사용한 이전 편집기 열기", "openNextRecentlyUsedEditorInGroup": "그룹에서 최근에 사용한 다음 편집기 열기", diff --git a/i18n/kor/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 6c0c854e4bf..b32e252f6bf 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "활성 편집기를 탭 또는 그룹 단위로 이동", "editorCommand.activeEditorMove.arg.name": "활성 편집기 이동 인수", - "editorCommand.activeEditorMove.arg.description": "인수 속성: * '를': 문자열 값을 제공 하 고 위치를 이동.\n\t* ' 의해': 문자열 이동에 대 한 단위를 제공 하는 값. 탭 또는 그룹.\n\t* ' value': 얼마나 많은 위치 또는 이동 하는 절대 위치를 제공 하는 숫자 값.", - "commandDeprecated": "**{0}** 명령이 제거되었습니다. 대신 **{1}** 명령을 사용할 수 있습니다.", - "openKeybindings": "바로 가기 키 구성" + "editorCommand.activeEditorMove.arg.description": "인수 속성: * '를': 문자열 값을 제공 하 고 위치를 이동.\n\t* ' 의해': 문자열 이동에 대 한 단위를 제공 하는 값. 탭 또는 그룹.\n\t* ' value': 얼마나 많은 위치 또는 이동 하는 절대 위치를 제공 하는 숫자 값." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index dedfef7381b..aaa9957a9bf 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "텍스트 파일 비교 편집기입니다.", "navigate.next.label": "다음 변경 내용", "navigate.prev.label": "이전 변경 내용", - "inlineDiffLabel": "인라인 보기로 전환", - "sideBySideDiffLabel": "세로 정렬 보기로 전환" + "toggleIgnoreTrimWhitespace.label": "자르기 공백 무시" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index a290c099837..13cca1a3336 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "닫기", - "closeOthers": "기타 항목 닫기", - "closeRight": "오른쪽에 있는 항목 닫기", - "closeAll": "모두 닫기", - "closeAllUnmodified": "미수정 항목 닫기", - "keepOpen": "열린 상태 유지", - "showOpenedEditors": "열려 있는 편집기 표시", "araLabelEditorActions": "편집기 작업" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index fbf734ff7aa..4777ec24002 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[지원되지 않음]", + "userIsAdmin": "[관리자]", + "userIsSudo": "[슈퍼유저]", "devExtensionWindowTitlePrefix": "[확장 개발 호스트]" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/kor/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index b4ccb557e6a..8b6ad71cd4e 100644 --- a/i18n/kor/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/kor/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -3,6 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{ - "hideView": "사이드바에서 숨기기" -} \ No newline at end of file +{} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/common/theme.i18n.json b/i18n/kor/src/vs/workbench/common/theme.i18n.json index c43957e4bd8..cbb96bc285b 100644 --- a/i18n/kor/src/vs/workbench/common/theme.i18n.json +++ b/i18n/kor/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "활성 탭 배경색입니다. 탭은 편집기 영역에서 편집기의 컨테이너입니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 여러 편집기 그룹이 있을 수 있습니다.", "tabInactiveBackground": "비활성 탭 배경색입니다. 탭은 편집기 영역에서 편집기의 컨테이너입니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 여러 편집기 그룹이 있을 수 있습니다.", + "tabHoverBackground": "마우스 커서를 올려놓았을 때의 탭 배경색. 탭은 편집 영역에서 편집기를 감싸고 있습니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 편집기 그룹이 여러 개일 수 있습니다.", + "tabUnfocusedHoverBackground": "마우스 커서를 올려놓았을 때 포커스를 받지 못한 탭 배경색. 탭은 편집 영역에서 편집기를 감싸고 있습니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 편집기 그룹이 여러 개일 수 있습니다.", "tabBorder": "탭을 서로 구분하기 위한 테두리입니다. 탭은 편집기 영역에서 편집기의 컨테이너입니다. 한 편집기 그룹에 여러 탭을 열 수 있습니다. 여러 편집기 그룹이 있을 수 있습니다.", "tabActiveBorder": "활성 탭을 강조 표시하기 위한 테두리입니다. 탭은 편집기 영역에서 편집기의 컨테이너입니다. 한 편집기 그룹에 여러 탭을 열 수 있습니다. 여러 편집기 그룹이 있을 수 있습니다.", "tabActiveUnfocusedBorder": "포커스가 없는 그룹에서 활성 탭을 강조 표시하기 위한 테두리입니다. 탭은 편집기 영역에서 편집기의 컨테이너입니다. 한 편집기 그룹에 여러 탭을 열 수 있습니다. 여러 편집기 그룹이 있을 수 있습니다.", + "tabHoverBorder": "마우스 커서를 올려놓았을 때 활성 탭의 테두리. 탭은 편집 영역에서 편집기를 감싸고 있습니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 편집기 그룹이 여러 개일 수 있습니다.", + "tabUnfocusedHoverBorder": "마우스 커서를 올려놓았을 때 포커스를 받지 못한 그룹에서 활성 탭 테두리. 탭은 편집 영역에서 편집기를 감싸고 있습니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 편집기 그룹이 여러 개일 수 있습니다.", "tabActiveForeground": "활성 그룹의 활성 탭 전경색입니다. 탭은 편집기 영역에서 편집기의 컨테이너입니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 여러 편집기 그룹이 있을 수 있습니다.", "tabInactiveForeground": "활성 그룹의 비활성 탭 전경색입니다. 탭은 편집기 영역에서 편집기의 컨테이너입니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 여러 편집기 그룹이 있을 수 있습니다.", "tabUnfocusedActiveForeground": "포커스가 없는 그룹의 활성 탭 전경색입니다. 탭은 편집기 영역에서 편집기의 컨테이너입니다. 한 편집기 그룹에서 여러 탭을 열 수 있습니다. 여러 편집기 그룹이 있을 수 있습니다.", @@ -16,7 +20,7 @@ "editorGroupBackground": "편집기 그룹의 배경색입니다. 편집기 그룹은 편집기의 컨테이너입니다. 배경색은 편집기 그룹을 끌 때 표시됩니다.", "tabsContainerBackground": "탭을 사용도록 설정한 경우 편집기 그룹 제목 머리글의 배경색입니다. 편집기 그룹은 편집기의 컨테이너입니다.", "tabsContainerBorder": "탭을 사용하도록 설정한 경우 편집기 그룹 제목 머리글의 테두리 색입니다. 편집기 그룹은 편집기의 컨테이너입니다.", - "editorGroupHeaderBackground": "탭을 사용하지 않도록 설정한 경우 편집기 그룹 제목 머리글의 배경색입니다. 편집기 그룹은 편집기의 컨테이너입니다.", + "editorGroupHeaderBackground": "탭을 사용하지 않도록 설정한 경우(`\"workbench.editor.showTabs\": false`) 편집기 그룹 제목 머리글의 배경색입니다. 편집기 그룹은 편집기의 컨테이너입니다.", "editorGroupBorder": "여러 편집기 그룹을 서로 구분하기 위한 색입니다. 편집기 그룹은 편집기의 컨테이너입니다.", "editorDragAndDropBackground": "편집기를 끌 때 배경색입니다. 편집기 내용이 계속 비추어 보이도록 이 색은 투명해야 합니다.", "panelBackground": "패널 배경색입니다. 패널은 편집기 영역 아래에 표시되며 출력 및 통합 터미널 같은 보기가 포함됩니다.", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "열린 폴더가 없을 때 사이드바 및 편집기와 구분하는 상태 표시줄 테두리 색입니다. 상태 표시줄은 창의 맨 아래에 표시됩니다.", "statusBarItemActiveBackground": "클릭할 때의 상태 표시줄 항목 배경색입니다. 상태 표시줄은 창의 맨 아래에 표시됩니다.", "statusBarItemHoverBackground": "마우스로 가리킬 때의 상태 표시줄 항목 배경색입니다. 상태 표시줄은 창의 맨 아래에 표시됩니다.", - "statusBarProminentItemBackground": "상태 표시줄 주요 항목 배경색입니다. 주요 항목은 중요도를 나타내는 다른 상태 표시줄 항목보다 눈에 잘 띕니다. 상태 표시줄은 창의 맨 아래에 표시됩니다.", - "statusBarProminentItemHoverBackground": "마우스로 가리킬 때의 상태 표시줄 주요 항목 배경색입니다. 주요 항목은 중요도를를 나타내는 다른 상태 표시줄 항목보다 눈에 잘 띕니다. 상태 표시줄은 창의 맨 아래에 표시됩니다.", + "statusBarProminentItemBackground": " 상태 표시줄 주요 항목 배경 색. 주요 항목은 중요성을 알려주기 위해 다른 상태 표시줄 항목보다 눈에 띕니다. 예제를 보기 위해 명령 팔레트에서 '포커스 이동을 위해 탭 키 토글' 모드를 변경합니다. 창 아래쪽에 상태 표시줄이 나타납니다.", + "statusBarProminentItemHoverBackground": "마우스 커서를 올렸을 때 상태 표시줄 주요 항목 배경 색. 주요 항목은 중요성을 알려주기 위해 다른 상태 표시줄 항목보다 눈에 띕니다. 예제를 보기 위해 명령 팔레트에서 '포커스 이동을 위해 탭 키 토글' 모드를 변경합니다. 창 아래쪽에 상태 표시줄이 나타납니다.", "activityBarBackground": "작업 막대 배경색입니다. 작업 막대는 맨 왼쪽이나 오른쪽에 표시되며 사이드바의 뷰 간을 전환하는 데 사용할 수 있습니다.", "activityBarForeground": "작업 막대 전경 색(예: 아이콘에 사용됨)입니다. 작업 막대는 오른쪽이나 왼쪽 끝에 표시되며 사이드바의 보기 간을 전환할 수 있습니다.", "activityBarBorder": "사이드바와 구분하는 작업 막대 테두리색입니다. 작업 막대는 오른쪽이나 왼쪽 끝에 표시되며 사이드바의 보기 간을 전환할 수 있습니다.", diff --git a/i18n/kor/src/vs/workbench/common/views.i18n.json b/i18n/kor/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..6a3532ad44d --- /dev/null +++ b/i18n/kor/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "ID `{0}`이(가) 포함된 뷰가 위치 `{1}`에 이미 등록되어 있습니다." +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/kor/src/vs/workbench/electron-browser/actions.i18n.json index 96f43aced40..a1086cd9b19 100644 --- a/i18n/kor/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/kor/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "편집기 닫기", "closeWindow": "창 닫기", "closeWorkspace": "작업 영역 닫기", "noWorkspaceOpened": "현재 이 인스턴스에 열려 있는 작업 영역이 없습니다.", @@ -52,21 +51,5 @@ "displayLanguage": "VSCode의 표시 언어를 정의합니다.", "doc": "지원되는 언어 목록은 {0} 을(를) 참조하세요.", "restart": "값을 변경하려면 VSCode를 다시 시작해야 합니다.", - "fail.createSettings": "{0}'({1})을(를) 만들 수 없습니다.", - "openLogsFolder": "로그 폴더 열기", - "showLogs": "로그 표시...", - "mainProcess": "기본", - "sharedProcess": "공유", - "rendererProcess": "렌더러", - "extensionHost": "확장 호스트", - "selectProcess": "프로세스 선택", - "setLogLevel": "로그 수준 설정", - "trace": "Trace", - "debug": "디버그", - "info": "정보", - "warn": "경고", - "err": "오류", - "critical": "Critical", - "off": "Off", - "selectLogLevel": "로그 수준 선택" + "fail.createSettings": "{0}'({1})을(를) 만들 수 없습니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/kor/src/vs/workbench/electron-browser/main.contribution.i18n.json index b3ca18516e9..612e6f3495e 100644 --- a/i18n/kor/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "보기", "help": "도움말", "file": "파일", - "developer": "개발자", "workspaces": "작업 영역", + "developer": "개발자", + "workbenchConfigurationTitle": "워크벤치", "showEditorTabs": "열려 있는 편집기를 탭에서 표시할지 여부를 제어합니다.", "workbench.editor.labelFormat.default": "파일 이름을 표시합니다. 탭이 사용하도록 설정되어 있고 하나의 그룹에서 파일 2개의 이름이 동일하면, 각 파일 경로의 특정 섹션이 추가됩니다. 탭이 사용하도록 설정되어 있지 않으면, 작업 영역 폴더에 대한 경로는 편집기가 활성 상태일 때 표시됩니다.", "workbench.editor.labelFormat.short": "디렉터리 이름 앞에 오는 파일의 이름을 표시합니다.", @@ -20,23 +21,23 @@ "showIcons": "열린 편집기를 아이콘과 함께 표시할지 여부를 제어합니다. 이를 위해서는 아이콘 테마도 사용하도록 설정해야 합니다.", "enablePreview": "열려 있는 편집기를 미리 보기로 표시할지 여부를 제어합니다. 미리 보기 편집기는 유지된 상태까지(예: 두 번 클릭 또는 편집을 통해) 다시 사용되며 기울임꼴 글꼴 스타일로 표시됩니다.", "enablePreviewFromQuickOpen": "Quick Open에서 연 편집기를 미리 보기로 표시할지 여부를 제어합니다. 미리 보기 편집기는 유지된 상태까지(예: 두 번 클릭 또는 편집을 통해) 다시 사용됩니다.", + "closeOnFileDelete": "일부 다른 프로세스에서 파일을 삭제하거나 이름을 바꿀 때 파일을 표시하는 편집기를 자동으로 닫을지 여부를 제어합니다. 사용하지 않도록 설정하는 경우 이러한 이벤트가 발생하면 편집기가 더티 상태로 계속 열려 있습니다. 응용 프로그램 내에서 삭제하면 항상 편집기가 닫히고 데이터를 유지하기 위해 더티 파일은 닫히지 않습니다.", "editorOpenPositioning": "편집기가 열리는 위치를 제어합니다. 현재 활성 편집기의 왼쪽 또는 오른쪽에서 편집기를 열려면 '왼쪽' 또는 '오른쪽'을 선택합니다. 현재 활성 편집기와 독립적으로 편집기를 열려면 '처음' 또는 '마지막'을 선택합니다.", "revealIfOpen": "편집기를 여는 경우 보이는 그룹 중 하나에 표시할지 여부를 제어합니다. 사용하지 않도록 설정할 경우 편집기가 기본적으로 현재 활성 편집기 그룹에 열립니다. 사용하도록 설정할 경우 현재 활성 편집기 그룹에서 편집기가 다시 열리지 않고 이미 열린 편집기가 표시됩니다. 강제로 편집기가 특정 그룹에서 열리거나 현재 활성 그룹 옆에 열리도록 하는 등의 일부 경우에는 이 설정이 무시됩니다.", + "swipeToNavigate": "세 손가락으로 가로로 살짝 밀어 열려 있는 파일 간을 이동합니다.", "commandHistory": "명령 팔레트 기록을 유지하기 위해 최근 사용한 명령 개수를 제어합니다. 0으로 설정하면 명령 기록을 사용하지 않습니다.", "preserveInput": "다음에 열 때 마지막으로 명령 팔레트에 입력한 내용을 복원할지 결정합니다.", "closeOnFocusLost": "Quick Open가 포커스를 잃으면 자동으로 닫을지 여부를 제어합니다.", "openDefaultSettings": "설정을 열면 모든 기본 설정을 표시하는 편집기도 열리는지 여부를 제어합니다.", "sideBarLocation": "사이드바의 위치를 제어합니다. 워크벤치의 왼쪽이나 오른쪽에 표시될 수 있습니다.", + "panelDefaultLocation": "패널의 기본 위치를 제어합니다. 워크벤치의 아래 또는 오른쪽에 표시될 수 있습니다.", "statusBarVisibility": "워크벤치 아래쪽에서 상태 표시줄의 표시 유형을 제어합니다.", "activityBarVisibility": "워크벤치에서 작업 막대의 표시 유형을 제어합니다.", - "closeOnFileDelete": "일부 다른 프로세스에서 파일을 삭제하거나 이름을 바꿀 때 파일을 표시하는 편집기를 자동으로 닫을지 여부를 제어합니다. 사용하지 않도록 설정하는 경우 이러한 이벤트가 발생하면 편집기가 더티 상태로 계속 열려 있습니다. 응용 프로그램 내에서 삭제하면 항상 편집기가 닫히고 데이터를 유지하기 위해 더티 파일은 닫히지 않습니다.", - "enableNaturalLanguageSettingsSearch": "설정에 대한 자연어 검색 모드를 사용할지 여부를 제어합니다.", "fontAliasing": "워크벤치에서 글꼴 앨리어싱 방식을 제어합니다.\n- 기본: 서브 픽셀 글꼴 다듬기. 대부분의 일반 디스플레이에서 가장 선명한 글꼴 제공\n- 안티앨리어싱: 서브 픽셀이 아닌 픽셀 단위에서 글꼴 다듬기. 전반적으로 더 밝은 느낌을 줄 수 있음\n- 없음: 글꼴 다듬기 사용 안 함. 텍스트 모서리가 각지게 표시됨", "workbench.fontAliasing.default": "서브 픽셀 글꼴 다듬기. 대부분의 일반 디스플레이에서 가장 선명한 텍스트를 제공합니다. ", "workbench.fontAliasing.antialiased": "서브 픽셀이 아닌 픽셀 수준에서 글꼴을 다듬습니다. 전반적으로 글꼴이 더 밝게 표시됩니다.", "workbench.fontAliasing.none": "글꼴 다듬기를 사용하지 않습니다. 텍스트 가장자리가 각지게 표시됩니다.", - "swipeToNavigate": "세 손가락으로 가로로 살짝 밀어 열려 있는 파일 간을 이동합니다.", - "workbenchConfigurationTitle": "워크벤치", + "enableNaturalLanguageSettingsSearch": "설정에 대한 자연어 검색 모드를 사용할지 여부를 제어합니다.", "windowConfigurationTitle": "창", "window.openFilesInNewWindow.on": "파일이 새 창에서 열립니다.", "window.openFilesInNewWindow.off": "파일이 파일의 폴더가 열려 있는 창 또는 마지막 활성 창에서 열립니다.", diff --git a/i18n/kor/src/vs/workbench/electron-browser/window.i18n.json b/i18n/kor/src/vs/workbench/electron-browser/window.i18n.json index dc0deb8eb7f..c019b85acbe 100644 --- a/i18n/kor/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/kor/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "잘라내기", "copy": "복사", "paste": "붙여넣기", - "selectAll": "모두 선택" + "selectAll": "모두 선택", + "runningAsRoot": "{0}을(를) 루트 사용자로 실행하지 않는 것이 좋습니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index e3166a31b49..55b56ed3448 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "디버그 도구 모음 배경색입니다." + "debugToolBarBackground": "디버그 도구 모음 배경색입니다.", + "debugToolBarBorder": "디버그 도구 모음 테두리색입니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 0530d6e3338..744cd683e86 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "디버기", - "debug.terminal.not.available.error": "통합 터미널을 사용할 수 없습니다." + "debug.terminal.title": "디버기" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 50730f44076..318c2b33d6f 100644 --- a/i18n/kor/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "새 명령 프롬프트 열기", "globalConsoleActionMacLinux": "새 터미널 열기", "scopedConsoleActionWin": "명령 프롬프트에서 열기", - "scopedConsoleActionMacLinux": "터미널에서 열기", - "openFolderInIntegratedTerminal": "터미널에서 열기" + "scopedConsoleActionMacLinux": "터미널에서 열기" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index 3b5fdb0caac..ec5f81cd482 100644 --- a/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "최근에 연 파일을 기반으로 확장이 권장됩니다.", + "neverShowAgain": "다시 표시 안 함", + "close": "닫기", "workspaceRecommendation": "이 확장은 현재 작업 영역 사용자가 권장합니다.", + "fileBasedRecommendation": "최근에 연 파일을 기반으로 확장이 권장됩니다.", "exeBasedRecommendation": "{0}이(가) 설치되어 있으므로 이 확장을 권장합니다.", "reallyRecommended2": "이 파일 형식에 대해 '{0}' 확장이 권장됩니다.", "reallyRecommendedExtensionPack": "이 파일 형식에 대해 '{0}' 확장 팩이 권장됩니다.", "showRecommendations": "권장 사항 표시", "install": "설치", - "neverShowAgain": "다시 표시 안 함", - "close": "닫기", "workspaceRecommended": "이 작업 영역에 확장 권장 사항이 있습니다.", "installAll": "모두 설치", "ignoreExtensionRecommendations": "확장 권장 사항을 모두 무시하시겠습니까?", diff --git a/i18n/kor/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..f1ae7883f32 --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "워크벤치" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/kor/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 70dd8169321..9595a565713 100644 --- a/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,25 @@ "filesCategory": "파일", "revealInSideBar": "세로 막대에 표시", "acceptLocalChanges": "변경을 적용하고 디스크 콘텐츠 덮어쓰기", - "revertLocalChanges": "변경 내용을 취소하고 디스크의 콘텐츠로 되돌리기" + "revertLocalChanges": "변경 내용을 취소하고 디스크의 콘텐츠로 되돌리기", + "copyPathOfActive": "활성 파일의 경로 복사", + "saveAllInGroup": "그룹의 모든 항목 저장", + "saveFiles": "파일 모두 저장", + "revert": "파일 되돌리기", + "compareActiveWithSaved": "활성 파일을 저장된 파일과 비교", + "closeEditor": "편집기 닫기", + "view": "보기", + "openToSide": "측면에서 열기", + "revealInWindows": "탐색기에 표시", + "revealInMac": "Finder에 표시", + "openContainer": "상위 폴더 열기", + "copyPath": "경로 복사", + "saveAll": "모두 저장", + "compareWithSaved": "저장된 항목과 비교", + "compareSource": "비교를 위해 선택", + "close": "닫기", + "closeOthers": "기타 항목 닫기", + "closeUnmodified": "미수정 항목 닫기", + "closeAll": "모두 닫기", + "deleteFile": "영구히 삭제" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 87d00a4c77a..63c70d80b92 100644 --- a/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "다시 시도", - "rename": "이름 바꾸기", "newFile": "새 파일", "newFolder": "새 폴더", + "rename": "이름 바꾸기", + "delete": "삭제", + "copyFile": "복사", + "pasteFile": "붙여넣기", + "retry": "다시 시도", "openFolderFirst": "안에 파일이나 폴더를 만들려면 먼저 폴더를 엽니다.", "newUntitledFile": "제목이 없는 새 파일", "createNewFile": "새 파일", @@ -28,26 +31,14 @@ "confirmDeleteMessageFile": "'{0}'을(를) 영구히 삭제할까요?", "irreversible": "이 작업은 취소할 수 없습니다.", "permDelete": "영구히 삭제", - "delete": "삭제", "importFiles": "파일 가져오기", "confirmOverwrite": "이름이 같은 파일 또는 폴더가 대상 폴더에 이미 있습니다. 덮어쓸까요?", "replaceButtonLabel": "바꾸기(&&R)", - "copyFile": "복사", - "pasteFile": "붙여넣기", "duplicateFile": "중복", - "openToSide": "측면에서 열기", - "compareSource": "비교를 위해 선택", "globalCompareFile": "활성 파일을 다음과 비교...", "openFileToCompare": "첫 번째 파일을 열어서 다른 파일과 비교합니다.", - "compareWith": "'{0}'과(와) '{1}' 비교", - "compareFiles": "파일 비교", "refresh": "새로 고침", - "save": "저장", - "saveAs": "다른 이름으로 저장...", - "saveAll": "모두 저장", "saveAllInGroup": "그룹의 모든 항목 저장", - "saveFiles": "파일 모두 저장", - "revert": "파일 되돌리기", "focusOpenEditors": "열려 있는 편집기 뷰에 포커스", "focusFilesExplorer": "파일 탐색기에 포커스", "showInExplorer": "세로 막대에서 활성 파일 표시", @@ -56,20 +47,11 @@ "refreshExplorer": "탐색기 새로 고침", "openFileInNewWindow": "새 창에서 활성 파일 열기", "openFileToShowInNewWindow": "먼저 파일 한 개를 새 창에서 엽니다.", - "revealInWindows": "탐색기에 표시", - "revealInMac": "Finder에 표시", - "openContainer": "상위 폴더 열기", - "revealActiveFileInWindows": "Windows 탐색기에 활성 파일 표시", - "revealActiveFileInMac": "Finder에 활성 파일 표시", - "openActiveFileContainer": "활성 파일의 상위 폴더 열기", "copyPath": "경로 복사", - "copyPathOfActive": "활성 파일의 경로 복사", "emptyFileNameError": "파일 또는 폴더 이름을 입력해야 합니다.", "fileNameExistsError": "파일 또는 폴더 **{0}**이(가) 이 위치에 이미 있습니다. 다른 이름을 선택하세요.", "invalidFileNameError": "**{0}**(이)라는 이름은 파일 또는 폴더 이름으로 올바르지 않습니다. 다른 이름을 선택하세요.", "filePathTooLongError": "**{0}**(이)라는 이름을 사용하면 경로가 너무 길어집니다. 짧은 이름을 선택하세요.", - "compareWithSaved": "활성 파일을 저장된 파일과 비교", - "modifiedLabel": "{0}(디스크) ↔ {1}", "compareWithClipboard": "클립보드와 활성 파일 비교", "clipboardComparisonLabel": "클립보드 ↔ {0}" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index f77f75c5013..3ba45c45801 100644 --- a/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "첫 번째 파일을 열어서 경로를 복사합니다.", - "openFileToReveal": "첫 번째 파일을 열어서 나타냅니다." + "revealInWindows": "탐색기에 표시", + "revealInMac": "Finder에 표시", + "openContainer": "상위 폴더 열기", + "saveAs": "다른 이름으로 저장...", + "save": "저장", + "saveAll": "모두 저장", + "removeFolderFromWorkspace": "작업 영역에서 폴더 삭제", + "modifiedLabel": "{0}(디스크) ↔ {1}", + "openFileToReveal": "첫 번째 파일을 열어서 나타냅니다.", + "openFileToCopy": "첫 번째 파일을 열어서 경로를 복사합니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 64e3a748c1d..f166c5489ca 100644 --- a/i18n/kor/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,6 @@ "editorConfigurationTitle": "편집기", "formatOnSave": "파일 저장 시 서식을 지정합니다. 포맷터를 사용할 수 있어야 하며, 파일이 자동으로 저장되지 않아야 하고, 편집기가 종료되지 않아야 합니다.", "explorerConfigurationTitle": "파일 탐색기", - "openEditorsVisible": "열려 있는 편집기 창에 표시되는 편집기 수입니다. 창을 숨기려면 0으로 설정합니다.", - "dynamicHeight": "열려 있는 편집기 섹션의 높이가 요소 수에 따라 동적으로 조정되는지 여부를 제어합니다.", "autoReveal": "탐색기에서 파일을 열 때 자동으로 표시하고 선택할지를 제어합니다.", "enableDragAndDrop": "탐색기에서 끌어서 놓기를 통한 파일 및 폴더 이동을 허용하는지를 제어합니다.", "confirmDragAndDrop": "끌어서 놓기를 사용하여 파일 및 폴더를 이동하기 위해 탐색기에서 확인을 요청해야 하는지 제어합니다.", diff --git a/i18n/kor/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/kor/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 6cf353ae712..33af3c52303 100644 --- a/i18n/kor/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,10 @@ // Do not edit this file. It is machine generated. { "userGuide": "오른쪽 편집기 도구 모음의 작업을 사용하여 변경 내용을 **실행 취소**하거나 디스크의 콘텐츠를 변경 내용으로 **덮어쓰기**", - "discard": "삭제", "overwrite": "덮어쓰기", "retry": "다시 시도", - "readonlySaveError": "'{0}'을(를) 저장하지 못했습니다. 파일이 쓰기 보호되어 있습니다. 보호를 제거하려면 '덮어쓰기'를 선택하세요.", + "discard": "삭제", + "permissionDeniedSaveError": "저장 실패 '{0}': 권한 부족. 관리자로 다시 시도하려면 '관리자로 다시 시도'를 선택하세요.", "genericSaveError": "'{0}'을(를) 저장하지 못했습니다. {1}", "staleSaveError": "'{0}'을(를) 저장하지 못했습니다. 디스크의 내용이 최신 버전입니다. 버전을 디스크에 있는 버전과 비교하려면 **비교**를 클릭하세요.", "compareChanges": "비교", diff --git a/i18n/kor/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/kor/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index 56030126c94..3f6a56914c0 100644 --- a/i18n/kor/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "열려 있는 편집기", "openEditosrSection": "열려 있는 편집기 섹션", - "dirtyCounter": "{0}이(가) 저장되지 않음", - "saveAll": "모두 저장", - "closeAllUnmodified": "미수정 항목 닫기", - "closeAll": "모두 닫기", - "compareWithSaved": "저장된 항목과 비교", - "close": "닫기", - "closeOthers": "기타 항목 닫기" + "dirtyCounter": "{0}이(가) 저장되지 않음" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..c6b46a532f7 --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "mainLog": "로그(메인)", + "rendererLog": "로그(창)", + "extensionsLog": "로그(확장 호스트)", + "developer": "개발자" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/kor/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..e36190cd574 --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "로그 폴더 열기", + "showLogs": "로그 표시...", + "mainProcess": "기본", + "sharedProcess": "공유", + "rendererProcess": "창", + "selectProcess": "프로세스 선택", + "setLogLevel": "로그 수준 설정", + "trace": "Trace", + "debug": "디버그", + "info": "정보", + "warn": "경고", + "err": "오류", + "critical": "Critical", + "off": "Off" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/kor/src/vs/workbench/parts/markers/common/messages.i18n.json index f9e867de14d..f0b9f22340c 100644 --- a/i18n/kor/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "viewCategory": "보기", - "problems.view.toggle.label": "설정/해제 문제", - "problems.view.focus.label": "포커스 문제", "problems.panel.configuration.title": "문제 보기", "problems.panel.configuration.autoreveal": "문제 보기를 열 때 문제 보기에 자동으로 파일이 표시되어야 하는지를 제어합니다.", "markers.panel.title.problems": "문제", diff --git a/i18n/kor/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..921f1b58efc --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "출력", + "logViewer": "로그 표시기", + "viewCategory": "보기", + "clearOutput.label": "출력 내용 지우기" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/kor/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..9261a8ba1e2 --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "{0} - 출력" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/kor/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index 188fd9c37da..9dc8bd95b1f 100644 --- a/i18n/kor/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "자연어 검색을 사용해 보세요!", "defaultSettings": "설정을 오른쪽 편집기에 넣어서 덮어씁니다.", "noSettingsFound": "설정을 찾을 수 없습니다.", "settingsSwitcherBarAriaLabel": "설정 전환기", "userSettings": "사용자 설정", "workspaceSettings": "작업 영역 설정", - "folderSettings": "폴더 설정", - "enableFuzzySearch": "자연어 검색 사용" + "folderSettings": "폴더 설정" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/kor/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index de4c67a1e30..90960b4f14d 100644 --- a/i18n/kor/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "일반적으로 사용되는 설정", - "mostRelevant": "가장 관련 있는 항목", "defaultKeybindingsHeader": "키 바인딩을 키 바인딩 파일에 배치하여 덮어씁니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index 0be24d926bb..c631d0cd782 100644 --- a/i18n/kor/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "보기", "commandsHandlerDescriptionDefault": "명령 표시 및 실행", "gotoLineDescriptionMac": "줄 이동", "gotoLineDescriptionWin": "줄 이동", diff --git a/i18n/kor/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index 4b848835e91..29d19883f06 100644 --- a/i18n/kor/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,6 @@ "toggleGitViewlet": "Git 표시", "source control": "소스 제어", "toggleSCMViewlet": "SCM 표시", - "view": "보기" + "view": "보기", + "scmConfigurationTitle": "SCM" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/kor/src/vs/workbench/parts/search/browser/searchActions.i18n.json index b045a022b27..68680603aad 100644 --- a/i18n/kor/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "이전 검색어 표시", "showSearchViewlet": "검색 표시", "findInFiles": "파일에서 찾기", - "findInFilesWithSelectedText": "선택한 텍스트가 있는 파일에서 찾기", "replaceInFiles": "파일에서 바꾸기", - "replaceInFilesWithSelectedText": "선택한 텍스트가 있는 파일에서 바꾸기", "RefreshAction.label": "새로 고침", "CollapseDeepestExpandedLevelAction.label": "모두 축소", "ClearSearchResultsAction.label": "지우기", diff --git a/i18n/kor/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index 9b239f6fd5f..bbdbfe77846 100644 --- a/i18n/kor/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -7,7 +7,9 @@ "showTriggerActions": "작업 영역에서 기호로 이동...", "name": "검색", "search": "검색", + "showSearchViewlet": "검색 표시", "view": "보기", + "findInFiles": "파일에서 찾기", "openAnythingHandlerDescription": "파일로 이동", "openSymbolDescriptionNormal": "작업 영역에서 기호로 이동", "searchOutputChannelTitle": "검색", diff --git a/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..37d5355620e --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.1": "({0})", + "preferences": "기본 설정" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 582f284bf10..7a0857e6f8d 100644 --- a/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,10 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "코드 조각의 언어 선택", - "openSnippet.errorOnCreate": "{0}을(를) 만들 수 없음", - "openSnippet.label": "사용자 코드 조각 열기", - "preferences": "기본 설정", "snippetSchema.json.default": "빈 코드 조각", "snippetSchema.json": "사용자 코드 조각 구성", "snippetSchema.json.prefix": "IntelliSense에서 코드 조각을 선택할 때 사용할 접두사입니다.", diff --git a/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..587455cd532 --- /dev/null +++ b/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "사용자 코드 조각" +} \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index c423047529b..b33ab06f4bb 100644 --- a/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "`contributes.{0}.language`에 알 수 없는 언어가 있습니다. 제공된 값: {1}", "invalid.path.0": "`contributes.{0}.path`에 문자열이 필요합니다. 제공된 값: {1}", + "invalid.language": "`contributes.{0}.language`에 알 수 없는 언어가 있습니다. 제공된 값: {1}", "invalid.path.1": "확장 폴더({2})에 포함할 `contributes.{0}.path`({1})가 필요합니다. 확장이 이식 불가능해질 수 있습니다.", "vscode.extension.contributes.snippets": "코드 조각을 적용합니다.", "vscode.extension.contributes.snippets-language": "이 코드 조각이 적용되는 언어 식별자입니다.", "vscode.extension.contributes.snippets-path": "코드 조각 파일의 경로입니다. 이 경로는 확장 폴더의 상대 경로이며 일반적으로 './snippets/'로 시작합니다.", "badVariableUse": "'{0}' 확장의 1개 이상의 코드 조각은 snippet-variables 및 snippet-placeholders와 혼동하기 쉽습니다(자세한 내용은 https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax를 참조하세요).", "badFile": "코드 조각 파일 \"{0}\"을(를) 읽을 수 없습니다.", - "source.snippet": "사용자 코드 조각", "detail.snippet": "{0}({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json b/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json index 32869d50216..8483a433151 100644 --- a/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json @@ -8,6 +8,5 @@ "terminal.foreground": "터미널의 전경색입니다.", "terminalCursor.foreground": "터미널 커서의 전경색입니다.", "terminalCursor.background": "터미널 커서의 배경색입니다. 블록 커서와 겹친 문자의 색상을 사용자 정의할 수 있습니다.", - "terminal.selectionBackground": "터미널의 선택 영역 배경색입니다.", - "terminal.ansiColor": "터미널의 '{0}' ANSI 색입니다." + "terminal.selectionBackground": "터미널의 선택 영역 배경색입니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index b21bf5b25fa..ed40b375339 100644 --- a/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,6 @@ "terminal.integrated.chooseWindowsShellInfo": "사용자 지정 단추를 선택하여 기본 터미널 셸을 변경할 수 있습니다.", "customize": "사용자 지정", "cancel": "취소", - "never again": "다시 표시 안 함", "terminal.integrated.chooseWindowsShell": "기본으로 설정할 터미널 셸을 선택하세요. 나중에 설정에서 이 셸을 변경할 수 있습니다.", "terminalService.terminalCloseConfirmationSingular": "활성 터미널 세션이 있습니다. 종료할까요?", "terminalService.terminalCloseConfirmationPlural": "{0}개의 활성 터미널 세션이 있습니다. 종료할까요?" diff --git a/i18n/kor/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/kor/src/vs/workbench/parts/update/electron-browser/update.i18n.json index bb502a90cb6..485a7f763c8 100644 --- a/i18n/kor/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -23,6 +23,7 @@ "commandPalette": "명령 팔레트...", "settings": "설정", "keyboardShortcuts": "바로 가기 키(&&K)", + "userSnippets": "사용자 코드 조각", "selectTheme.label": "색 테마", "themes.selectIconTheme.label": "파일 아이콘 테마", "not available": "업데이트를 사용할 수 없음", diff --git a/i18n/kor/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/kor/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index d48fe3d053e..196d40bcdb5 100644 --- a/i18n/kor/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/kor/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "파일이 디렉터리입니다.", + "fileNotModifiedError": "파일 수정 안 됨", "fileBinaryError": "파일이 이진인 것 같으므로 테스트로 열 수 없습니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/kor/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index db19c348ac8..56bf06242e3 100644 --- a/i18n/kor/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/kor/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "{0}에 대한 변경 내용을 저장할까요?", "saveChangesMessages": "다음 {0}개 파일에 대한 변경 내용을 저장할까요?", - "moreFile": "...1개의 추가 파일이 표시되지 않음", - "moreFiles": "...{0}개의 추가 파일이 표시되지 않음", "saveAll": "모두 저장(&&S)", "save": "저장(&&S)", "dontSave": "저장 안 함(&&N)", diff --git a/i18n/kor/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/kor/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index d365ddcbff5..ae661bf4187 100644 --- a/i18n/kor/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/kor/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "No file icons", "iconThemeError": "File icon theme is unknown or not installed.", "workbenchColors": "현재 선택한 색 테마에서 색을 재정의합니다.", - "editorColors": "현재 선택된 색 테마에서 편집기 색상과 글꼴 스타일을 재정의합니다.", "editorColors.comments": "주석의 색 및 스타일을 설정합니다.", "editorColors.strings": "문자열 리터럴의 색 및 스타일을 설정합니다.", "editorColors.keywords": "키워드의 색과 스타일을 설정합니다.", @@ -19,5 +18,6 @@ "editorColors.types": "형식 선언 및 참조의 색 및 스타일을 설정합니다.", "editorColors.functions": "함수 선언 및 참조의 색 및 스타일을 설정합니다.", "editorColors.variables": "변수 선언 및 참조의 색 및 스타일을 설정합니다.", - "editorColors.textMateRules": "textmate 테마 설정 규칙을 사용하여 색 및 스타일을 설정합니다(고급)." + "editorColors.textMateRules": "textmate 테마 설정 규칙을 사용하여 색 및 스타일을 설정합니다(고급).", + "editorColors": "현재 선택된 색 테마에서 편집기 색상과 글꼴 스타일을 재정의합니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/kor/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index e836eb6be3f..a2425123fe5 100644 --- a/i18n/kor/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/kor/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "작업 영역 구성 파일에 쓸 수 없습니다. 파일을 열고 오류/경고를 수정한 다음 다시 시도하세요.", "errorWorkspaceConfigurationFileDirty": "파일이 변경되어 작업 영역 구성 파일에 쓸 수 없습니다. 저장하고 다시 시도하세요.", "openWorkspaceConfigurationFile": "작업 영역 구성 파일 열기", - "close": "닫기", - "enterWorkspace.close": "닫기", - "enterWorkspace.dontShowAgain": "다시 표시 안 함", - "enterWorkspace.moreInfo": "추가 정보", - "enterWorkspace.prompt": "VS Code에서 여러 개의 파일을 작업하는 방법에 대해 자세히 알아보세요." + "close": "닫기" } \ No newline at end of file diff --git a/i18n/ptb/extensions/git/out/autofetch.i18n.json b/i18n/ptb/extensions/git/out/autofetch.i18n.json index 1c3c1cf318d..5df527f070d 100644 --- a/i18n/ptb/extensions/git/out/autofetch.i18n.json +++ b/i18n/ptb/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "Sim", + "read more": "Ler Mais", "no": "Não", - "not now": "Agora Não", - "suggest auto fetch": "Deseja habilitar o autopreenchimento dos repositórios Git?" + "not now": "Pergunte-me depois", + "suggest auto fetch": "Você gostaria que o Code executasse periodicamente `git fetch`?" } \ No newline at end of file diff --git a/i18n/ptb/extensions/git/out/commands.i18n.json b/i18n/ptb/extensions/git/out/commands.i18n.json index 03a6223ad1d..b56c7d4a6f4 100644 --- a/i18n/ptb/extensions/git/out/commands.i18n.json +++ b/i18n/ptb/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\n é IRREVERSÍVEL, o conjunto de trabalho atual será PERDIDO PARA SEMPRE.", "yes discard tracked": "Descartar 1 arquivo controlado", "yes discard tracked multiple": "Descartar arquivos {0} controlados", + "unsaved files single": "O seguinte arquivo não foi salvo: [0}.\n\nGostaria de salvá-lo antes de executar o commit?", + "unsaved files": "Existem {0} arquivos não salvos.\n\nGostaria de salvá-los antes de executar o commit?", + "save and commit": "Salvar Tudo & Confirmar", + "commit": "Confirmar de qualquer maneira", "no staged changes": "Não há nenhuma modificação escalonada para confirmar.\n\nGostaria de escalonar automaticamente todas as suas alterações e confirmá-las diretamente?", "always": "Sempre", "no changes": "Não há mudanças para confirmar.", @@ -64,12 +68,13 @@ "no remotes to pull": "O seu repositório não possui remotos configurados para efetuar pull.", "pick remote pull repo": "Selecione um remoto para efeutar o pull da ramificação", "no remotes to push": "O seu repositório não possui remotos configurados para efetuar push.", - "push with tags success": "Envio de rótulos finalizado com sucesso.", "nobranch": "Por favor, faça checkout em um ramo para fazer push em um remoto.", + "confirm publish branch": "O branch '{0}' não possui um branch superior. Você quer publicar este branch?", + "ok": "OK", + "push with tags success": "Envio de rótulos finalizado com sucesso.", "pick remote": "Pegue um remoto para publicar o ramo '{0}':", "sync is unpredictable": "Esta ação vai fazer push e pull nos commits de e para '{0}'.", - "ok": "OK", - "never again": "Ok, Nunca Mostrar Novamente", + "never again": "OK, Não Mostrar Novamente", "no remotes to publish": "Seu repositório não possui remotos configurados para publicação.", "no changes stash": "Não há nenhuma mudança para esconder.", "provide stash message": "Opcionalmente forneça uma mensagem para esconder.", diff --git a/i18n/ptb/extensions/git/out/repository.i18n.json b/i18n/ptb/extensions/git/out/repository.i18n.json index 214c9e1d36f..df6cf8fd751 100644 --- a/i18n/ptb/extensions/git/out/repository.i18n.json +++ b/i18n/ptb/extensions/git/out/repository.i18n.json @@ -27,6 +27,6 @@ "staged changes": "Alterações em Etapas", "changes": "Alterações", "ok": "OK", - "neveragain": "Nunca Mostrar Novamente", + "neveragain": "Não mostrar novamente", "huge": "O repositório git em '{0}' tem muitas atualizações ativas, somente um subconjunto de funcionalidades do Git será habilitado." } \ No newline at end of file diff --git a/i18n/ptb/extensions/git/package.i18n.json b/i18n/ptb/extensions/git/package.i18n.json index 81db50ac04f..670378da7f5 100644 --- a/i18n/ptb/extensions/git/package.i18n.json +++ b/i18n/ptb/extensions/git/package.i18n.json @@ -54,12 +54,12 @@ "command.stashPopLatest": "Pop mais recente Stash", "config.enabled": "Se o git estiver habilitado", "config.path": "Caminho para o executável do git", + "config.autoRepositoryDetection": "Se os repositórios devem ser detectados automaticamente", "config.autorefresh": "Se a atualização automática estiver habilitada", "config.autofetch": "Se a recuperação automática estiver habilitada", "config.enableLongCommitWarning": "Se mensagens longas de confirmação devem ter aviso", "config.confirmSync": "Confirmar antes de sincronizar repositórios git", "config.countBadge": "Controla o contador de distintivos do git. 'todos' considera todas as alterações. 'rastreado' considera apenas as alterações controladas. 'desligado' desliga o contador.", - "config.checkoutType": "Controla quais tipos de ramos são listados quando executando `Checkout para... `. `todos` mostra todas as referências, `local` mostra apenas os ramos locais, `etiqueta` mostra apenas etiquetas e `remoto` mostra apenas os ramos remotos.", "config.ignoreLegacyWarning": "Ignora o aviso de Git legado", "config.ignoreMissingGitWarning": "Ignora o aviso quando Git não existir.", "config.ignoreLimitWarning": "Ignora o aviso quando houver muitas alterações em um repositório", @@ -72,5 +72,6 @@ "colors.deleted": "Cor para recursos excluídos.", "colors.untracked": "Cor para recursos não controlados.", "colors.ignored": "Cor para recursos ignorados.", - "colors.conflict": "Cor para recursos com conflitos." + "colors.conflict": "Cor para recursos com conflitos.", + "colors.submodule": "Cor para recursos de sub-módulos." } \ No newline at end of file diff --git a/i18n/ptb/extensions/typescript/out/commands.i18n.json b/i18n/ptb/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..01c9f9ae0d9 --- /dev/null +++ b/i18n/ptb/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "Favor abrir uma pasta no VS Code para usar um projeto TypeScript ou JavaScript", + "typescript.projectConfigUnsupportedFile": "Não foi possível determinar o projeto TypeScript ou JavaScript. Tipo de arquivo não suportado", + "typescript.projectConfigCouldNotGetInfo": "Não foi possível determinar o projeto TypeScript ou JavaScript", + "typescript.noTypeScriptProjectConfig": "Arquivo não é parte de um projeto TypeScript", + "typescript.noJavaScriptProjectConfig": "Arquivo não é parte de um projeto JavaScript", + "typescript.configureTsconfigQuickPick": "Configurar tsconfig.json", + "typescript.configureJsconfigQuickPick": "Configurar jsconfig.json", + "typescript.projectConfigLearnMore": "Saiba Mais" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/ptb/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/ptb/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/base/node/ps.i18n.json b/i18n/ptb/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..e8b9b91a595 --- /dev/null +++ b/i18n/ptb/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "Coletando informações de CPU e memória. Isso pode demorar alguns segundos." +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/ptb/src/vs/editor/common/config/commonEditorConfig.i18n.json index 52ffce48a73..3e9436d02bf 100644 --- a/i18n/ptb/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/ptb/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "Números de linhas são renderizados em números absolutos.", "lineNumbers.relative": "Números de linhas são renderizadas como distância em linhas até a posição do cursor.", "lineNumbers.interval": "Números de linhas são renderizados a cada 10 linhas.", - "lineNumbers": "Controla a exibição dos números de linha. Os valores possíveis são 'on', 'off' e 'relative'.", + "lineNumbers": "Controla a exibição dos números de linha. Os valores possíveis são 'on', 'off', 'relative' e 'interval'.", "rulers": "Renderiza réguas verticais após um certo número de caracteres de espaço. Use vários valores para várias réguas. Réguas não serão desenhadas se a matriz estiver vazia", "wordSeparators": "Caracteres que serão usados como separadores de palavras ao fazer navegação relacionada a palavras ou operações", "tabSize": "O número de espaços equivalentes a uma tabulação. Esta configuração é sobreposta com base no conteúdo do arquivo quando `editor.detectIndentation` está ligado.", @@ -72,6 +72,7 @@ "cursorBlinking": "Controla o estilo de animação do cursor, os valores possíveis são 'blink', 'smooth', 'phase', 'expand' e 'solid'", "mouseWheelZoom": "Alterar o zoom da fonte editor quando utilizada a roda do mouse e pressionando Ctrl", "cursorStyle": "Controla o estilo do cursor, os valores aceitos são 'block', 'block-outline', 'line', 'line-thin', 'underline' e 'underline-thin'", + "lineCursorWidth": "Controla a largura do cursor quando editor.cursorStyle está definido como 'line'", "fontLigatures": "Habilita ligaduras de fontes", "hideCursorInOverviewRuler": "Controla se o cursor deve ficar oculto na régua de visão geral.", "renderWhitespace": "Controla como o editor deve rendenizar caracteres de espaços em branco, possibilidades são 'none', 'boundary' e 'all'. A opção 'boundary' não rendeniza espaços simples entre palavras.", diff --git a/i18n/ptb/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/ptb/src/vs/editor/common/view/editorColorRegistry.i18n.json index 434fe65993d..27de662d885 100644 --- a/i18n/ptb/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/ptb/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,7 @@ { "lineHighlight": "Cor de fundo para a posição do cursor na seleção de linhas.", "lineHighlightBorderBox": "Cor de fundo para a borda em volta da linha na posição do cursor", - "rangeHighlight": "Cor de fundo dos ranges selecionados, assim como abertura instantânea e descoberta de recursos ", + "rangeHighlight": "Cor de fundo dos intervalos selecionados, assim como da abertura instantânea e localização de recursos. A cor não deve ser opaca para evitar esconder as decorações subjacentes", "caret": "Cor do cursor no editor.", "editorCursorBackground": "A cor de fundo do cursor do editor. Permite customizar a cor de um caractere sobreposto pelo bloco do cursor.", "editorWhitespaces": "Cor dos caracteres em branco no editor", diff --git a/i18n/ptb/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/ptb/src/vs/editor/contrib/gotoError/gotoError.i18n.json index d05aeee6c34..5be9785fd64 100644 --- a/i18n/ptb/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/ptb/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "Ir para o Próximo Erro ou Aviso", - "markerAction.previous.label": "Ir para o Erro ou Aviso Anterior", + "markerAction.next.label": "Ir para o Próximo Problema (Erro, Aviso, Informação)", + "markerAction.previous.label": "Ir para o Problema Anterior (Erro, Aviso, Informação)", "editorMarkerNavigationError": "Ferramenta de marcação de edição apresentando error na cor ", "editorMarkerNavigationWarning": "Ferramenta de marcação de edição apresentando adventência na cor", "editorMarkerNavigationInfo": "Cor de informação da ferramenta de navegação do marcador do editor.", diff --git a/i18n/ptb/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/ptb/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index 6ccc873b02c..99acb12e285 100644 --- a/i18n/ptb/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/ptb/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "Cor de fundo de um símbolo durante acesso de leitura, como ao ler uma variável.", - "wordHighlightStrong": "Cor de fundo de um símbolo durante acesso de escrita, como ao escrever uma variável.", + "wordHighlight": "Cor de fundo de um símbolo durante o acesso de leitura, como ao ler uma variável. A cor não deve ser opaca para não ocultar as decorações subjacentes.", + "wordHighlightStrong": "Cor de fundo de um símbolo durante o acesso de escrita, como ao escrever uma variável. A cor não deve ser opaca para não ocultar as decorações subjacentes.", "overviewRulerWordHighlightForeground": "Visão geral da cor do marcador da régua para destaques de símbolos.", "overviewRulerWordHighlightStrongForeground": "Visão geral da cor do marcador da régua para gravação de destaques de símbolos.", "wordHighlight.next.label": "Ir para o próximo símbolo em destaque", diff --git a/i18n/ptb/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/ptb/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index 28adcb87065..5ade9a9290c 100644 --- a/i18n/ptb/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/ptb/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "'{0}' nao é um identificador de menu válido ", "missing.command": "Identificador do comando para ser executado. O comando deve ser declarado na seção de 'Comandos'", "missing.altCommand": "Referências ao item de menu no alt-command '{0}' qual nao é definido na sessão 'comandos'", - "dupe.command": "Itens de referencias do mesmo comando como padrão e alt-command", - "nosupport.altCommand": "Desculpe, mas atualmente somente o groupo 'navegação' do menu 'editor/título' suporta alt-commands" + "dupe.command": "Itens de referencias do mesmo comando como padrão e alt-command" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/platform/environment/node/argv.i18n.json b/i18n/ptb/src/vs/platform/environment/node/argv.i18n.json index ed9e5aca99c..72fb01e6637 100644 --- a/i18n/ptb/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/ptb/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,35 @@ "diff": "Comparar dois arquivos entre si.", "add": "Adicione pasta(s) para a última janela ativa.", "goto": "Abra um arquivo no caminho sobre a linha especificada e a posição do caractere.", - "locale": "Para localização utilize (ex. en-US ou zh-TW).", "newWindow": "Força uma nova instância do Código.", - "performance": "Comece com o 'Desenvolvedor: Desempenho de inicialização' comando habilitado.", - "prof-startup": "Rodar o CPU profiler durante a inicialização", - "inspect-extensions": "Permite depuração e criação de perfis de extensões. Verifique as ferramentas de desenvolvimento para a conexão uri.", - "inspect-brk-extensions": "Permitir depuração e criação de perfil de extensões com o host de extensão em pausa após o início. Verifique as ferramentas do desenvolvedor para a conexão uri.", "reuseWindow": "Forçar a abertura de um arquivo ou pasta na última janela ativa", - "userDataDir": "Especifica o diretório que os dados do usuário serão mantidos, útil quando estiver rodando como root.", - "log": "Nível de log a ser utilizado. O padrão é 'info'. Os valores permitidos são 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'.", - "verbose": "Imprimir a saída detalhada (Implica -- esperar).", "wait": "Espere pelos arquivos a serem fechados antes de retornar.", + "locale": "Para localização utilize (ex. en-US ou zh-TW).", + "userDataDir": "Especifica o diretório que os dados do usuário serão mantidos, útil quando estiver rodando como root.", + "version": "Versão de impressão", + "help": "Uso de impressão.", "extensionHomePath": "Defina o caminho raíz para as extensões.", "listExtensions": "Lista de extensões instaladas", "showVersions": "Exibir versões de extensões instaladas, quando estiver usando --list-extension", "installExtension": "Instala uma extensão.", "uninstallExtension": "Desinstala uma extensão.", "experimentalApis": "Permite recursos de api propostos para uma extensão.", - "disableExtensions": "Desabilita todas as extensões instaladas.", - "disableGPU": "Desabilita aceleração de hardware da GPU.", + "verbose": "Imprimir a saída detalhada (Implica -- esperar).", + "log": "Nível de log a ser utilizado. O padrão é 'info'. Os valores permitidos são 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'.", "status": "Utilização do processo de impressão e informações de diagnóstico.", - "version": "Versão de impressão", - "help": "Uso de impressão.", + "performance": "Comece com o 'Desenvolvedor: Desempenho de inicialização' comando habilitado.", + "prof-startup": "Rodar o CPU profiler durante a inicialização", + "disableExtensions": "Desabilita todas as extensões instaladas.", + "inspect-extensions": "Permite depuração e criação de perfis de extensões. Verifique as ferramentas de desenvolvimento para a conexão uri.", + "inspect-brk-extensions": "Permitir depuração e criação de perfil de extensões com o host de extensão em pausa após o início. Verifique as ferramentas do desenvolvedor para a conexão uri.", + "disableGPU": "Desabilita aceleração de hardware da GPU.", + "uploadLogs": "Envia os registros de atividade da sessão atual para um destino seguro.", "usage": "Uso", "options": "opções", "paths": "caminhos", - "optionsUpperCase": "Opções" + "stdinWindows": "Para ler a saída de outro programa, adicione '-' ao final (ex. 'echo Hello World | {0} -')", + "stdinUnix": "Para ler do stdin, adicione '-' ao final (ex. 'ps aux | grep code | {0} -')", + "optionsUpperCase": "Opções", + "extensionsManagement": "Gerenciamento de Extensões", + "troubleshooting": "Solução de problemas" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/ptb/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index 98c0be5cdcb..4fe84adc13b 100644 --- a/i18n/ptb/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/ptb/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,15 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "Extensão inválida: pacote.json nao é um arquivo JSON válido", - "restartCodeLocal": "Por favor reinicie Code antes de reinstalar {0}.", + "restartCode": "Por favor reinicie Code antes de reinstalar {0}.", "installingOutdatedExtension": "Uma nova versão desta extensão já está instalada. Você deseja sobrescrever esta instalação com a versão mais antiga?", "override": "Sobrescrever", "cancel": "Cancelar", - "notFoundCompatible": "Não foi possível instalar porque a extensão '{0}' compatível com a versão atual '{1}' do VS Code não foi encontrada.", - "quitCode": "Não foi possível instalar porque uma instância obsoleta da extensão ainda está em execução. Por favor, pare e inicie o VS Code antes de reinstalar.", - "exitCode": "Não foi possível instalar porque uma instância obsoleta da extensão ainda está em execução. Por favor, pare e inicie o VS Code antes de reinstalar.", + "errorInstallingDependencies": "Erro ao instalar dependências. {0}", + "notFoundCompatible": "Não foi possível instalar '{0}; não existe nenhuma versão compatível com o VSCode '{1}'.", "notFoundCompatibleDependency": "Não foi possível instalar porque a extensão dependente '{0}' compatível com a versão atual '{1}' do VS Code não foi encontrada.", + "quitCode": "Não foi possível instalar a extensão. Por favor, saia e reinicie o VS Code antes de reinstalar.", + "exitCode": "Não foi possível instalar a extensão. Por favor, saia e reinicie o VS Code antes de reinstalar.", "uninstallDependeciesConfirmation": "Gostaria de desinstalar '{0}' somente, ou suas dependências também?", "uninstallOnly": "Apenas", "uninstallAll": "Todos", diff --git a/i18n/ptb/src/vs/platform/message/common/message.i18n.json b/i18n/ptb/src/vs/platform/message/common/message.i18n.json index 620c63edd07..0d24937956e 100644 --- a/i18n/ptb/src/vs/platform/message/common/message.i18n.json +++ b/i18n/ptb/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "Fechar", "later": "Mais tarde", - "cancel": "Cancelar" + "cancel": "Cancelar", + "moreFile": "... 1 arquivo adicional não está mostrado", + "moreFiles": "... {0} arquivos adicionais não estão mostrados" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/ptb/src/vs/platform/theme/common/colorRegistry.i18n.json index 6f399a88a06..ad9e4de8759 100644 --- a/i18n/ptb/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/ptb/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,12 @@ "editorWidgetBorder": "Cor da borda das ferramentas do editor. A cor é usada somente se a ferramenta escolhe ter uma borda e a cor não é substituída por uma ferramenta.", "editorSelectionBackground": "Cor de seleção do editor.", "editorSelectionForeground": "Cor do texto selecionado para alto contraste.", - "editorInactiveSelection": "Cor de seleção em um editor inativo.", - "editorSelectionHighlight": "Cor de regiões com o mesmo conteúdo da seleção.", + "editorInactiveSelection": "Cor da seleção em um editor inativo. A cor não deve ser opaca para não esconder decorações subjacentes.", + "editorSelectionHighlight": "Cor para regiões com o mesmo conteúdo da seleção. A cor não deve ser opaca para não esconder decorações subjacentes.", "editorFindMatch": "Cor da correspondência de pesquisa atual.", - "findMatchHighlight": "Cor dos outros resultados de pesquisa.", - "findRangeHighlight": "Cor da faixa que limita a pesquisa.", - "hoverHighlight": "Realçar abaixo da palavra onde é mostrado item flutuante", + "findMatchHighlight": "Cor dos outros termos que correspondem ao da pesquisa. A cor não deve ser opaca para não esconder as decorações subjacentes.", + "findRangeHighlight": "Cor do intervalo limitando a pesquisa. A cor não deve ser opaca para não esconder decorações subjacentes.", + "hoverHighlight": "Destaque abaixo da palavra para qual um flutuador é mostrado. A cor não deve ser opaca para não esconder decorações subjacentes.", "hoverBackground": "Cor de fundo para o item flutuante do editor", "hoverBorder": "Cor da borda para o item flutuante do editor.", "activeLinkForeground": "Cor dos links ativos.", @@ -76,12 +76,12 @@ "diffEditorRemoved": "Cor de fundo para texto que foi removido.", "diffEditorInsertedOutline": "Cor de contorno para o texto que foi inserido.", "diffEditorRemovedOutline": "Cor de contorno para o texto que foi removido.", - "mergeCurrentHeaderBackground": "Cor de fundo de cabeçalho atual em conflito de mesclagem em linha.", - "mergeCurrentContentBackground": "Cor de fundo de conteúdo atual em conflito de mesclagem em linha.", - "mergeIncomingHeaderBackground": "Cor de fundo de cabeçalho de entrada em conflito de mesclagem em linha.", - "mergeIncomingContentBackground": "Cor de fundo de conteúdo de entrada em conflito de mesclagem em linha.", - "mergeCommonHeaderBackground": "Ancestral comum da cor de fundo do cabeçalho em conflitos de mesclagem inline.", - "mergeCommonContentBackground": "Ancestral comum da cor de fundo do conteúdo em conflitos de mesclagem inline. ", + "mergeCurrentHeaderBackground": "Fundo do cabeçalho atual em conflitos de merge inline. A cor não deve ser opaca para não esconder decorações subjacentes.", + "mergeCurrentContentBackground": "Fundo do conteúdo atual em conflitos de merge inline. A cor não deve ser opaca para não esconder decorações subjacentes.", + "mergeIncomingHeaderBackground": "Fundo do cabeçalho entrante em conflitos de merge inline. A cor não deve ser opaca para não esconder decorações subjacentes.", + "mergeIncomingContentBackground": "Fundo do conteúdo entrante em conflitos de merge inline. A cor não deve ser opaca para não esconder decorações subjacentes.", + "mergeCommonHeaderBackground": "Fundo comum do cabeçalho antepassado em conflitos de merge inline. A cor não deve ser opaca para não esconder decorações subjacentes.", + "mergeCommonContentBackground": "Fundo comum do conteúdo antepassado em conflitos de merge inline. A cor não deve ser opaca para não esconder decorações subjacentes.", "mergeBorder": "Cor da borda dos cabeçalhos e separadores estão em conflito de mesclagem em linha.", "overviewRulerCurrentContentForeground": "Cor de fundo de régua de visuaização atual em conflito de mesclagem em linha.", "overviewRulerIncomingContentForeground": "Cor de fundo de régua de visuaização de entrada em conflito de mesclagem em linha.", diff --git a/i18n/ptb/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/ptb/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..d2677dfdc5b --- /dev/null +++ b/i18n/ptb/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "saveParticipants": "Executando Salvamento de Participantes..." +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/ptb/src/vs/workbench/api/node/extHostTreeViews.i18n.json index d5ca67a9353..2d6a1561774 100644 --- a/i18n/ptb/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/ptb/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "treeView.notRegistered": "Nenhuma visualização de árvore com id '{0}' registrado.", - "treeItem.notFound": "Nenhum item de árvore com id '{0}' encontrado.", - "treeView.duplicateElement": "Elemento {0} já está registrado" + "treeView.duplicateElement": "Elemento com id {0} já está registrado" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/ptb/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index ee4fc530361..3bc4ff33bb9 100644 --- a/i18n/ptb/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "Alternar Localização da Barra Lateral", + "toggleSidebarPosition": "Alternar a Posição da Barra Lateral", "view": "Exibir" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/ptb/src/vs/workbench/browser/actions/workspaceActions.i18n.json index 18546fb98ab..84f170bd32c 100644 --- a/i18n/ptb/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "Abrir arquivo...", "openFolder": "Abrir Pasta...", "openFileFolder": "Abrir...", - "addFolderToWorkspace": "Adicionar pasta ao espaço de trabalho...", - "add": "&& Adicionar", - "addFolderToWorkspaceTitle": "Adicionar pasta ao espaço de trabalho", "globalRemoveFolderFromWorkspace": "Remover pasta da área de trabalho", - "removeFolderFromWorkspace": "Remover pasta da área de trabalho", - "openFolderSettings": "Abrir configurações da pasta", "saveWorkspaceAsAction": "Salvar o espaço de trabalho como...", "save": "&&Salvar", "saveWorkspace": "Salvar o espaço de trabalho", "openWorkspaceAction": "Abrir o Espaço de Trabalho...", "openWorkspaceConfigFile": "Abrir o Arquivo de Configuração do Espaço de Trabalho", - "openFolderAsWorkspaceInNewWindow": "Abrir a pasta como espaço de trabalho em nova janela", - "workspaceFolderPickerPlaceholder": "Selecione a pasta de trabalho" + "openFolderAsWorkspaceInNewWindow": "Abrir a pasta como espaço de trabalho em nova janela" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/ptb/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..34b9d5b4435 --- /dev/null +++ b/i18n/ptb/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "Adicionar pasta ao espaço de trabalho...", + "add": "&&Adicionar", + "addFolderToWorkspaceTitle": "Adicionar pasta ao espaço de trabalho", + "workspaceFolderPickerPlaceholder": "Selecione a pasta do espaço de trabalho" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/ptb/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index d1d8a425227..229a03e2233 100644 --- a/i18n/ptb/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,18 @@ "groupThreePicker": "Mostrar editores no terceiro grupo", "allEditorsPicker": "Mostrar todos editores abertos", "view": "Exibir", - "file": "Arquivo" + "file": "Arquivo", + "close": "Fechar", + "closeOthers": "Fechar Outros", + "closeRight": "Fechar à direita", + "closeAllUnmodified": "Fechar Não Modificados", + "closeAll": "Fechar todos", + "keepOpen": "Manter aberto", + "toggleInlineView": "Alternar para exibição embutida", + "showOpenedEditors": "Mostrar editores abertos", + "keepEditor": "Manter editor", + "closeEditorsInGroup": "Fechar todos editores no grupo", + "closeUnmodifiedEditors": "Fechar os Editores Não Modificados no Grupo", + "closeOtherEditors": "Fechar outros editores", + "closeRightEditors": "Fechar editores à direita" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/ptb/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index 5035a541040..d43b455c264 100644 --- a/i18n/ptb/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "Fechar editor", "revertAndCloseActiveEditor": "Reverter e fechar editor", "closeEditorsToTheLeft": "Fechar editores à esquerda ", - "closeEditorsToTheRight": "Fechar editores à direita", "closeAllEditors": "Fechar todos editores", - "closeUnmodifiedEditors": "Fechar os Editores Não Modificados no Grupo", "closeEditorsInOtherGroups": "Fechar editores nos outros grupos", - "closeOtherEditorsInGroup": "Fechar outros editores", - "closeEditorsInGroup": "Fechar todos editores no grupo", "moveActiveGroupLeft": "Mover grupo de editores para esquerda", "moveActiveGroupRight": "Mover grupo de editores para direita", "minimizeOtherEditorGroups": "Minimizar outros grupos de editores", "evenEditorGroups": "Igualar larguras de grupos de editores", "maximizeEditor": "Maximizar grupo de editor e ocultar barra lateral", - "keepEditor": "Manter editor", "openNextEditor": "Abrir próximo editor", "openPreviousEditor": "Abrir editor anterior", "nextEditorInGroup": "Abrir próximo editor no grupo", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "Mostrar editores no primeiro grupo", "showEditorsInSecondGroup": "Mostrar editores no segundo grupo", "showEditorsInThirdGroup": "Mostrar editores no terceiro grupo", - "showEditorsInGroup": "Mostrar editores no grupo", "showAllEditors": "Mostrar todos editores", "openPreviousRecentlyUsedEditorInGroup": "Abrir o Editor Anterior Recentemente Usado no Grupo", "openNextRecentlyUsedEditorInGroup": "Abrir o Próximo Editor Recentemente Usado no Grupo", @@ -54,5 +48,8 @@ "moveEditorLeft": "Mover o Editor para a Esquerda", "moveEditorRight": "Mover o Editor para a Direita", "moveEditorToPreviousGroup": "Mover o Editor para o Grupo Anterior", - "moveEditorToNextGroup": "Mover o Editor para o Próximo Grupo" + "moveEditorToNextGroup": "Mover o Editor para o Próximo Grupo", + "moveEditorToFirstGroup": "Mover o Editor para o Primeiro Grupo", + "moveEditorToSecondGroup": "Mover o Editor para o Segundo Grupo", + "moveEditorToThirdGroup": "Mover o Editor para o Terceiro Grupo" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/ptb/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 4b701929e85..550e345a27f 100644 --- a/i18n/ptb/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "Mover o editor ativo por guias ou grupos", "editorCommand.activeEditorMove.arg.name": "Argumento de movimento do editor ativo", - "editorCommand.activeEditorMove.arg.description": "Propriedades do argumento:\n* 'to': Valor do tipo sequencia de caracteres fornecendo onde se mover.\n\t* 'by': sequência de valor, proporcionando a unidade para o movimento. Por guia ou por grupo.\n\t* 'value': valor numérico, fornecendo quantas posições ou uma posição absoluta para mover.", - "commandDeprecated": "Comando **{0}** foi removido. Você pode usar **{1}** em vez disso", - "openKeybindings": "Configurar os atalhos de teclado" + "editorCommand.activeEditorMove.arg.description": "Propriedades do argumento:\n* 'to': Valor do tipo sequencia de caracteres fornecendo onde se mover.\n\t* 'by': sequência de valor, proporcionando a unidade para o movimento. Por guia ou por grupo.\n\t* 'value': valor numérico, fornecendo quantas posições ou uma posição absoluta para mover." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/ptb/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index 8af2aff62d5..1e1fde93df0 100644 --- a/i18n/ptb/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "Editor de comparação de arquivos texto.", "navigate.next.label": "Próxima Alteração", "navigate.prev.label": "Alteração Anterior", - "inlineDiffLabel": "Alternar para exibição embutida", - "sideBySideDiffLabel": "Alternar para exibição lado a lado" + "toggleIgnoreTrimWhitespace.label": "Ignore espaços em branco" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/ptb/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index aafa87dc9bf..b78b8688cfd 100644 --- a/i18n/ptb/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "Fechar", - "closeOthers": "Fechar Outros", - "closeRight": "Fechar à direita", - "closeAll": "Fechar todos", - "closeAllUnmodified": "Fechar Não Modificados", - "keepOpen": "Manter aberto", - "showOpenedEditors": "Mostrar editores abertos", "araLabelEditorActions": "Ações de editor" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/ptb/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index 1c3db4d572b..4c843f96e08 100644 --- a/i18n/ptb/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[Sem Suporte]", + "userIsAdmin": "[Administrador]", + "userIsSudo": "[Superusuário]", "devExtensionWindowTitlePrefix": "[Host de Desenvolvimento de Extensão]" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/ptb/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index a2d4770e337..e40ee5163a0 100644 --- a/i18n/ptb/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/ptb/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -4,5 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "hideView": "Ocultar a Barra Lateral" + "hideView": "Ocultar" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/common/theme.i18n.json b/i18n/ptb/src/vs/workbench/common/theme.i18n.json index 0ed9a7f5447..b8e2f1b3570 100644 --- a/i18n/ptb/src/vs/workbench/common/theme.i18n.json +++ b/i18n/ptb/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "Cor de fundo da guia ativa. As guias são os recipientes para editores na área do editor. Várias guias podem ser abertas em um grupo de editores. Podem haver vários grupos de editor.", "tabInactiveBackground": "Cor de fundo da guia inativa. As guias são os recipientes para editores na área do editor. Várias guias podem ser abertas em um grupo de editores. Podem haver vários grupos de editor.", + "tabHoverBackground": "Cor de fundo da guia ao passar o mouse. As guias são os contêineres para editores na área do editor. Várias guias podem ser abertas em um grupo de editor. Podem existir vários grupos de editor.", + "tabUnfocusedHoverBackground": "Cor de fundo da guia em um grupo fora de foco ao passar o mouse. As guias são os contêineres para editores na área do editor. Várias guias podem ser abertas em um grupo de editor. Podem existir vários grupos de editor.", "tabBorder": "Borda para separar uma guia das outras. As guias são os recipientes para editores na área do editor. Várias guias podem ser abertas em um grupo de editores. Podem haver vários grupos de editor.", "tabActiveBorder": "Borda para destacar guias ativas. As guias são os recipientes para editores na área do editor. Várias guias podem ser abertas em um grupo de editores. Podem haver vários grupos de editores.", "tabActiveUnfocusedBorder": "Borda para destacar guias ativas em um grupo fora de foco. As guias são os recipientes para editores na área do editor. Várias guias podem ser abertas em um grupo de editores. Podem haver vários grupos de editores.", + "tabHoverBorder": "Borda para destacar guias ao passar o mouse. As guias são os contêineres para editores na área do editor. Várias guias podem ser abertas em um grupo de editor. Podem existir vários grupos de editor.", + "tabUnfocusedHoverBorder": "Borda para destacar guias em um grupo fora de foco ao passar o mouse. As guias são os contêineres para editores na área do editor. Várias guias podem ser abertas em um grupo de editor. Podem existir vários grupos de editor.", "tabActiveForeground": "Cor de primeiro plano da guia ativa em um grupo ativo. As guias são os recipientes para editores na área do editor. Várias guias podem ser abertas em um grupo de editores. Podem haver vários grupos de editor.", "tabInactiveForeground": "Cor de primeiro plano da guia inativa em um grupo ativo. As guias são os recipientes para editores na área do editor. Várias guias podem ser abertas em um grupo de editores. Podem haver vários grupos de editor.", "tabUnfocusedActiveForeground": "Cor de primeiro plano da aba ativa em um grupo fora de foco. As guias são os recipientes para editores na área do editor. Várias guias podem ser abertas em um grupo de editores. Podem haver vários grupos de editores.", @@ -16,7 +20,7 @@ "editorGroupBackground": "Cor de fundo de um grupo de editor. Grupos de editor são os recipientes dos editores. A cor de fundo é mostrada ao arrastar o editor de grupos ao redor.", "tabsContainerBackground": "Cor de fundo do cabeçalho do título do grupo de editor quando as guias são habilitadas. Grupos de editor são os recipientes dos editores.", "tabsContainerBorder": "Cor da borda do cabeçalho do título do grupo de editor quando as guias estão habilitadas. Grupos de editor são os recipientes dos editores.", - "editorGroupHeaderBackground": "Cor de fundo do título do cabeçalho do grupo de editor quando as guias são desabilitadas. Grupos de editor são os recipientes dos editores.", + "editorGroupHeaderBackground": "Cor de fundo do título no cabeçalho do grupo de editor quando guias estiverem desabilitadas (`\"workbench.editor.showTabs\": false`). Grupos de editor são os contêineres dos editores.", "editorGroupBorder": "Cor para separar múltiplos grupos de editor de outro. Grupos de editor são os recipientes dos editores.", "editorDragAndDropBackground": "Cor de fundo ao arrastar editores. A cor deve ter transparência para que o conteúdo do editor ainda possa ser visto.", "panelBackground": "Cor de fundo do painel. Os painéis são mostrados abaixo da área do editor e contém visualizações como saída e terminal integrado.", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "Cor da borda da barra de status separando para a barra lateral e editor quando nenhuma pasta é aberta. A barra de status é mostrada na parte inferior da janela.", "statusBarItemActiveBackground": "Cor de fundo do item da barra de status quando você clicado. A barra de status é mostrada na parte inferior da janela.", "statusBarItemHoverBackground": "Cor de fundo do item da barra de status quando estiver passando sobre ele. A barra de status é mostrada na parte inferior da janela.", - "statusBarProminentItemBackground": "Cor de fundo de itens proeminentes da barra de status. Itens proeminentes destacam-se outras entradas da barra de status para indicar a importância. A barra de status é mostrada na parte inferior da janela.", - "statusBarProminentItemHoverBackground": "Cor de fundo dos itens proeminentes de barra de status quando estiver passando sobre eles. Itens proeminentes destacam-se outras entradas de barra de status para indicar a importância. A barra de status é mostrada na parte inferior da janela.", + "statusBarProminentItemBackground": "Cor de fundo de itens proeminentes na barra de status. Itens proeminentes destacam-se de outros itens na barra de status para indicar importância. Altere o modo `Alternar Tecla Tab Move o Foco` da paleta de comandos para ver um exemplo. A barra de status é exibida na parte inferior da janela.", + "statusBarProminentItemHoverBackground": "Cor de fundo de itens proeminentes na barra de status ao passar o mouse sobre sobre eles. Itens proeminentes destacam-se de outros itens na barra de status para indicar importância. Altere o modo `Alternar Tecla Tab Move o Foco` da paleta de comandos para ver um exemplo. A barra de status é exibida na parte inferior da janela.", "activityBarBackground": "Cor de fundo da barra de atividades. Barra de atividade está visível à esquerda ou à direita e permite alternar entre as visualizações da barra lateral.", "activityBarForeground": "Cor de primeiro plano da barra de atividades (por exemplo, usada para os ícones). A barra de atividades está visível à esquerda ou à direita e permite alternar entre as visualizações da barra lateral.", "activityBarBorder": "Cor da borda da barra de atividades separando a barra lateral. A barra de atividade é mostrada à esquerda ou à direita e permite alternar entre as visualizações da barra lateral.", diff --git a/i18n/ptb/src/vs/workbench/common/views.i18n.json b/i18n/ptb/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..b7201e3d4af --- /dev/null +++ b/i18n/ptb/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "Uma exibição com id '{0}' já está registrada na localização '{1}'" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/ptb/src/vs/workbench/electron-browser/actions.i18n.json index 67b112045f5..44851d18637 100644 --- a/i18n/ptb/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/ptb/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "Fechar Editor", "closeWindow": "Fechar Janela", "closeWorkspace": "Fechar o espaço de trabalho", "noWorkspaceOpened": "Não há nenhum espaço de trabalho aberto nessa instância para ser fechado.", @@ -52,21 +51,5 @@ "displayLanguage": "Define o idioma de exibição do VSCode.", "doc": "Veja {0} para obter uma lista dos idiomas suportados.", "restart": "Modificar o valor requer reinicialização do VSCode.", - "fail.createSettings": "Não foi possível criar '{0}' ({1}).", - "openLogsFolder": "Abrir Pasta de Logs", - "showLogs": "Exibir Logs...", - "mainProcess": "Principal", - "sharedProcess": "Compartilhado", - "rendererProcess": "Renderizador", - "extensionHost": "Host de Extensão", - "selectProcess": "Selecionar processo", - "setLogLevel": "Definir Nível de Log", - "trace": "Rastreamento", - "debug": "Depurar", - "info": "Informações", - "warn": "Aviso", - "err": "Erro", - "critical": "Crítico", - "off": "Desligado", - "selectLogLevel": "Selecione o nível de log" + "fail.createSettings": "Não foi possível criar '{0}' ({1})." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/ptb/src/vs/workbench/electron-browser/main.contribution.i18n.json index 06f44d416ff..e83d165cd84 100644 --- a/i18n/ptb/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "Exibir", "help": "Ajuda", "file": "Arquivo", - "developer": "Desenvolvedor", "workspaces": "Espaços de trabalho", + "developer": "Desenvolvedor", + "workbenchConfigurationTitle": "Área de Trabalho", "showEditorTabs": "Controla se os editores abertos devem ou não serem exibidos em abas.", "workbench.editor.labelFormat.default": "Mostra o nome do arquivo. Quando guias estiverem ativadas e dois arquivos em um grupo tiverem o mesmo nome, a seção de distinção para cada caminho de arquivo é adicionada. Quando guias estiverem desativadas, o caminho relativo para a pasta do espaço de trabalho é exibida se o editor estiver ativo.", "workbench.editor.labelFormat.short": "Mostrar o nome do arquivo seguido pelo nome do diretório.", @@ -20,23 +21,23 @@ "showIcons": "Controla se os editores abertos devem ou não ser exibidos com um ícone. Requer um tema de ícone para ser habilitado. ", "enablePreview": "Controla se editores abertos mostram uma visualização. Editores de visualização são reutilizados até que eles sejam mantidos (por exemplo, através do duplo clique ou edição) e aparecerem com um estilo de fonte em itálico.", "enablePreviewFromQuickOpen": "Controla se os editores abertos da Abertura Rápida são exibidos como visualização. Os editores de visualização são reutilizados até serem preservados (por exemplo, através de um duplo clique ou edição).", + "closeOnFileDelete": "Controla se os editores que mostram um arquivo devem fechar automaticamente quanto o arquivo é apagado ou renomeado por algum outro processo. Desativar isso manterá o editor aberto como sujo neste evento. Note que apagar do aplicativo sempre fechará o editor e os arquivos sujos nunca fecharão para preservar seus dados.", "editorOpenPositioning": "Controla onde os editores serão abertos. Escolha 'esquerda' ou 'direita' para abrir os editores à esquerda ou à direita do editor ativo. Selecione 'primeiro' ou 'último' para abrir os editores independentemente do ativo no momento.", "revealIfOpen": "Controla se um editor é exibido em qualquer um dos grupos, se aberto. Se desabilitado, um editor será aberto preferencialmente no grupo de editores ativo. Se habilitado, um editor já aberto será exibido no grupo de editores ativo, ao invés de ser aberto novamente. Note que há alguns casos onde esta configuração é ignorada, por exemplo, quando for forçada a abertura de um editor em um grupo específico ou ao lado do grupo atualmente ativo.", + "swipeToNavigate": "Navegue entre arquivos abertos usando o deslizamento horizontal de três dedos.", "commandHistory": "Controla o número de comandos usados recentemente a serem mantidos no histórico da paleta de comando. Definir como 0 para desativar o histórico de comandos.", "preserveInput": "Controla se a última entrada digitada na paleta de comandos deve ser restaurada ao abri-la da próxima vez.", "closeOnFocusLost": "Controla se Abertura Rápida deve fechar automaticamente caso perca o foco.", "openDefaultSettings": "Controla se a abertura de configurações também abre um editor mostrando todas as configurações padrão.", "sideBarLocation": "Controla a localização da barra lateral. Ele pode ser exibido à esquerda ou à direita da área de trabalho.", + "panelDefaultLocation": "Controla o local padrão do painel. Pode ser visualizado na parte inferior ou no lado direito da área de trabalho.", "statusBarVisibility": "Controla a visibilidade da barra de status na parte inferior da área de trabalho.", "activityBarVisibility": "Controla a visibilidade da barra de atividades na área de trabalho.", - "closeOnFileDelete": "Controla se os editores que mostram um arquivo devem fechar automaticamente quanto o arquivo é apagado ou renomeado por algum outro processo. Desativar isso manterá o editor aberto como sujo neste evento. Note que apagar do aplicativo sempre fechará o editor e os arquivos sujos nunca fecharão para preservar seus dados.", - "enableNaturalLanguageSettingsSearch": "Controla se deve habilitar o modo de busca de linguagem natural para as configurações.", "fontAliasing": "Controla o método de identificação de fonte no espaço de trabalho.\n- padrão: Suavização de fonte subpixel. Na maioria dos monitores não-retina isto mostrará o texto mais nítido\n- antialiased: Suaviza a fonte no nível do pixel, em oposição a subpixel. Pode fazer a fonte aparecer mais clara de um modo geral \n- nenhum: Desabilita a suavização de fonte. Texto será mostrado com bordas irregulares", "workbench.fontAliasing.default": "Suavização de fonte subpixel. Na maioria dos monitores não-retina isto mostrará o texto mais nítido.", "workbench.fontAliasing.antialiased": "Suavizar a fonte no nível do pixel, em oposição a subpixel. Pode fazer com que a fonte apareça mais clara de uma forma geral.", "workbench.fontAliasing.none": "Desabilita a suavização de fonte. Texto será mostrado com bordas irregulares.", - "swipeToNavigate": "Navegue entre arquivos abertos usando o deslizamento horizontal de três dedos.", - "workbenchConfigurationTitle": "Área de Trabalho", + "enableNaturalLanguageSettingsSearch": "Controla se deve habilitar o modo de busca de linguagem natural para as configurações.", "windowConfigurationTitle": "Janela", "window.openFilesInNewWindow.on": "Arquivos serão abertos em uma nova janela", "window.openFilesInNewWindow.off": "Arquivos serão abertos em uma nova janela com a pasta de arquivos aberta ou com a última janela ativa.", diff --git a/i18n/ptb/src/vs/workbench/electron-browser/window.i18n.json b/i18n/ptb/src/vs/workbench/electron-browser/window.i18n.json index 8a03ff87882..3bb18871ba8 100644 --- a/i18n/ptb/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/ptb/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "Recortar", "copy": "Copiar", "paste": "Colar", - "selectAll": "Selecionar Tudo" + "selectAll": "Selecionar Tudo", + "runningAsRoot": "Não é recomendado executar {0} como usuário root." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json b/i18n/ptb/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json index 421e5b19c79..05dd117d6de 100644 --- a/i18n/ptb/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/debug/browser/debugActionsWidget.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debugToolBarBackground": "Cor de fundo da barra de ferramentas de depuração." + "debugToolBarBackground": "Cor de fundo da barra de ferramentas de depuração.", + "debugToolBarBorder": "Cor da borda da barra de ferramentas de depuração." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/ptb/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 898a18605fb..68ea94e5a20 100644 --- a/i18n/ptb/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "depurado", - "debug.terminal.not.available.error": "Terminal integrado não disponível" + "debug.terminal.title": "depurado" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 548fff57edc..21d5f668ec9 100644 --- a/i18n/ptb/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "Abrir Novo Prompt de Comando", "globalConsoleActionMacLinux": "Abrir Novo Terminal", "scopedConsoleActionWin": "Abrir no Prompt de Comando", - "scopedConsoleActionMacLinux": "Abrir no Terminal", - "openFolderInIntegratedTerminal": "Abrir no Terminal" + "scopedConsoleActionMacLinux": "Abrir no Terminal" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/ptb/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index b4f99cdf746..d532a7ba72e 100644 --- a/i18n/ptb/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "Esta extensão é recomendada baseada nos arquivos que você abriu recentemente.", + "neverShowAgain": "Não mostrar novamente", + "close": "Fechar", "workspaceRecommendation": "Esta extensão é recomendada pelos usuários da área de trabalho atual.", + "fileBasedRecommendation": "Esta extensão é recomendada baseada nos arquivos que você abriu recentemente.", "exeBasedRecommendation": "Esta extensão é recomendada porque você tem {0} instalado.", "reallyRecommended2": "A extensão {0} é recomendada para este tipo de arquivo.", "reallyRecommendedExtensionPack": "O pacote de extensão '{0}' é recomendado para este tipo de arquivo.", "showRecommendations": "Mostrar Recomendações", "install": "Instalar", - "neverShowAgain": "Não mostrar novamente", - "close": "Fechar", "workspaceRecommended": "Este espaço de trabalho possui recomendações de extensão.", "installAll": "Instalar Tudo", "ignoreExtensionRecommendations": "Você quer ignorar todas as recomendações de extensão?", diff --git a/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..25e6a323be4 --- /dev/null +++ b/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "Área de Trabalho", + "feedbackVisibility": "Controla a visibilidade do feedback no Twitter (smiley) na barra de status na região inferior da área de trabalho." +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json b/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json index 5d3c22c39a8..db165d19e5b 100644 --- a/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedback.i18n.json @@ -16,6 +16,7 @@ "request a missing feature": "Solicitar um recurso ausente", "tell us why?": "Diga-nos porquê?", "commentsHeader": "Comentários", + "showFeedback": "Mostrar Smiley de Feedback na Barra de Status", "tweet": "Tweetar", "character left": "caractere à esquerda", "characters left": "caracteres à esquerda", diff --git a/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..afb315a42d4 --- /dev/null +++ b/i18n/ptb/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "hide": "Ocultar" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 464da97e4e9..a67013312a3 100644 --- a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,27 @@ "filesCategory": "Arquivo", "revealInSideBar": "Revelar na Barra Lateral", "acceptLocalChanges": "Usar suas alterações e substituir o conteúdo do disco", - "revertLocalChanges": "Descartar as alterações e reverter para o conteúdo no disco" + "revertLocalChanges": "Descartar as alterações e reverter para o conteúdo no disco", + "copyPathOfActive": "Copiar Caminho do Arquivo Ativo", + "saveAllInGroup": "Salvar Todos no Grupo", + "saveFiles": "Salvar todos os arquivos", + "revert": "Reverter Arquivo", + "compareActiveWithSaved": "Comparar o Arquivo Ativo com o Arquivo Salvo", + "closeEditor": "Fechar Editor", + "view": "Exibir", + "openToSide": "Aberto para o lado", + "revealInWindows": "Revelar no Explorer", + "revealInMac": "Revelar no Finder", + "openContainer": "Abrir a Pasta", + "copyPath": "Copiar Caminho", + "saveAll": "Salvar Todos", + "compareWithSaved": "Comparar com o salvo", + "compareWithSelected": "Comparar com o Selecionado", + "compareSource": "Selecione para comparar", + "compareSelected": "Comparar Selecionado", + "close": "Fechar", + "closeOthers": "Fechar Outros", + "closeUnmodified": "Fechar Não Modificados", + "closeAll": "Fechar todos", + "deleteFile": "Excluir permanentemente" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 18ed68af70c..02499c21575 100644 --- a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "Tentar novamente", - "rename": "Renomear", "newFile": "Novo Arquivo", "newFolder": "Nova Pasta", + "rename": "Renomear", + "delete": "Excluir", + "copyFile": "Copiar", + "pasteFile": "Colar", + "retry": "Tentar novamente", "openFolderFirst": "Abrir uma pasta primeiro para criar arquivos ou pastas dentro dele.", "newUntitledFile": "Novo Arquivo Sem Título", "createNewFile": "Novo Arquivo", @@ -15,39 +18,32 @@ "deleteButtonLabelRecycleBin": "&&Mover para Lixeira", "deleteButtonLabelTrash": "&&Mover para o Lixo", "deleteButtonLabel": "&&Excluir", + "dirtyMessageFilesDelete": "Você está excluindo arquivos com alterações não salvas. Você quer continuar?", "dirtyMessageFolderOneDelete": "Você está excluindo uma pasta com alterações não salvas em 1 arquivo. Você quer continuar?", "dirtyMessageFolderDelete": "Você está excluindo uma pasta com alterações não salvas em {0} arquivos. Você quer continuar?", "dirtyMessageFileDelete": "Você está excluindo um arquivo com alterações não salvas. Você quer continuar?", "dirtyWarning": "Suas alterações serão perdidas se você não salvá-las.", + "confirmMoveTrashMessageMultiple": "Você tem certeza que deseja excluir os seguintes {0} arquivos?", "confirmMoveTrashMessageFolder": "Tem certeza de que deseja excluir '{0}' e seu conteúdo?", "confirmMoveTrashMessageFile": "Tem certeza de que deseja excluir '{0}'?", "undoBin": "Você pode restaurar da lixeira.", "undoTrash": "Você pode restaurar a partir do lixo.", "doNotAskAgain": "Não me pergunte novamente", + "confirmDeleteMessageMultiple": "Você tem certeza que deseja excluir permanentemente os seguintes {0} arquivos?", "confirmDeleteMessageFolder": "Tem certeza de que deseja excluir permanentemente '{0}' e seu conteúdo?", "confirmDeleteMessageFile": "Tem certeza de que deseja excluir permanentemente '{0}'?", "irreversible": "Esta ação é irreversível!", "permDelete": "Excluir permanentemente", - "delete": "Excluir", "importFiles": "Importar Arquivos", "confirmOverwrite": "Um arquivo ou pasta com o mesmo nome já existe na pasta de destino. Você quer substituí-lo?", "replaceButtonLabel": "&&Substituir", - "copyFile": "Copiar", - "pasteFile": "Colar", + "fileDeleted": "Arquivo foi excluído ou movido durante o processo", + "fileIsAncestor": "Arquivo a ser copiado é um ancestral da pasta de destino.", "duplicateFile": "Duplicar", - "openToSide": "Aberto para o lado", - "compareSource": "Selecione para comparar", "globalCompareFile": "Compare o Arquivo Ativo Com...", "openFileToCompare": "Abrir um arquivo primeiro para compará-lo com outro arquivo.", - "compareWith": "Comparar '{0}' com '{1}'", - "compareFiles": "Comparar Arquivos", "refresh": "Atualizar", - "save": "Salvar", - "saveAs": "Salvar como...", - "saveAll": "Salvar Todos", "saveAllInGroup": "Salvar Todos no Grupo", - "saveFiles": "Salvar todos os arquivos", - "revert": "Reverter Arquivo", "focusOpenEditors": "Foco na Visualização dos Editores Abertos", "focusFilesExplorer": "Foco no Explorador de Arquivos", "showInExplorer": "Revelar o Arquivo Ativo na Barra Lateral", @@ -56,20 +52,11 @@ "refreshExplorer": "Atualizar Explorador", "openFileInNewWindow": "Abrir o Arquivo Ativo em uma Nova Janela", "openFileToShowInNewWindow": "Abrir um arquivo primeiro para abrir em uma nova janela", - "revealInWindows": "Revelar no Explorer", - "revealInMac": "Revelar no Finder", - "openContainer": "Abrir a Pasta", - "revealActiveFileInWindows": "Revelar Arquivo Ativo no Windows Explorer", - "revealActiveFileInMac": "Revelar Arquivo Ativo no Finder", - "openActiveFileContainer": "Abrir a Pasta do Arquivo Ativo.", "copyPath": "Copiar Caminho", - "copyPathOfActive": "Copiar Caminho do Arquivo Ativo", "emptyFileNameError": "Um nome de arquivo ou pasta deve ser fornecido.", "fileNameExistsError": "Um arquivo ou pasta **{0}** já existe neste local. Escolha um nome diferente.", "invalidFileNameError": "O nome **{0}** não é válido como um nome de arquivo ou pasta. Por favor, escolha um nome diferente.", "filePathTooLongError": "O nome **{0}** resulta em um caminho muito longo. Escolha um nome mais curto.", - "compareWithSaved": "Comparar o Arquivo Ativo com o Arquivo Salvo", - "modifiedLabel": "{0} (em disco) ↔ {1}", "compareWithClipboard": "Compare o Arquivo Ativo com a Área de Transferência", "clipboardComparisonLabel": "Área de Transferência ↔ {0}" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index 2e61a1656c8..7a2c7c9c70d 100644 --- a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "Abrir um arquivo primeiro para copiar seu caminho", - "openFileToReveal": "Abrir um arquivo primeiro para revelar" + "revealInWindows": "Revelar no Explorer", + "revealInMac": "Revelar no Finder", + "openContainer": "Abrir a Pasta", + "saveAs": "Salvar como...", + "save": "Salvar", + "saveAll": "Salvar Todos", + "removeFolderFromWorkspace": "Remover pasta da área de trabalho", + "genericRevertError": "Falha ao reverter '{0}': {1}", + "modifiedLabel": "{0} (em disco) ↔ {1}", + "openFileToReveal": "Abrir um arquivo primeiro para revelar", + "openFileToCopy": "Abrir um arquivo primeiro para copiar seu caminho" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 0e95d226253..8488c0881d3 100644 --- a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,7 @@ "editorConfigurationTitle": "Editor", "formatOnSave": "Formata um arquivo no salvamento. Um formatador deve estar disponível, o arquivo não deve ser salvo automaticamente e editor não deve ser desligado.", "explorerConfigurationTitle": "Explorador de arquivos", - "openEditorsVisible": "Número de editores mostrado no painel Abrir Editores. Configurá-lo para 0 irá ocultar o painel.", - "dynamicHeight": "Controla se a altura da seção de editores abertos deve adaptar-se dinamicamente para o número de elementos ou não.", + "openEditorsVisible": "Número de editores mostrados no painel Editores Abertos.", "autoReveal": "Controla se o explorador deve automaticamente revelar e selecionar arquivos ao abri-los.", "enableDragAndDrop": "Controla se o explorador deve permitir mover arquivos e pastas através de arrastar e soltar.", "confirmDragAndDrop": "Controla se o explorer deve pedir a confirmação ao mover arquivos ou pastas através de arrastar e soltar.", diff --git a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 09a29894643..5f8a28ec46b 100644 --- a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,14 @@ // Do not edit this file. It is machine generated. { "userGuide": "Use as ações na barra de ferramentas de editor para a direita para **desfazer** suas alterações ou **substituir** o conteúdo no disco com as alterações", - "discard": "Descartar", + "overwriteElevated": "Sobrescrever como Admin...", + "saveElevated": "Tentar novamente como Admin...", "overwrite": "Sobrescrever", "retry": "Tentar novamente", - "readonlySaveError": "Falha ao salvar '{0}': O arquivo está protegido contra gravação. Selecione 'Substituir' para remover a proteção.", + "discard": "Descartar", + "readonlySaveErrorAdmin": "Falha ao salvar '{0}': O arquivo está protegido contra gravação. Selecione 'Sobrescrever como Admin' para tentar novamente como administrador.", + "readonlySaveError": "Falha ao salvar '{0}': O arquivo está protegido contra gravação. Selecione 'Sobrescrever' para tentar remover a proteção.", + "permissionDeniedSaveError": "Falha ao salvar '{0}': Permissões insuficientes. Selecione 'Tentar novamente como Admin' para tentar novamente como administrador.", "genericSaveError": "Erro ao salvar '{0}': {1}", "staleSaveError": "Falha ao salvar '{0}': O conteúdo no disco é mais recente. Clique em **Comparar** para comparar a sua versão com a do disco.", "compareChanges": "Comparar", diff --git a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json index 02afd8f004f..e29cc00e9bf 100644 --- a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.i18n.json @@ -10,6 +10,7 @@ "dropFolder": "Você quer adicionar a pasta no espaço de trabalho?", "addFolders": "&&Adicionar Pastas", "addFolder": "&&Adicionar Pasta", + "confirmMultiMove": "Você tem certeza que deseja mover os seguintes {0} arquivos?", "confirmMove": "Tem certeza que deseja mover '{0}'?", "doNotAskAgain": "Não me pergunte novamente", "moveButtonLabel": "&&Mover", diff --git a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index 83f2a510196..e075736dad3 100644 --- a/i18n/ptb/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "Abrir Editores", "openEditosrSection": "Abrir Seção de Editores", - "dirtyCounter": "{0} não salvos", - "saveAll": "Salvar Todos", - "closeAllUnmodified": "Fechar Não Modificados", - "closeAll": "Fechar todos", - "compareWithSaved": "Comparar com o salvo", - "close": "Fechar", - "closeOthers": "Fechar Outros" + "dirtyCounter": "{0} não salvos" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..05cf5d42db3 --- /dev/null +++ b/i18n/ptb/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "mainLog": "Log (Principal)", + "sharedLog": "Log (Compartilhado)", + "rendererLog": "Log (Janela)", + "extensionsLog": "Log (Host de Extensão)", + "developer": "Desenvolvedor" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/ptb/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..2bd2313c928 --- /dev/null +++ b/i18n/ptb/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "Abrir Pasta de Logs", + "showLogs": "Exibir Logs...", + "mainProcess": "Principal", + "sharedProcess": "Compartilhado", + "rendererProcess": "Janela", + "extensionHost": "Host de Extensão", + "selectProcess": "Selecionar processo", + "openLogFile": "Abrir Arquivo de Log...", + "setLogLevel": "Definir Nível de Log", + "trace": "Rastreamento", + "debug": "Depurar", + "info": "Informações", + "warn": "Aviso", + "err": "Erro", + "critical": "Crítico", + "off": "Desligado", + "selectLogLevel": "Selecione o nível de log" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/ptb/src/vs/workbench/parts/markers/common/messages.i18n.json index ad1f8b439c5..e304c1044a9 100644 --- a/i18n/ptb/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,8 @@ // Do not edit this file. It is machine generated. { "viewCategory": "Exibir", - "problems.view.toggle.label": "Alternar Problemas", - "problems.view.focus.label": "Problemas de foco", + "problems.view.toggle.label": "Esconder/exibir Problemas (Erros, Avisos, Infos)", + "problems.view.focus.label": "Focar Problemas (Erros, Avisos, Infos)", "problems.panel.configuration.title": "Visualização de Problemas", "problems.panel.configuration.autoreveal": "Controla se a visaulização de problemas evela os arquivos automaticamente ao abri-los", "markers.panel.title.problems": "Problemas", diff --git a/i18n/ptb/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..9a9c6f73156 --- /dev/null +++ b/i18n/ptb/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "Saída", + "logViewer": "Visualizador do Log", + "viewCategory": "Exibir", + "clearOutput.label": "Limpar saída" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/ptb/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..383a9f4835d --- /dev/null +++ b/i18n/ptb/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "{0} - Saída", + "channel": "Canal de saída para '{0}'" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json b/i18n/ptb/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json index 4027814e08d..75c87388f26 100644 --- a/i18n/ptb/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/preferences/browser/keybindingsEditor.i18n.json @@ -17,6 +17,7 @@ "resetLabel": "Redefinir Keybinding", "showConflictsLabel": "Mostrar Conflitos", "copyLabel": "Copiar", + "copyCommandLabel": "Copiar Comando", "error": "Erro '{0}' enquanto edita keybinding. Por favor, abra o arquivo 'keybindings.json' e verifique.", "command": "Comando", "keybinding": "KeyBinding", diff --git a/i18n/ptb/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json b/i18n/ptb/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json index 49fd2fe9bd8..0877b71005f 100644 --- a/i18n/ptb/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/preferences/browser/preferencesEditor.i18n.json @@ -11,6 +11,8 @@ "oneSettingFound": "1 Configuração correspondente", "settingsFound": "{0} Configurações correspondentes", "totalSettingsMessage": "Total {0} Configurações", + "nlpResult": "Resultados da Linguagem Natural", + "filterResult": "Resultados Filtrados", "defaultSettings": "Configurações Padrão", "defaultFolderSettings": "Configuração Padrão da Pasta", "defaultEditorReadonly": "Editar no editor do lado direito para substituir os padrões.", diff --git a/i18n/ptb/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/ptb/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index 800b9bf18e2..df12c20c366 100644 --- a/i18n/ptb/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "Tente a busca de linguagem natural!", "defaultSettings": "Coloque suas configurações no editor do lado direito para substituir.", "noSettingsFound": "Não há configurações encontradas.", "settingsSwitcherBarAriaLabel": "Chave de Configurações", "userSettings": "Configurações de Usuário", "workspaceSettings": "Configurações de Espaço de Trabalho", - "folderSettings": "Configurações da Pasta", - "enableFuzzySearch": "Habilitar busca de linguagem natural" + "folderSettings": "Configurações da Pasta" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/ptb/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index 9f80cd79e8b..6427118b75b 100644 --- a/i18n/ptb/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "Comumente Utilizado", - "mostRelevant": "Mais Relevante", "defaultKeybindingsHeader": "Substituir as chaves de ligações, colocando-os em seu arquivo de chave ligações." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index e3c6204b605..75a93eabf9c 100644 --- a/i18n/ptb/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "Exibir", "commandsHandlerDescriptionDefault": "Exibir e executar comandos", "gotoLineDescriptionMac": "Ir para linha", "gotoLineDescriptionWin": "Ir para linha", diff --git a/i18n/ptb/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index 117ddc11b04..668463cff46 100644 --- a/i18n/ptb/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,9 @@ "toggleGitViewlet": "Mostrar Git", "source control": "Controle de código-fonte", "toggleSCMViewlet": "Mostrar SCM", - "view": "Exibir" + "view": "Exibir", + "scmConfigurationTitle": "SCM", + "alwaysShowProviders": "Se deverá sempre mostrar a seção Provedor de Controle de Código Fonte.", + "diffDecorations": "Controla decorações do diff no editor.", + "inputCounter": "Controla quando exibir o contador de entrada." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json b/i18n/ptb/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json index fc4f8f90311..916c6469ab8 100644 --- a/i18n/ptb/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/scm/electron-browser/scmViewlet.i18n.json @@ -6,6 +6,9 @@ { "scm providers": "Provedores de Controle de Código Fonte", "hideRepository": "Ocultar", + "commitMessageInfo": "{0} caracteres na linha atual", + "commitMessageCountdown": "{0} caracteres restantes na linha atual", + "commitMessageWarning": "{0} caracteres sobre {1} na linha atual", "installAdditionalSCMProviders": "Instalar provedores de SCM adicionais...", "no open repo": "Não existem provedores controle de código fonte ativos.", "source control": "Controle de código-fonte", diff --git a/i18n/ptb/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/ptb/src/vs/workbench/parts/search/browser/searchActions.i18n.json index 34ded87a267..62c0f96918e 100644 --- a/i18n/ptb/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "Mostrar Termo de Pesquisa Anterior", "showSearchViewlet": "Mostrar Busca", "findInFiles": "Localizar nos Arquivos", - "findInFilesWithSelectedText": "Localizar nos Arquivos Com o Texto Selecionado", "replaceInFiles": "Substituir nos Arquivos", - "replaceInFilesWithSelectedText": "Substituir nos Arquivos Com o Texto Selecionado", "RefreshAction.label": "Atualizar", "CollapseDeepestExpandedLevelAction.label": "Recolher tudo", "ClearSearchResultsAction.label": "Limpar", diff --git a/i18n/ptb/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index b7b7494e9e4..1676173518c 100644 --- a/i18n/ptb/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "Procurar na pasta...", + "findInWorkspace": "Procurar no Espaço de Trabalho...", "showTriggerActions": "Ir para Símbolo no Espaço de Trabalho...", "name": "Pesquisar", "search": "Pesquisar", + "showSearchViewlet": "Mostrar Busca", "view": "Exibir", + "findInFiles": "Localizar nos Arquivos", "openAnythingHandlerDescription": "Ir para o Arquivo", "openSymbolDescriptionNormal": "Ir para o Símbolo em Área de Trabalho", "searchOutputChannelTitle": "Pesquisar", @@ -18,5 +22,6 @@ "useRipgrep": "Controla se utiliza ripgrep em buscas de texto e de arquivo", "useIgnoreFiles": "Controla se utiliza arquivos .gitignore e .ignore por padrão ao fazer pesquisas de arquivos.", "search.quickOpen.includeSymbols": "Configurar para incluir resultados de uma pesquisa símbolo global nos resultados do arquivo para Abertura Rápida.", - "search.followSymlinks": "Controla quando seguir symlinks ao realizar uma busca." + "search.followSymlinks": "Controla quando seguir symlinks ao realizar uma busca.", + "search.smartCase": "Faz pesquisas do tipo case-insensitive se o termo for totalmente minúsculo, caso contrário, faz pesquisas do tipo case-sensitive." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..be32250a3f7 --- /dev/null +++ b/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.scope": "(global)", + "global.1": "({0})", + "new.global": "Novo Arquivo de Trechos de Código Global...", + "group.global": "Trechos de código existentes", + "new.global.sep": "Novos Trechos de Código", + "openSnippet.pickLanguage": "Selecionar Arquivo de Trechos de Código ou Criar Trechos de Código", + "openSnippet.label": "Configurar Trechos de Código do Usuário", + "preferences": "Preferências" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index b9823c384ad..5cad5c0f57d 100644 --- a/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,13 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "Selecionar Idioma para o Trecho", - "openSnippet.errorOnCreate": "Não é possível criar {0}", - "openSnippet.label": "Abrir trechos de código do usuário", - "preferences": "Preferências", "snippetSchema.json.default": "Trecho de código vazio", "snippetSchema.json": "Configuração do trecho do usuário", "snippetSchema.json.prefix": "O prefixo usado ao selecionar o trecho no intelliSense", "snippetSchema.json.body": "O conteúdo do trecho. Use '$1', '${1:defaultText}' para definir as posições do cursor, use '$0' para a posição final do cursor. Insira valores de variáveis com '${varName}' e '${varName:defaultText}', por exemplo ' Este é o arquivo: $TM_FILENAME'.", - "snippetSchema.json.description": "A descrição do trecho." + "snippetSchema.json.description": "A descrição do trecho.", + "snippetSchema.json.scope": "Uma lista de nomes de linguagem para a qual este trecho de código aplica-se, por exemplo 'typescript,javascript'." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..bfdaf9232d5 --- /dev/null +++ b/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "Trecho de código do usuário" +} \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index a2c0fbab96a..142b52e21ef 100644 --- a/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "Linguagem desconhecida em `contributes.{0}.language`. Valor fornecido: {1}", "invalid.path.0": "Esperada uma string em `contributes.{0}.path`. Valor informado: {1}", + "invalid.language.0": "Quando a linguagem for omitida, o valor de `contributes.{0}.path` deve ser um arquivo-`.code-snippets`. Valor definido: {1}", + "invalid.language": "Linguagem desconhecida em `contributes.{0}.language`. Valor fornecido: {1}", "invalid.path.1": "É esperado que `contributes.{0}.path` ({1}) seja incluído na pasta da extensão ({2}). Isto pode tornar a extensão não portável.", "vscode.extension.contributes.snippets": "Contribui aos trechos de código.", "vscode.extension.contributes.snippets-language": "Identificador de linguagem para o qual este trecho de código contribui.", "vscode.extension.contributes.snippets-path": "Caminho do arquivo de trechos de código. O caminho é relativo à pasta de extensão e normalmente começa com '. /snippets/'.", "badVariableUse": "Um ou mais trechos da extensão '{0}' provavelmente se confundem com trechos de código de variáveis e trechos de código de espaços reservados (veja https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax para mais detalhes)", "badFile": "O arquivo de trechos \"{0}\" não pôde ser lido.", - "source.snippet": "Trecho de código do usuário", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json b/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json index d97a515c6ea..f45a86033e6 100644 --- a/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.i18n.json @@ -14,6 +14,7 @@ "terminal.integrated.shell.windows": "O caminho do shell que o terminal utiliza no Windows. Quando estiver usando shells fornecidos com o Windows (cmd, PowerShell ou Bash no Ubuntu).", "terminal.integrated.shellArgs.windows": "Os argumentos de linha de comando a serem utilizados no terminal do Windows.", "terminal.integrated.rightClickCopyPaste": "Quando configurado, isto evitará que o menu de contexto apareça quando pressionado o botão direito do mouse dentro do terminal, em vez disso vai copiar quando há uma seleção e colar quando não há nenhuma seleção.", + "terminal.integrated.copyOnSelection": "Quando ativado, texto selecionado no terminal será copiado para a área de transferência.", "terminal.integrated.fontFamily": "Controla a família de fontes do terminal, este padrão é o valor do editor.fontFamily.", "terminal.integrated.fontSize": "Controla o tamanho da fonte em pixels do terminal.", "terminal.integrated.lineHeight": "Controla a altura da linha do terminal, este número é multiplicado pelo tamanho da fonte do terminal para obter a altura real da linha em pixels.", @@ -24,10 +25,12 @@ "terminal.integrated.setLocaleVariables": "Controla se as variáveis locais são definidas na inicialização do terminal, este padrão é verdadeiro no OS X e falso em outras plataformas.", "terminal.integrated.cwd": "Um caminho de início explícito onde o terminal será lançado, isso é usado como o diretório de trabalho atual (cwd) para o processo shell. Isto pode ser particularmente útil em configurações de espaço de trabalho se o diretório raiz não é um cwd conveniente.", "terminal.integrated.confirmOnExit": "Confirmar na saída se ainda houverem sessões de terminal ativas.", + "terminal.integrated.enableBell": "Se o sino do terminal está habilitado ou não.", "terminal.integrated.commandsToSkipShell": "Um conjunto de IDs de comando, cujas combinações de teclas não serão enviadas para o shell e sempre serão tratadas por código. Isto permite o uso de combinações de teclas que normalmente seriam consumidas pelo shell para agir da mesma forma quando o terminal não é focado, por exemplo ctrl+p para Execução Rápida.", "terminal.integrated.env.osx": "Objeto com variáveis de ambiente que serão adicionadas ao VS Code e utilizadas pelo terminal no Mac OS X", "terminal.integrated.env.linux": "Objeto com variáveis de ambiente que serão adicionadas ao VS Code e utilizadas pelo terminal no Linux", "terminal.integrated.env.windows": "Objeto com variáveis de ambiente que serão adicionadas ao VS Code e utilizadas pelo terminal no Windows", + "terminal.integrated.showExitAlert": "Mostrar alerta 'O processo terminal foi encerrado com código de saída' quando o código de saída é diferente de zero.", "terminalCategory": "Terminal", "viewCategory": "Exibir" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json b/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json index 2ee45b6deb3..f59efd68a97 100644 --- a/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalActions.i18n.json @@ -14,6 +14,8 @@ "workbench.action.terminal.deleteWordRight": "Excluir Palavra à Direita", "workbench.action.terminal.new": "Criar Novo Terminal Integrado", "workbench.action.terminal.new.short": "Novo Terminal", + "workbench.action.terminal.newWorkspacePlaceholder": "Selecione o diretório de trabalho atual para novo terminal", + "workbench.action.terminal.newInActiveWorkspace": "Criar Novo Terminal Integrado (No Espaço de Trabalho Ativo)", "workbench.action.terminal.focus": "Focalizar Terminal", "workbench.action.terminal.focusNext": "Focalizar Próximo Terminal", "workbench.action.terminal.focusPrevious": "Focalizar Terminal Anterior", diff --git a/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json b/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json index 655ae8902e5..345ffbe4d25 100644 --- a/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json @@ -9,5 +9,5 @@ "terminalCursor.foreground": "A cor de primeiro plano do cursor do terminal.", "terminalCursor.background": "A cor de fundo do cursor do terminal. Permite personalizar a cor de um personagem sobreposto por um cursor de bloco.", "terminal.selectionBackground": "A cor de fundo de seleção do terminal.", - "terminal.ansiColor": "'{0}' cor ansi no terminal." + "terminal.ansiColor": "'{0}' cor ANSI no terminal." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index 83214ad4be8..53b433626d5 100644 --- a/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,7 @@ "terminal.integrated.chooseWindowsShellInfo": "Você pode alterar o terminal shell padrão selecionando o botão Personalizar.", "customize": "Personalizar", "cancel": "Cancelar", - "never again": "Ok, Nunca Mostrar Novamente", + "never again": "OK, Não Mostrar Novamente", "terminal.integrated.chooseWindowsShell": "Selecione o seu terminal shell preferido, você pode alterar isso mais tarde em suas configurações", "terminalService.terminalCloseConfirmationSingular": "Há uma sessão ativa de terminal, você quer finalizá-la?", "terminalService.terminalCloseConfirmationPlural": "Existem {0} sessões ativas de terminal, você quer finalizá-las?" diff --git a/i18n/ptb/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/ptb/src/vs/workbench/parts/update/electron-browser/update.i18n.json index 6a2cfcb15ab..84ce2109e07 100644 --- a/i18n/ptb/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/ptb/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -13,7 +13,7 @@ "read the release notes": "Bem-vindo a {0} v{1}! Gostaria de ler as Notas da Versão?", "licenseChanged": "Nossos termos de licença mudaram, favor revisá-los.", "license": "Ler Licença", - "neveragain": "Nunca Mostrar Novamente", + "neveragain": "Não mostrar novamente", "64bitisavailable": "{0} para Windows de 64 bits está agora disponível!", "learn more": "Saiba Mais", "updateIsReady": "Nova atualização de {0} disponível.", @@ -23,6 +23,7 @@ "commandPalette": "Paleta de comandos...", "settings": "Configurações", "keyboardShortcuts": "Atalhos de Teclado", + "userSnippets": "Trecho de código do usuário", "selectTheme.label": "Tema de Cores", "themes.selectIconTheme.label": "Arquivo de Ícone do Tema", "not available": "Atualizações Indisponíveis", diff --git a/i18n/ptb/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/ptb/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 7b91deaec2e..1cc780952f6 100644 --- a/i18n/ptb/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/ptb/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "Arquivo é um diretório", + "fileNotModifiedError": "Arquivo não modificado desde", "fileBinaryError": "Arquivo parece ser binário e não pode ser aberto como texto" } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/services/files/node/fileService.i18n.json b/i18n/ptb/src/vs/workbench/services/files/node/fileService.i18n.json index ae4ae718743..dba7ada15b5 100644 --- a/i18n/ptb/src/vs/workbench/services/files/node/fileService.i18n.json +++ b/i18n/ptb/src/vs/workbench/services/files/node/fileService.i18n.json @@ -10,6 +10,7 @@ "fileTooLargeError": "Arquivo muito grande para abrir", "fileNotFoundError": "Arquivo não encontrado ({0})", "fileBinaryError": "Arquivo parece ser binário e não pode ser aberto como texto", + "filePermission": "Permissão negada ao escrever no arquivo ({0})", "fileExists": "Arquivo a ser criado já existe ({0})", "fileMoveConflict": "Não é possível mover/copiar. Arquivo já existe no destino.", "unableToMoveCopyError": "Não é possível mover/copiar. Arquivo poderia substituir a pasta em que está contida.", diff --git a/i18n/ptb/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json b/i18n/ptb/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json index fedfd5457f0..4e6320dddaa 100644 --- a/i18n/ptb/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json +++ b/i18n/ptb/src/vs/workbench/services/keybinding/electron-browser/keybindingService.i18n.json @@ -22,5 +22,6 @@ "keybindings.json.when": "Condição quando a chave está ativa.", "keybindings.json.args": "Argumentos a serem passados para o comando para executar.", "keyboardConfigurationTitle": "Teclado", - "dispatch": "Controla a lógica de pressionamentos de teclas a ser usada para envio, se será 'code' (recomendado) ou 'keyCode'." + "dispatch": "Controla a lógica de pressionamentos de teclas a ser usada para envio, se será 'code' (recomendado) ou 'keyCode'.", + "touchbar.enabled": "Habilita os botões do touchbar do macOS no teclado se disponível." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/ptb/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index 491b19e87c4..f86146be73a 100644 --- a/i18n/ptb/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/ptb/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "Você quer salvar as alterações feitas para {0}?", "saveChangesMessages": "Você quer salvar as alterações para os seguintes {0} arquivos?", - "moreFile": "... 1 arquivo adicional não está mostrado", - "moreFiles": "... {0} arquivos adicionais não estão mostrados", "saveAll": "&&Salvar tudo", "save": "&&Salvar", "dontSave": "&&Não Salvar", diff --git a/i18n/ptb/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/ptb/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index 15017c07157..164708fcd63 100644 --- a/i18n/ptb/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/ptb/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "Nenhum arquivo de ícones", "iconThemeError": "Arquivo de tema de ícones é desconhecido ou não está instalado.", "workbenchColors": "Substitui as cores do tema do tema de cores atualmente selecionado.", - "editorColors": "Substitui as cores e o estilo da fonte do editor do tema de cores atualmente selecionado.", "editorColors.comments": "Define as cores e estilos para os comentários", "editorColors.strings": "Define as cores e estilos para textos literais.", "editorColors.keywords": "Define as cores e estilos para palavras-chave.", @@ -19,5 +18,6 @@ "editorColors.types": "Define as cores e estilos para declarações de tipo e referências.", "editorColors.functions": "Define as cores e estilos para declarações de funções e referências.", "editorColors.variables": "Define as cores e estilos para declarações de variáveis e referências.", - "editorColors.textMateRules": "Define as cores e estilos usando regras de temas textmate (avançado)." + "editorColors.textMateRules": "Define as cores e estilos usando regras de temas textmate (avançado).", + "editorColors": "Substitui as cores e o estilo da fonte do editor do tema de cores atualmente selecionado." } \ No newline at end of file diff --git a/i18n/ptb/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/ptb/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 078a8eb1b7d..73fdc1bd8e4 100644 --- a/i18n/ptb/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/ptb/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "Não é possível escrever no arquivo de configuração. Por favor, abra o arquivo para corrigir erros/avisos nele e tente novamente.", "errorWorkspaceConfigurationFileDirty": "Não é possível escrever no arquivo de configuração do espaço de trabalho porque o arquivo está sujo. Por favor, salve-o e tente novamente.", "openWorkspaceConfigurationFile": "Abrir o Arquivo de Configuração do Espaço de Trabalho", - "close": "Fechar", - "enterWorkspace.close": "Fechar", - "enterWorkspace.dontShowAgain": "Não mostrar novamente", - "enterWorkspace.moreInfo": "Mais informações", - "enterWorkspace.prompt": "Saiba mais sobre como trabalhar com várias pastas no VS Code." + "close": "Fechar" } \ No newline at end of file diff --git a/i18n/rus/extensions/git/out/autofetch.i18n.json b/i18n/rus/extensions/git/out/autofetch.i18n.json index 1e461cf4629..d3d761f3636 100644 --- a/i18n/rus/extensions/git/out/autofetch.i18n.json +++ b/i18n/rus/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,6 @@ // Do not edit this file. It is machine generated. { "yes": "Да", - "no": "Нет", - "not now": "Не сейчас", - "suggest auto fetch": "Вы хотите включить автоматическое получение для репозиториев Git?" + "read more": "Подробнее", + "no": "Нет" } \ No newline at end of file diff --git a/i18n/rus/extensions/git/out/commands.i18n.json b/i18n/rus/extensions/git/out/commands.i18n.json index d8d6feaa35d..b99a2ac09aa 100644 --- a/i18n/rus/extensions/git/out/commands.i18n.json +++ b/i18n/rus/extensions/git/out/commands.i18n.json @@ -64,12 +64,11 @@ "no remotes to pull": "Для вашего репозитория не настроены удаленные репозитории для получения данных.", "pick remote pull repo": "Выберите удаленный компьютер, с которого следует загрузить ветвь", "no remotes to push": "Для вашего репозитория не настроены удаленные репозитории для отправки данных.", - "push with tags success": "Файлы с тегами успешно отправлены.", "nobranch": "Извлеките ветвь, чтобы передать данные в удаленный репозиторий.", + "ok": "ОК", + "push with tags success": "Файлы с тегами успешно отправлены.", "pick remote": "Выберите удаленный сервер, на котором нужно опубликовать ветвь \"{0}\":", "sync is unpredictable": "Это действие отправляет фиксации в \"{0}\" и извлекает их из этого расположения.", - "ok": "ОК", - "never again": "ОК. Больше не показывать", "no remotes to publish": "Для вашего репозитория не настроены удаленные репозитории для публикации.", "no changes stash": "Отсутствуют изменения, которые необходимо спрятать.", "provide stash message": "Укажите сообщение о скрытии", diff --git a/i18n/rus/extensions/git/package.i18n.json b/i18n/rus/extensions/git/package.i18n.json index dcff3e1c9f0..bb4a19e4ed2 100644 --- a/i18n/rus/extensions/git/package.i18n.json +++ b/i18n/rus/extensions/git/package.i18n.json @@ -59,7 +59,6 @@ "config.enableLongCommitWarning": "Следует ли предупреждать о длинных сообщениях о фиксации", "config.confirmSync": "Подтвердите синхронизацию репозиториев GIT.", "config.countBadge": "\nУправляет счетчиком Git. При указании значения \"all\" подсчитываются все изменения, при указании значения \"tracked\" — только отслеживаемые изменения, при указании значения \"off\" счетчик отключается.", - "config.checkoutType": "Определяет типы ветвей, которые выводятся при выборе пункта меню \"Извлечь в...\". При указании значения \"all\" отображаются все ссылки, \"local\" — только локальные ветви, \"tags\" — только теги, а \"remote\" — только удаленные ветви.", "config.ignoreLegacyWarning": "Игнорирует предупреждение об устаревшей версии Git", "config.ignoreMissingGitWarning": "Игнорирует предупреждение об отсутствии Git", "config.ignoreLimitWarning": "Игнорировать предупреждение, когда в репозитории слишком много изменений", diff --git a/i18n/rus/extensions/typescript/out/commands.i18n.json b/i18n/rus/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..719d56f4f92 --- /dev/null +++ b/i18n/rus/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "Откройте папку в VS Code, чтобы использовать проект JavaScript или TypeScript.", + "typescript.projectConfigUnsupportedFile": "Не удалось определить проект TypeScript или JavaScript. Неподдерживаемый тип файла", + "typescript.projectConfigCouldNotGetInfo": "Не удалось определить проект TypeScript или JavaScript.", + "typescript.noTypeScriptProjectConfig": "Файл не является частью проекта TypeScript.", + "typescript.noJavaScriptProjectConfig": "Файл не является частью проекта JavaScript.", + "typescript.configureTsconfigQuickPick": "Настроить tsconfig.json", + "typescript.configureJsconfigQuickPick": "Настроить jsconfig.json", + "typescript.projectConfigLearnMore": "Дополнительные сведения" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/rus/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/rus/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/base/node/ps.i18n.json b/i18n/rus/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..94c012b641d --- /dev/null +++ b/i18n/rus/src/vs/base/node/ps.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "collecting": "Сбор информации о процессоре и памяти. Это может занять пару секунд." +} \ No newline at end of file diff --git a/i18n/rus/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/rus/src/vs/editor/common/config/commonEditorConfig.i18n.json index f265f8d9eaa..acc13bcc696 100644 --- a/i18n/rus/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/rus/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "Отображаются абсолютные номера строк.", "lineNumbers.relative": "Отображаемые номера строк вычисляются как расстояние в строках до положения курсора.", "lineNumbers.interval": "Номера строк отображаются каждые 10 строк.", - "lineNumbers": "Управляет отображением номеров строк. Возможные значения: \"on\", \"off\" и \"relative\".", + "lineNumbers": "Управляет отображением номеров строк. Возможные значения: 'on', 'off', 'relative' и 'interval'.", "rulers": "Отображать вертикальные линейки после определенного числа моноширинных символов. Для отображения нескольких линеек укажите несколько значений. Если не указано ни одного значения, вертикальные линейки отображаться не будут.", "wordSeparators": "Символы, которые будут использоваться как разделители слов при выполнении навигации или других операций, связанных со словами.", "tabSize": "Число пробелов в табуляции. Этот параметр переопределяется на основе содержимого файла, если установлен параметр \"editor.detectIndentation\".", @@ -72,6 +72,7 @@ "cursorBlinking": "Управляет стилем анимации курсора. Допустимые значения: \"blink\", \"smooth\", \"phase\", \"expand\" и \"solid\"", "mouseWheelZoom": "Изменение размера шрифта в редакторе при нажатой клавише CTRL и движении колесика мыши", "cursorStyle": "Определяет стиль курсора. Допустимые значения: \"block\", \"block-outline\", \"line\", \"line-thin\", \"underline\" и \"underline-thin\"", + "lineCursorWidth": "Управляет шириной курсора, когда для параметра editor.cursorStyle установлено значение 'line'", "fontLigatures": "Включает лигатуры шрифта.", "hideCursorInOverviewRuler": "Управляет скрытием курсора в обзорной линейке.", "renderWhitespace": "Определяет, должен ли редактор обрабатывать символы пробела; возможные значения: \"none\", \"boundary\" и \"all\". Параметр \"boundary\" не обрабатывает единичные пробелы между словами.", diff --git a/i18n/rus/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/rus/src/vs/editor/common/view/editorColorRegistry.i18n.json index 4801d2ec386..435033a9d39 100644 --- a/i18n/rus/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/rus/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,6 @@ { "lineHighlight": "Цвет фона для выделения строки в позиции курсора.", "lineHighlightBorderBox": "Цвет фона границ вокруг строки в позиции курсора.", - "rangeHighlight": "Цвет фона выделенных диапазонов, например в функциях быстрого открытия и поиска.", "caret": "Цвет курсора редактора.", "editorCursorBackground": "Цвет фона курсора редактора. Позволяет настраивать цвет символа, перекрываемого прямоугольным курсором.", "editorWhitespaces": "Цвет пробелов в редакторе.", diff --git a/i18n/rus/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/rus/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 5ca181d11bd..46e2fc5601e 100644 --- a/i18n/rus/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/rus/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "Перейти к следующей ошибке или предупреждению", - "markerAction.previous.label": "Перейти к предыдущей ошибке или предупреждению", "editorMarkerNavigationError": "Цвет ошибки в мини-приложении навигации по меткам редактора.", "editorMarkerNavigationWarning": "Цвет предупреждения в мини-приложении навигации по меткам редактора.", "editorMarkerNavigationInfo": "Цвет информационного сообщения в мини-приложении навигации по меткам редактора.", diff --git a/i18n/rus/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/rus/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index ab058cc24db..0894ee93e1f 100644 --- a/i18n/rus/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/rus/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "Цвет фона символа при доступе на чтение, например считывании переменной.", - "wordHighlightStrong": "Цвет фона символа при доступе на запись, например записи переменной.", "overviewRulerWordHighlightForeground": "Цвет метки линейки в окне просмотра для выделений символов.", "overviewRulerWordHighlightStrongForeground": "Цвет метки линейки в окне просмотра для выделений символов, доступных для записи. ", "wordHighlight.next.label": "Перейти к следующему выделению символов", diff --git a/i18n/rus/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/rus/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index b8216927851..74a4edfb15c 100644 --- a/i18n/rus/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/rus/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "\"{0}\" не является допустимым идентификатором меню", "missing.command": "Элемент меню ссылается на команду \"{0}\", которая не определена в разделе commands.", "missing.altCommand": "Элемент меню ссылается на альтернативную команду \"{0}\", которая не определена в разделе commands.", - "dupe.command": "Элемент меню ссылается на одну и ту же команду как команду по умолчанию и альтернативную команду", - "nosupport.altCommand": "Сейчас только группа navigation меню editor/title поддерживает альтернативные команды" + "dupe.command": "Элемент меню ссылается на одну и ту же команду как команду по умолчанию и альтернативную команду" } \ No newline at end of file diff --git a/i18n/rus/src/vs/platform/environment/node/argv.i18n.json b/i18n/rus/src/vs/platform/environment/node/argv.i18n.json index 7314aa06087..efe216539da 100644 --- a/i18n/rus/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/rus/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,32 @@ "diff": "Сравнение двух файлов друг с другом", "add": "Добавление папок в последнее активное окно.", "goto": "Открытие файла по указанному пути с выделением указанного символа в указанной строке.", - "locale": "Языковой стандарт, который следует использовать (например, en-US или zh-TW).", "newWindow": "Принудительно запустить новый экземпляр Code.", - "performance": "Запустите с включенной командой \"Developer: Startup Performance\".", - "prof-startup": "Запустить профилировщик ЦП при запуске", - "inspect-extensions": "Разрешить отладку и профилирование расширений. Проверьте URI подключения для инструментов разработчика.", - "inspect-brk-extensions": "Разрешить отладку и профилирование расширений, когда узел расширения приостановлен после запуска. Проверьте URI подключения для инструментов разработчика. ", "reuseWindow": "Принудительно открыть файл или папку в последнем активном окне.", - "userDataDir": "Указывает каталог, в котором хранятся данные пользователей, используется в случае выполнения от имени привилегированного пользователя.", - "log": "Используемый уровень ведения журнала. Значение по умолчанию — \"info\". Допустимые значения: \"critical\", \"error\", \"warn\", \"info\", \"debug\", \"trace\", \"off\".", - "verbose": "Печать подробного вывода (подразумевает использование параметра \"--wait\").", "wait": "Дождаться закрытия файлов перед возвратом.", + "locale": "Языковой стандарт, который следует использовать (например, en-US или zh-TW).", + "userDataDir": "Указывает каталог, в котором хранятся данные пользователей, используется в случае выполнения от имени привилегированного пользователя.", + "version": "Печать версии.", + "help": "Распечатать данные об использовании.", "extensionHomePath": "Задайте корневой путь для расширений.", "listExtensions": "Перечислить существующие расширения.", "showVersions": "Показать версии установленных расширений при указании параметра --list-extension.", "installExtension": "Устанавливает расширение.", "uninstallExtension": "Удаляет расширение.", "experimentalApis": "Включает предложенные функции API для расширения.", - "disableExtensions": "Отключить все установленные расширения.", - "disableGPU": "Отключить аппаратное ускорение GPU.", + "verbose": "Печать подробного вывода (подразумевает использование параметра \"--wait\").", + "log": "Используемый уровень ведения журнала. Значение по умолчанию — \"info\". Допустимые значения: \"critical\", \"error\", \"warn\", \"info\", \"debug\", \"trace\", \"off\".", "status": "Выводить сведения об использовании процесса и диагностическую информацию.", - "version": "Печать версии.", - "help": "Распечатать данные об использовании.", + "performance": "Запустите с включенной командой \"Developer: Startup Performance\".", + "prof-startup": "Запустить профилировщик ЦП при запуске", + "disableExtensions": "Отключить все установленные расширения.", + "inspect-extensions": "Разрешить отладку и профилирование расширений. Проверьте URI подключения для инструментов разработчика.", + "inspect-brk-extensions": "Разрешить отладку и профилирование расширений, когда узел расширения приостановлен после запуска. Проверьте URI подключения для инструментов разработчика. ", + "disableGPU": "Отключить аппаратное ускорение GPU.", "usage": "Использование", "options": "параметры", "paths": "пути", + "stdinWindows": "Чтобы прочитать вывод другой программы, добавьте '-' (например 'echo Hello World | {0} -')", + "stdinUnix": "Чтобы получить данные с stdin, добавьте '-' (например, 'ps aux | grep code | {0} -')\n", "optionsUpperCase": "Параметры" } \ No newline at end of file diff --git a/i18n/rus/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/rus/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index c25a9a85ff7..54111e4751d 100644 --- a/i18n/rus/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/rus/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,13 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "Недопустимое расширение: package.json не является файлом JSON.", - "restartCodeLocal": "Перезапустите код перед переустановкой {0}.", + "restartCode": "Перезапустите код перед переустановкой {0}.", "installingOutdatedExtension": "Уже установлена более новая версия этого расширения. Вы хотите переопределить ее более старой версией?", "override": "Переопределить", "cancel": "Отмена", - "notFoundCompatible": "Не удается выполнить установку, так как не найдено расширение '{0}', совместимое с текущей версией VS Code '{1}'.", - "quitCode": "Не удается выполнить установку, так как устаревший экземпляр расширения еще запущен. Закройте и снова откройте VS Code, затем запустите установку повторно.", - "exitCode": "Не удается выполнить установку, так как устаревший экземпляр расширения еще запущен. Закройте и снова откройте VS Code, затем запустите установку повторно. ", + "notFoundCompatible": "Невозможно установить '{0}'; нет версии, совместимой с VS Code '{1}'.", "notFoundCompatibleDependency": "Не удается выполнить установку, так как не найдено зависимое расширение '{0}', совместимое с текущей версией VS Code '{1}'. ", + "exitCode": "Невозможно установить расширение. Пожалуйста, выйдите и зайдите в VS Code перед переустановкой.", "uninstallDependeciesConfirmation": "Вы хотите удалить \"{0}\" отдельно или вместе с зависимостями?", "uninstallOnly": "Только", "uninstallAll": "Все", diff --git a/i18n/rus/src/vs/platform/message/common/message.i18n.json b/i18n/rus/src/vs/platform/message/common/message.i18n.json index 62863fdeb53..aab52c88b34 100644 --- a/i18n/rus/src/vs/platform/message/common/message.i18n.json +++ b/i18n/rus/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "Закрыть", "later": "Позже", - "cancel": "Отмена" + "cancel": "Отмена", + "moreFile": "...1 дополнительный файл не показан", + "moreFiles": "...не показано дополнительных файлов: {0}" } \ No newline at end of file diff --git a/i18n/rus/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/rus/src/vs/platform/theme/common/colorRegistry.i18n.json index 98e2cebe278..bbb9e4cefb0 100644 --- a/i18n/rus/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/rus/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,7 @@ "editorWidgetBorder": "Цвет границы мини-приложений редактора. Этот цвет используется только в том случае, если у мини-приложения есть граница и если этот цвет не переопределен мини-приложением.", "editorSelectionBackground": "Цвет выделения редактора.", "editorSelectionForeground": "Цвет выделенного текста в режиме высокого контраста.", - "editorInactiveSelection": "Цвет выделения в неактивном редакторе.", - "editorSelectionHighlight": "Цвет регионов с тем же содержимым, что и в выделении.", "editorFindMatch": "Цвет текущего поиска совпадений.", - "findMatchHighlight": "Цвет других совпадений поиска.", - "findRangeHighlight": "Цвет диапазона, ограничивающего поиск.", - "hoverHighlight": "Выделение под словом, для которого показано наведение.", "hoverBackground": "Цвет фона при наведении указателя на редактор.", "hoverBorder": "Цвет границ при наведении указателя на редактор.", "activeLinkForeground": "Цвет активных ссылок.", @@ -76,12 +71,6 @@ "diffEditorRemoved": "Цвет фона для удаленных строк.", "diffEditorInsertedOutline": "Цвет контура для добавленных строк.", "diffEditorRemovedOutline": "Цвет контура для удаленных строк.", - "mergeCurrentHeaderBackground": "Цвет фона текущего заголовка во внутренних конфликтах слияния.", - "mergeCurrentContentBackground": "Цвет фона текущего содержимого во внутренних конфликтах слияния.", - "mergeIncomingHeaderBackground": "Цвет фона входящего заголовка во внутренних конфликтах слияния.", - "mergeIncomingContentBackground": "Цвет фона входящего содержимого во внутренних конфликтах слияния.", - "mergeCommonHeaderBackground": "Цвет фона заголовка для общего предка во внутренних конфликтах слияния.", - "mergeCommonContentBackground": "Цвет фона содержимого для общего предка во внутренних конфликтах слияния.", "mergeBorder": "Цвет границы заголовков и разделителя во внутренних конфликтах слияния.", "overviewRulerCurrentContentForeground": "Цвет переднего плана линейки текущего окна во внутренних конфликтах слияния.", "overviewRulerIncomingContentForeground": "Цвет переднего плана линейки входящего окна во внутренних конфликтах слияния.", diff --git a/i18n/rus/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/rus/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/rus/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/rus/src/vs/workbench/api/node/extHostTreeViews.i18n.json index 9f9c8f9221d..9dad9f3a71b 100644 --- a/i18n/rus/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/rus/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -4,7 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "treeView.notRegistered": "Отсутствует зарегистрированное представление в виде дерева с идентификатором '{0}'.", - "treeItem.notFound": "Отсутствует элемент дерева с идентификатором '{0}'.", - "treeView.duplicateElement": "Элемент {0} уже зарегистрирован" + "treeView.notRegistered": "Отсутствует зарегистрированное представление в виде дерева с идентификатором '{0}'." } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/rus/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index 3e03b98e62c..b88aead69da 100644 --- a/i18n/rus/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/rus/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "Расположение боковой панели", "view": "Просмотреть" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/rus/src/vs/workbench/browser/actions/workspaceActions.i18n.json index 7f87d17117e..c63304e93ba 100644 --- a/i18n/rus/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/rus/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "Открыть файл...", "openFolder": "Открыть папку...", "openFileFolder": "Открыть...", - "addFolderToWorkspace": "Добавить папку в рабочую область...", - "add": "&&Добавить", - "addFolderToWorkspaceTitle": "Добавить папку в рабочую область", "globalRemoveFolderFromWorkspace": "Удалить папку из рабочей области...", - "removeFolderFromWorkspace": "Удалить папку из рабочей области", - "openFolderSettings": "Открыть параметры папок", "saveWorkspaceAsAction": "Сохранить рабочую область как...", "save": "Сохранить", "saveWorkspace": "Сохранить рабочую область", "openWorkspaceAction": "Открыть рабочую область...", "openWorkspaceConfigFile": "Открыть файл конфигурации рабочей области", - "openFolderAsWorkspaceInNewWindow": "Открыть папку как рабочую область в новом окне", - "workspaceFolderPickerPlaceholder": "Выберите папку рабочей области" + "openFolderAsWorkspaceInNewWindow": "Открыть папку как рабочую область в новом окне" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/rus/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..80b92b74445 --- /dev/null +++ b/i18n/rus/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "Добавить папку в рабочую область...", + "add": "&&Добавить", + "addFolderToWorkspaceTitle": "Добавить папку в рабочую область", + "workspaceFolderPickerPlaceholder": "Выберите папку рабочей области" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/rus/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index 3c123d9ce41..6382785efa1 100644 --- a/i18n/rus/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,17 @@ "groupThreePicker": "Показать редакторы в третьей группе", "allEditorsPicker": "Показать все открытые редакторы", "view": "Просмотр", - "file": "Файл" + "file": "Файл", + "close": "Закрыть", + "closeOthers": "Закрыть другие", + "closeRight": "Закрыть справа", + "closeAllUnmodified": "Закрыть без изменений", + "closeAll": "Закрыть все", + "keepOpen": "Оставить открытым", + "showOpenedEditors": "Показать открытые редакторы", + "keepEditor": "Сохранить редактор", + "closeEditorsInGroup": "Закрыть все редакторы в группе", + "closeUnmodifiedEditors": "Закрыть редакторы без изменений в группе", + "closeOtherEditors": "Закрыть другие редакторы", + "closeRightEditors": "Закрыть редакторы справа" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/rus/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index 4dba80c961d..f1572dc1c18 100644 --- a/i18n/rus/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/rus/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "Закрыть редактор", "revertAndCloseActiveEditor": "Отменить изменения и закрыть редактор", "closeEditorsToTheLeft": "Закрыть редакторы слева", - "closeEditorsToTheRight": "Закрыть редакторы справа", "closeAllEditors": "Закрыть все редакторы", - "closeUnmodifiedEditors": "Закрыть редакторы без изменений в группе", "closeEditorsInOtherGroups": "Закрыть редакторы в других группах", - "closeOtherEditorsInGroup": "Закрыть другие редакторы", - "closeEditorsInGroup": "Закрыть все редакторы в группе", "moveActiveGroupLeft": "Переместить группу редакторов влево", "moveActiveGroupRight": "Переместить группу редакторов вправо", "minimizeOtherEditorGroups": "Свернуть другие группы редакторов", "evenEditorGroups": "Уравнять ширину групп редакторов", "maximizeEditor": "Развернуть группу редакторов и скрыть боковую панель", - "keepEditor": "Сохранить редактор", "openNextEditor": "Открыть следующий редактор", "openPreviousEditor": "Открыть предыдущий редактор", "nextEditorInGroup": "Открыть следующий редактор в группе", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "Показать редакторы в первой группе", "showEditorsInSecondGroup": "Показать редакторы во второй группе", "showEditorsInThirdGroup": "Показать редакторы в третьей группе", - "showEditorsInGroup": "Показать редакторы в группе", "showAllEditors": "Показать все редакторы", "openPreviousRecentlyUsedEditorInGroup": "Открыть предыдущий недавно использованный редактор в группе", "openNextRecentlyUsedEditorInGroup": "Открыть следующий недавно использованный редактор в группе", diff --git a/i18n/rus/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/rus/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 32e566863c8..64223b3c4b5 100644 --- a/i18n/rus/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/rus/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "Перемещение активного редактора по вкладкам или группам", "editorCommand.activeEditorMove.arg.name": "Аргумент перемещения активного редактора", - "editorCommand.activeEditorMove.arg.description": "Свойства аргумента:\n\t* 'to': строковое значение, указывающее направление перемещения.\n\t* 'by': строковое значение, указывающее единицу перемещения (вкладка или группа).\n\t* 'value': числовое значение, указывающее количество позиций перемещения или абсолютную позицию для перемещения.", - "commandDeprecated": "Команда **{0}** удалена. Вместо нее можно использовать **{1}**", - "openKeybindings": "Настройка сочетаний клавиш" + "editorCommand.activeEditorMove.arg.description": "Свойства аргумента:\n\t* 'to': строковое значение, указывающее направление перемещения.\n\t* 'by': строковое значение, указывающее единицу перемещения (вкладка или группа).\n\t* 'value': числовое значение, указывающее количество позиций перемещения или абсолютную позицию для перемещения." } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/rus/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index 7e9ef4fb62e..f8b0ee45376 100644 --- a/i18n/rus/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/rus/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -10,7 +10,5 @@ "editableEditorWithInputAriaLabel": "{0}. Редактор сравнения текстовых файлов.", "editableEditorAriaLabel": "Редактор сравнения текстовых файлов.", "navigate.next.label": "Следующее исправление", - "navigate.prev.label": "Предыдущее исправление", - "inlineDiffLabel": "Переключиться на представление в строке", - "sideBySideDiffLabel": "Переключиться на параллельное представление" + "navigate.prev.label": "Предыдущее исправление" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/rus/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index f09bdce2324..cf0dce309ed 100644 --- a/i18n/rus/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/rus/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "Закрыть", - "closeOthers": "Закрыть другие", - "closeRight": "Закрыть справа", - "closeAll": "Закрыть все", - "closeAllUnmodified": "Закрыть без изменений", - "keepOpen": "Оставить открытым", - "showOpenedEditors": "Показать открытые редакторы", "araLabelEditorActions": "Действия редактора" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/rus/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index 6dd99f557bc..8b6ad71cd4e 100644 --- a/i18n/rus/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/rus/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -3,6 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{ - "hideView": "Скрыть из боковой панели" -} \ No newline at end of file +{} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/common/theme.i18n.json b/i18n/rus/src/vs/workbench/common/theme.i18n.json index bd0d0f8b98b..364c328c4c0 100644 --- a/i18n/rus/src/vs/workbench/common/theme.i18n.json +++ b/i18n/rus/src/vs/workbench/common/theme.i18n.json @@ -16,7 +16,6 @@ "editorGroupBackground": "Цвет фона группы редакторов. Группы редакторов представляют собой контейнеры редакторов. Цвет фона отображается при перетаскивании групп редакторов.", "tabsContainerBackground": "Цвет фона для заголовка группы редакторов, когда вкладки включены. Группы редакторов представляют собой контейнеры редакторов.", "tabsContainerBorder": "Цвет границы для заголовка группы редакторов, когда вкладки включены. Группы редакторов представляют собой контейнеры редакторов.", - "editorGroupHeaderBackground": "Цвет фона для заголовка группы редакторов, когда вкладки отключены. Группы редакторов представляют собой контейнеры редакторов.", "editorGroupBorder": "Цвет для разделения нескольких групп редакторов. Группы редакторов — это контейнеры редакторов.", "editorDragAndDropBackground": "Цвет фона при перетаскивании редакторов. Этот цвет должен обладать прозрачностью, чтобы содержимое редактора оставалось видимым.", "panelBackground": "Цвет фона панели. Панели показаны под областью редактора и содержат такие представления, как выходные данные и встроенный терминал.", @@ -33,8 +32,6 @@ "statusBarNoFolderBorder": "Цвет границы строки состояния, который распространяется на боковую панель и редактор, когда открытые папки отсутствуют. Строка состояния расположена в нижней части окна.", "statusBarItemActiveBackground": "Цвет фона элементов панели состояния при щелчке. Панель состояния отображается внизу окна.", "statusBarItemHoverBackground": "Цвет фона элементов панели состояния при наведении. Панель состояния отображается внизу окна.", - "statusBarProminentItemBackground": "Цвет фона приоритетных элементов панели состояния. Приоритетные элементы выделяются на фоне других элементов панели состояния, чтобы подчеркнуть их значение. Панель состояния отображается в нижней части окна.", - "statusBarProminentItemHoverBackground": "Цвет фона приоритетных элементов панели состояния при наведении. Приоритетные элементы выделяются на фоне других элементов панели состояния, чтобы подчеркнуть их значение. Панель состояния отображается в нижней части окна.", "activityBarBackground": "Цвет фона панели действий. Панель действий отображается слева или справа и позволяет переключаться между представлениями боковой панели.", "activityBarForeground": "Цвет переднего плана панели действий (например, цвет, используемый для значков). Панель действий отображается слева или справа и позволяет переключаться между представлениями боковой панели.", "activityBarBorder": "Цвет границы панели действий, который распространяется на боковую панель. Панель действий отображается слева или справа и позволяет переключаться между представлениями в боковой панели.", diff --git a/i18n/rus/src/vs/workbench/common/views.i18n.json b/i18n/rus/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..2feabab41e5 --- /dev/null +++ b/i18n/rus/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "Представление с идентификатором '{0}' уже зарегистрировано в расположении '{1}'" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/rus/src/vs/workbench/electron-browser/actions.i18n.json index 2380d05741c..5768ee78d85 100644 --- a/i18n/rus/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/rus/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "Закрыть редактор", "closeWindow": "Закрыть окно", "closeWorkspace": "Закрыть рабочую область", "noWorkspaceOpened": "В этом экземпляре отсутствуют открытые рабочие области.", @@ -52,21 +51,5 @@ "displayLanguage": "Определяет язык интерфейса VSCode.", "doc": "Список поддерживаемых языков см. в {0}.", "restart": "Для изменения значения требуется перезапуск VSCode.", - "fail.createSettings": "Невозможно создать \"{0}\" ({1}).", - "openLogsFolder": "Открыть папку журналов", - "showLogs": "Показать журналы...", - "mainProcess": "Главный", - "sharedProcess": "Общий", - "rendererProcess": "Отрисовщик", - "extensionHost": "Узел расширения", - "selectProcess": "Выберите процесс", - "setLogLevel": "Установите уровень ведения журнала", - "trace": "Трассировка", - "debug": "Отладка", - "info": "Сведения", - "warn": "Предупреждение", - "err": "Ошибка", - "critical": "Критический", - "off": "Отключено", - "selectLogLevel": "Установите уровень ведения журнала" + "fail.createSettings": "Невозможно создать \"{0}\" ({1})." } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/rus/src/vs/workbench/electron-browser/main.contribution.i18n.json index f0c8c83bedf..e6779131585 100644 --- a/i18n/rus/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "Просмотреть", "help": "Справка", "file": "Файл", - "developer": "Разработчик", "workspaces": "Рабочие области", + "developer": "Разработчик", + "workbenchConfigurationTitle": "Workbench", "showEditorTabs": "Определяет, должны ли открытые редакторы отображаться на вкладках или нет.", "workbench.editor.labelFormat.default": "Отображать имя файла. Если вкладки включены и в одной группе есть два файла с одинаковыми именами, то к имени каждого из этих файлов будут добавлены различающиеся части пути. Если вкладки отключены, то для активного редактора отображается путь по отношению к папке рабочей области.", "workbench.editor.labelFormat.short": "Отображать имя файла и имя каталога.", @@ -20,8 +21,10 @@ "showIcons": "Определяет, должны ли открытые редакторы отображаться со значком. Требует включить тему значков.", "enablePreview": "Определяет, отображаются ли открытые редакторы в режиме предварительного просмотра. Редакторы в режиме предварительного просмотра можно использовать, пока они открыты (например, с помощью двойного щелчка мыши или изменения). Текст в таких редакторах отображается курсивом.", "enablePreviewFromQuickOpen": "Определяет, отображаются ли редакторы из Quick Open в режиме предварительного просмотра. Редакторы в режиме предварительного просмотра повторно используются до сохранения (например, с помощью двойного щелчка или изменения).", + "closeOnFileDelete": "Определяет, следует ли автоматически закрывать редакторы, когда отображаемый в них файл удален или переименован другим процессом. При отключении этой функции редактор остается открытым в качестве черновика. Обратите внимание, что при удалении из приложения редактор закрывается всегда и что файлы черновиков никогда не закрываются для сохранения данных.", "editorOpenPositioning": "Определяет место открытия редакторов. Выберите 'left' или 'right', чтобы открывать редакторы слева или справа от активного редактора. Выберите 'first' или 'last', чтобы открывать редакторы независимо от активного редактора.", "revealIfOpen": "Определяет, отображается ли редактор в какой-либо из видимых групп при открытии. Если функция отключена, редактор открывается в текущей активной группе редакторов. Если функция включена, вместо открытия уже открытый редактор будет отображен в текущей активной группе редакторов. Обратите внимание, что в некоторых случаях этот параметр игнорируется, например при принудительном открытии редактора в определенной группе или сбоку от текущей активной группы редакторов.", + "swipeToNavigate": "Переключайтесь между открытыми файлами, проводя по экрану по горизонтали тремя пальцами.", "commandHistory": "Определяет количество недавно использованных команд, которые следует хранить в журнале палитры команд. Установите значение 0, чтобы отключить журнал команд.", "preserveInput": "Определяет, следует ли восстановить последнюю введенную команду в палитре команд при следующем открытии палитры.", "closeOnFocusLost": "Управляет автоматическим закрытием Quick Open при потере фокуса.", @@ -29,14 +32,11 @@ "sideBarLocation": "Определяет расположение боковой панели: слева или справа от рабочего места.", "statusBarVisibility": "Управляет видимостью строки состояния в нижней части рабочего места.", "activityBarVisibility": "Управляет видимостью панели действий на рабочем месте.", - "closeOnFileDelete": "Определяет, следует ли автоматически закрывать редакторы, когда отображаемый в них файл удален или переименован другим процессом. При отключении этой функции редактор остается открытым в качестве черновика. Обратите внимание, что при удалении из приложения редактор закрывается всегда и что файлы черновиков никогда не закрываются для сохранения данных.", - "enableNaturalLanguageSettingsSearch": "Определяет, следует ли включить режим поиска естественного языка для параметров.", "fontAliasing": "Управляет методом сглаживания шрифтов в рабочей области.-по умолчанию: субпиксельное сглаживание шрифтов; позволит добиться максимальной четкости текста на большинстве дисплеев за исключением Retina - сглаживание: сглаживание шрифтов на уровне пикселей, в отличие от субпиксельного сглаживания; позволит сделать шрифт более светлым в целом - нет: сглаживание шрифтов отключено; текст будет отображаться с неровными острыми краями ", "workbench.fontAliasing.default": "Субпиксельное сглаживание шрифтов; позволит добиться максимальной четкости текста на большинстве дисплеев за исключением Retina.", "workbench.fontAliasing.antialiased": "Сглаживание шрифтов на уровне пикселей, в отличие от субпиксельного сглаживания. Может сделать шрифт светлее в целом.", "workbench.fontAliasing.none": "Отключает сглаживание шрифтов; текст будет отображаться с неровными острыми краями.", - "swipeToNavigate": "Переключайтесь между открытыми файлами, проводя по экрану по горизонтали тремя пальцами.", - "workbenchConfigurationTitle": "Workbench", + "enableNaturalLanguageSettingsSearch": "Определяет, следует ли включить режим поиска естественного языка для параметров.", "windowConfigurationTitle": "Окно", "window.openFilesInNewWindow.on": "Файлы будут открываться в новом окне.", "window.openFilesInNewWindow.off": "Файлы будут открываться в окне с открытой папкой файлов или последнем активном окне.", diff --git a/i18n/rus/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/rus/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index 64ed05c0958..80636157f78 100644 --- a/i18n/rus/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "отлаживаемый объект", - "debug.terminal.not.available.error": "Интегрированный терминал недоступен." + "debug.terminal.title": "отлаживаемый объект" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 4671a2c1d23..7b4f9ca1fd9 100644 --- a/i18n/rus/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "Открыть новую командную строку", "globalConsoleActionMacLinux": "Открыть новый терминал", "scopedConsoleActionWin": "Открыть в командной строке", - "scopedConsoleActionMacLinux": "Открыть в терминале", - "openFolderInIntegratedTerminal": "Открыть в терминале" + "scopedConsoleActionMacLinux": "Открыть в терминале" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/rus/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index 3e00ebd8896..f674a1cb200 100644 --- a/i18n/rus/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "Рекомендуется использовать это расширение (на основе недавно открытых файлов).", + "neverShowAgain": "Больше не показывать", + "close": "Закрыть", "workspaceRecommendation": "Это расширение рекомендуется пользователями текущей рабочей области.", + "fileBasedRecommendation": "Рекомендуется использовать это расширение (на основе недавно открытых файлов).", "exeBasedRecommendation": "Рекомендуется использовать это расширение, так как установлено {0}.", "reallyRecommended2": "Для этого типа файлов рекомендуется использовать расширение '{0}'.", "reallyRecommendedExtensionPack": "Для этого типа файлов рекомендуется использовать пакет расширений '{0}'.", "showRecommendations": "Показать рекомендации", "install": "Установить", - "neverShowAgain": "Больше не показывать", - "close": "Закрыть", "workspaceRecommended": "Эта рабочая область включает рекомендации по расширениям.", "installAll": "Установить все", "ignoreExtensionRecommendations": "Вы действительно хотите проигнорировать все рекомендации по расширениям?", diff --git a/i18n/rus/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..933a96a0d6f --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "Рабочее место" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/rus/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 821930bfc87..8ff5f3c27f7 100644 --- a/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,24 @@ "filesCategory": "Файл", "revealInSideBar": "Показать в боковой панели", "acceptLocalChanges": "Использовать изменения и перезаписать содержимое диска", - "revertLocalChanges": "Отменить изменения и вернуться к содержимому на диске" + "revertLocalChanges": "Отменить изменения и вернуться к содержимому на диске", + "copyPathOfActive": "Копировать путь к активному файлу", + "saveAllInGroup": "Сохранить все в группе", + "revert": "Отменить изменения в файле", + "compareActiveWithSaved": "Сравнить активный файл с сохраненным", + "closeEditor": "Закрыть редактор", + "view": "Просмотр", + "openToSide": "Открыть сбоку", + "revealInWindows": "Отобразить в проводнике", + "revealInMac": "Отобразить в Finder", + "openContainer": "Открыть содержащую папку", + "copyPath": "Скопировать путь", + "saveAll": "Сохранить все", + "compareWithSaved": "Сравнить с сохраненным", + "compareSource": "Выбрать для сравнения", + "close": "Закрыть", + "closeOthers": "Закрыть другие", + "closeUnmodified": "Закрыть без изменений", + "closeAll": "Закрыть все", + "deleteFile": "Удалить навсегда" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 8e87ab6930a..33066ff5f33 100644 --- a/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "Повторить попытку", - "rename": "Переименовать", "newFile": "Создать файл", "newFolder": "Создать папку", + "rename": "Переименовать", + "delete": "Удалить", + "copyFile": "Копировать", + "pasteFile": "Вставить", + "retry": "Повторить попытку", "openFolderFirst": "Сначала откройте папку, в которой будут созданы файлы и папки.", "newUntitledFile": "Новый файл без имени", "createNewFile": "Создать файл", @@ -28,26 +31,14 @@ "confirmDeleteMessageFile": "Вы действительно хотите удалить \"{0}\" без возможности восстановления?", "irreversible": "Это действие необратимо.", "permDelete": "Удалить навсегда", - "delete": "Удалить", "importFiles": "Импорт файлов", "confirmOverwrite": "Файл или папка с таким именем уже существует в конечной папке. Заменить их?", "replaceButtonLabel": "Заменить", - "copyFile": "Копировать", - "pasteFile": "Вставить", "duplicateFile": "Дублировать", - "openToSide": "Открыть сбоку", - "compareSource": "Выбрать для сравнения", "globalCompareFile": "Сравнить активный файл с...", "openFileToCompare": "Чтобы сравнить файл с другим файлом, сначала откройте его.", - "compareWith": "Сравнить '{0}' с '{1}'", - "compareFiles": "Сравнить файлы", "refresh": "Обновить", - "save": "Сохранить", - "saveAs": "Сохранить как...", - "saveAll": "Сохранить все", "saveAllInGroup": "Сохранить все в группе", - "saveFiles": "Сохранить все файлы", - "revert": "Отменить изменения в файле", "focusOpenEditors": "Фокус на представлении открытых редакторов", "focusFilesExplorer": "Фокус на проводнике", "showInExplorer": "Показать активный файл в боковой панели", @@ -56,20 +47,11 @@ "refreshExplorer": "Обновить окно проводника", "openFileInNewWindow": "Открыть активный файл в новом окне", "openFileToShowInNewWindow": "Чтобы открыть файл в новом окне, сначала откройте его.", - "revealInWindows": "Отобразить в проводнике", - "revealInMac": "Отобразить в Finder", - "openContainer": "Открыть содержащую папку", - "revealActiveFileInWindows": "Отобразить активный файл в проводнике", - "revealActiveFileInMac": "Отобразить активный файл в Finder", - "openActiveFileContainer": "Открыть папку, содержащую активный файл", "copyPath": "Скопировать путь", - "copyPathOfActive": "Копировать путь к активному файлу", "emptyFileNameError": "Необходимо указать имя файла или папки.", "fileNameExistsError": "Файл или папка **{0}** уже существует в данном расположении. Выберите другое имя.", "invalidFileNameError": "Имя **{0}** недопустимо для файла или папки. Выберите другое имя.", "filePathTooLongError": "Из-за использования имени **{0}** путь слишком длинный. Выберите более короткое имя.", - "compareWithSaved": "Сравнить активный файл с сохраненным", - "modifiedLabel": "{0} (на диске) ↔ {1}", "compareWithClipboard": "Сравнить активный файл с буфером обмена", "clipboardComparisonLabel": "Буфер обмена ↔ {0}" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index f51fb88b34b..18416689c01 100644 --- a/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "Чтобы скопировать путь к файлу, сначала откройте его", - "openFileToReveal": "Чтобы отобразить файл, сначала откройте его" + "revealInWindows": "Отобразить в проводнике", + "revealInMac": "Отобразить в Finder", + "openContainer": "Открыть содержащую папку", + "saveAs": "Сохранить как...", + "save": "Сохранить", + "saveAll": "Сохранить все", + "removeFolderFromWorkspace": "Удалить папку из рабочей области", + "modifiedLabel": "{0} (на диске) ↔ {1}", + "openFileToReveal": "Чтобы отобразить файл, сначала откройте его", + "openFileToCopy": "Чтобы скопировать путь к файлу, сначала откройте его" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index d0ffe58b0f9..6f4f5194bc6 100644 --- a/i18n/rus/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,6 @@ "editorConfigurationTitle": "Редактор", "formatOnSave": "Форматирование файла при сохранении. Модуль форматирования должен быть доступен, файл не должен сохраняться автоматически, а работа редактора не должна завершаться.", "explorerConfigurationTitle": "Проводник", - "openEditorsVisible": "Число редакторов, отображаемых на панели открытых редакторов. Задайте значение 0, чтобы скрыть панель.", - "dynamicHeight": "Определяет, будет ли высота раздела открытых редакторов динамически адаптироваться к количеству элементов.", "autoReveal": "Определяет, будет ли проводник автоматически отображать и выбирать файлы при их открытии.", "enableDragAndDrop": "Определяет, разрешено ли перемещение файлов и папок перетаскиванием в проводнике.", "confirmDragAndDrop": "Определяет, должно ли запрашиваться подтверждение при перемещении файлов и папок в проводнике.", diff --git a/i18n/rus/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/rus/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index d5622eec39a..a99d73ed519 100644 --- a/i18n/rus/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,9 @@ // Do not edit this file. It is machine generated. { "userGuide": "Используйте команды на панели инструментов редактора справа для **отмены** изменений или **перезаписи** содержимого на диске с учетом этих изменений", - "discard": "Отмена", "overwrite": "Перезаписать", "retry": "Повторить попытку", - "readonlySaveError": "Не удалось сохранить \"{0}\": файл защищен от записи. Чтобы снять защиту, нажмите \"Перезаписать\".", + "discard": "Отмена", "genericSaveError": "Не удалось сохранить \"{0}\": {1}", "staleSaveError": "Не удалось сохранить \"{0}\": содержимое на диске более новое. Чтобы сравнить свою версию с версией на диске, нажмите **Сравнить**.", "compareChanges": "Сравнить", diff --git a/i18n/rus/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/rus/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index ecfb243efe9..e8bc16acb29 100644 --- a/i18n/rus/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "Открытые редакторы", "openEditosrSection": "Раздел открытых редакторов", - "dirtyCounter": "Не сохранено: {0}", - "saveAll": "Сохранить все", - "closeAllUnmodified": "Закрыть без изменений", - "closeAll": "Закрыть все", - "compareWithSaved": "Сравнить с сохраненным", - "close": "Закрыть", - "closeOthers": "Закрыть другие" + "dirtyCounter": "Не сохранено: {0}" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..fa130c143cf --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "developer": "Разработчик" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/rus/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..6d7a48207b9 --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "Открыть папку журналов", + "mainProcess": "Главный", + "sharedProcess": "Общий", + "rendererProcess": "Окно", + "extensionHost": "Узел расширения", + "setLogLevel": "Установите уровень ведения журнала", + "trace": "Трассировка", + "debug": "Отладка", + "info": "Сведения", + "warn": "Предупреждение", + "err": "Ошибка", + "off": "Отключено", + "selectLogLevel": "Установите уровень ведения журнала" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/rus/src/vs/workbench/parts/markers/common/messages.i18n.json index 4a0ebeccf87..c561464b583 100644 --- a/i18n/rus/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "viewCategory": "Просмотреть", - "problems.view.toggle.label": "Показать/скрыть проблемы", - "problems.view.focus.label": "Проблемы с фокусом", "problems.panel.configuration.title": "Представление \"Проблемы\"", "problems.panel.configuration.autoreveal": "Определяет, следует ли представлению \"Проблемы\" отображать файлы при их открытии", "markers.panel.title.problems": "Проблемы", diff --git a/i18n/rus/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..68cc0434ecd --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "Вывод", + "viewCategory": "Просмотр", + "clearOutput.label": "Очистить выходные данные" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/rus/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/rus/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index cdba5fc34b2..aa42a73f571 100644 --- a/i18n/rus/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "Попробуйте режим поиска естественного языка!", "defaultSettings": "Чтобы переопределить параметры по умолчанию, укажите свои параметры в области справа.", "noSettingsFound": "Параметры не найдены.", "settingsSwitcherBarAriaLabel": "Переключатель параметров", "userSettings": "Параметры пользователя", "workspaceSettings": "Параметры рабочей области", - "folderSettings": "Параметры папок", - "enableFuzzySearch": "Включить режим поиска естественного языка" + "folderSettings": "Параметры папок" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/rus/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index 345c107b419..3305d6aa84d 100644 --- a/i18n/rus/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "Часто используемые", - "mostRelevant": "Наиболее релевантные", "defaultKeybindingsHeader": "Перезапишите настраиваемое сочетание клавиш, поместив их в файл настраиваемых сочетаний клавиш." } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index a683b0d8467..f0071d32bf8 100644 --- a/i18n/rus/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "Просмотр", "commandsHandlerDescriptionDefault": "Показать и выполнить команды", "gotoLineDescriptionMac": "Перейти к строке", "gotoLineDescriptionWin": "Перейти к строке", diff --git a/i18n/rus/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json index 029a91dd121..9b3baff6083 100644 --- a/i18n/rus/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/scm/electron-browser/scm.contribution.i18n.json @@ -7,5 +7,6 @@ "toggleGitViewlet": "Показать GIT", "source control": "Система управления версиями", "toggleSCMViewlet": "Показать SCM", - "view": "Просмотреть" + "view": "Просмотреть", + "scmConfigurationTitle": "SCM" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/rus/src/vs/workbench/parts/search/browser/searchActions.i18n.json index acbdea84856..cd1b6966535 100644 --- a/i18n/rus/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "Показать предыдущее условие поиска", "showSearchViewlet": "Показать средство поиска", "findInFiles": "Найти в файлах", - "findInFilesWithSelectedText": "Найти в файлах с выделенным текстом", "replaceInFiles": "Заменить в файлах", - "replaceInFilesWithSelectedText": "Заменить в файлах с выделенным текстом", "RefreshAction.label": "Обновить", "CollapseDeepestExpandedLevelAction.label": "Свернуть все", "ClearSearchResultsAction.label": "Очистить", diff --git a/i18n/rus/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index fb91734ab3b..e2ad0465583 100644 --- a/i18n/rus/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -7,7 +7,9 @@ "showTriggerActions": "Перейти к символу в рабочей области...", "name": "Поиск", "search": "Поиск", + "showSearchViewlet": "Показать средство поиска", "view": "Просмотр", + "findInFiles": "Найти в файлах", "openAnythingHandlerDescription": "Перейти к файлу", "openSymbolDescriptionNormal": "Перейти к символу в рабочей области", "searchOutputChannelTitle": "Поиск", diff --git a/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..26ab76b193c --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.1": "({0})", + "preferences": "Параметры" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index a3a8c117e65..0bfa5d00f22 100644 --- a/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,10 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "Выберите язык для фрагментов кода", - "openSnippet.errorOnCreate": "Не удалось создать {0}.", - "openSnippet.label": "Открыть пользовательские фрагменты", - "preferences": "Параметры", "snippetSchema.json.default": "Пустой фрагмент", "snippetSchema.json": "Настройка фрагмента пользователя", "snippetSchema.json.prefix": "Префикс, используемый при выборе фрагмента в Intellisense.", diff --git a/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..dd3a311fe89 --- /dev/null +++ b/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "Фрагмент кода пользователя" +} \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index 6c5ec091a1a..afe0462f8a1 100644 --- a/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "Неизвестный язык в contributes.{0}.language. Указанное значение: {1}", "invalid.path.0": "В contributes.{0}.path требуется строка. Указанное значение: {1}", + "invalid.language": "Неизвестный язык в contributes.{0}.language. Указанное значение: {1}", "invalid.path.1": "contributes.{0}.path ({1}) должен был быть включен в папку расширения ({2}). Это может сделать расширение непереносимым.", "vscode.extension.contributes.snippets": "Добавляет фрагменты.", "vscode.extension.contributes.snippets-language": "Идентификатор языка, для которого добавляется этот фрагмент.", "vscode.extension.contributes.snippets-path": "Путь к файлу фрагментов. Путь указывается относительно папки расширения и обычно начинается с \"./snippets/\".", "badVariableUse": "Похоже, что в одном или нескольких фрагментах расширения \"{0}\" перепутаны переменные и заполнители. Дополнительные сведения см. на странице https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax.", "badFile": "Не удалось прочитать файл фрагмента \"{0}\".", - "source.snippet": "Фрагмент кода пользователя", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json b/i18n/rus/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json index fc208588fb0..04ba7d28169 100644 --- a/i18n/rus/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json @@ -8,6 +8,5 @@ "terminal.foreground": "Цвет переднего плана терминала.", "terminalCursor.foreground": "Цвет переднего плана курсора терминала.", "terminalCursor.background": "Цвет фона курсора терминала. Позволяет выбрать цвет символа, который перекрывается блочным курсором.", - "terminal.selectionBackground": "Цвет фона выделения терминала.", - "terminal.ansiColor": "Цвет ANSI \"{0}\" в терминале." + "terminal.selectionBackground": "Цвет фона выделения терминала." } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/rus/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index 440d374ef82..9de408a9653 100644 --- a/i18n/rus/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,6 @@ "terminal.integrated.chooseWindowsShellInfo": "Вы можете изменить оболочку терминала по умолчанию, нажав кнопку \"Настроить\".", "customize": "Настроить", "cancel": "Отмена", - "never again": "ОК. Больше не показывать", "terminal.integrated.chooseWindowsShell": "Выберите предпочитаемую оболочку терминала. Ее можно позже изменить в параметрах", "terminalService.terminalCloseConfirmationSingular": "Есть активный сеанс терминала, завершить его?", "terminalService.terminalCloseConfirmationPlural": "Есть несколько активных сеансов терминала ({0}), завершить их?" diff --git a/i18n/rus/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/rus/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 54fbd1ada7b..04cb07cdd65 100644 --- a/i18n/rus/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/rus/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileNotModifiedError": "undefined", "fileBinaryError": "Похоже, файл является двоичным, и его нельзя открыть как текстовый." } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/rus/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index fd9cd98e381..27106b8b44d 100644 --- a/i18n/rus/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/rus/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "Сохранить изменения, внесенные в {0}?", "saveChangesMessages": "Сохранить изменения в указанных файлах ({0})?", - "moreFile": "...1 дополнительный файл не показан", - "moreFiles": "...не показано дополнительных файлов: {0}", "saveAll": "&&Сохранить все", "save": "&&Сохранить", "dontSave": "&&Не сохранять", diff --git a/i18n/rus/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/rus/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index 9cba5bba5fd..768f28f6eae 100644 --- a/i18n/rus/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/rus/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "No file icons", "iconThemeError": "File icon theme is unknown or not installed.", "workbenchColors": "Переопределяет цвета из выбранной цветовой темы.", - "editorColors": "Переопределяет цвета редактора и стиль шрифта из текущей выбранной цветовой темы.", "editorColors.comments": "Задает цвета и стили для комментариев", "editorColors.strings": "Задает цвета и стили для строковых литералов.", "editorColors.keywords": "Задает цвета и стили для ключевых слов.", @@ -19,5 +18,6 @@ "editorColors.types": "Задает цвета и стили для объявлений типов и ссылок. ", "editorColors.functions": "Задает цвета и стили для объявлений функций и ссылок. ", "editorColors.variables": "Задает цвета и стили для объявлений переменных и для ссылок. ", - "editorColors.textMateRules": "Задает цвета и стили с использованием правил оформления textmate (расширенный параметр)." + "editorColors.textMateRules": "Задает цвета и стили с использованием правил оформления textmate (расширенный параметр).", + "editorColors": "Переопределяет цвета редактора и стиль шрифта из текущей выбранной цветовой темы." } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/rus/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 019229d3fbb..d4e81ae004d 100644 --- a/i18n/rus/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/rus/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "Не удается записать файл конфигурации рабочей области. Откройте файл, исправьте ошибки и предупреждения и повторите попытку.", "errorWorkspaceConfigurationFileDirty": "Не удается записать файл конфигурации рабочей области, так как файл был изменен. Сохраните файл и повторите попытку.", "openWorkspaceConfigurationFile": "Открыть файл конфигурации рабочей области", - "close": "Закрыть", - "enterWorkspace.close": "Закрыть", - "enterWorkspace.dontShowAgain": "Больше не показывать", - "enterWorkspace.moreInfo": "Дополнительные сведения", - "enterWorkspace.prompt": "Дополнительные сведения о работе с несколькими папками в VS Code." + "close": "Закрыть" } \ No newline at end of file diff --git a/i18n/trk/extensions/git/out/autofetch.i18n.json b/i18n/trk/extensions/git/out/autofetch.i18n.json index 95a3249f5f4..737e720ea79 100644 --- a/i18n/trk/extensions/git/out/autofetch.i18n.json +++ b/i18n/trk/extensions/git/out/autofetch.i18n.json @@ -5,7 +5,8 @@ // Do not edit this file. It is machine generated. { "yes": "Evet", + "read more": "Devamını oku", "no": "Hayır", - "not now": "Şu An İstemiyorum", - "suggest auto fetch": "Otomatik Git depoları alımını etkinleştirmek ister misiniz?" + "not now": "Daha sonra hatırlat", + "suggest auto fetch": "Code'un düzenli olarak `git fetch` komutunu çalıştırmasını ister misiniz?" } \ No newline at end of file diff --git a/i18n/trk/extensions/git/out/commands.i18n.json b/i18n/trk/extensions/git/out/commands.i18n.json index fac3c95bae7..1f602af17de 100644 --- a/i18n/trk/extensions/git/out/commands.i18n.json +++ b/i18n/trk/extensions/git/out/commands.i18n.json @@ -41,6 +41,10 @@ "confirm discard all 2": "{0}\n\nBu GERİ DÖNDÜRÜLEMEZ, mevcut çalışma grubunuz TAMAMEN KAYBOLACAK.", "yes discard tracked": "İzlenen 1 Dosyayı Göz Ardı Et", "yes discard tracked multiple": "İzlenen {0} Dosyayı Göz Ardı Et", + "unsaved files single": "Aşağıdaki dosya kaydedilmemiş: {0}.\n\nCommit'lemeden önce kaydetmek ister misiniz?", + "unsaved files": "{0} kaydedilmemiş dosya var.\n\nCommit'lemeden önce kaydetmek ister misiniz?", + "save and commit": "Tümünü Kaydet & Commit'le", + "commit": "Yine de Commit'le", "no staged changes": "Commit'lenecek hazırlanmış değişiklik yok.\n\nTüm değişikliklerinizi otomatik olarak hazırlamak ve direkt olarak commit'lemek ister misiniz?", "always": "Her Zaman", "no changes": "Commit'lenecek değişiklik yok.", @@ -64,12 +68,12 @@ "no remotes to pull": "Deponuzda çekme işleminin yapılacağı hiçbir uzak uçbirim yapılandırılmamış.", "pick remote pull repo": "Dalın çekileceği bir uzak uçbirim seçin", "no remotes to push": "Deponuzda gönderimin yapılacağı hiçbir uzak uçbirim yapılandırılmamış.", - "push with tags success": "Başarılı bir şekilde etiketlerle gönderildi.", "nobranch": "Lütfen uzak uçbirime gönderilecek dala geçiş yapın.", + "confirm publish branch": "'{0}' dalında bir ana depo(upstream) dalı bulunmuyor. Bu dalı yayınlamak ister misiniz?", + "ok": "Tamam", + "push with tags success": "Başarılı bir şekilde etiketlerle gönderildi.", "pick remote": "'{0}' dalının yayınlanacağı bir uzak uçbirim seçin:", "sync is unpredictable": "Bu eylem, '{0}' esas projesine commitleri gönderecek ve alacaktır.", - "ok": "Tamam", - "never again": "Tamam, Tekrar Gösterme", "no remotes to publish": "Deponuzda yayınlamanın yapılacağı hiçbir uzak uçbirim yapılandırılmamış.", "no changes stash": "Geçici olarak saklanacak bir değişiklik yok.", "provide stash message": "İsteğe bağlı olarak bir geçici olarak saklama mesajı belirtin", diff --git a/i18n/trk/extensions/git/out/main.i18n.json b/i18n/trk/extensions/git/out/main.i18n.json index 34a8658c392..ebd9e4be3fa 100644 --- a/i18n/trk/extensions/git/out/main.i18n.json +++ b/i18n/trk/extensions/git/out/main.i18n.json @@ -7,7 +7,7 @@ "looking": "Git, şu konumda aranıyor: {0}", "using git": "{1} yolundaki git {0} kullanılıyor", "downloadgit": "Git'i İndir", - "neverShowAgain": "Tekrar gösterme", + "neverShowAgain": "Tekrar Gösterme", "notfound": "Git bulunamadı. Git'i kurun veya 'git.path' ayarı ile yapılandırın.", "updateGit": "Git'i Güncelle", "git20": "git {0} yüklemiş olarak görünüyorsunuz. Code, git >= 2 ile en iyi şekilde çalışır" diff --git a/i18n/trk/extensions/git/package.i18n.json b/i18n/trk/extensions/git/package.i18n.json index 3955baf58a0..193dcf3dff8 100644 --- a/i18n/trk/extensions/git/package.i18n.json +++ b/i18n/trk/extensions/git/package.i18n.json @@ -54,12 +54,12 @@ "command.stashPopLatest": "En Son Geçici Olarak Saklananı Geri Yükle", "config.enabled": "Git'in etkinleştirilip etkinleştirilmediği", "config.path": "Çalıştırılabilir Git dosyasının yolu", + "config.autoRepositoryDetection": "Depoların otomatik olarak algılanıp algılanmayacağı", "config.autorefresh": "Otomatik yenilemenin etkinleştirilip etkinleştirilmediği", "config.autofetch": "Otomatik getirmenin etkinleştirilip etkinleştirilmediği", "config.enableLongCommitWarning": "Uzun commit mesajları hakkında uyarıda bulunulup bulunulmayacağı", "config.confirmSync": "Git depolarını senkronize etmeden önce onaylayın", "config.countBadge": "Git gösterge sayacını denetler. `all` tüm değişiklikleri sayar. `tracked` sadece izlenen değişikliklikleri sayar. `off` ise kapatır.", - "config.checkoutType": "`Geçiş Yap...` çalıştırılırken listelenecek dal türlerini denetler. `all` tüm başvuruları gösterir, `local` sadece yerel dalları gösterir, `tags` sadece etiketleri gösterir ve `remote` sadece uzak uçbirim dallarını gösterir.", "config.ignoreLegacyWarning": "Eski Git uyarısını görmezden gelir", "config.ignoreMissingGitWarning": "Git mevcut olmadığında uyarıyı yok sayar", "config.ignoreLimitWarning": "Bir depoda çok fazla değişiklik var uyarısını görmezden gelir", @@ -72,5 +72,6 @@ "colors.deleted": "Silinen kaynakların rengi.", "colors.untracked": "İzlenmeyen kaynakların rengi.", "colors.ignored": "Yok sayılan kaynakların rengi.", - "colors.conflict": "Çakışma içeren kaynakların rengi." + "colors.conflict": "Çakışma içeren kaynakların rengi.", + "colors.submodule": "Alt modül kaynaklarının rengi." } \ No newline at end of file diff --git a/i18n/trk/extensions/typescript/out/commands.i18n.json b/i18n/trk/extensions/typescript/out/commands.i18n.json new file mode 100644 index 00000000000..2751d3bb07c --- /dev/null +++ b/i18n/trk/extensions/typescript/out/commands.i18n.json @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "typescript.projectConfigNoWorkspace": "Bir TypeScript veya JavaScript projesini kullanmak için lütfen bir klasör açın", + "typescript.projectConfigUnsupportedFile": "TypeScript mi yoksa JavaScript mi projesi olduğu tespit edilemedi. Desteklenmeyen dosya türü", + "typescript.projectConfigCouldNotGetInfo": "TypeScript mi yoksa JavaScript mi projesi olduğu tespit edilemedi", + "typescript.noTypeScriptProjectConfig": "Dosya bir TypeScript projesinin bir parçası değil", + "typescript.noJavaScriptProjectConfig": "Dosya bir JavaScript projesinin bir parçası değil", + "typescript.configureTsconfigQuickPick": "tsconfig.json'u yapılandır", + "typescript.configureJsconfigQuickPick": "jsconfig.json'u yapılandır", + "typescript.projectConfigLearnMore": "Daha Fazla Bilgi Edin" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json b/i18n/trk/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json new file mode 100644 index 00000000000..ed15423097d --- /dev/null +++ b/i18n/trk/src/vs/base/browser/ui/selectBox/selectBoxCustom.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "selectAriaOption": "{0}" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/base/node/ps.i18n.json b/i18n/trk/src/vs/base/node/ps.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/trk/src/vs/base/node/ps.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/trk/src/vs/editor/common/config/commonEditorConfig.i18n.json b/i18n/trk/src/vs/editor/common/config/commonEditorConfig.i18n.json index 3a5d4006fd7..d00cee8579f 100644 --- a/i18n/trk/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/trk/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -14,7 +14,7 @@ "lineNumbers.on": "Satır numaraları mutlak sayı olarak gösterilir.", "lineNumbers.relative": "Satır numaraları imlecin konumuna olan uzaklık olarak gösterilir.", "lineNumbers.interval": "Satır numaraları her 10 satırda bir gösterilir.", - "lineNumbers": "Satır numaralarının görüntülenmesini denetler. Olası değerler 'on', 'off' ve 'relative'dir.", + "lineNumbers": "Satır numaralarının görüntülenmesini denetler. Olası değerler 'on', 'off', 'relative' ve 'interval'dir.\n", "rulers": "Belirli bir eşit genişlikli karakterlerden sonra dikey cetveller göster. Birden çok cetvel için birden çok değer kullanın. Dizi boş ise cetvel gösterilmez", "wordSeparators": "Sözcüklerle ilgili gezinti veya işlem yaparken kelime ayırıcı olarak kullanılacak karakterler", "tabSize": "Bir sekmenin eşit olduğu boşluk sayısı. Bu ayar, `editor.detectIndentation` açıkken dosya içeriğine bağlı olarak geçersiz kılınır.", diff --git a/i18n/trk/src/vs/editor/common/view/editorColorRegistry.i18n.json b/i18n/trk/src/vs/editor/common/view/editorColorRegistry.i18n.json index 6022a86b6cc..8fb29c3b6d6 100644 --- a/i18n/trk/src/vs/editor/common/view/editorColorRegistry.i18n.json +++ b/i18n/trk/src/vs/editor/common/view/editorColorRegistry.i18n.json @@ -6,7 +6,6 @@ { "lineHighlight": "İmlecin bulunduğu satırın vurgusunun arka plan rengi.", "lineHighlightBorderBox": "İmlecin bulunduğu satırın kenarlığının arka plan rengi.", - "rangeHighlight": "Hızlı açma ve bulma özellikleri gibi vurgulanan alanların arka plan rengi.", "caret": "Düzenleyici imlecinin rengi.", "editorCursorBackground": "Düzenleyici imlecinin arka plan rengi. Bir blok imlecinin kapladığı bir karakterin rengini özelleştirmeyi sağlar.", "editorWhitespaces": "Düzenleyicideki boşluk karakterlerinin rengi.", diff --git a/i18n/trk/src/vs/editor/contrib/gotoError/gotoError.i18n.json b/i18n/trk/src/vs/editor/contrib/gotoError/gotoError.i18n.json index 6bc3935d6f4..b9f1dd5ddfd 100644 --- a/i18n/trk/src/vs/editor/contrib/gotoError/gotoError.i18n.json +++ b/i18n/trk/src/vs/editor/contrib/gotoError/gotoError.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "title.wo_source": "({0}/{1})", - "markerAction.next.label": "Sonraki Hata veya Uyarıya Git", - "markerAction.previous.label": "Önceki Hata veya Uyarıya Git", "editorMarkerNavigationError": "Düzenleyicinin işaretçi gezinti aracının hata rengi.", "editorMarkerNavigationWarning": "Düzenleyicinin işaretçi gezinti aracının uyarı rengi.", "editorMarkerNavigationInfo": "Düzenleyicinin işaretçi gezinti aracının bilgilendirme rengi.", diff --git a/i18n/trk/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json b/i18n/trk/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json index 6faf663326d..f6e38f50e99 100644 --- a/i18n/trk/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json +++ b/i18n/trk/src/vs/editor/contrib/wordHighlighter/wordHighlighter.i18n.json @@ -4,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "wordHighlight": "Bir değişkeni okumak gibi, okuma-erişimi sırasındaki bir sembolün arka plan rengi.", - "wordHighlightStrong": "Bir değişkene yazmak gibi, yazma-erişimi sırasındaki bir sembolün arka plan rengi.", "overviewRulerWordHighlightForeground": "Sembol vurguları için genel bakış cetvelinin işaretleyici rengi.", "overviewRulerWordHighlightStrongForeground": "Yazma erişimli sembol vurguları için genel bakış cetvelinin işaretleyici rengi.", "wordHighlight.next.label": "Sonraki Sembol Vurgusuna Git", diff --git a/i18n/trk/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json b/i18n/trk/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json index 5ddafd4b6b9..5565278f23e 100644 --- a/i18n/trk/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json +++ b/i18n/trk/src/vs/platform/actions/electron-browser/menusExtensionPoint.i18n.json @@ -40,6 +40,5 @@ "menuId.invalid": "`{0}` geçerli bir menü tanımlayıcısı değil", "missing.command": "Menü ögesi, 'commands' bölümünde tanımlanmamış bir `{0}` komutuna başvuruyor.", "missing.altCommand": "Menü ögesi, 'commands' bölümünde tanımlanmamış bir `{0}` alternatif komutuna başvuruyor.", - "dupe.command": "Menü ögesi, aynı varsayılan ve alternatif komutlarına başvuruyor", - "nosupport.altCommand": "Üzgünüz, fakat sadece 'editor/title' menüsünün 'navigation' grubu alternatif komutları destekliyor" + "dupe.command": "Menü ögesi, aynı varsayılan ve alternatif komutlarına başvuruyor" } \ No newline at end of file diff --git a/i18n/trk/src/vs/platform/environment/node/argv.i18n.json b/i18n/trk/src/vs/platform/environment/node/argv.i18n.json index a4c4cd296d5..6838345e4f9 100644 --- a/i18n/trk/src/vs/platform/environment/node/argv.i18n.json +++ b/i18n/trk/src/vs/platform/environment/node/argv.i18n.json @@ -8,30 +8,34 @@ "diff": "İki dosyayı birbiriyle karşılaştır.", "add": "Son aktif pencereye klasör(ler) ekle.", "goto": "Konumdaki bir dosyayı belirtilen satır ve sütunda aç.", - "locale": "Kullanılacak yerel dil (örnek: en-US veya zh-TW).", "newWindow": "Yeni bir Code örneğini zorla.", - "performance": "'Geliştirici: Başlangıç Performansı' komutu etkinleştirilmiş olarak başlat.", - "prof-startup": "Başlangıç sırasında CPU profil oluşturucusunu çalıştır", - "inspect-extensions": "Eklentilerde hata ayıklama ve ayrımlamaya izin ver. Bağlantı URI'ı için geliştirici araçlarını kontrol edin.", - "inspect-brk-extensions": "Eklentilerde hata ayıklama ve ayrımlamaya eklenti sunucusu başladıktan hemen sonra duraklatılacak şekilde izin ver. Bağlantı URI'ı için geliştirici araçlarını kontrol edin.", "reuseWindow": "Bir dosya veya klasörü son etkin pencerede açmaya zorlayın.", - "userDataDir": "Kullanıcı verilerinin tutulacağı klasörü belirtir, root olarak çalışırken yararlıdır.", - "log": "Kullanılacak günlüğe yazma düzeyi. Varsayılan değer 'info'dur. İzin verilen değerler 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off' şeklindedir.", - "verbose": "Ayrıntılı çıktı oluştur (--wait anlamına gelir).", "wait": "Geri dönmeden önce dosyaların kapanmasını bekle.", + "locale": "Kullanılacak yerel dil (örnek: en-US veya zh-TW).", + "userDataDir": "Kullanıcı verilerinin tutulacağı klasörü belirtir, root olarak çalışırken yararlıdır.", + "version": "Sürümü göster.", + "help": "Kullanımı göster.", "extensionHomePath": "Eklentilerin kök dizinini belirle.", "listExtensions": "Yüklü eklentileri listele.", "showVersions": "--list-extensions'u kullanırken, yüklü eklentilerin sürümlerini gösterir.", "installExtension": "Bir eklenti yükler.", "uninstallExtension": "Bir eklentiyi kaldırır.", "experimentalApis": "Bir eklenti için önerilen API özelliklerini etkinleştirir.", - "disableExtensions": "Yüklü tüm eklentileri devre dışı bırak.", - "disableGPU": "GPU donanım hızlandırmasını devre dışı bırak.", + "verbose": "Ayrıntılı çıktı oluştur (--wait anlamına gelir).", + "log": "Kullanılacak günlüğe yazma düzeyi. Varsayılan değer 'info'dur. İzin verilen değerler 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off' şeklindedir.", "status": "İşlem kullanımını ve tanılama bilgilerini yazdır.", - "version": "Sürümü göster.", - "help": "Kullanımı göster.", + "performance": "'Geliştirici: Başlangıç Performansı' komutu etkinleştirilmiş olarak başlat.", + "prof-startup": "Başlangıç sırasında CPU profil oluşturucusunu çalıştır", + "disableExtensions": "Yüklü tüm eklentileri devre dışı bırak.", + "inspect-extensions": "Eklentilerde hata ayıklama ve ayrımlamaya izin ver. Bağlantı URI'ı için geliştirici araçlarını kontrol edin.", + "inspect-brk-extensions": "Eklentilerde hata ayıklama ve ayrımlamaya eklenti sunucusu başladıktan hemen sonra duraklatılacak şekilde izin ver. Bağlantı URI'ı için geliştirici araçlarını kontrol edin.", + "disableGPU": "GPU donanım hızlandırmasını devre dışı bırak.", "usage": "Kullanım", "options": "seçenekler", "paths": "yollar", - "optionsUpperCase": "Seçenekler" + "stdinWindows": "Başka bir programın çıktısını okumak için '-' karakterini ekleyin. (ör. 'echo Hello World | {0} -')", + "stdinUnix": "stdin'den okutmak için '-' karakterini ekleyin (ör. 'ps aux | grep code | {0} -')", + "optionsUpperCase": "Seçenekler", + "extensionsManagement": "Eklenti Yönetimi", + "troubleshooting": "Sorun giderme" } \ No newline at end of file diff --git a/i18n/trk/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json b/i18n/trk/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json index 7cf70b2f373..79f9fd64611 100644 --- a/i18n/trk/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json +++ b/i18n/trk/src/vs/platform/extensionManagement/node/extensionManagementService.i18n.json @@ -5,14 +5,15 @@ // Do not edit this file. It is machine generated. { "invalidManifest": "Eklenti geçersiz: package.json bir JSON dosyası değil.", - "restartCodeLocal": "{0} eklentisini yeniden yüklemeden önce lütfen Code'u yeniden başlatın.", + "restartCode": "{0} eklentisini yeniden yüklemeden önce lütfen Code'u yeniden başlatın.", "installingOutdatedExtension": "Bu eklentinin daha yeni bir sürümü zaten yüklü. Bunu, daha eski bir sürümle geçersiz kılmak ister misiniz?", "override": "Geçersiz Kıl", "cancel": "İptal", - "notFoundCompatible": "Yükleme başarısız oldu çünkü, '{0}' eklentisinin uyumlu olduğu VS Code'un '{1}' sürümü bulunamadı.", - "quitCode": "Yükleme başarısız oldu çünkü, eklentinin eski bir örneği hâlâ çalışıyor. Yeniden yüklemeden önce lütfen VS Code'dan çıkın ve tekrar açın.", - "exitCode": "Yükleme başarısız oldu çünkü, eklentinin eski bir örneği hâlâ çalışıyor. Yeniden yüklemeden önce lütfen VS Code'dan çıkın ve tekrar açın.", + "errorInstallingDependencies": "Bağımlılıklar yüklenirken hata oluştu. {0}", + "notFoundCompatible": "'{0}' yüklenemiyor; VS Code '{1}' ile uyumlu mevcut bir sürümü yok.", "notFoundCompatibleDependency": "Yükleme başarısız oldu çünkü, bağımlılığı bulunan '{0}' eklentisinin uyumlu olduğu VS Code'un '{1}' sürümü bulunamadı.", + "quitCode": "Eklenti yüklenemedi. Lütfen yeniden yüklemeden önce VS Code'u sonlandırın ve tekrar başlatın.", + "exitCode": "Eklenti yüklenemedi. Lütfen yeniden yüklemeden önce VS Code'u sonlandırın ve tekrar başlatın.", "uninstallDependeciesConfirmation": "Yalnızca '{0}' eklentisini mi yoksa bağımlılıklarını da kaldırmak ister misiniz?", "uninstallOnly": "Sadece Eklenti", "uninstallAll": "Tümü", diff --git a/i18n/trk/src/vs/platform/integrity/node/integrityServiceImpl.i18n.json b/i18n/trk/src/vs/platform/integrity/node/integrityServiceImpl.i18n.json index 8d0fe384379..a5e03c83816 100644 --- a/i18n/trk/src/vs/platform/integrity/node/integrityServiceImpl.i18n.json +++ b/i18n/trk/src/vs/platform/integrity/node/integrityServiceImpl.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "integrity.ok": "Tamam", - "integrity.dontShowAgain": "Tekrar gösterme", + "integrity.dontShowAgain": "Tekrar Gösterme", "integrity.moreInfo": "Daha fazla bilgi", "integrity.prompt": "{0} kurulumunuz bozuk görünüyor. Lütfen yeniden yükleyin." } \ No newline at end of file diff --git a/i18n/trk/src/vs/platform/message/common/message.i18n.json b/i18n/trk/src/vs/platform/message/common/message.i18n.json index 4f9a44f9383..3d5ccdec1e6 100644 --- a/i18n/trk/src/vs/platform/message/common/message.i18n.json +++ b/i18n/trk/src/vs/platform/message/common/message.i18n.json @@ -6,5 +6,7 @@ { "close": "Kapat", "later": "Daha Sonra", - "cancel": "İptal" + "cancel": "İptal", + "moreFile": "...1 ek dosya gösterilmiyor", + "moreFiles": "...{0} ek dosya gösterilmiyor" } \ No newline at end of file diff --git a/i18n/trk/src/vs/platform/theme/common/colorRegistry.i18n.json b/i18n/trk/src/vs/platform/theme/common/colorRegistry.i18n.json index d6e0e3db142..f57a875d1db 100644 --- a/i18n/trk/src/vs/platform/theme/common/colorRegistry.i18n.json +++ b/i18n/trk/src/vs/platform/theme/common/colorRegistry.i18n.json @@ -63,12 +63,7 @@ "editorWidgetBorder": "Editör araçlarının kenarlık rengi. Renk, araç bir kenarlığı olmasına karar verdiğinde ve renk hiçbir eklenti tarafından geçersiz kılınmadığında kullanılır.", "editorSelectionBackground": "Düzenleyici seçiminin rengi.", "editorSelectionForeground": "Yüksek karşıtlık için seçilen metnin rengi.", - "editorInactiveSelection": "Bir pasif düzenleyicideki seçimin rengi.", - "editorSelectionHighlight": "Seçimle aynı içeriğe sahip bölgelerin rengi.", "editorFindMatch": "Geçerli arama eşleşmesinin rengi.", - "findMatchHighlight": "Diğer arama eşleşmelerinin rengi.", - "findRangeHighlight": "Aramayı sınırlayan aralığı renklendirin.", - "hoverHighlight": "Bağlantı vurgusu gösterilen bir sözcüğün altını vurgulayın.", "hoverBackground": "Düzenleyici bağlantı vurgusunun arka plan rengi.", "hoverBorder": "Düzenleyici bağlantı vurgusunun kenarlık rengi.", "activeLinkForeground": "Aktif bağlantıların rengi.", @@ -76,12 +71,6 @@ "diffEditorRemoved": "Çıkarılan metnin arka plan rengi.", "diffEditorInsertedOutline": "Eklenen metnin ana hat rengi.", "diffEditorRemovedOutline": "Çıkarılan metnin ana hat rengi.", - "mergeCurrentHeaderBackground": "Satır içi birleştirme çakışmalarında geçerli üstbilgi arka planı.", - "mergeCurrentContentBackground": "Satır içi birleştirme çakışmalarında geçerli içerik arka planı.", - "mergeIncomingHeaderBackground": "Satır içi birleştirme çakışmalarında gelen üstbilgi arka planı.", - "mergeIncomingContentBackground": "Satır içi birleştirme çakışmalarında gelen içerik arka planı.", - "mergeCommonHeaderBackground": "Satır içi birleştirme çakışmalarında ortak ata üstbilgisi arka planı.", - "mergeCommonContentBackground": "Satır içi birleştirme çakışmalarında ortak ata içeriği arka planı.", "mergeBorder": "Satır içi birleştirme çakışmalarında üst bilgi ve ayırıcıdaki kenarlık rengi.", "overviewRulerCurrentContentForeground": "Satır içi birleştirme çakışmalarında geçerli genel bakış cetveli ön planı.", "overviewRulerIncomingContentForeground": "Satır içi birleştirme çakışmalarında gelen genel bakış cetveli ön planı.", diff --git a/i18n/trk/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json b/i18n/trk/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json new file mode 100644 index 00000000000..94c6abc9b61 --- /dev/null +++ b/i18n/trk/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "saveParticipants": "Katılımcıların Kaydedilmesi İşlemi Çalıştırılıyor..." +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/api/node/extHostTreeViews.i18n.json b/i18n/trk/src/vs/workbench/api/node/extHostTreeViews.i18n.json index a3dd0ab5f95..737337540bf 100644 --- a/i18n/trk/src/vs/workbench/api/node/extHostTreeViews.i18n.json +++ b/i18n/trk/src/vs/workbench/api/node/extHostTreeViews.i18n.json @@ -4,7 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "treeView.notRegistered": "Kayıtlı '{0}' Id'li ağaç görünümü yok.", - "treeItem.notFound": "'{0}' Id'li ağaç ögesi yok.", - "treeView.duplicateElement": "{0} ögesi zaten kayıtlı" + "treeView.notRegistered": "Kayıtlı '{0}' Id'li ağaç görünümü yok." } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json b/i18n/trk/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json index b5c1cbc783e..1658e6a34d6 100644 --- a/i18n/trk/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/actions/toggleSidebarPosition.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "toggleLocation": "Kenar Çubuğu Konumunu Değiştir", "view": "Görüntüle" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/actions/workspaceActions.i18n.json b/i18n/trk/src/vs/workbench/browser/actions/workspaceActions.i18n.json index a8ba8956df1..43558a9d00d 100644 --- a/i18n/trk/src/vs/workbench/browser/actions/workspaceActions.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/actions/workspaceActions.i18n.json @@ -7,17 +7,11 @@ "openFile": "Dosya Aç...", "openFolder": "Klasör Aç...", "openFileFolder": "Aç...", - "addFolderToWorkspace": "Çalışma Alanına Klasör Ekle...", - "add": "&&Ekle", - "addFolderToWorkspaceTitle": "Çalışma Alanına Klasör Ekle", "globalRemoveFolderFromWorkspace": "Çalışma Alanından Klasör Kaldır...", - "removeFolderFromWorkspace": "Çalışma Alanından Klasör Kaldır", - "openFolderSettings": "Klasör Ayarlarını Aç", "saveWorkspaceAsAction": "Çalışma Alanını Farklı Kaydet...", "save": "&&Kaydet", "saveWorkspace": "Çalışma Alanını Kaydet", "openWorkspaceAction": "Çalışma Alanı Aç...", "openWorkspaceConfigFile": "Çalışma Alanı Yapılandırma Dosyasını Aç", - "openFolderAsWorkspaceInNewWindow": "Klasörü Yeni Pencerede Çalışma Alanı Olarak Aç", - "workspaceFolderPickerPlaceholder": "Çalışma alanı klasörü seçin" + "openFolderAsWorkspaceInNewWindow": "Klasörü Yeni Pencerede Çalışma Alanı Olarak Aç" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/actions/workspaceCommands.i18n.json b/i18n/trk/src/vs/workbench/browser/actions/workspaceCommands.i18n.json new file mode 100644 index 00000000000..1b71f510ec6 --- /dev/null +++ b/i18n/trk/src/vs/workbench/browser/actions/workspaceCommands.i18n.json @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "addFolderToWorkspace": "Çalışma Alanına Klasör Ekle...", + "add": "&&Ekle", + "addFolderToWorkspaceTitle": "Çalışma Alanına Klasör Ekle", + "workspaceFolderPickerPlaceholder": "Çalışma alanı klasörü seçin" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json b/i18n/trk/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json index 5ff77e04882..4ee34bebb2d 100644 --- a/i18n/trk/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/parts/editor/editor.contribution.i18n.json @@ -13,5 +13,17 @@ "groupThreePicker": "Üçüncü Gruptaki Düzenleyicileri Göster", "allEditorsPicker": "Açık Tüm Düzenleyicileri Göster", "view": "Görüntüle", - "file": "Dosya" + "file": "Dosya", + "close": "Kapat", + "closeOthers": "Diğerlerini Kapat", + "closeRight": "Sağdakileri Kapat", + "closeAllUnmodified": "Değiştirilmeyenleri Kapat", + "closeAll": "Tümünü Kapat", + "keepOpen": "Açık Tut", + "showOpenedEditors": "Açık Düzenleyicileri Göster", + "keepEditor": "Düzenleyiciyi Tut", + "closeEditorsInGroup": "Gruptaki Tüm Düzenleyicileri Kapat", + "closeUnmodifiedEditors": "Gruptaki Değiştirilmemiş Düzenleyicileri Kapat", + "closeOtherEditors": "Diğer Düzenleyicileri Kapat", + "closeRightEditors": "Düzenleyicinin Sağındakileri Kapat" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/parts/editor/editorActions.i18n.json b/i18n/trk/src/vs/workbench/browser/parts/editor/editorActions.i18n.json index b32e97503d9..3264a4ed56e 100644 --- a/i18n/trk/src/vs/workbench/browser/parts/editor/editorActions.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/parts/editor/editorActions.i18n.json @@ -17,18 +17,13 @@ "closeEditor": "Düzenleyiciyi Kapat", "revertAndCloseActiveEditor": "Geri Al ve Düzenleyiciyi Kapat", "closeEditorsToTheLeft": "Düzenleyicinin Solundakileri Kapat", - "closeEditorsToTheRight": "Düzenleyicinin Sağındakileri Kapat", "closeAllEditors": "Tüm Düzenleyicileri Kapat", - "closeUnmodifiedEditors": "Gruptaki Değiştirilmemiş Düzenleyicileri Kapat", "closeEditorsInOtherGroups": "Diğer Gruplardaki Tüm Düzenleyicileri Kapat", - "closeOtherEditorsInGroup": "Diğer Düzenleyicileri Kapat", - "closeEditorsInGroup": "Gruptaki Tüm Düzenleyicileri Kapat", "moveActiveGroupLeft": "Düzenleyici Grubunu Sola Taşı", "moveActiveGroupRight": "Düzenleyici Grubunu Sağa Taşı", "minimizeOtherEditorGroups": "Diğer Düzenleyici Gruplarını Küçült", "evenEditorGroups": "Düzenleyici Grup Genişliklerini Eşitle", "maximizeEditor": "Düzenleyici Grubunu Olabildiğince Genişlet ve Kenar Çubuğunu Gizle", - "keepEditor": "Düzenleyiciyi Tut", "openNextEditor": "Sonraki Düzenleyiciyi Aç", "openPreviousEditor": "Önceki Düzenleyiciyi Aç", "nextEditorInGroup": "Gruptaki Sonraki Düzenleyiciyi Aç", @@ -42,7 +37,6 @@ "showEditorsInFirstGroup": "İlk Gruptaki Düzenleyicileri Göster", "showEditorsInSecondGroup": "İkinci Gruptaki Düzenleyicileri Göster", "showEditorsInThirdGroup": "Üçüncü Gruptaki Düzenleyicileri Göster", - "showEditorsInGroup": "Gruptaki Düzenleyicileri Göster", "showAllEditors": "Tüm Düzenleyicileri Göster", "openPreviousRecentlyUsedEditorInGroup": "Gruptaki Son Kullanılan Önceki Düzenleyiciyi Aç", "openNextRecentlyUsedEditorInGroup": "Gruptaki Son Kullanılan Sonraki Düzenleyiciyi Aç", @@ -54,5 +48,8 @@ "moveEditorLeft": "Düzenleyiciyi Sola Taşı", "moveEditorRight": "Düzenleyiciyi Sağa Taşı", "moveEditorToPreviousGroup": "Düzenleyiciyi Önceki Gruba Taşı", - "moveEditorToNextGroup": "Düzenleyiciyi Sonraki Gruba Taşı" + "moveEditorToNextGroup": "Düzenleyiciyi Sonraki Gruba Taşı", + "moveEditorToFirstGroup": "Düzenleyiciyi İlk Gruba Taşı", + "moveEditorToSecondGroup": "Düzenleyiciyi İkinci Gruba Taşı", + "moveEditorToThirdGroup": "Düzenleyiciyi Üçüncü Gruba Taşı" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json b/i18n/trk/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json index 4eac419d706..0f560d95c00 100644 --- a/i18n/trk/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/parts/editor/editorCommands.i18n.json @@ -6,7 +6,5 @@ { "editorCommand.activeEditorMove.description": "Aktif düzenleyiciyi sekmeler veya gruplar halinde taşıyın", "editorCommand.activeEditorMove.arg.name": "Aktif düzenleyici taşıma argümanı", - "editorCommand.activeEditorMove.arg.description": "Argüman Özellikleri:\n\t* 'to': Nereye taşınacağını belirten dize değeri.\n\t* 'by': Kaç birim taşınacağını belirten dize değeri. Sekme veya gruba göre.\n\t* 'value': Kaç tane pozisyonun taşınacağını belirten sayı değeri.", - "commandDeprecated": "**{0}** komutu kaldırıldı. Onun yerine **{1}** komutunu kullanabilirsiniz", - "openKeybindings": "Klavye Kısayollarını Yapılandır" + "editorCommand.activeEditorMove.arg.description": "Argüman Özellikleri:\n\t* 'to': Nereye taşınacağını belirten dize değeri.\n\t* 'by': Kaç birim taşınacağını belirten dize değeri. Sekme veya gruba göre.\n\t* 'value': Kaç tane pozisyonun taşınacağını belirten sayı değeri." } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json b/i18n/trk/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json index 9fb7a026e34..e73c3315e6d 100644 --- a/i18n/trk/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/parts/editor/textDiffEditor.i18n.json @@ -11,6 +11,5 @@ "editableEditorAriaLabel": "Metin dosyası karşılaştırma düzenleyicisi.", "navigate.next.label": "Sonraki Değişiklik", "navigate.prev.label": "Önceki Değişiklik", - "inlineDiffLabel": "Satır İçi Görünüme Geç", - "sideBySideDiffLabel": "Yan Yana Görünüme Geç" + "toggleIgnoreTrimWhitespace.label": "Kırpma Boşluğunu Yoksay" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/parts/editor/titleControl.i18n.json b/i18n/trk/src/vs/workbench/browser/parts/editor/titleControl.i18n.json index 18e318decfd..d62c167e7b6 100644 --- a/i18n/trk/src/vs/workbench/browser/parts/editor/titleControl.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/parts/editor/titleControl.i18n.json @@ -5,11 +5,5 @@ // Do not edit this file. It is machine generated. { "close": "Kapat", - "closeOthers": "Diğerlerini Kapat", - "closeRight": "Sağdakileri Kapat", - "closeAll": "Tümünü Kapat", - "closeAllUnmodified": "Değiştirilmeyenleri Kapat", - "keepOpen": "Açık Tut", - "showOpenedEditors": "Açık Düzenleyicileri Göster", "araLabelEditorActions": "Düzenleyici eylemleri" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json b/i18n/trk/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json index f143e04de94..1b5f24a5398 100644 --- a/i18n/trk/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/parts/titlebar/titlebarPart.i18n.json @@ -5,5 +5,7 @@ // Do not edit this file. It is machine generated. { "patchedWindowTitle": "[Desteklenmiyor]", + "userIsAdmin": "[Yönetici]", + "userIsSudo": "[Süper Kullanıcı]", "devExtensionWindowTitlePrefix": "[Eklenti Geliştirme Sunucusu]" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json b/i18n/trk/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json index d61355ad2f9..8b6ad71cd4e 100644 --- a/i18n/trk/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json +++ b/i18n/trk/src/vs/workbench/browser/parts/views/viewsViewlet.i18n.json @@ -3,6 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. -{ - "hideView": "Kenar Çubuğunda Gizle" -} \ No newline at end of file +{} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/common/theme.i18n.json b/i18n/trk/src/vs/workbench/common/theme.i18n.json index 9eb9ad116a5..02c2f8fa5d6 100644 --- a/i18n/trk/src/vs/workbench/common/theme.i18n.json +++ b/i18n/trk/src/vs/workbench/common/theme.i18n.json @@ -6,9 +6,13 @@ { "tabActiveBackground": "Aktif sekme arka plan rengi. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", "tabInactiveBackground": "Pasif sekme arka plan rengi. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", + "tabHoverBackground": "Fareyle üzerine gelindiğinde sekme arka plan rengi. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", + "tabUnfocusedHoverBackground": "Fareyle üzerine gelindiğinde odaklanılmamış bir gruptaki aktif sekmenin arka plan rengi. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", "tabBorder": "Sekmeleri birbirinden ayıran kenarlığın rengi. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", "tabActiveBorder": "Aktif sekmeleri vurgulayacak kenarlık. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", "tabActiveUnfocusedBorder": "Odaklanılmamış bir gruptaki aktif sekmeleri vurgulayacak kenarlık. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", + "tabHoverBorder": "Fareyle üzerine gelindiğinde sekmeleri vurgulayacak kenarlık. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", + "tabUnfocusedHoverBorder": "Fareyle üzerine gelindiğinde odaklanılmamış bir gruptaki sekmeleri vurgulayacak kenarlık. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", "tabActiveForeground": "Aktif bir gruptaki aktif sekmenin ön plan rengi. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", "tabInactiveForeground": "Aktif bir gruptaki pasif sekmenin ön plan rengi. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", "tabUnfocusedActiveForeground": "Odaklanılmamış bir gruptaki aktif sekmenin ön plan rengi. Sekmeler, düzenleyici alanındaki düzenleyicilerin kapsayıcılarıdır. Bir düzenleyici grubunda birden fazla sekme açılabilir. Birden fazla düzenleyici grupları var olabilir.", @@ -16,7 +20,7 @@ "editorGroupBackground": "Bir düzenleyici grubunun arka plan rengi. Düzenleyici grupları, düzenleyicilerin kapsayıcılarıdır. Arka plan rengi, düzenleyici grubunu sürüklerken gösterilir.", "tabsContainerBackground": "Sekmeler etkinleştirilmiş durumdayken, düzenleyici grubu başlık üstbilgisi arka plan rengi. Düzenleyici grupları, düzenleyicilerin kapsayıcılarıdır. ", "tabsContainerBorder": "Sekmeler etkinleştirilmiş durumdayken, düzenleyici grubu başlık üstbilgisi kenarlık rengi. Düzenleyici grupları, düzenleyicilerin kapsayıcılarıdır. ", - "editorGroupHeaderBackground": "Sekmeler devre dışı iken, düzenleyici grubu başlık üstbilgisi arka plan rengi. Düzenleyici grupları, düzenleyicilerin kapsayıcılarıdır. ", + "editorGroupHeaderBackground": "Sekmeler devre dışı iken, düzenleyici grubu başlık üstbilgisi arka plan rengi (`\"workbench.editor.showTabs\": false`). Düzenleyici grupları, düzenleyicilerin kapsayıcılarıdır. ", "editorGroupBorder": "Birden fazla düzenleyici grubunu birbirinden ayıracak renk. Düzenleyici grupları, düzenleyicilerin kapsayıcılarıdır. ", "editorDragAndDropBackground": "Düzenleyici grubunu sürüklerken gösterilecek arka plan rengi. Düzenleyici içeriğinin hâlâ iyi görünmeye devam edebilmesi için renk şeffaf olmalıdır.", "panelBackground": "Panel arka plan rengi. Paneller düzenleyici alanının altında gösterilir ve çıktı ve entegre terminal gibi görünümler içerir.", @@ -33,8 +37,8 @@ "statusBarNoFolderBorder": "Hiçbir klasör açık olmadığında durum çubuğunu kenar çubuğundan ve düzenleyiciden ayıran kenarlık rengi. Durum çubuğu, pencerenin alt kısmında gösterilir.", "statusBarItemActiveBackground": "Durum çubuğu ögesi tıklanırken arka plan rengi. Durum çubuğu, pencerenin alt kısmında gösterilir.", "statusBarItemHoverBackground": "Durum çubuğu ögesinin mouse ile üzerine gelindiğindeki arka plan rengi. Durum çubuğu, pencerenin alt kısmında gösterilir.", - "statusBarProminentItemBackground": "Durum çubuğu belirgin ögelerinin arka plan rengi. Belirgin ögeler, önemi belirtmek için diğer durum çubuğu girdilerinden öne çıkarılır. Durum çubuğu, pencerenin alt kısmında gösterilir.", - "statusBarProminentItemHoverBackground": "Durum çubuğu belirgin ögelerinin mouse ile üzerine gelindiğindeki arka plan rengi. Belirgin ögeler, önemi belirtmek için diğer durum çubuğu girdilerinden öne çıkarılır. Durum çubuğu, pencerenin alt kısmında gösterilir.", + "statusBarProminentItemBackground": "Durum çubuğu belirgin ögelerinin arka plan rengi. Belirgin ögeler, önemi belirtmek için diğer durum çubuğu girdilerinden öne çıkarılır. Bir örnek görmek için komut paletinden `Tab Tuşu İle Odak Değiştirmeyi Aç/Kapat` ile modu değiştirin. Durum çubuğu, pencerenin alt kısmında gösterilir.", + "statusBarProminentItemHoverBackground": "Fareyle üzerine gelindiğinde durum çubuğu belirgin ögelerinin arka plan rengi. Belirgin ögeler, önemi belirtmek için diğer durum çubuğu girdilerinden öne çıkarılır. Bir örnek görmek için komut paletinden `Tab Tuşu İle Odak Değiştirmeyi Aç/Kapat` ile modu değiştirin. Durum çubuğu, pencerenin alt kısmında gösterilir.", "activityBarBackground": "Etkinlik çubuğu arka plan rengi. Etkinlik çubuğu, en sol veya en sağda gösterilir ve kenar çubuğunun görünümleriyle yer değiştirmeye izin verir.", "activityBarForeground": "Etkinlik çubuğu ön plan rengi (ör. simgeler için kullanılır). Etkinlik çubuğu, en sol veya en sağda gösterilir ve kenar çubuğunun görünümleriyle yer değiştirmeye izin verir.", "activityBarBorder": "Etkinlik çubuğunu kenar çubuğundan ayıran kenarlığın rengi. Etkinlik çubuğu, en sol veya en sağda gösterilir ve kenar çubuğunun görünümleriyle yer değiştirmeye izin verir.", diff --git a/i18n/trk/src/vs/workbench/common/views.i18n.json b/i18n/trk/src/vs/workbench/common/views.i18n.json new file mode 100644 index 00000000000..d412455fd99 --- /dev/null +++ b/i18n/trk/src/vs/workbench/common/views.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "duplicateId": "`{0}` kimliğine sahip bir görünüm `{1}` konumunda zaten kayıtlı" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/electron-browser/actions.i18n.json b/i18n/trk/src/vs/workbench/electron-browser/actions.i18n.json index e3e29379b77..5cb1f86f054 100644 --- a/i18n/trk/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/trk/src/vs/workbench/electron-browser/actions.i18n.json @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "closeActiveEditor": "Düzenleyiciyi Kapat", "closeWindow": "Pencereyi Kapat", "closeWorkspace": "Çalışma Alanını Kapat", "noWorkspaceOpened": "Şu an bu örnekte kapatmak için açık bir çalışma alanı bulunmuyor.", @@ -52,21 +51,5 @@ "displayLanguage": "VSCode'un görüntüleme dilini tanımlar.", "doc": "Desteklenen dillerin listesi için göz atın: {0}", "restart": "Değeri değiştirirseniz VSCode'u yeniden başlatmanız gerekir.", - "fail.createSettings": " '{0}' oluşturulamadı ({1}).", - "openLogsFolder": "Günlük Klasörünü Aç", - "showLogs": "Günlükleri Göster...", - "mainProcess": "Ana", - "sharedProcess": "Paylaşılan", - "rendererProcess": "Render Alan", - "extensionHost": "Eklenti Sunucusu", - "selectProcess": "İşlem seçin", - "setLogLevel": "Günlük Düzeyini Ayarla", - "trace": "İzle", - "debug": "Hata Ayıklama", - "info": "Bilgi", - "warn": "Uyarı", - "err": "Hata", - "critical": "Kritik", - "off": "Kapalı", - "selectLogLevel": "Günlük düzeyini seçin" + "fail.createSettings": " '{0}' oluşturulamadı ({1})." } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/electron-browser/main.contribution.i18n.json b/i18n/trk/src/vs/workbench/electron-browser/main.contribution.i18n.json index 8aacc6f4f6e..b66debcf9ce 100644 --- a/i18n/trk/src/vs/workbench/electron-browser/main.contribution.i18n.json +++ b/i18n/trk/src/vs/workbench/electron-browser/main.contribution.i18n.json @@ -7,8 +7,9 @@ "view": "Görüntüle", "help": "Yardım", "file": "Dosya", - "developer": "Geliştirici", "workspaces": "Çalışma Alanları", + "developer": "Geliştirici", + "workbenchConfigurationTitle": "Çalışma Ekranı", "showEditorTabs": "Açık düzenleyicilerin sekmelerde gösterilip gösterilmeyeceğini denetler", "workbench.editor.labelFormat.default": "Dosyanın adını göster. Sekmeler etkinleştirilmiş ve bir grupta iki dosya aynı ada sahiplerse, her dosyanın yolundaki ayırt edici bölümler eklenir. Sekmeler devre dışı ve düzenleyici aktifse, çalışma alanı klasörüne göreli yol gösterilir.", "workbench.editor.labelFormat.short": "Dosyanın adını ve ardından dizin adını göster.", @@ -20,23 +21,23 @@ "showIcons": "Açık düzenleyicilerin bir simge ile gösterilip gösterilmemelerini denetler. Bu, bir simge temasının etkinleştirilmesini de gerektirir.", "enablePreview": "Açık düzenleyicilerin önizleme olarak gösterilip gösterilmeyeceğini denetler. Önizleme düzenleyicileri kalıcı olarak açılana kadar (ör. çift tıklama veya düzenleme ile) tekrar kullanılırlar ve italik yazı tipiyle gösterilirler.", "enablePreviewFromQuickOpen": "Hızlı Aç'taki açık düzenleyicilerin önizleme olarak gösterilip gösterilmeyeceğini denetler. Önizleme düzenleyicileri kalıcı olarak açılana kadar (ör. çift tıklama veya düzenleme ile) tekrar kullanılırlar.", + "closeOnFileDelete": "Düzenleyicinin gösterdiği bir dosyanın, başka bir işlem tarafından silinmesi veya yeniden adlandırması durumunda dosyayı otomatik olarak kapatıp kapatmamasını denetler. Bunu devre dışı bırakmak, böyle bir durumda düzenleyicinin kaydedilmemiş değişiklikler içeriyor durumunda kalmasını sağlar. Uygulama içinde silmek, düzenleyiciyi her zaman kapatır ve kaydedilmemiş değişiklikler içeren dosyalar, verilerinizin korunması için otomatik olarak kapatılmaz.", "editorOpenPositioning": "Düzenleyicilerin nerede açılacağını denetler. Düzenleyicileri, şu an geçerli olanın soluna veya sağına açmak için 'left' veya 'right' seçeneklerinden birini seçin. Düzenleyicileri, geçerli olandan bağımsız bir şekilde açmak için 'first' veya 'last' seçeneklerinden birini seçin.", "revealIfOpen": "Düzenleyicinin görünen gruplardan herhangi birinde açıldıysa ortaya çıkarılıp çıkarılmayacağını denetler. Devre dışı bırakılırsa; bir düzenleyici, o an aktif düzenleyici grubunda açılmayı tercih edecektir. Etkinleştirilirse; o an aktif düzenleyici grubunda tekrar açılmak yerine, zaten açık olan düzenleyici ortaya çıkarılacaktır. Bu ayarın yok sayılacağı bazı durumların olduğunu unutmayın, ör. bir düzenleyiciyi, belirli bir grupta veya o an aktif grubun yanına açmaya zorladığınızda. ", + "swipeToNavigate": "Yatay olarak üç parmakla kaydırma ile açık dosyalar arasında gezinin.", "commandHistory": "Komut paleti geçmişinde tutulacak son kullanılan komutların sayısını denetler. Komut geçmişini kapatmak için 0 olarak ayarlayın.", "preserveInput": "Komut paletine son girilen girdinin, bir sonraki açılışta tekrar yer alıp almayacağını denetler.", "closeOnFocusLost": "Hızlı Aç'ın odağını kaybettiğinde otomatik olarak kapanıp kapanmayacağını denetler.", "openDefaultSettings": "Ayarları açmanın ayrıca tüm varsayılan ayarları gösteren bir düzenleyici açıp açmayacağını denetler.", "sideBarLocation": "Kenar çubuğunun konumunu denetler. Çalışma ekranının ya solunda ya da sağında gösterilebilir.", + "panelDefaultLocation": "Panelin varsayılan konumunu denetler. Çalışma ekranının ya altında ya da sağında gösterilebilir.", "statusBarVisibility": "Çalışma ekranının altındaki durum çubuğunun görünürlüğünü denetler.", "activityBarVisibility": "Çalışma ekranındaki etkinlik çubuğunun görünürlüğünü denetler.", - "closeOnFileDelete": "Düzenleyicinin gösterdiği bir dosyanın, başka bir işlem tarafından silinmesi veya yeniden adlandırması durumunda dosyayı otomatik olarak kapatıp kapatmamasını denetler. Bunu devre dışı bırakmak, böyle bir durumda düzenleyicinin kaydedilmemiş değişiklikler içeriyor durumunda kalmasını sağlar. Uygulama içinde silmek, düzenleyiciyi her zaman kapatır ve kaydedilmemiş değişiklikler içeren dosyalar, verilerinizin korunması için otomatik olarak kapatılmaz.", - "enableNaturalLanguageSettingsSearch": "Ayarlar için doğal dil arama modunun etkinleştirilip etkinleştirilmeyeceğini denetler.", "fontAliasing": "Çalışma ekranındaki yazı tipi yumuşatma yöntemini denetler.\n- default: Alt-piksel yazı tipi yumuşatma. Bu, çoğu retina olmayan ekranda en keskin metni verir\n- antialiased: Alt-pikselin tersine, pikselin seviyesine göre yazı tipini yumuşat. Yazı tipinin genel olarak daha açık görünmesini sağlayabilir\n- none: Yazı tipi yumuşatmayı devre dışı bırakır. Metin pürüzlü keskin kenarlarla gösterilir.", "workbench.fontAliasing.default": "Alt-piksel yazı tipi yumuşatma. Bu, çoğu retina olmayan ekranda en keskin metni verir.", "workbench.fontAliasing.antialiased": "Alt-pikselin tersine, pikselin seviyesine göre yazı tipini yumuşat. Yazı tipinin genel olarak daha açık görünmesini sağlayabilir.", "workbench.fontAliasing.none": "Yazı tipi yumuşatmayı devre dışı bırakır. Metin pürüzlü keskin kenarlarla gösterilir.", - "swipeToNavigate": "Yatay olarak üç parmakla kaydırma ile açık dosyalar arasında gezinin.", - "workbenchConfigurationTitle": "Çalışma Ekranı", + "enableNaturalLanguageSettingsSearch": "Ayarlar için doğal dil arama modunun etkinleştirilip etkinleştirilmeyeceğini denetler.", "windowConfigurationTitle": "Pencere", "window.openFilesInNewWindow.on": "Dosyalar yeni bir pencerede açılacak", "window.openFilesInNewWindow.off": "Dosyalar, dosyaların klasörünün olduğu pencerede veya son aktif pencerede açılacak", diff --git a/i18n/trk/src/vs/workbench/electron-browser/window.i18n.json b/i18n/trk/src/vs/workbench/electron-browser/window.i18n.json index c583af8e7cc..394ee06ccfd 100644 --- a/i18n/trk/src/vs/workbench/electron-browser/window.i18n.json +++ b/i18n/trk/src/vs/workbench/electron-browser/window.i18n.json @@ -9,5 +9,6 @@ "cut": "Kes", "copy": "Kopyala", "paste": "Yapıştır", - "selectAll": "Tümünü Seç" + "selectAll": "Tümünü Seç", + "runningAsRoot": "[0] uygulamasını root olarak çalıştırmanız önerilmez." } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.i18n.json b/i18n/trk/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.i18n.json index 01e4868daa1..793bdc84f28 100644 --- a/i18n/trk/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "wordWrapMigration.ok": "Tamam", - "wordWrapMigration.dontShowAgain": "Tekrar gösterme", + "wordWrapMigration.dontShowAgain": "Tekrar Gösterme", "wordWrapMigration.openSettings": "Ayarları Aç", "wordWrapMigration.prompt": "`editor.wrappingColumn` ayarı, `editor.wordWrap` yüzünden kullanım dışıdır." } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json b/i18n/trk/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json index b5f38fd9078..d27710092c4 100644 --- a/i18n/trk/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/debug/electron-browser/terminalSupport.i18n.json @@ -4,6 +4,5 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "debug.terminal.title": "hata ayıklanan", - "debug.terminal.not.available.error": "Entegre terminal mevcut değil" + "debug.terminal.title": "hata ayıklanan" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json index 010a09cd0cb..ca0fb5ce188 100644 --- a/i18n/trk/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/execution/electron-browser/execution.contribution.i18n.json @@ -12,6 +12,5 @@ "globalConsoleActionWin": "Yeni Komut İstemi Aç", "globalConsoleActionMacLinux": "Yeni Terminal Aç", "scopedConsoleActionWin": "Komut İsteminde Aç", - "scopedConsoleActionMacLinux": "Terminalde Aç", - "openFolderInIntegratedTerminal": "Terminalde Aç" + "scopedConsoleActionMacLinux": "Terminalde Aç" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json b/i18n/trk/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json index 63820e9cd1c..53e00fca247 100644 --- a/i18n/trk/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.i18n.json @@ -4,15 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "fileBasedRecommendation": "Bu eklenti yakınlarda açtığınız dosyalara dayanarak tavsiye ediliyor.", + "neverShowAgain": "Tekrar gösterme", + "close": "Kapat", "workspaceRecommendation": "Bu eklenti geçerli çalışma alanı kullanıcıları tarafından tavsiye ediliyor.", + "fileBasedRecommendation": "Bu eklenti yakınlarda açtığınız dosyalara dayanarak tavsiye ediliyor.", "exeBasedRecommendation": "Bu eklenti, sizde {0} kurulu olduğu için tavsiye ediliyor.", "reallyRecommended2": "'{0}' eklentisi bu dosya türü için tavsiye edilir.", "reallyRecommendedExtensionPack": "'{0}' eklenti paketi bu dosya türü için tavsiye edilir.", "showRecommendations": "Tavsiyeleri Göster", "install": "Yükle", - "neverShowAgain": "Tekrar gösterme", - "close": "Kapat", "workspaceRecommended": "Bu çalışma alanı bazı eklentileri tavsiye ediyor.", "installAll": "Tümünü Yükle", "ignoreExtensionRecommendations": "Tüm eklenti tavsiyelerini yok saymak istiyor musunuz?", diff --git a/i18n/trk/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json new file mode 100644 index 00000000000..0b6bb4e4396 --- /dev/null +++ b/i18n/trk/src/vs/workbench/parts/feedback/electron-browser/feedback.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "workbenchConfigurationTitle": "Çalışma Ekranı" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json b/i18n/trk/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/trk/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json index 09b50f5c819..101a33d0a50 100644 --- a/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.i18n.json @@ -7,5 +7,26 @@ "filesCategory": "Dosya", "revealInSideBar": "Kenar Çubuğunda Ortaya Çıkar", "acceptLocalChanges": "Değişikliklerinizi kullanın ve diskteki içeriklerin üzerine yazın", - "revertLocalChanges": "Değişikliklerinizi göz ardı edin ve diskteki içeriğe geri dönün" + "revertLocalChanges": "Değişikliklerinizi göz ardı edin ve diskteki içeriğe geri dönün", + "copyPathOfActive": "Aktif Dosyanın Yolunu Kopyala", + "saveAllInGroup": "Gruptaki Tümünü Kadet", + "saveFiles": "Tüm Dosyaları Kaydet", + "revert": "Dosyayı Geri Döndür", + "compareActiveWithSaved": "Aktif Dosyayı Kaydedilenle Karşılaştır", + "closeEditor": "Düzenleyiciyi Kapat", + "view": "Görüntüle", + "openToSide": "Yana Aç", + "revealInWindows": "Gezginde Ortaya Çıkar", + "revealInMac": "Finder'da Ortaya Çıkar", + "openContainer": "İçeren Klasörü Aç", + "copyPath": "Yolu Kopyala", + "saveAll": "Tümünü Kaydet", + "compareWithSaved": "Kaydedilenle Karşılaştır", + "compareWithSelected": "Seçilenle Karşılaştır", + "compareSource": "Karşılaştırma İçin Seç", + "close": "Kapat", + "closeOthers": "Diğerlerini Kapat", + "closeUnmodified": "Değiştirilmeyenleri Kapat", + "closeAll": "Tümünü Kapat", + "deleteFile": "Kalıcı Olarak Sil" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json b/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json index 2be3f4a5668..e326729b004 100644 --- a/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileActions.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "retry": "Yeniden Dene", - "rename": "Yeniden Adlandır", "newFile": "Yeni Dosya", "newFolder": "Yeni Klasör", + "rename": "Yeniden Adlandır", + "delete": "Sil", + "copyFile": "Kopyala", + "pasteFile": "Yapıştır", + "retry": "Yeniden Dene", "openFolderFirst": "İçinde dosyalar veya klasörler oluşturmak için ilk olarak bir klasör açın.", "newUntitledFile": "Yeni İsimsiz Dosya", "createNewFile": "Yeni Dosya", @@ -28,26 +31,16 @@ "confirmDeleteMessageFile": "'{0}' öğesini kalıcı olarak silmek istediğinizden emin misiniz?", "irreversible": "Bu eylem geri döndürülemez!", "permDelete": "Kalıcı Olarak Sil", - "delete": "Sil", "importFiles": "Dosya İçe Aktar", "confirmOverwrite": "Hedef klasörde aynı ada sahip bir dosya veya klasör zaten var. Değiştirmek istiyor musunuz?", "replaceButtonLabel": "&&Değiştir", - "copyFile": "Kopyala", - "pasteFile": "Yapıştır", + "fileDeleted": "Dosya bu arada silindi veya taşındı", + "fileIsAncestor": "Hedef klasör, kopyalanacak klasörün içinde yer alıyor", "duplicateFile": "Çoğalt", - "openToSide": "Yana Aç", - "compareSource": "Karşılaştırma İçin Seç", "globalCompareFile": "Aktif Dosyayı Karşılaştır...", "openFileToCompare": "Bir başka dosya ile karşılaştırmak için ilk olarak bir dosya açın.", - "compareWith": "'{0}' dosyasını '{1}' ile karşılaştır", - "compareFiles": "Dosyaları Karşılaştır", "refresh": "Yenile", - "save": "Kaydet", - "saveAs": "Farklı Kaydet...", - "saveAll": "Tümünü Kaydet", "saveAllInGroup": "Gruptaki Tümünü Kadet", - "saveFiles": "Tüm Dosyaları Kaydet", - "revert": "Dosyayı Geri Döndür", "focusOpenEditors": "Açık Düzenleyiciler Görünümüne Odakla", "focusFilesExplorer": "Dosya Gezginine Odakla", "showInExplorer": "Aktif Dosyayı Kenar Çubuğunda Ortaya Çıkar", @@ -56,20 +49,11 @@ "refreshExplorer": "Gezgini Yenile", "openFileInNewWindow": "Aktif Dosyayı Yeni Pencerede Aç", "openFileToShowInNewWindow": "Yeni pencerede açmak için ilk olarak bir dosya açın", - "revealInWindows": "Gezginde Ortaya Çıkar", - "revealInMac": "Finder'da Ortaya Çıkar", - "openContainer": "İçeren Klasörü Aç", - "revealActiveFileInWindows": "Aktif Dosyayı Windows Gezgini'nde Ortaya Çıkar", - "revealActiveFileInMac": "Aktif Dosyayı Finder'da Ortaya Çıkar", - "openActiveFileContainer": "Aktif Dosyayı İçeren Klasörü Aç", "copyPath": "Yolu Kopyala", - "copyPathOfActive": "Aktif Dosyanın Yolunu Kopyala", "emptyFileNameError": "Bir dosya veya klasör adı sağlanması gerekiyor.", "fileNameExistsError": "Bu konumda bir **{0}** dosyası veya klasörü zaten mevcut. Lütfen başka bir ad seçin.", "invalidFileNameError": "**{0}** adı, bir dosya veya klasör adı olarak geçerli değildir. Lütfen başka bir ad seçin.", "filePathTooLongError": "**{0}** adı çok uzun bir yol ile sonuçlanıyor. Lütfen daha kısa bir ad seçin.", - "compareWithSaved": "Aktif Dosyayı Kaydedilenle Karşılaştır", - "modifiedLabel": "{0} (diskte) ↔ {1}", "compareWithClipboard": "Aktif Dosyayı Panodakiyle Karşılaştır", "clipboardComparisonLabel": "Pano ↔ {0}" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json b/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json index 699305824d3..c0c7d53c884 100644 --- a/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/files/electron-browser/fileCommands.i18n.json @@ -4,6 +4,15 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openFileToCopy": "Yolunu kopyalamak için ilk olarak bir dosya açın", - "openFileToReveal": "Ortaya çıkarmak için ilk olarak bir dosya açın" + "revealInWindows": "Gezginde Ortaya Çıkar", + "revealInMac": "Finder'da Ortaya Çıkar", + "openContainer": "İçeren Klasörü Aç", + "saveAs": "Farklı Kaydet...", + "save": "Kaydet", + "saveAll": "Tümünü Kaydet", + "removeFolderFromWorkspace": "Çalışma Alanından Klasör Kaldır", + "genericRevertError": "'{0}' geri döndürülemedi: {1}", + "modifiedLabel": "{0} (diskte) ↔ {1}", + "openFileToReveal": "Ortaya çıkarmak için ilk olarak bir dosya açın", + "openFileToCopy": "Yolunu kopyalamak için ilk olarak bir dosya açın" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json index 4948cddf5c4..642be842a15 100644 --- a/i18n/trk/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/files/electron-browser/files.contribution.i18n.json @@ -36,8 +36,6 @@ "editorConfigurationTitle": "Düzenleyici", "formatOnSave": "Dosyayı kaydederken biçimlendir. Bir biçimlendirici mevcut olmalıdır, dosya otomatik olarak kaydedilmemelidir, ve düzenleyici kapanmıyor olmalıdır.", "explorerConfigurationTitle": "Dosya Gezgini", - "openEditorsVisible": "Açık Editörler bölmesinde gösterilen düzenleyici sayısı. Bölmeyi gizlemek için 0 olarak ayarlayın.", - "dynamicHeight": "Açık düzenleyiciler bölümü yüksekliğinin öge sayısına göre dinamik olarak uyarlanıp uyarlanmayacağını denetler.", "autoReveal": "Gezginin dosyaları açarken, onları otomatik olarak ortaya çıkartmasını ve seçmesini denetler.", "enableDragAndDrop": "Gezgeinin sürükle bırak ile dosyaları ve klasörleri taşımaya izin verip vermeyeceğini denetler.", "confirmDragAndDrop": "Gezginin, sürükle bırak ile dosyalar ve klasörlerin taşındığı zaman onay isteyip istemeyeceğini denetler.", diff --git a/i18n/trk/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json b/i18n/trk/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json index 660d16789d0..a7b5a9c8bb9 100644 --- a/i18n/trk/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/files/electron-browser/saveErrorHandler.i18n.json @@ -5,10 +5,14 @@ // Do not edit this file. It is machine generated. { "userGuide": "Değişikliklerinizi **geri al**mak veya diskteki içeriğin **üzerine yaz**mak için düzenleyicideki araç çubuğunu kullanabilirsiniz", - "discard": "At", + "overwriteElevated": "Yönetici Olarak Üzerine Yaz...", + "saveElevated": "Yönetici Olarak Yeniden Dene...", "overwrite": "Üzerine Yaz", "retry": "Yeniden Dene", - "readonlySaveError": "'{0}' kaydedilemedi: Dosya yazmaya karşı korunuyor. Korumayı kaldırmak için 'Üzerine Yaz'ı seçin.", + "discard": "At", + "readonlySaveErrorAdmin": "'{0}' kaydedilemedi: Dosya yazmaya karşı korunuyor. Yönetici olarak denemek için 'Yönetici Olarak Üzerine Yaz'ı seçin.", + "readonlySaveError": "'{0}' kaydedilemedi: Dosya yazmaya karşı korunuyor. Korumayı kaldırmayı denemek için 'Üzerine Yaz'ı seçin.", + "permissionDeniedSaveError": "'{0}' kaydedilemedi: Yetersiz yetki. Yönetici olarak denemek için 'Yönetici Olarak Yeniden Dene'yi seçin.", "genericSaveError": "'{0}' kaydedilemedi: ({1}).", "staleSaveError": "'{0}' kaydedilemedi: Diskteki içerik daha yeni. Sizdeki sürüm ile disktekini karşılaştırmak için **Karşılaştır**a tıklayın.", "compareChanges": "Karşılaştır", diff --git a/i18n/trk/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json b/i18n/trk/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json index 9f1cee51d98..d1e6467f5d8 100644 --- a/i18n/trk/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.i18n.json @@ -6,11 +6,5 @@ { "openEditors": "Açık Düzenleyiciler", "openEditosrSection": "Açık Düzenleyiciler Bölümü", - "dirtyCounter": "{0} kaydedilmemiş", - "saveAll": "Tümünü Kaydet", - "closeAllUnmodified": "Değiştirilmeyenleri Kapat", - "closeAll": "Tümünü Kapat", - "compareWithSaved": "Kaydedilenle Karşılaştır", - "close": "Kapat", - "closeOthers": "Diğerlerini Kapat" + "dirtyCounter": "{0} kaydedilmemiş" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json new file mode 100644 index 00000000000..aeb7121cb05 --- /dev/null +++ b/i18n/trk/src/vs/workbench/parts/logs/electron-browser/logs.contribution.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "developer": "Geliştirici" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json b/i18n/trk/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json new file mode 100644 index 00000000000..ad7b602e907 --- /dev/null +++ b/i18n/trk/src/vs/workbench/parts/logs/electron-browser/logsActions.i18n.json @@ -0,0 +1,19 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "openLogsFolder": "Günlük Klasörünü Aç", + "showLogs": "Günlükleri Göster...", + "rendererProcess": "Pencere", + "extensionHost": "Eklenti Sunucusu", + "selectProcess": "İşlem seçin", + "setLogLevel": "Günlük Düzeyini Ayarla", + "trace": "İzle", + "debug": "Hata Ayıklama", + "info": "Bilgi", + "warn": "Uyarı", + "err": "Hata", + "selectLogLevel": "Günlük düzeyini seçin" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/markers/common/messages.i18n.json b/i18n/trk/src/vs/workbench/parts/markers/common/messages.i18n.json index fe543da8a99..ca58bfe5d32 100644 --- a/i18n/trk/src/vs/workbench/parts/markers/common/messages.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/markers/common/messages.i18n.json @@ -5,8 +5,6 @@ // Do not edit this file. It is machine generated. { "viewCategory": "Görüntüle", - "problems.view.toggle.label": "Sorunları Aç/Kapat", - "problems.view.focus.label": "Sorunlara Odakla", "problems.panel.configuration.title": "Sorunlar Görünümü", "problems.panel.configuration.autoreveal": "Sorunlar görünümünün; dosyalar açılırken, dosyaları otomatik olarak ortaya çıkarıp çıkarmayacağını denetler.", "markers.panel.title.problems": "Sorunlar", diff --git a/i18n/trk/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json new file mode 100644 index 00000000000..fe8f6125b1a --- /dev/null +++ b/i18n/trk/src/vs/workbench/parts/output/electron-browser/output.contribution.i18n.json @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "output": "Çıktı", + "viewCategory": "Görüntüle", + "clearOutput.label": "Çıktıyı Temizle" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json b/i18n/trk/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json new file mode 100644 index 00000000000..8b6ad71cd4e --- /dev/null +++ b/i18n/trk/src/vs/workbench/parts/output/electron-browser/outputServices.i18n.json @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json b/i18n/trk/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json index dad393ec3bf..dc51088525e 100644 --- a/i18n/trk/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/preferences/browser/preferencesWidgets.i18n.json @@ -4,12 +4,10 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "defaultSettingsFuzzyPrompt": "Doğal dil aramasını deneyin!", "defaultSettings": "Geçersiz kılmak için ayarlarınızı sağ taraftaki düzeyiciye ekleyin.", "noSettingsFound": "Hiçbir Ayar Bulunamadı.", "settingsSwitcherBarAriaLabel": "Ayar Değiştirici", "userSettings": "Kullanıcı Ayarları", "workspaceSettings": "Çalışma Alanı Ayarları", - "folderSettings": "Klasör Ayarları", - "enableFuzzySearch": "Doğal dil aramasını etkinleştir" + "folderSettings": "Klasör Ayarları" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json b/i18n/trk/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json index ad4ed40e889..dc4c28efe52 100644 --- a/i18n/trk/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/preferences/common/preferencesModels.i18n.json @@ -5,6 +5,5 @@ // Do not edit this file. It is machine generated. { "commonlyUsed": "Yaygın Olarak Kullanılan", - "mostRelevant": "En Uygun", "defaultKeybindingsHeader": "Tuş bağları dosyanıza yerleştirerek tuş bağlarının üzerine yazın." } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json index fe14853bad6..018ca1806dd 100644 --- a/i18n/trk/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "view": "Görüntüle", "commandsHandlerDescriptionDefault": "Komutları Göster ve Çalıştır", "gotoLineDescriptionMac": "Satıra Git", "gotoLineDescriptionWin": "Satıra Git", diff --git a/i18n/trk/src/vs/workbench/parts/search/browser/searchActions.i18n.json b/i18n/trk/src/vs/workbench/parts/search/browser/searchActions.i18n.json index cf14cf9120f..d06d8e0857e 100644 --- a/i18n/trk/src/vs/workbench/parts/search/browser/searchActions.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/search/browser/searchActions.i18n.json @@ -12,9 +12,7 @@ "previousSearchTerm": "Önceki Arama Terimini Göster", "showSearchViewlet": "Aramayı Göster", "findInFiles": "Dosyalarda Bul", - "findInFilesWithSelectedText": "Seçili Metni Dosyalarda Bul", "replaceInFiles": "Dosyalardakileri Değiştir", - "replaceInFilesWithSelectedText": "Dosyalardaki Seçili Metni Değiştir", "RefreshAction.label": "Yenile", "CollapseDeepestExpandedLevelAction.label": "Tümünü Daralt", "ClearSearchResultsAction.label": "Temizle", diff --git a/i18n/trk/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json index fd6f32d47d6..58d2149f726 100644 --- a/i18n/trk/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/search/electron-browser/search.contribution.i18n.json @@ -4,10 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "findInFolder": "Klasörde Bul...", + "findInWorkspace": "Çalışma Alanında Bul...", "showTriggerActions": "Çalışma Alanında Sembole Git...", "name": "Ara", "search": "Ara", + "showSearchViewlet": "Aramayı Göster", "view": "Görüntüle", + "findInFiles": "Dosyalarda Bul", "openAnythingHandlerDescription": "Dosyaya Git", "openSymbolDescriptionNormal": "Çalışma Alanında Sembole Git", "searchOutputChannelTitle": "Ara", diff --git a/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json b/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json new file mode 100644 index 00000000000..a6843828675 --- /dev/null +++ b/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/configureSnippets.i18n.json @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "global.1": "({0})", + "preferences": "Tercihler" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json b/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json index 11671c7d0b4..7e1c6237303 100644 --- a/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.i18n.json @@ -4,10 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "openSnippet.pickLanguage": "Parçacık için Dil seçin", - "openSnippet.errorOnCreate": "{0} oluşturulamadı", - "openSnippet.label": "Kullanıcı Parçacıklarını Aç", - "preferences": "Tercihler", "snippetSchema.json.default": "Boş parçacık", "snippetSchema.json": "Kullanıcı parçacığı yapılandırması", "snippetSchema.json.prefix": "Parçacığı IntelliSense'de seçerken kullanılacak ön ek", diff --git a/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json b/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json new file mode 100644 index 00000000000..d246a5f624d --- /dev/null +++ b/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippetsFile.i18n.json @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Do not edit this file. It is machine generated. +{ + "source.snippet": "Kullanıcı Parçacığı" +} \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json b/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json index ebad445a20b..8257fed50b0 100644 --- a/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/snippets/electron-browser/snippetsService.i18n.json @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "invalid.language": "`contributes.{0}.language` ögesinde bilinmeyen dil. Sağlanan değer: {1}", "invalid.path.0": "`contributes.{0}.path` ögesinde dize bekleniyor. Sağlanan değer: {1}", + "invalid.language": "`contributes.{0}.language` ögesinde bilinmeyen dil. Sağlanan değer: {1}", "invalid.path.1": "`contributes.{0}.path` ögesinin ({1}) eklentinin klasöründe ({2}) yer alması bekleniyor. Bu, eklentiyi taşınamaz yapabilir.", "vscode.extension.contributes.snippets": "Parçacıklara ekleme yapar.", "vscode.extension.contributes.snippets-language": "Bu parçacığın ekleneceği dilin tanımlayıcısı.", "vscode.extension.contributes.snippets-path": "Parçacıklar dosyasının yolu. Yol, eklenti klasörüne görecelidir ve genellikle './snippets/' ile başlar.", "badVariableUse": "'{0}' eklentisindeki bir veya daha çok parçacık yüksek olasılıkla parçacık değişkenleri ile parçacık yer tutucularını karıştırıyor (daha fazla bilgi için https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax adresini ziyaret edin).", "badFile": "Parçacık dosyası \"{0}\" okunamadı.", - "source.snippet": "Kullanıcı Parçacığı", "detail.snippet": "{0} ({1})", "snippetSuggest.longLabel": "{0}, {1}" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json b/i18n/trk/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json index a994ebe0909..644e7e44a52 100644 --- a/i18n/trk/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/terminal/electron-browser/terminalColorRegistry.i18n.json @@ -8,6 +8,5 @@ "terminal.foreground": "Terminalin ön plan rengi.", "terminalCursor.foreground": "Terminal imlecinin ön plan rengi.", "terminalCursor.background": "Terminal imlecinin arka plan rengi. Bir blok imlecinin kapladığı bir karakterin rengini özelleştirmeyi sağlar.", - "terminal.selectionBackground": "Terminalin seçim arkaplanı rengi.", - "terminal.ansiColor": "Terminalde '{0}' ANSI rengi." + "terminal.selectionBackground": "Terminalin seçim arkaplanı rengi." } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json b/i18n/trk/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json index a30794054e1..2c0a6d7607f 100644 --- a/i18n/trk/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/terminal/electron-browser/terminalService.i18n.json @@ -7,7 +7,6 @@ "terminal.integrated.chooseWindowsShellInfo": "Özelleştir butonuna tıklayıp varsayılan terminal kabuğunu seçebilirsiniz.", "customize": "Özelleştir", "cancel": "İptal", - "never again": "Tamam, Tekrar Gösterme", "terminal.integrated.chooseWindowsShell": "Tercih ettiğiniz terminal kabuğunu seçin, bunu daha sonra ayarlarınızdan değiştirebilirsiniz", "terminalService.terminalCloseConfirmationSingular": "Aktif bir terminal oturumu var, sonlandırmak istiyor musunuz?", "terminalService.terminalCloseConfirmationPlural": "{0} aktif terminal oturumu var, bunları sonlandırmak istiyor musunuz?" diff --git a/i18n/trk/src/vs/workbench/parts/update/electron-browser/update.i18n.json b/i18n/trk/src/vs/workbench/parts/update/electron-browser/update.i18n.json index 61ebe35f50c..64fe6d494db 100644 --- a/i18n/trk/src/vs/workbench/parts/update/electron-browser/update.i18n.json +++ b/i18n/trk/src/vs/workbench/parts/update/electron-browser/update.i18n.json @@ -23,6 +23,7 @@ "commandPalette": "Komut Paleti...", "settings": "Ayarlar", "keyboardShortcuts": "Klavye Kısayolları", + "userSnippets": "Kullanıcı Parçacıkları", "selectTheme.label": "Renk Teması", "themes.selectIconTheme.label": "Dosya Simgesi Teması", "not available": "Güncelleştirme Yok", diff --git a/i18n/trk/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json b/i18n/trk/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json index 320c074b5d2..699613ce8f0 100644 --- a/i18n/trk/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json +++ b/i18n/trk/src/vs/workbench/services/files/electron-browser/remoteFileService.i18n.json @@ -4,5 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "fileIsDirectoryError": "Dosya bir dizindir", + "fileNotModifiedError": "Dosya şu tarihten beri değiştirilmemiş:", "fileBinaryError": "Dosya ikili olarak görünüyor ve metin olarak açılamıyor" } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json b/i18n/trk/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json index 5284725dbcb..f0547df6a62 100644 --- a/i18n/trk/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json +++ b/i18n/trk/src/vs/workbench/services/textfile/electron-browser/textFileService.i18n.json @@ -6,8 +6,6 @@ { "saveChangesMessage": "{0} dosyasına yaptığınız değişiklikleri kaydetmek istiyor musunuz?", "saveChangesMessages": "Aşağıdaki {0} dosyaya yaptığınız değişiklikleri kaydetmek istiyor musunuz?", - "moreFile": "...1 ek dosya gösterilmiyor", - "moreFiles": "...{0} ek dosya gösterilmiyor", "saveAll": "&&Tümünü Kaydet", "save": "&&Kaydet", "dontSave": "Kaydet&&me", diff --git a/i18n/trk/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json b/i18n/trk/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json index 06e828ba73e..f60dda6f647 100644 --- a/i18n/trk/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json +++ b/i18n/trk/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.i18n.json @@ -11,7 +11,6 @@ "noIconThemeDesc": "Dosya simgesi yok", "iconThemeError": "Dosya simgesi teması bilinmiyor veya yüklenmemiş.", "workbenchColors": "Şu an seçili renk temasındaki renkleri geçersiz kılar.", - "editorColors": "Şu an seçili renk temasındaki düzenleyici renklerini ve yazı tipi stilini geçersiz kılar.", "editorColors.comments": "Yorumların rengini ve stillerini ayarlar", "editorColors.strings": "Dizelerin rengini ve stillerini ayarlar.", "editorColors.keywords": "Anahtar sözcüklerin rengini ve stillerini ayarlar.", @@ -19,5 +18,6 @@ "editorColors.types": "Tür bildirimi ve başvurularının rengini ve stillerini ayarlar.", "editorColors.functions": "Fonksiyon bildirimi ve başvurularının rengini ve stillerini ayarlar.", "editorColors.variables": "Değişken bildirimi ve başvurularının rengini ve stillerini ayarlar.", - "editorColors.textMateRules": "Textmate tema kurallarını kullanarak renkleri ve stilleri ayarlar (gelişmiş)." + "editorColors.textMateRules": "Textmate tema kurallarını kullanarak renkleri ve stilleri ayarlar (gelişmiş).", + "editorColors": "Şu an seçili renk temasındaki düzenleyici renklerini ve yazı tipi stilini geçersiz kılar." } \ No newline at end of file diff --git a/i18n/trk/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json b/i18n/trk/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json index 38e103f1ee8..19e6e2498a4 100644 --- a/i18n/trk/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json +++ b/i18n/trk/src/vs/workbench/services/workspace/node/workspaceEditingService.i18n.json @@ -7,9 +7,5 @@ "errorInvalidTaskConfiguration": "Çalışma alanı yapılandırma dosyasına yazılamıyor. Lütfen dosyadaki hata/uyarıları düzeltmek için dosyayı açın ve tekrar deneyin.", "errorWorkspaceConfigurationFileDirty": "Kaydedilmemiş değişiklikler içerdiği için çalışma alanı yapılandırma dosyasına yazılamıyor. Lütfen dosyayı kaydedin ve tekrar deneyin.", "openWorkspaceConfigurationFile": "Çalışma Alanı Yapılandırma Dosyasını Aç", - "close": "Kapat", - "enterWorkspace.close": "Kapat", - "enterWorkspace.dontShowAgain": "Tekrar Gösterme", - "enterWorkspace.moreInfo": "Daha Fazla Bilgi", - "enterWorkspace.prompt": "VS Code'da birden çok klasörle çalışmak hakkında daha fazla bilgi edinin." + "close": "Kapat" } \ No newline at end of file diff --git a/package.json b/package.json index aa70e1e524a..3312dc66b2d 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "vscode-debugprotocol": "1.25.0", "vscode-ripgrep": "^0.7.1-patch.0", "vscode-textmate": "^3.2.0", - "vscode-xterm": "3.1.0-beta2", + "vscode-xterm": "3.1.0-beta5", "yauzl": "2.8.0" }, "devDependencies": { diff --git a/product.json b/product.json index 49f852e2928..cbb7fbae771 100644 --- a/product.json +++ b/product.json @@ -10,6 +10,7 @@ "win32NameVersion": "Microsoft Code OSS", "win32RegValueName": "CodeOSS", "win32AppId": "{{E34003BB-9E10-4501-8C11-BE3FAA83F23F}", + "win32x64AppId": "{{D77B7E06-80BA-4137-BCF4-654B95CCEBC5}", "win32AppUserModelId": "Microsoft.CodeOSS", "win32ShellNameShort": "C&ode - OSS", "darwinBundleIdentifier": "com.visualstudio.code.oss", diff --git a/resources/linux/bin/code.sh b/resources/linux/bin/code.sh index ca71a94db9e..55f50b6f1c1 100755 --- a/resources/linux/bin/code.sh +++ b/resources/linux/bin/code.sh @@ -7,7 +7,7 @@ if [ "$(id -u)" = "0" ]; then for i in $@ do - if [[ $i == --user-data-dir=* || $i == --file-write ]]; then + if [[ $i == --user-data-dir || $i == --user-data-dir=* || $i == --file-write ]]; then CAN_LAUNCH_AS_ROOT=1 fi done diff --git a/src/typings/vscode-xterm.d.ts b/src/typings/vscode-xterm.d.ts index a8000eec916..5e76f2033ee 100644 --- a/src/typings/vscode-xterm.d.ts +++ b/src/typings/vscode-xterm.d.ts @@ -67,6 +67,11 @@ declare module 'vscode-xterm' { */ lineHeight?: number; + /** + * Whether to treat option as the meta key. + */ + macOptionIsMeta?: boolean; + /** * The number of rows in the terminal. */ @@ -332,6 +337,12 @@ declare module 'vscode-xterm' { */ deregisterLinkMatcher(matcherId: number): void; + /** + * Enters screen reader navigation mode. This will only work when + * the screenReaderMode option is true. + */ + enterNavigationMode(): void; + /** * Gets whether the terminal has an active selection. */ @@ -416,7 +427,7 @@ declare module 'vscode-xterm' { * Retrieves an option's value from the terminal. * @param key The option key. */ - getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean; + getOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean; /** * Retrieves an option's value from the terminal. * @param key The option key. @@ -461,7 +472,7 @@ declare module 'vscode-xterm' { * @param key The option key. * @param value The option value. */ - setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void; + setOption(key: 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'enableBold' | 'macOptionIsMeta' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell', value: boolean): void; /** * Sets an option on the terminal. * @param key The option key. diff --git a/src/vs/base/browser/dnd.ts b/src/vs/base/browser/dnd.ts index b95e397071f..85bc36aac42 100644 --- a/src/vs/base/browser/dnd.ts +++ b/src/vs/base/browser/dnd.ts @@ -49,6 +49,11 @@ export const DataTransfers = { */ URL: 'URL', + /** + * Application specific resource transfer type when multiple resources are being dragged. + */ + URLS: 'URLS', + /** * Browser specific transfer type to download. */ @@ -58,4 +63,4 @@ export const DataTransfers = { * Typicaly transfer type for copy/paste transfers. */ TEXT: 'text/plain' -}; \ No newline at end of file +}; diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index 6e6a73fb542..66125a6d41a 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -63,8 +63,8 @@ /* make sure selection color wins when a label is being selected */ .monaco-tree.focused .selected .monaco-icon-label, /* tree */ .monaco-tree.focused .selected .monaco-icon-label::after, -.monaco-list:focus .focused.selected .monaco-icon-label, /* list */ -.monaco-list:focus .focused.selected .monaco-icon-label::after +.monaco-list:focus .selected .monaco-icon-label, /* list */ +.monaco-list:focus .selected .monaco-icon-label::after { color: inherit !important; } diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index e1c22181d06..0c72f6ff5e3 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -7,7 +7,7 @@ import 'vs/css!./list'; import { IDisposable } from 'vs/base/common/lifecycle'; import { range } from 'vs/base/common/arrays'; import { IDelegate, IRenderer, IListEvent } from './list'; -import { List, IListOptions, IListStyles } from './listWidget'; +import { List, IListCreationOptions, IListStyles, IListOptions } from './listWidget'; import { IPagedModel } from 'vs/base/common/paging'; import Event, { mapEvent } from 'vs/base/common/event'; @@ -67,7 +67,7 @@ export class PagedList { container: HTMLElement, delegate: IDelegate, renderers: IPagedRenderer[], - options: IListOptions = {} // TODO@Joao: should be IListOptions + options: IListCreationOptions = {} // TODO@Joao: should be IListOptions ) { const pagedRenderers = renderers.map(r => new PagedRenderer>(r, () => this.model)); this.list = new List(container, delegate, pagedRenderers, options); @@ -166,6 +166,10 @@ export class PagedList { this.list.setSelection(indexes); } + getSelection(): number[] { + return this.list.getSelection(); + } + layout(height?: number): void { this.list.layout(height); } @@ -177,4 +181,8 @@ export class PagedList { style(styles: IListStyles): void { this.list.style(styles); } + + updateOptions(options: IListOptions): void { + this.list.updateOptions(options); + } } \ No newline at end of file diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index d5450e24c9d..1ee43f1916c 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -265,7 +265,7 @@ class KeyboardController implements IDisposable { constructor( private list: List, private view: ListView, - options: IListOptions + options: IListCreationOptions ) { const multipleSelectionSupport = !(options.multipleSelectionSupport === false); this.disposables = []; @@ -344,18 +344,6 @@ class KeyboardController implements IDisposable { } } -function isSelectionSingleChangeEvent(event: IListMouseEvent | IListTouchEvent): boolean { - return platform.isMacintosh ? event.browserEvent.metaKey : event.browserEvent.ctrlKey; -} - -function isSelectionRangeChangeEvent(event: IListMouseEvent | IListTouchEvent): boolean { - return event.browserEvent.shiftKey; -} - -function isSelectionChangeEvent(event: IListMouseEvent | IListTouchEvent): boolean { - return isSelectionSingleChangeEvent(event) || isSelectionRangeChangeEvent(event); -} - class MouseController implements IDisposable { private multipleSelectionSupport: boolean; @@ -396,7 +384,7 @@ class MouseController implements IDisposable { constructor( private list: List, private view: ListView, - private options: IListOptions = {} + private options: IListCreationOptions = {} ) { this.multipleSelectionSupport = options.multipleSelectionSupport !== false; @@ -408,6 +396,26 @@ class MouseController implements IDisposable { Gesture.addTarget(view.domNode); } + updateOptions(options: IListOptions): void { + this.options.useAltAsMultiSelectModifier = options.useAltAsMultiSelectModifier; + } + + private isSelectionSingleChangeEvent(event: IListMouseEvent | IListTouchEvent): boolean { + if (this.options.useAltAsMultiSelectModifier) { + return event.browserEvent.altKey; + } + + return platform.isMacintosh ? event.browserEvent.metaKey : event.browserEvent.ctrlKey; + } + + private isSelectionRangeChangeEvent(event: IListMouseEvent | IListTouchEvent): boolean { + return event.browserEvent.shiftKey; + } + + private isSelectionChangeEvent(event: IListMouseEvent | IListTouchEvent): boolean { + return this.isSelectionSingleChangeEvent(event) || this.isSelectionRangeChangeEvent(event); + } + private onMouseDown(e: IListMouseEvent | IListTouchEvent): void { if (this.options.focusOnMouseDown === false) { e.browserEvent.preventDefault(); @@ -419,14 +427,14 @@ class MouseController implements IDisposable { let reference = this.list.getFocus()[0]; reference = reference === undefined ? this.list.getSelection()[0] : reference; - if (this.multipleSelectionSupport && isSelectionRangeChangeEvent(e)) { + if (this.multipleSelectionSupport && this.isSelectionRangeChangeEvent(e)) { return this.changeSelection(e, reference); } const focus = e.index; this.list.setFocus([focus]); - if (this.multipleSelectionSupport && isSelectionChangeEvent(e)) { + if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) { return this.changeSelection(e, reference); } @@ -437,7 +445,7 @@ class MouseController implements IDisposable { } private onPointer(e: IListMouseEvent): void { - if (this.multipleSelectionSupport && isSelectionChangeEvent(e)) { + if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) { return; } @@ -449,7 +457,7 @@ class MouseController implements IDisposable { } private onDoubleClick(e: IListMouseEvent): void { - if (this.multipleSelectionSupport && isSelectionChangeEvent(e)) { + if (this.multipleSelectionSupport && this.isSelectionChangeEvent(e)) { return; } @@ -461,7 +469,7 @@ class MouseController implements IDisposable { private changeSelection(e: IListMouseEvent | IListTouchEvent, reference: number | undefined): void { const focus = e.index; - if (isSelectionRangeChangeEvent(e) && reference !== undefined) { + if (this.isSelectionRangeChangeEvent(e) && reference !== undefined) { const min = Math.min(reference, focus); const max = Math.max(reference, focus); const rangeSelection = range(min, max + 1); @@ -475,7 +483,7 @@ class MouseController implements IDisposable { const newSelection = disjunction(rangeSelection, relativeComplement(selection, contiguousRange)); this.list.setSelection(newSelection); - } else if (isSelectionSingleChangeEvent(e)) { + } else if (this.isSelectionSingleChangeEvent(e)) { const selection = this.list.getSelection(); const newSelection = selection.filter(i => i !== focus); @@ -492,7 +500,11 @@ class MouseController implements IDisposable { } } -export interface IListOptions extends IListViewOptions, IListStyles { +export interface IListOptions { + useAltAsMultiSelectModifier?: boolean; +} + +export interface IListCreationOptions extends IListViewOptions, IListStyles, IListOptions { identityProvider?: IIdentityProvider; ariaLabel?: string; mouseSupport?: boolean; @@ -533,7 +545,7 @@ const defaultStyles: IListStyles = { listDropBackground: Color.fromHex('#383B3D') }; -const DefaultOptions: IListOptions = { +const DefaultOptions: IListCreationOptions = { keyboardSupport: true, mouseSupport: true, multipleSelectionSupport: true @@ -662,8 +674,9 @@ export class List implements ISpliceable, IDisposable { private eventBufferer = new EventBufferer(); private view: ListView; private spliceable: ISpliceable; - private disposables: IDisposable[]; + protected disposables: IDisposable[]; private styleElement: HTMLStyleElement; + private mouseController: MouseController; @memoize get onFocusChange(): Event> { return mapEvent(this.eventBufferer.wrapEvent(this.focus.onChange), e => this.toListEvent(e)); @@ -709,7 +722,7 @@ export class List implements ISpliceable, IDisposable { container: HTMLElement, delegate: IDelegate, renderers: IRenderer[], - options: IListOptions = DefaultOptions + options: IListCreationOptions = DefaultOptions ) { const aria = new Aria(); this.focus = new FocusTrait(i => this.getElementDomId(i)); @@ -744,9 +757,9 @@ export class List implements ISpliceable, IDisposable { } if (typeof options.mouseSupport !== 'boolean' || options.mouseSupport) { - const controller = new MouseController(this, this.view, options); - this.disposables.push(controller); - this.onContextMenu = controller.onContextMenu; + this.mouseController = new MouseController(this, this.view, options); + this.disposables.push(this.mouseController); + this.onContextMenu = this.mouseController.onContextMenu; } this.onFocusChange(this._onFocusChange, this, this.disposables); @@ -759,6 +772,12 @@ export class List implements ISpliceable, IDisposable { this.style(options); } + updateOptions(options: IListOptions): void { + if (this.mouseController) { + this.mouseController.updateOptions(options); + } + } + splice(start: number, deleteCount: number, elements: T[] = []): void { if (deleteCount === 0 && elements.length === 0) { return; diff --git a/src/vs/base/browser/ui/splitview/grid.ts b/src/vs/base/browser/ui/splitview/grid.ts new file mode 100644 index 00000000000..fd0c585ff11 --- /dev/null +++ b/src/vs/base/browser/ui/splitview/grid.ts @@ -0,0 +1,149 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import Event, { anyEvent } from 'vs/base/common/event'; +import { Orientation } from 'vs/base/browser/ui/sash/sash'; +import { append, $ } from 'vs/base/browser/dom'; +import { SplitView, IView } from 'vs/base/browser/ui/splitview/splitview'; +export { Orientation } from 'vs/base/browser/ui/sash/sash'; + +export class GridNode implements IView { + + get minimumSize(): number { + let result = 0; + + for (const child of this.children) { + for (const grandchild of child.children) { + result += grandchild.minimumSize; + } + } + + return result === 0 ? 50 : result; + } + + readonly maximumSize = Number.MAX_VALUE; + + private _onDidChange: Event = Event.None; + get onDidChange(): Event { + return this._onDidChange; + } + + protected orientation: Orientation | undefined; + protected size: number | undefined; + protected orthogonalSize: number | undefined; + private splitview: SplitView | undefined; + private children: GridNode[] = []; + private color: string | undefined; + + constructor(private parent?: GridNode, orthogonalSize?: number, color?: string) { + this.orthogonalSize = orthogonalSize; + this.color = color || `hsl(${Math.round(Math.random() * 360)}, 72%, 72%)`; + } + + render(container: HTMLElement): void { + container = append(container, $('.node')); + container.style.backgroundColor = this.color; + + append(container, $('.action', { onclick: () => this.split(container, Orientation.HORIZONTAL) }, '⬌')); + append(container, $('.action', { onclick: () => this.split(container, Orientation.VERTICAL) }, '⬍')); + } + + protected split(container: HTMLElement, orientation: Orientation): void { + if (this.parent && this.parent.orientation === orientation) { + const index = this.parent.children.indexOf(this); + this.parent.addChild(this.size / 2, this.orthogonalSize, index + 1); + } else { + this.branch(container, orientation); + } + } + + protected branch(container: HTMLElement, orientation: Orientation): void { + this.orientation = orientation; + container.innerHTML = ''; + + this.splitview = new SplitView(container, { orientation }); + this.layout(this.size); + this.orthogonalLayout(this.orthogonalSize); + + this.addChild(this.orthogonalSize / 2, this.size, 0, this.color); + this.addChild(this.orthogonalSize / 2, this.size); + } + + layout(size: number): void { + this.size = size; + + for (const child of this.children) { + child.orthogonalLayout(size); + } + } + + orthogonalLayout(size: number): void { + this.orthogonalSize = size; + + if (this.splitview) { + this.splitview.layout(size); + } + } + + private addChild(size: number, orthogonalSize: number, index?: number, color?: string): void { + const child = new GridNode(this, orthogonalSize, color); + this.splitview.addView(child, size, index); + + if (typeof index === 'number') { + this.children.splice(index, 0, child); + } else { + this.children.push(child); + } + + this._onDidChange = anyEvent(...this.children.map(c => c.onDidChange)); + } +} + +export class RootGridNode extends GridNode { + + private width: number; + private height: number; + + protected branch(container: HTMLElement, orientation: Orientation): void { + if (orientation === Orientation.VERTICAL) { + this.size = this.width; + this.orthogonalSize = this.height; + } else { + this.size = this.height; + this.orthogonalSize = this.width; + } + + super.branch(container, orientation); + } + + layoutBox(width: number, height: number): void { + if (this.orientation === Orientation.VERTICAL) { + this.layout(width); + this.orthogonalLayout(height); + } else if (this.orientation === Orientation.HORIZONTAL) { + this.layout(height); + this.orthogonalLayout(width); + } else { + this.width = width; + this.height = height; + } + } +} + +export class Grid { + + private root: RootGridNode; + + constructor(container: HTMLElement) { + this.root = new RootGridNode(); + this.root.render(container); + } + + layout(width: number, height: number): void { + this.root.layoutBox(width, height); + } +} diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index 41d3de5c826..045645a3f68 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -20,4 +20,5 @@ .monaco-split-view2.horizontal > .split-view-view { height: 100%; + display: inline-block; } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 9c6657154b8..833a2180803 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -161,7 +161,7 @@ export class SplitView implements IDisposable { } view.render(container, this.orientation); - this.relayout(); + this.relayout(index); this.state = State.Idle; } diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index dee1ce7c360..93c6dda80c2 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -255,7 +255,7 @@ export class ThrottledDelayer extends Delayer> { this.throttler = new Throttler(); } - trigger(promiseFactory: ITask>, delay?: number): Promise { + trigger(promiseFactory: ITask>, delay?: number): TPromise { return super.trigger(() => this.throttler.queue(promiseFactory), delay); } } diff --git a/src/vs/base/common/glob.ts b/src/vs/base/common/glob.ts index 7314589644a..451a01bb666 100644 --- a/src/vs/base/common/glob.ts +++ b/src/vs/base/common/glob.ts @@ -220,8 +220,12 @@ function parseRegExp(pattern: string): string { } } - // Tail: Add the slash we had split on if there is more to come and the next one is not a globstar - if (index < segments.length - 1 && segments[index + 1] !== GLOBSTAR) { + // Tail: Add the slash we had split on if there is more to come and the remaining pattern is not a globstar + // For example if pattern: some/**/*.js we want the "/" after some to be included in the RegEx to prevent + // a folder called "something" to match as well. + // However, if pattern: some/**, we tolerate that we also match on "something" because our globstar behaviour + // is to match 0-N segments. + if (index < segments.length - 1 && (segments[index + 1] !== GLOBSTAR || index + 2 < segments.length)) { regEx += PATH_REGEX; } diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index e8f135512e7..e00cc11da16 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -30,7 +30,7 @@ export function getPathLabel(resource: URI | string, rootProvider?: IWorkspaceFo } if (resource.scheme !== 'file' && resource.scheme !== 'untitled') { - return resource.authority + resource.path; + return resource.with({ query: null, fragment: null }).toString(true); } // return early if we can resolve a relative path label from the root @@ -362,4 +362,4 @@ export function mnemonicButtonLabel(label: string): string { export function unmnemonicLabel(label: string): string { return label.replace(/&/g, '&&'); -} \ No newline at end of file +} diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 4b883338383..3012d4a5b15 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -12,9 +12,9 @@ export function basenameOrAuthority(resource: uri): string { return paths.basename(resource.fsPath) || resource.authority; } -export function isEqualOrParent(first: uri, second: uri, ignoreCase?: boolean): boolean { - if (first.scheme === second.scheme && first.authority === second.authority) { - return paths.isEqualOrParent(first.fsPath, second.fsPath, ignoreCase); +export function isEqualOrParent(resource: uri, candidate: uri, ignoreCase?: boolean): boolean { + if (resource.scheme === candidate.scheme && resource.authority === candidate.authority) { + return paths.isEqualOrParent(resource.fsPath, candidate.fsPath, ignoreCase); } return false; @@ -42,3 +42,23 @@ export function dirname(resource: uri): uri { path: paths.dirname(resource.path) }); } + +export function distinctParents(items: T[], resourceAccessor: (item: T) => uri): T[] { + const distinctParents: T[] = []; + for (let i = 0; i < items.length; i++) { + const candidateResource = resourceAccessor(items[i]); + if (items.some((otherItem, index) => { + if (index === i) { + return false; + } + + return isEqualOrParent(candidateResource, resourceAccessor(otherItem)); + })) { + continue; + } + + distinctParents.push(items[i]); + } + + return distinctParents; +} \ No newline at end of file diff --git a/src/vs/base/node/request.ts b/src/vs/base/node/request.ts index 30fdfb643fb..d50506cc21a 100644 --- a/src/vs/base/node/request.ts +++ b/src/vs/base/node/request.ts @@ -28,7 +28,7 @@ export interface IRequestOptions { password?: string; headers?: any; timeout?: number; - data?: any; + data?: string | Stream; agent?: Agent; followRedirects?: number; strictSSL?: boolean; @@ -63,6 +63,7 @@ export function request(options: IRequestOptions): TPromise { : getNodeRequest(options); return rawRequestPromise.then(rawRequest => { + return new TPromise((c, e) => { const endpoint = parseUrl(options.url); @@ -83,7 +84,6 @@ export function request(options: IRequestOptions): TPromise { req = rawRequest(opts, (res: http.ClientResponse) => { const followRedirects = isNumber(options.followRedirects) ? options.followRedirects : 3; - if (res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers['location']) { request(assign({}, options, { url: res.headers['location'], @@ -107,7 +107,12 @@ export function request(options: IRequestOptions): TPromise { } if (options.data) { - req.write(options.data); + if (typeof options.data === 'string') { + req.write(options.data); + } else { + options.data.pipe(req); + return; + } } req.end(); diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts new file mode 100644 index 00000000000..f9275777a53 --- /dev/null +++ b/src/vs/base/test/common/resources.test.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as assert from 'assert'; +import URI from 'vs/base/common/uri'; +import { distinctParents } from 'vs/base/common/resources'; + +suite('Resources', () => { + + test('distinctParents', () => { + + // Basic + let resources = [ + URI.file('/some/folderA/file.txt'), + URI.file('/some/folderB/file.txt'), + URI.file('/some/folderC/file.txt') + ]; + + let distinct = distinctParents(resources, r => r); + assert.equal(distinct.length, 3); + assert.equal(distinct[0].toString(), resources[0].toString()); + assert.equal(distinct[1].toString(), resources[1].toString()); + assert.equal(distinct[2].toString(), resources[2].toString()); + + // Parent / Child + resources = [ + URI.file('/some/folderA'), + URI.file('/some/folderA/file.txt'), + URI.file('/some/folderA/child/file.txt'), + URI.file('/some/folderA2/file.txt'), + URI.file('/some/file.txt') + ]; + + distinct = distinctParents(resources, r => r); + assert.equal(distinct.length, 3); + assert.equal(distinct[0].toString(), resources[0].toString()); + assert.equal(distinct[1].toString(), resources[3].toString()); + assert.equal(distinct[2].toString(), resources[4].toString()); + }); +}); \ No newline at end of file diff --git a/src/vs/base/test/node/glob.test.ts b/src/vs/base/test/node/glob.test.ts index 25dc9c517a6..df770c9c862 100644 --- a/src/vs/base/test/node/glob.test.ts +++ b/src/vs/base/test/node/glob.test.ts @@ -301,6 +301,22 @@ suite('Glob', () => { assert(!glob.match(p, '/xpackage.json')); }); + test('issue 41724', function () { + let p = 'some/**/*.js'; + + assert(glob.match(p, 'some/foo.js')); + assert(glob.match(p, 'some/folder/foo.js')); + assert(!glob.match(p, 'something/foo.js')); + assert(!glob.match(p, 'something/folder/foo.js')); + + p = 'some/**/*'; + + assert(glob.match(p, 'some/foo.js')); + assert(glob.match(p, 'some/folder/foo.js')); + assert(!glob.match(p, 'something/foo.js')); + assert(!glob.match(p, 'something/folder/foo.js')); + }); + test('brace expansion', function () { let p = '*.{html,js}'; diff --git a/src/vs/code/buildfile.js b/src/vs/code/buildfile.js index f94e19b95b8..0293acbb5be 100644 --- a/src/vs/code/buildfile.js +++ b/src/vs/code/buildfile.js @@ -21,6 +21,7 @@ exports.collectModules= function() { createModuleDescription('vs/code/electron-main/main', []), createModuleDescription('vs/code/node/cli', []), createModuleDescription('vs/code/node/cliProcessMain', ['vs/code/node/cli']), - createModuleDescription('vs/code/electron-browser/sharedProcess/sharedProcessMain', []) + createModuleDescription('vs/code/electron-browser/sharedProcess/sharedProcessMain', []), + createModuleDescription('vs/code/electron-browser/issue/issueReporterMain', []) ]; }; \ No newline at end of file diff --git a/src/vs/code/electron-browser/issue/issueReporter.html b/src/vs/code/electron-browser/issue/issueReporter.html new file mode 100644 index 00000000000..553c3d51de5 --- /dev/null +++ b/src/vs/code/electron-browser/issue/issueReporter.html @@ -0,0 +1,102 @@ + + + + + + + + +
+ +
+ + +
+ +
+ + + + + + +
+ +
+
+ + +
+
+ + +
+
+ +
+
+
+ My System Info + + + + +
+ +
+
+
+
+
+ Currently Running Processes + + + + +
+ +
+
+
+
+
+ My Workspace Stats + + + + +
+							
+								
+							
+						
+
+
+
+ + + + +
+ + We support GitHub-flavored Markdown. + After submitting, you will still be able to edit your issue on GitHub. + + + +
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/src/vs/code/electron-browser/issue/issueReporter.js b/src/vs/code/electron-browser/issue/issueReporter.js new file mode 100644 index 00000000000..31dc101872f --- /dev/null +++ b/src/vs/code/electron-browser/issue/issueReporter.js @@ -0,0 +1,89 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +const path = require('path'); +const remote = require('electron').remote; + +function parseURLQueryArgs() { + const search = window.location.search || ''; + + return search.split(/[?&]/) + .filter(function (param) { return !!param; }) + .map(function (param) { return param.split('='); }) + .filter(function (param) { return param.length === 2; }) + .reduce(function (r, param) { r[param[0]] = decodeURIComponent(param[1]); return r; }, {}); +} + +function createScript(src, onload) { + const script = document.createElement('script'); + script.src = src; + script.addEventListener('load', onload); + + const head = document.getElementsByTagName('head')[0]; + head.insertBefore(script, head.lastChild); +} + +function uriFromPath(_path) { + var pathName = path.resolve(_path).replace(/\\/g, '/'); + if (pathName.length > 0 && pathName.charAt(0) !== '/') { + pathName = '/' + pathName; + } + + return encodeURI('file://' + pathName); +} + +function main() { + const args = parseURLQueryArgs(); + const configuration = JSON.parse(args['config'] || '{}') || {}; + + const extractKey = function (e) { + return [ + e.ctrlKey ? 'ctrl-' : '', + e.metaKey ? 'meta-' : '', + e.altKey ? 'alt-' : '', + e.shiftKey ? 'shift-' : '', + e.keyCode + ].join(''); + }; + + const TOGGLE_DEV_TOOLS_KB = (process.platform === 'darwin' ? 'meta-alt-73' : 'ctrl-shift-73'); // mac: Cmd-Alt-I, rest: Ctrl-Shift-I + const RELOAD_KB = (process.platform === 'darwin' ? 'meta-82' : 'ctrl-82'); // mac: Cmd-R, rest: Ctrl-R + + window.addEventListener('keydown', function (e) { + const key = extractKey(e); + if (key === TOGGLE_DEV_TOOLS_KB) { + remote.getCurrentWebContents().toggleDevTools(); + } else if (key === RELOAD_KB) { + remote.getCurrentWindow().reload(); + } + }); + + // Load the loader and start loading the workbench + const rootUrl = uriFromPath(configuration.appRoot) + '/out'; + + // In the bundled version the nls plugin is packaged with the loader so the NLS Plugins + // loads as soon as the loader loads. To be able to have pseudo translation + createScript(rootUrl + '/vs/loader.js', function () { + define('fs', ['original-fs'], function (originalFS) { return originalFS; }); // replace the patched electron fs with the original node fs for all AMD code + + window.MonacoEnvironment = {}; + + var nlsConfig = { availableLanguages: {} }; + require.config({ + baseUrl: rootUrl, + 'vs/nls': nlsConfig, + nodeCachedDataDir: configuration.nodeCachedDataDir, + nodeModules: [/*BUILD->INSERT_NODE_MODULES*/] + }); + + require(['vs/code/electron-browser/issue/issueReporterMain'], (issueReporter) => { + issueReporter.startup(configuration); + }); + }); +} + +main(); diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts new file mode 100644 index 00000000000..f37957e1518 --- /dev/null +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -0,0 +1,395 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import 'vs/css!./media/issueReporter'; +import { shell, ipcRenderer, webFrame } from 'electron'; +import { $ } from 'vs/base/browser/dom'; +import * as browser from 'vs/base/browser/browser'; +import product from 'vs/platform/node/product'; +import pkg from 'vs/platform/node/package'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { Client as ElectronIPCClient } from 'vs/base/parts/ipc/electron-browser/ipc.electron-browser'; +import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc'; +import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { IWindowConfiguration, IWindowsService } from 'vs/platform/windows/common/windows'; +import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; +import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; +import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; +import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc'; +import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; +import { IssueReporterModel, IssueReporterData } from 'vs/code/electron-browser/issue/issueReporterModel'; +import { IssueReporterStyles } from 'vs/platform/issue/common/issue'; + +export function startup(configuration: IWindowConfiguration) { + const issueReporter = new IssueReporter(configuration); + issueReporter.render(); +} + +export class IssueReporter extends Disposable { + private environmentService: IEnvironmentService; + private telemetryService: ITelemetryService; + private issueReporterModel: IssueReporterModel; + + constructor(configuration: IWindowConfiguration) { + super(); + + this.issueReporterModel = new IssueReporterModel({ + issueType: 0, + includeSystemInfo: true, + includeWorkspaceInfo: true, + includeProcessInfo: true + }); + + ipcRenderer.on('issueStyleResponse', (event, styles: IssueReporterStyles) => { + this.applyZoom(styles.zoomLevel); + this.applyStyles(styles); + }); + + ipcRenderer.on('issueInfoResponse', (event, info) => { + this.issueReporterModel.update(info); + + this.updateAllBlocks(this.issueReporterModel.getData()); + + const submitButton = document.getElementById('github-submit-btn'); + submitButton.disabled = false; + submitButton.textContent = 'Preview on GitHub'; + }); + + ipcRenderer.send('issueInfoRequest'); + ipcRenderer.send('issueStyleRequest'); + + this.initServices(configuration); + this.setEventHandlers(); + } + + render(): void { + this.renderBlocks(); + } + + private applyZoom(zoomLevel: number) { + webFrame.setZoomLevel(zoomLevel); + browser.setZoomFactor(webFrame.getZoomFactor()); + // See https://github.com/Microsoft/vscode/issues/26151 + // Cannot be trusted because the webFrame might take some time + // until it really applies the new zoom level + browser.setZoomLevel(webFrame.getZoomLevel(), /*isTrusted*/false); + } + + private applyStyles(styles: IssueReporterStyles) { + const styleTag = document.createElement('style'); + const content: string[] = []; + + if (styles.inputBackground) { + content.push(`input, textarea, select { background-color: ${styles.inputBackground}; }`); + } + + if (styles.inputBorder) { + content.push(`input, textarea, select { border: 1px solid ${styles.inputBorder}; }`); + } else { + content.push(`input, textarea, select { border: none; }`); + } + + if (styles.inputForeground) { + content.push(`input, textarea, select { color: ${styles.inputForeground}; }`); + } + + if (styles.inputErrorBorder) { + content.push(`.invalid-input, .invalid-input:focus { border: 1px solid ${styles.inputErrorBorder}; }`); + } + + if (styles.inputActiveBorder) { + content.push(`input[type='text']:focus, textarea:focus, select:focus, summary:focus { border: 1px solid ${styles.inputActiveBorder}; outline-style: none; }`); + } + + if (styles.textLinkColor) { + content.push(`a { color: ${styles.textLinkColor}; }`); + } + + if (styles.buttonBackground) { + content.push(`button { background-color: ${styles.buttonBackground}; }`); + } + + if (styles.buttonForeground) { + content.push(`button { color: ${styles.buttonForeground}; }`); + } + + if (styles.buttonHoverBackground) { + content.push(`button:hover:enabled { background-color: ${styles.buttonHoverBackground}; }`); + } + + if (styles.textLinkColor) { + content.push(`a { color: ${styles.textLinkColor}; }`); + } + + styleTag.innerHTML = content.join('\n'); + document.head.appendChild(styleTag); + + document.body.style.backgroundColor = styles.backgroundColor; + document.body.style.color = styles.color; + } + + private initServices(configuration: IWindowConfiguration): void { + const serviceCollection = new ServiceCollection(); + const mainProcessClient = new ElectronIPCClient(String(`window${configuration.windowId}`)); + + const windowsChannel = mainProcessClient.getChannel('windows'); + serviceCollection.set(IWindowsService, new WindowsChannelClient(windowsChannel)); + this.environmentService = new EnvironmentService(configuration, configuration.execPath); + + const sharedProcess = (serviceCollection.get(IWindowsService)).whenSharedProcessReady() + .then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${configuration.windowId}`)); + + const instantiationService = new InstantiationService(serviceCollection, true); + if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) { + const channel = getDelayedChannel(sharedProcess.then(c => c.getChannel('telemetryAppender'))); + const appender = new TelemetryAppenderClient(channel); + const commonProperties = resolveCommonProperties(product.commit, pkg.version, configuration.machineId, this.environmentService.installSourcePath); + const piiPaths = [this.environmentService.appRoot, this.environmentService.extensionsPath]; + const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths }; + + const telemetryService = instantiationService.createInstance(TelemetryService, config); + this._register(telemetryService); + + this.telemetryService = telemetryService; + } else { + this.telemetryService = NullTelemetryService; + } + } + + private setEventHandlers(): void { + document.getElementById('issue-type').addEventListener('change', (event: Event) => { + this.issueReporterModel.update({ issueType: parseInt((event.target).value) }); + this.render(); + }); + + document.getElementById('includeSystemInfo').addEventListener('click', (event: Event) => { + event.stopPropagation(); + this.issueReporterModel.update({ includeSystemInfo: !this.issueReporterModel.getData().includeSystemInfo }); + }); + + document.getElementById('includeProcessInfo').addEventListener('click', (event: Event) => { + event.stopPropagation(); + this.issueReporterModel.update({ includeProcessInfo: !this.issueReporterModel.getData().includeSystemInfo }); + }); + + document.getElementById('includeWorkspaceInfo').addEventListener('click', (event: Event) => { + event.stopPropagation(); + this.issueReporterModel.update({ includeWorkspaceInfo: !this.issueReporterModel.getData().includeWorkspaceInfo }); + }); + + document.getElementById('description').addEventListener('blur', (event: Event) => { + this.issueReporterModel.update({ issueDescription: (event.target).value }); + }); + + function addIssuesToList(list, issueJSON) { + for (let i = 0; i < 5; i++) { + const link = $('a', { href: issueJSON[i].html_url }); + link.textContent = issueJSON[i].title; + link.addEventListener('click', (event) => { + shell.openExternal((event.target).href); + }); + + const item = $('li', {}, link); + list.appendChild(item); + } + } + + document.getElementById('issue-title').addEventListener('blur', (event) => { + const title = (event.target).value; + const similarIssues = document.getElementById('similar-issues'); + similarIssues.innerHTML = ''; + + if (title) { + const query = `is:issue+repo:microsoft/vscode+${title}`; + window.fetch(`https://api.github.com/search/issues?q=${query}&per_page=5`).then((response) => { + response.json().then(result => { + if (result.items.length) { + const issues = $('ul'); + const issuesText = $('div.list-title'); + issuesText.textContent = 'Similar issues:'; + addIssuesToList(issues, result.items); + similarIssues.appendChild(issuesText); + similarIssues.appendChild(issues); + } + }); + }).catch((error) => { + console.log(error); + }); + } + }); + + document.getElementById('github-submit-btn').addEventListener('click', () => this.createIssue()); + } + + private renderBlocks(): void { + // Depending on Issue Type, we render different blocks and text + const { issueType } = this.issueReporterModel.getData(); + const systemBlock = document.querySelector('.block-system'); + const processBlock = document.querySelector('.block-process'); + const workspaceBlock = document.querySelector('.block-workspace'); + + const descriptionTitle = document.querySelector('.block-description .block-title'); + const descriptionSubtitle = document.querySelector('.block-description .block-subtitle'); + + // 1 - Bug + if (issueType === 0) { + show(systemBlock); + hide(processBlock); + hide(workspaceBlock); + + descriptionTitle.innerHTML = 'Steps to reproduce *'; + show(descriptionSubtitle); + descriptionSubtitle.innerHTML = 'How did you encounter this problem? Clear steps to reproduce the problem help our investigation. What did you expect to happen and what actually happened?'; + } + // 2 - Perf Issue + else if (issueType === 1) { + show(systemBlock); + show(processBlock); + show(workspaceBlock); + + descriptionTitle.innerHTML = 'Steps to reproduce *'; + show(descriptionSubtitle); + descriptionSubtitle.innerHTML = 'When did this performance issue happen? For example, does it occur on startup or after a specific series of actions? Any details you can provide help our investigation.'; + } + // 3 - Feature Request + else { + hide(systemBlock); + hide(processBlock); + hide(workspaceBlock); + + descriptionTitle.innerHTML = 'Description *'; + hide(descriptionSubtitle); + } + } + + private validateInput(inputId: string): boolean { + const inputElement = (document.getElementById(inputId)); + if (!inputElement.value) { + show(document.getElementById(`${inputId}-validation-error`)); + inputElement.classList.add('invalid-input'); + return false; + } else { + hide(document.getElementById(`${inputId}-validation-error`)); + inputElement.classList.remove('invalid-input'); + return true; + } + } + + private validateInputs(): boolean { + let isValid = true; + ['issue-title', 'description'].forEach(elementId => { + isValid = this.validateInput(elementId) && isValid; + + }); + + return isValid; + } + + private createIssue(): void { + if (!this.validateInputs()) { + // If inputs are invalid, set focus to the first one and add listeners on them + // to detect further changes + (document.getElementsByClassName('invalid-input')[0]).focus(); + + document.getElementById('issue-title').addEventListener('input', (event) => { + this.validateInput('issue-title'); + }); + + document.getElementById('description').addEventListener('input', (event) => { + this.validateInput('description'); + }); + return; + } + + if (this.telemetryService) { + /* __GDPR__ + "issueReporterSubmit" : { + "issueType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType }); + } + + const issueTitle = (document.getElementById('issue-title')).value; + const baseUrl = `https://github.com/microsoft/vscode/issues/new?title=${issueTitle}&body=`; + const issueBody = this.issueReporterModel.serialize(); + shell.openExternal(baseUrl + encodeURIComponent(issueBody)); + } + + /** + * Update blocks + */ + + private updateAllBlocks(state) { + this.updateVersionInfo(state); + this.updateSystemInfo(state); + this.updateProcessInfo(state); + this.updateWorkspaceInfo(state); + } + + private updateVersionInfo = (state: IssueReporterData) => { + const version = document.getElementById('vscode-version'); + (version).value = state.versionInfo.vscodeVersion; + + const osversion = document.getElementById('os'); + (osversion).value = state.versionInfo.os; + } + + private updateSystemInfo = (state) => { + const target = document.querySelector('.block-system .block-info'); + let tableHtml = ''; + Object.keys(state.systemInfo).forEach(k => { + tableHtml += ` + + ${k} + ${state.systemInfo[k]} +`; + }); + target.innerHTML = `${tableHtml}
`; + } + + private updateProcessInfo = (state) => { + const target = document.querySelector('.block-process .block-info'); + + let tableHtml = ` + + pid + CPU % + Memory (MB) + Name + +`; + state.processInfo.forEach(p => { + tableHtml += ` + + ${p.pid} + ${p.cpu} + ${p.memory} + ${p.name} +`; + }); + target.innerHTML = `${tableHtml}
`; + } + + private updateWorkspaceInfo = (state) => { + document.querySelector('.block-workspace .block-info code').textContent = '\n' + state.workspaceInfo; + } +} + +// helper functions + +function hide(el) { + el.classList.add('hidden'); +} +function show(el) { + el.classList.remove('hidden'); +} diff --git a/src/vs/code/electron-browser/issue/issueReporterModel.ts b/src/vs/code/electron-browser/issue/issueReporterModel.ts new file mode 100644 index 00000000000..ab6facf3a25 --- /dev/null +++ b/src/vs/code/electron-browser/issue/issueReporterModel.ts @@ -0,0 +1,134 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { assign } from 'vs/base/common/objects'; + +export interface IssueReporterData { + issueType?: number; + issueDescription?: string; + versionInfo?: any; + systemInfo?: any; + processInfo?: any; + workspaceInfo?: any; + includeSystemInfo?: boolean; + includeWorkspaceInfo?: boolean; + includeProcessInfo?: boolean; +} + +export class IssueReporterModel { + private _data: IssueReporterData; + + constructor(initialData?: IssueReporterData) { + this._data = initialData || {}; + } + + getData(): IssueReporterData { + return this._data; + } + + update(newData: IssueReporterData): void { + assign(this._data, newData); + } + + serialize(): string { + return ` +### Issue Type +${this.getIssueTypeTitle()} + +### Description + +${this._data.issueDescription} + +### VS Code Info + +VS Code version: ${this._data.versionInfo && this._data.versionInfo.vscodeVersion} +OS version: ${this._data.versionInfo && this._data.versionInfo.os} + +${this.getInfos()} + + +`; + } + + private getIssueTypeTitle(): string { + if (this._data.issueType === 0) { + return 'Bug'; + } else if (this._data.issueType === 1) { + return 'Performance Issue'; + } else { + return 'Feature Request'; + } + } + + private getInfos(): string { + let info = ''; + + if (this._data.includeSystemInfo) { + info += this.generateSystemInfoMd(); + } + + // For perf issue, add process info and workspace info too + if (this._data.issueType === 1) { + + if (this._data.includeProcessInfo) { + info += this.generateProcessInfoMd(); + } + + if (this._data.includeWorkspaceInfo) { + info += this.generateWorkspaceInfoMd(); + } + } + + return info; + } + + private generateSystemInfoMd(): string { + let md = `
+System Info + +|Item|Value| +|---|---| +`; + + Object.keys(this._data.systemInfo).forEach(k => { + md += `|${k}|${this._data.systemInfo[k]}|\n`; + }); + + md += '\n
'; + + return md; + } + + private generateProcessInfoMd(): string { + let md = `
+Process Info + +|pid|CPU|Memory (MB)|Name| +|---|---|---|---| +`; + + this._data.processInfo.forEach(p => { + md += `|${p.pid}|${p.cpu}|${p.memory}|${p.name}|\n`; + }); + + md += '\n
'; + + return md; + } + + private generateWorkspaceInfoMd(): string { + return `
+Workspace Info + +\`\`\` +${this._data.workspaceInfo}; +\`\`\` + +
+`; + } +} \ No newline at end of file diff --git a/src/vs/code/electron-browser/issue/media/issueReporter.css b/src/vs/code/electron-browser/issue/media/issueReporter.css new file mode 100644 index 00000000000..cb43afc9bc1 --- /dev/null +++ b/src/vs/code/electron-browser/issue/media/issueReporter.css @@ -0,0 +1,220 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Table + */ + +table { + width: 100%; + max-width: 100%; + margin-bottom: 1rem; + background-color: transparent; + border-collapse: collapse; +} +th { + vertical-align: bottom; + border-bottom: 2px solid #e9ecef; + padding: .75rem; + border-top: 1px solid #e9ecef; + text-align: inherit; +} +tr:nth-of-type(even) { + background-color: rgba(0,0,0,.05); +} +td { + padding: .75rem; + vertical-align: top; + border-top: 1px solid #e9ecef; +} + +/** + * Forms + */ +input, textarea { + display: block; + width: 100%; + padding: .375rem .75rem; + margin: 0; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + border-radius: .25rem; + border: 1px solid #ced4da; +} +textarea { + overflow: auto; + resize: vertical; +} +small { + color: #868e96; + display: block; + margin-top: .25rem; + font-size: 80%; + font-weight: 400; +} + +/** + * Button + */ +button { + display: inline-block; + font-weight: 400; + line-height: 1.25; + text-align: center; + white-space: nowrap; + vertical-align: middle; + user-select: none; + padding: .5rem 1rem; + font-size: 1rem; + border-radius: .25rem; + background: none; +} + +select { + height: calc(2.25rem + 2px); + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + border-radius: 0.25rem; + border: none; +} + +* { + box-sizing: border-box; +} +html { + font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif; + color: #CCCCCC; +} + +body { + margin: 0; + background-color: #1E1E1E; +} + +.hidden { + display: none; +} + +#block-container { + margin-top: 20px; +} + +.block { + margin-bottom: 20px; +} +.block summary { + margin-bottom: 16px; +} + +.block .block-info { + width: 100%; + font-family: 'Menlo', 'Courier New', 'Courier', monospace; + font-size: 14px; + overflow: auto; + overflow-wrap: break-word; +} +pre { + margin: 0; +} +pre code { + font-family: 'Menlo', 'Courier New', 'Courier', monospace; +} + +button:hover:enabled { + cursor: pointer; +} + +button:disabled { + cursor: auto; +} + +#issue-reporter { + max-width: 80vw; + margin-left: auto; + margin-right: auto; + margin-top: 2em; +} + +#github-submit-btn { + float: right; + margin-top: 10px; + margin-bottom: 10px; + +} + +.two-col { + display: inline-block; + width: 49%; +} + +#vscode-version { + width: 90%; +} + +.input-group { + margin-bottom: 1em; +} + +select, input, textarea { + margin-top: 10px; +} + +.validation-error { + font-size: 12px; + font-weight: bold; + margin-top: 1em; +} + +.caption { + display: inline-block; + font-size: 12px; +} + +input[type="checkbox"] { + margin-left: 1em; + width: auto; + display: inline-block; +} + +input:disabled { + opacity: 0.6; +} + +.list-title { + margin-top: 1em; + margin-left: 1em; +} + +/* Default styles, overwritten if a theme is provided */ +input, select, textarea { + background-color: #3c3c3c; + border: none; + color: #cccccc; +} + +a { + color: #CCCCCC; +} + +.invalid-input { + border: 1px solid #be1100; +} + +.required-input { + color: #be1100; +} + +button { + background-color: #007ACC; + color: #fff; + border: none; +} \ No newline at end of file diff --git a/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts b/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts new file mode 100644 index 00000000000..16c41488e74 --- /dev/null +++ b/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as assert from 'assert'; +import { IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel'; + +suite('IssueReporter', () => { + + test('serializes model', () => { + const issueReporterModel = new IssueReporterModel(); + assert.equal(issueReporterModel.serialize(), + ` +### Issue Type +Feature Request + +### Description + +undefined + +### VS Code Info + +VS Code version: undefined +OS version: undefined + + + + +`); + }); +}); diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/contributions.ts b/src/vs/code/electron-browser/sharedProcess/contrib/contributions.ts index 9690ef75a7c..593d731262f 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/contributions.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/contributions.ts @@ -7,7 +7,12 @@ import { NodeCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { LanguagePackExtensions } from 'vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions'; +import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; -export function createSharedProcessContributions(service: IInstantiationService): void { - service.createInstance(NodeCachedDataCleaner); +export function createSharedProcessContributions(service: IInstantiationService): IDisposable { + return combinedDisposable([ + service.createInstance(NodeCachedDataCleaner), + service.createInstance(LanguagePackExtensions) + ]); } diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions.ts b/src/vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions.ts new file mode 100644 index 00000000000..1add53f4777 --- /dev/null +++ b/src/vs/code/electron-browser/sharedProcess/contrib/languagePackExtensions.ts @@ -0,0 +1,108 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as pfs from 'vs/base/node/pfs'; +import { IExtensionManagementService, ILocalExtension, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { join } from 'vs/base/common/paths'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { Limiter } from 'vs/base/common/async'; +import { areSameExtensions, getGalleryExtensionIdFromLocal, getIdFromLocalExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; +import { ILogService } from 'vs/platform/log/common/log'; + +interface ILanguageSource { + extensionIdentifier: IExtensionIdentifier; + version: string; + path: string; +} + +export class LanguagePackExtensions extends Disposable { + + private languagePacksFilePath: string; + private languagePacksFileLimiter: Limiter; + + constructor( + @IExtensionManagementService private extensionManagementService: IExtensionManagementService, + @IEnvironmentService environmentService: IEnvironmentService, + @ILogService private logService: ILogService + ) { + super(); + this.languagePacksFilePath = join(environmentService.userDataPath, 'languagepacks.json'); + this.languagePacksFileLimiter = new Limiter(1); + + this._register(extensionManagementService.onDidInstallExtension(({ local }) => this.onDidInstallExtension(local))); + this._register(extensionManagementService.onDidUninstallExtension(({ identifier }) => this.onDidUninstallExtension(identifier))); + + this.reset(); + } + + private reset(): void { + this.extensionManagementService.getInstalled() + .then(installed => { + this.withLanguagePacks(languagePacks => { + for (const language of Object.keys(languagePacks)) { + languagePacks[language] = []; + } + this.addLanguagePacksFromExtensions(languagePacks, ...installed); + }); + }); + } + + private onDidInstallExtension(extension: ILocalExtension): void { + if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.locales && extension.manifest.contributes.locales.length) { + this.logService.debug('Adding language packs from the extension', extension.identifier.id); + this.withLanguagePacks(languagePacks => { + this.removeLanguagePacksFromExtensions(languagePacks, { id: getGalleryExtensionIdFromLocal(extension), uuid: extension.identifier.uuid }); + this.addLanguagePacksFromExtensions(languagePacks, extension); + }); + } + } + + private onDidUninstallExtension(identifier: IExtensionIdentifier): void { + this.logService.debug('Removing language packs from the extension', identifier.id); + this.withLanguagePacks(languagePacks => this.removeLanguagePacksFromExtensions(languagePacks, { id: getIdFromLocalExtensionId(identifier.id), uuid: identifier.uuid })); + } + + private addLanguagePacksFromExtensions(languagePacks: { [language: string]: ILanguageSource[] }, ...extensions: ILocalExtension[]): void { + for (const extension of extensions) { + if (extension && extension.manifest && extension.manifest.contributes && extension.manifest.contributes.locales && extension.manifest.contributes.locales.length) { + const extensionIdentifier = { id: getGalleryExtensionIdFromLocal(extension), uuid: extension.identifier.uuid }; + for (const localeContribution of extension.manifest.contributes.locales) { + const languageSources = languagePacks[localeContribution.locale] || []; + languageSources.splice(0, 0, { extensionIdentifier, path: join(extension.path, localeContribution.path), version: extension.manifest.version }); + languagePacks[localeContribution.locale] = languageSources; + } + } + } + } + + private removeLanguagePacksFromExtensions(languagePacks: { [language: string]: ILanguageSource[] }, ...extensionIdentifiers: IExtensionIdentifier[]): void { + for (const language of Object.keys(languagePacks)) { + languagePacks[language] = languagePacks[language].filter(languageSource => !extensionIdentifiers.some(extensionIdentifier => areSameExtensions(extensionIdentifier, languageSource.extensionIdentifier))); + } + } + + private withLanguagePacks(fn: (languagePacks: { [language: string]: ILanguageSource[] }) => T): TPromise { + return this.languagePacksFileLimiter.queue(() => { + let result: T = null; + return pfs.readFile(this.languagePacksFilePath, 'utf8') + .then(null, err => err.code === 'ENOENT' ? TPromise.as('{}') : TPromise.wrapError(err)) + .then<{ [language: string]: ILanguageSource[] }>(raw => { try { return JSON.parse(raw); } catch (e) { return {}; } }) + .then(languagePacks => { result = fn(languagePacks); return languagePacks; }) + .then(languagePacks => { + for (const language of Object.keys(languagePacks)) { + if (!(languagePacks[language] && languagePacks[language].length)) { + delete languagePacks[language]; + } + } + const raw = JSON.stringify(languagePacks); + this.logService.debug('Writing language packs', raw); + return pfs.writeFile(this.languagePacksFilePath, raw); + }) + .then(() => result, error => this.logService.error(error)); + }); + } +} \ No newline at end of file diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index b72b6847723..46fbe9ce0b2 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -51,13 +51,13 @@ import { KeyboardLayoutMonitor } from 'vs/code/electron-main/keyboard'; import URI from 'vs/base/common/uri'; import { WorkspacesChannel } from 'vs/platform/workspaces/common/workspacesIpc'; import { IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces'; -import { dirname, join } from 'path'; -import { touch } from 'vs/base/node/pfs'; import { getMachineId } from 'vs/base/node/id'; +import { IIssueService } from 'vs/platform/issue/common/issue'; +import { IssueChannel } from 'vs/platform/issue/common/issueIpc'; +import { IssueService } from 'vs/platform/issue/electron-main/issueService'; export class CodeApplication { - private static readonly APP_ICON_REFRESH_KEY = 'macOSAppIconRefresh3'; private static readonly MACHINE_ID_KEY = 'telemetry.machineId'; private toDispose: IDisposable[]; @@ -129,8 +129,16 @@ export class CodeApplication { } }); - const isValidWebviewSource = (source: string) => - !source || (URI.parse(source.toLowerCase()).toString() as any).startsWith(URI.file(this.environmentService.appRoot.toLowerCase()).toString()); + const isValidWebviewSource = (source: string): boolean => { + if (!source) { + return false; + } + if (source === 'data:text/html;charset=utf-8,%3C%21DOCTYPE%20html%3E%0D%0A%3Chtml%20lang%3D%22en%22%20style%3D%22width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3Chead%3E%0D%0A%09%3Ctitle%3EVirtual%20Document%3C%2Ftitle%3E%0D%0A%3C%2Fhead%3E%0D%0A%3Cbody%20style%3D%22margin%3A%200%3B%20overflow%3A%20hidden%3B%20width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3C%2Fbody%3E%0D%0A%3C%2Fhtml%3E') { + return true; + } + const srcUri: any = URI.parse(source.toLowerCase()).toString(); + return srcUri.startsWith(URI.file(this.environmentService.appRoot.toLowerCase()).toString()); + }; app.on('web-contents-created', (_event: any, contents) => { contents.on('will-attach-webview', (event: Electron.Event, webPreferences, params) => { @@ -303,6 +311,7 @@ export class CodeApplication { services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, machineId)); services.set(IWindowsService, new SyncDescriptor(WindowsService, this.sharedProcess)); services.set(ILaunchService, new SyncDescriptor(LaunchService)); + services.set(IIssueService, new SyncDescriptor(IssueService, machineId)); // Telemtry if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) { @@ -347,6 +356,10 @@ export class CodeApplication { const urlChannel = appInstantiationService.createInstance(URLChannel, urlService); this.electronIpcServer.registerChannel('url', urlChannel); + const issueService = accessor.get(IIssueService); + const issueChannel = new IssueChannel(issueService); + this.electronIpcServer.registerChannel('issue', issueChannel); + const workspacesService = accessor.get(IWorkspacesMainService); const workspacesChannel = appInstantiationService.createInstance(WorkspacesChannel, workspacesService); this.electronIpcServer.registerChannel('workspaces', workspacesChannel); @@ -425,18 +438,10 @@ export class CodeApplication { // Start shared process here this.sharedProcess.spawn(); - // Helps application icon refresh after an update with new icon is installed (macOS) - // TODO@Ben remove after a couple of releases - if (platform.isMacintosh) { - if (!this.stateService.getItem(CodeApplication.APP_ICON_REFRESH_KEY)) { - this.stateService.setItem(CodeApplication.APP_ICON_REFRESH_KEY, true); - - // 'exe' => /Applications/Visual Studio Code - Insiders.app/Contents/MacOS/Electron - const appPath = dirname(dirname(dirname(app.getPath('exe')))); - const infoPlistPath = join(appPath, 'Contents', 'Info.plist'); - touch(appPath).done(null, error => { /* ignore */ }); - touch(infoPlistPath).done(null, error => { /* ignore */ }); - } + // Launch Issue BrowserWindow if --issue is specified + if (this.environmentService.args.issue) { + const issueService = accessor.get(IIssueService); + issueService.openReporter(); } } diff --git a/src/vs/code/electron-main/diagnostics.ts b/src/vs/code/electron-main/diagnostics.ts index a1720cc0568..8a3fb1445fd 100644 --- a/src/vs/code/electron-main/diagnostics.ts +++ b/src/vs/code/electron-main/diagnostics.ts @@ -17,6 +17,77 @@ import { isWindows } from 'vs/base/common/platform'; import { app } from 'electron'; import { basename } from 'path'; +export interface VersionInfo { + vscodeVersion: string; + os: string; +} + +export interface SystemInfo { + CPUs?: string; + 'Memory (System)': string; + 'Load (avg)'?: string; + VM: string; + 'Screen Reader': string; + 'Process Argv': string; +} + +export interface ProcessInfo { + cpu: number; + memory: number; + pid: number; + name: string; +} + +export interface DiagnosticInfo { + versionInfo?: VersionInfo; + systemInfo?: SystemInfo; + processInfo?: ProcessInfo[]; + workspaceInfo?: string; +} + +export function buildDiagnostics(info: IMainProcessInfo): Promise { + return listProcesses(info.mainPID).then(rootProcess => { + const workspaceInfoMessages = []; + + // Workspace Stats + if (info.windows.some(window => window.folders && window.folders.length > 0)) { + info.windows.forEach(window => { + if (window.folders.length === 0) { + return; + } + + workspaceInfoMessages.push(`| Window (${window.title})`); + + window.folders.forEach(folder => { + try { + const stats = collectWorkspaceStats(folder, ['node_modules', '.git']); + let countMessage = `${stats.fileCount} files`; + if (stats.maxFilesReached) { + countMessage = `more than ${countMessage}`; + } + workspaceInfoMessages.push(`| Folder (${basename(folder)}): ${countMessage}`); + workspaceInfoMessages.push(formatWorkspaceStats(stats)); + + const launchConfigs = collectLaunchConfigs(folder); + if (launchConfigs.length > 0) { + workspaceInfoMessages.push(formatLaunchConfigs(launchConfigs)); + } + } catch (error) { + workspaceInfoMessages.push(`| Error: Unable to collect workpsace stats for folder ${folder} (${error.toString()})`); + } + }); + }); + } + + return { + versionInfo: getVersionInfo(), + systemInfo: getSystemInfo(info), + processInfo: getProcessList(info, rootProcess), + workspaceInfo: workspaceInfoMessages.join('\n') + }; + }); +} + export function printDiagnostics(info: IMainProcessInfo): Promise { return listProcesses(info.mainPID).then(rootProcess => { @@ -83,7 +154,6 @@ function formatWorkspaceStats(workspaceStats: WorkspaceStats): string { line += item; }; - // File Types let line = '| File types:'; const maxShown = 10; @@ -118,6 +188,81 @@ function formatLaunchConfigs(configs: WorkspaceStatItem[]): string { return output.join('\n'); } +function getVersionInfo(): VersionInfo { + return { + vscodeVersion: `${pkg.name} ${pkg.version} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})`, + os: `${os.type()} ${os.arch()} ${os.release()}` + }; +} + +function getSystemInfo(info: IMainProcessInfo): SystemInfo { + const MB = 1024 * 1024; + const GB = 1024 * MB; + + const systemInfo: SystemInfo = { + 'Memory (System)': `${(os.totalmem() / GB).toFixed(2)}GB (${(os.freemem() / GB).toFixed(2)}GB free)`, + VM: `${Math.round((virtualMachineHint.value() * 100))}%`, + 'Screen Reader': `${app.isAccessibilitySupportEnabled() ? 'yes' : 'no'}`, + 'Process Argv': `${info.mainArguments.join(' ')}` + }; + + const cpus = os.cpus(); + if (cpus && cpus.length > 0) { + systemInfo.CPUs = `${cpus[0].model} (${cpus.length} x ${cpus[0].speed})`; + } + + if (!isWindows) { + systemInfo['Load (avg)'] = `${os.loadavg().map(l => Math.round(l)).join(', ')}`; + } + + + return systemInfo; +} + +function getProcessList(info: IMainProcessInfo, rootProcess: ProcessItem): ProcessInfo[] { + const mapPidToWindowTitle = new Map(); + info.windows.forEach(window => mapPidToWindowTitle.set(window.pid, window.title)); + + const processes: ProcessInfo[] = []; + getProcessItem(mapPidToWindowTitle, processes, rootProcess, 0); + + if (rootProcess) { + getProcessItem(mapPidToWindowTitle, processes, rootProcess, 0); + } + + return processes; +} + +function getProcessItem(mapPidToWindowTitle: Map, processes: ProcessInfo[], item: ProcessItem, indent: number): void { + const isRoot = (indent === 0); + + const MB = 1024 * 1024; + + // Format name with indent + let name: string; + if (isRoot) { + name = `${product.applicationName} main`; + } else { + name = `${repeat('--', indent)} ${item.name}`; + + if (item.name === 'window') { + name = `${name} (${mapPidToWindowTitle.get(item.pid)})`; + } + } + const memory = process.platform === 'win32' ? item.mem : (os.totalmem() * (item.mem / 100)); + processes.push({ + cpu: Number(item.load.toFixed(0)), + memory: Number((memory / MB).toFixed(0)), + pid: Number((item.pid).toFixed(0)), + name + }); + + // Recurse into children if any + if (Array.isArray(item.children)) { + item.children.forEach(child => getProcessItem(mapPidToWindowTitle, processes, child, indent + 1)); + } +} + function formatEnvironment(info: IMainProcessInfo): string { const MB = 1024 * 1024; const GB = 1024 * MB; @@ -178,4 +323,4 @@ function formatProcessItem(mapPidToWindowTitle: Map, output: str if (Array.isArray(item.children)) { item.children.forEach(child => formatProcessItem(mapPidToWindowTitle, output, child, indent + 1)); } -} \ No newline at end of file +} diff --git a/src/vs/code/electron-main/launch.ts b/src/vs/code/electron-main/launch.ts index 86324ae6c63..17f5ac6ffde 100644 --- a/src/vs/code/electron-main/launch.ts +++ b/src/vs/code/electron-main/launch.ts @@ -10,7 +10,7 @@ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { ILogService } from 'vs/platform/log/common/log'; import { IURLService } from 'vs/platform/url/common/url'; import { IProcessEnvironment } from 'vs/base/common/platform'; -import { ParsedArgs } from 'vs/platform/environment/common/environment'; +import { ParsedArgs, IEnvironmentService } from 'vs/platform/environment/common/environment'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { OpenContext } from 'vs/platform/windows/common/windows'; import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows'; @@ -42,12 +42,14 @@ export interface ILaunchService { start(args: ParsedArgs, userEnv: IProcessEnvironment): TPromise; getMainProcessId(): TPromise; getMainProcessInfo(): TPromise; + getLogsPath(): TPromise; } export interface ILaunchChannel extends IChannel { call(command: 'start', arg: IStartArguments): TPromise; call(command: 'get-main-process-id', arg: null): TPromise; call(command: 'get-main-process-info', arg: null): TPromise; + call(command: 'get-logs-path', arg: null): TPromise; call(command: string, arg: any): TPromise; } @@ -66,6 +68,9 @@ export class LaunchChannel implements ILaunchChannel { case 'get-main-process-info': return this.service.getMainProcessInfo(); + + case 'get-logs-path': + return this.service.getLogsPath(); } return undefined; @@ -89,6 +94,10 @@ export class LaunchChannelClient implements ILaunchService { public getMainProcessInfo(): TPromise { return this.channel.call('get-main-process-info', null); } + + public getLogsPath(): TPromise { + return this.channel.call('get-logs-path', null); + } } export class LaunchService implements ILaunchService { @@ -99,32 +108,32 @@ export class LaunchService implements ILaunchService { @ILogService private logService: ILogService, @IWindowsMainService private windowsMainService: IWindowsMainService, @IURLService private urlService: IURLService, - @IWorkspacesMainService private workspacesMainService: IWorkspacesMainService + @IWorkspacesMainService private workspacesMainService: IWorkspacesMainService, + @IEnvironmentService private readonly environmentService: IEnvironmentService ) { } public start(args: ParsedArgs, userEnv: IProcessEnvironment): TPromise { this.logService.trace('Received data from other instance: ', args, userEnv); // Check early for open-url which is handled in URL service - const openUrl = this.startOpenUrl(args); - if (openUrl) { - return openUrl; + if (this.shouldOpenUrl(args)) { + return TPromise.as(null); } // Otherwise handle in windows service return this.startOpenWindow(args, userEnv); } - private startOpenUrl(args: ParsedArgs): TPromise { - const openUrlArg = args['open-url'] || []; - const openUrl = typeof openUrlArg === 'string' ? [openUrlArg] : openUrlArg; - if (openUrl.length > 0) { - openUrl.forEach(url => this.urlService.open(url)); + private shouldOpenUrl(args: ParsedArgs): boolean { + if (args['open-url'] && args._urls && args._urls.length > 0) { + // --open-url must contain -- followed by the url(s) + // process.argv is used over args._ as args._ are resolved to file paths at this point + args._urls.forEach(url => this.urlService.open(url)); - return TPromise.as(null); + return true; } - return void 0; + return false; } private startOpenWindow(args: ParsedArgs, userEnv: IProcessEnvironment): TPromise { @@ -180,6 +189,11 @@ export class LaunchService implements ILaunchService { } as IMainProcessInfo); } + public getLogsPath(): TPromise { + this.logService.trace('Received request for logs path from other instance.'); + return TPromise.as(this.environmentService.logsPath); + } + private getWindowInfo(window: ICodeWindow): IWindowInfo { const folders: string[] = []; @@ -200,4 +214,4 @@ export class LaunchService implements ILaunchService { folders } as IWindowInfo; } -} \ No newline at end of file +} diff --git a/src/vs/code/electron-main/logUploader.ts b/src/vs/code/electron-main/logUploader.ts new file mode 100644 index 00000000000..f4a034627d3 --- /dev/null +++ b/src/vs/code/electron-main/logUploader.ts @@ -0,0 +1,134 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as os from 'os'; +import * as cp from 'child_process'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as readline from 'readline'; + +import { localize } from 'vs/nls'; +import { ILaunchChannel } from 'vs/code/electron-main/launch'; +import { TPromise } from 'vs/base/common/winjs.base'; +import product from 'vs/platform/node/product'; +import { IRequestService } from 'vs/platform/request/node/request'; +import { IRequestContext } from 'vs/base/node/request'; + +interface PostResult { + readonly blob_id: string; +} + +class Endpoint { + private constructor( + public readonly url: string + ) { } + + public static getFromProduct(): Endpoint | undefined { + const logUploaderUrl = product.logUploaderUrl; + return logUploaderUrl ? new Endpoint(logUploaderUrl) : undefined; + } +} + +export async function uploadLogs( + channel: ILaunchChannel, + requestService: IRequestService +): TPromise { + const endpoint = Endpoint.getFromProduct(); + if (!endpoint) { + console.error(localize('invalidEndpoint', 'Invalid log uploader endpoint')); + return; + } + + const logsPath = await channel.call('get-logs-path', null); + + if (await promptUserToConfirmLogUpload(logsPath)) { + const outZip = await zipLogs(logsPath); + const result = await postLogs(endpoint, outZip, requestService); + console.log(localize('didUploadLogs', 'Uploaded logs ID: {0}', result.blob_id)); + } else { + console.log(localize('userDeniedUpload', 'Canceled upload')); + } +} + +async function promptUserToConfirmLogUpload( + logsPath: string +): Promise { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + + return new TPromise(resolve => + rl.question( + localize('logUploadPromptHeader', 'Upload session logs to secure endpoint?') + + '\n\n' + localize('logUploadPromptBody', 'Please review your log files: \'{0}\'', logsPath) + + '\n\n' + localize('logUploadPromptKey', 'Enter \'y\' to confirm upload...'), + (answer: string) => { + rl.close(); + resolve(answer && answer.trim()[0].toLowerCase() === 'y'); + })); +} + +async function postLogs( + endpoint: Endpoint, + outZip: string, + requestService: IRequestService +): TPromise { + let result: IRequestContext; + try { + result = await requestService.request({ + url: endpoint.url, + type: 'POST', + data: fs.createReadStream(outZip), + headers: { + 'Content-Type': 'application/zip', + 'Content-Length': fs.statSync(outZip).size + } + }); + } catch (e) { + console.log(localize('postError', 'Error posting logs: {0}', e)); + throw e; + } + + try { + return JSON.parse(result.stream.toString()); + } catch (e) { + console.log(localize('parseError', 'Error parsing response')); + throw e; + } +} + +function zipLogs( + logsPath: string +): TPromise { + const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vscode-log-upload')); + const outZip = path.join(tempDir, 'logs.zip'); + return new TPromise((resolve, reject) => { + doZip(logsPath, outZip, (err, stdout, stderr) => { + if (err) { + console.error(localize('zipError', 'Error zipping logs: {0}', err)); + reject(err); + } else { + resolve(outZip); + } + }); + }); +} + +function doZip( + logsPath: string, + outZip: string, + callback: (error: Error, stdout: string, stderr: string) => void +) { + switch (os.platform()) { + case 'win32': + return cp.execFile('powershell', ['-Command', `Compress-Archive -Path "${logsPath}" -DestinationPath ${outZip}`], { cwd: logsPath }, callback); + + default: + return cp.execFile('zip', ['-r', outZip, '.'], { cwd: logsPath }, callback); + } +} \ No newline at end of file diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 4da562dfb9c..ea7bf733406 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -66,7 +66,7 @@ function createServices(args: ParsedArgs, bufferLogService: BufferLogService): I services.set(IStateService, new SyncDescriptor(StateService)); services.set(IConfigurationService, new SyncDescriptor(ConfigurationService)); services.set(IRequestService, new SyncDescriptor(RequestService)); - services.set(IURLService, new SyncDescriptor(URLService, args['open-url'])); + services.set(IURLService, new SyncDescriptor(URLService, args['open-url'] ? args._urls : [])); services.set(IBackupMainService, new SyncDescriptor(BackupMainService)); return new InstantiationService(services, true); @@ -104,6 +104,7 @@ class ExpectedError extends Error { function setupIPC(accessor: ServicesAccessor): TPromise { const logService = accessor.get(ILogService); const environmentService = accessor.get(IEnvironmentService); + const requestService = accessor.get(IRequestService); function allowSetForegroundWindow(service: LaunchChannelClient): TPromise { let promise = TPromise.wrap(void 0); @@ -133,6 +134,12 @@ function setupIPC(accessor: ServicesAccessor): TPromise { throw new ExpectedError('Terminating...'); } + // Log uploader usage info + if (environmentService.args['upload-logs']) { + logService.warn('Warning: The --upload-logs argument can only be used if Code is already running. Please run it again after Code has started.'); + throw new ExpectedError('Terminating...'); + } + // dock might be hidden at this case due to a retry if (platform.isMacintosh) { app.dock.show(); @@ -170,7 +177,7 @@ function setupIPC(accessor: ServicesAccessor): TPromise { // Skip this if we are running with --wait where it is expected that we wait for a while. // Also skip when gathering diagnostics (--status) which can take a longer time. let startupWarningDialogHandle: number; - if (!environmentService.wait && !environmentService.status) { + if (!environmentService.wait && !environmentService.status && !environmentService.args['upload-logs']) { startupWarningDialogHandle = setTimeout(() => { showStartupWarningDialog( localize('secondInstanceNoResponse', "Another instance of {0} is running but not responding", product.nameShort), @@ -189,6 +196,13 @@ function setupIPC(accessor: ServicesAccessor): TPromise { }); } + // Log uploader + if (environmentService.args['upload-logs']) { + return import('vs/code/electron-main/logUploader') + .then(logUploader => logUploader.uploadLogs(channel, requestService)) + .then(() => TPromise.wrapError(new ExpectedError())); + } + logService.trace('Sending env to running instance...'); return allowSetForegroundWindow(service) diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 59229fbc739..aafae0c8ed9 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -327,7 +327,7 @@ export class CodeMenu { const showAll = new MenuItem({ label: nls.localize('mShowAll', "Show All"), role: 'unhide' }); const quit = new MenuItem(this.likeAction('workbench.action.quit', { label: nls.localize('miQuit', "Quit {0}", product.nameLong), click: () => { - if (this.windowsMainService.getWindowCount() === 0 || !!this.windowsMainService.getFocusedWindow()) { + if (this.windowsMainService.getWindowCount() === 0 || !!BrowserWindow.getFocusedWindow()) { this.windowsMainService.quit(); // fix for https://github.com/Microsoft/vscode/issues/39191 } } diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 0ac89554809..073f7dc441f 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -148,7 +148,7 @@ export class WindowsManager implements IWindowsMainService { this.windowsState.openedWindows = []; } - this.dialogs = new Dialogs(environmentService, telemetryService, stateService, this, this.logService); + this.dialogs = new Dialogs(environmentService, telemetryService, stateService, this); this.workspacesManager = new WorkspacesManager(workspacesMainService, backupMainService, environmentService, this); } @@ -369,7 +369,7 @@ export class WindowsManager implements IWindowsMainService { let foldersToRestore: string[] = []; let workspacesToRestore: IWorkspaceIdentifier[] = []; let emptyToRestore: string[] = []; - if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath) { + if (openConfig.initialStartup && !openConfig.cli.extensionDevelopmentPath && !openConfig.cli['disable-restore-windows']) { foldersToRestore = this.backupMainService.getFolderBackupPaths(); workspacesToRestore = this.backupMainService.getWorkspaceBackups(); // collect from workspaces with hot-exit backups @@ -1565,7 +1565,6 @@ class Dialogs { private telemetryService: ITelemetryService, private stateService: IStateService, private windowsMainService: IWindowsMainService, - private logService: ILogService // TODO@Ben remove logging when no longer needed ) { this.mapWindowToDialogQueue = new Map>(); this.noWindowDialogQueue = new Queue(); @@ -1645,31 +1644,22 @@ class Dialogs { private getDialogQueue(window?: ICodeWindow): Queue { if (!window) { - this.logService.info('getDialogQueue: using NO WINDOW queue. size: ', this.noWindowDialogQueue.size); return this.noWindowDialogQueue; } let windowDialogQueue = this.mapWindowToDialogQueue.get(window.id); if (!windowDialogQueue) { - this.logService.info('getDialogQueue: creating window dialog queue for window:', window.id); windowDialogQueue = new Queue(); this.mapWindowToDialogQueue.set(window.id, windowDialogQueue); - } else { - this.logService.info('getDialogQueue: found existing window dialog queue for window:', window.id); } - this.logService.info('getDialogQueue: size: ', windowDialogQueue.size); - return windowDialogQueue; } public showMessageBox(options: Electron.MessageBoxOptions, window?: ICodeWindow): TPromise { - this.logService.info('showMessageBox begin: ', options, window ? window.id : 'No Window'); return this.getDialogQueue(window).queue(() => { return new TPromise((c, e) => { - this.logService.info('showMessageBox opening'); dialog.showMessageBox(window ? window.win : void 0, options, (response: number, checkboxChecked: boolean) => { - this.logService.info('showMessageBox closed, response: ', response, checkboxChecked); c({ button: response, checkboxChecked }); }); }); @@ -1685,12 +1675,9 @@ class Dialogs { return path; } - this.logService.info('showSaveDialog begin: ', options, window ? window.id : 'No Window'); return this.getDialogQueue(window).queue(() => { return new TPromise((c, e) => { - this.logService.info('showSaveDialog opening'); dialog.showSaveDialog(window ? window.win : void 0, options, path => { - this.logService.info('showSaveDialog closed, response: ', path); c(normalizePath(path)); }); }); @@ -1706,12 +1693,9 @@ class Dialogs { return paths; } - this.logService.info('showOpenDialog begin: ', options, window ? window.id : 'No Window'); return this.getDialogQueue(window).queue(() => { return new TPromise((c, e) => { - this.logService.info('showOpenDialog opening'); dialog.showOpenDialog(window ? window.win : void 0, options, paths => { - this.logService.info('showOpenDialog closed, response: ', paths); c(normalizePaths(paths)); }); }); diff --git a/src/vs/code/node/paths.ts b/src/vs/code/node/paths.ts index 848b77a3c87..d54353ff72e 100644 --- a/src/vs/code/node/paths.ts +++ b/src/vs/code/node/paths.ts @@ -15,6 +15,11 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { realpathSync } from 'vs/base/node/extfs'; export function validatePaths(args: ParsedArgs): ParsedArgs { + // Track URLs if they're going to be used + if (args['open-url']) { + args._urls = args._; + args._ = []; + } // Realpath/normalize paths and watch out for goto line mode const paths = doValidatePaths(args._, args.goto); diff --git a/src/vs/editor/common/commonCodeEditor.ts b/src/vs/editor/common/commonCodeEditor.ts index 8f1ea366af2..3ebaf23011e 100644 --- a/src/vs/editor/common/commonCodeEditor.ts +++ b/src/vs/editor/common/commonCodeEditor.ts @@ -940,6 +940,9 @@ export abstract class CommonCodeEditor extends Disposable { this.listenersToRemove.push(this.model.onDidChangeDecorations((e) => this._onDidChangeModelDecorations.fire(e))); this.listenersToRemove.push(this.model.onDidChangeLanguage((e) => { + if (!this.model) { + return; + } this.domElement.setAttribute('data-mode-id', this.model.getLanguageIdentifier().language); this._onDidChangeModelLanguage.fire(e); })); diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index da33dd2058d..a51f6df0ba1 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -352,8 +352,8 @@ const editorConfiguration: IConfigurationNode = { 'type': 'string', 'enum': ['ctrlCmd', 'alt'], 'enumDescriptions': [ - nls.localize('multiCursorModifier.ctrlCmd', "Maps to `Control` on Windows and Linux and to `Command` on OSX."), - nls.localize('multiCursorModifier.alt', "Maps to `Alt` on Windows and Linux and to `Option` on OSX.") + nls.localize('multiCursorModifier.ctrlCmd', "Maps to `Control` on Windows and Linux and to `Command` on macOS."), + nls.localize('multiCursorModifier.alt', "Maps to `Alt` on Windows and Linux and to `Option` on macOS.") ], 'default': 'alt', 'description': nls.localize({ @@ -362,7 +362,7 @@ const editorConfiguration: IConfigurationNode = { '- `ctrlCmd` refers to a value the setting can take and should not be localized.', '- `Control` and `Command` refer to the modifier keys Ctrl or Cmd on the keyboard and can be localized.' ] - }, "The modifier to be used to add multiple cursors with the mouse. `ctrlCmd` maps to `Control` on Windows and Linux and to `Command` on OSX. The Go To Definition and Open Link mouse gestures will adapt such that they do not conflict with the multicursor modifier.") + }, "The modifier to be used to add multiple cursors with the mouse. `ctrlCmd` maps to `Control` on Windows and Linux and to `Command` on macOS. The Go To Definition and Open Link mouse gestures will adapt such that they do not conflict with the multicursor modifier.") }, 'editor.quickSuggestions': { 'anyOf': [ diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index 88d2f566d95..bf3193748a5 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -92,6 +92,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { private readonly _configuration: editorCommon.IConfiguration; private readonly _model: ITextModel; + private _knownModelVersionId: number; private readonly _viewModel: IViewModel; public context: CursorContext; private _cursors: CursorCollection; @@ -105,6 +106,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { super(); this._configuration = configuration; this._model = model; + this._knownModelVersionId = this._model.getVersionId(); this._viewModel = viewModel; this.context = new CursorContext(this._configuration, this._model, this._viewModel); this._cursors = new CursorCollection(this.context); @@ -115,6 +117,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { this._prevEditOperationType = EditOperationType.Other; this._register(this._model.onDidChangeRawContent((e) => { + this._knownModelVersionId = e.versionId; if (this._isHandling) { return; } @@ -128,6 +131,16 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { return; } + if (this._knownModelVersionId !== this._model.getVersionId()) { + // There are model change events that I didn't yet receive. + // + // This can happen when editing the model, and the view model receives the change events first, + // and the view model emits line mapping changed events, all before the cursor gets a chance to + // recover from markers. + // + // The model change listener above will be called soon and we'll ensure a valid cursor state there. + return; + } // Ensure valid state this.setStates('viewModel', CursorChangeReason.NotSet, this.getAll()); })); @@ -136,13 +149,13 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { this.context = new CursorContext(this._configuration, this._model, this._viewModel); this._cursors.updateContext(this.context); }; - this._register(model.onDidChangeLanguage((e) => { + this._register(this._model.onDidChangeLanguage((e) => { updateCursorContext(); })); - this._register(model.onDidChangeLanguageConfiguration(() => { + this._register(this._model.onDidChangeLanguageConfiguration(() => { updateCursorContext(); })); - this._register(model.onDidChangeOptions(() => { + this._register(this._model.onDidChangeOptions(() => { updateCursorContext(); })); this._register(this._configuration.onDidChange((e) => { diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index 9f25ed1118f..31f7b8be668 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -12,8 +12,9 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { Position, IPosition } from 'vs/editor/common/core/position'; import { Range, IRange } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; -import { ModelRawContentChangedEvent, IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelContentChange, ModelRawChange } from 'vs/editor/common/model/textModelEvents'; +import { ModelRawContentChangedEvent, IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelOptionsChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelContentChange } from 'vs/editor/common/model/textModelEvents'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; +import { ITextSnapshot } from 'vs/platform/files/common/files'; /** * Vertical Lane in the overview ruler of the editor. @@ -499,6 +500,14 @@ export interface ITextModel { */ getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string; + /** + * Get the text stored in this model. + * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed. + * @return The text snapshot (it is safe to consume it asynchronously). + * @internal + */ + createSnapshot(preserveBOM?: boolean): ITextSnapshot; + /** * Get the length of the text stored in this model. */ @@ -1078,7 +1087,9 @@ export interface ITextBuffer { getRangeAt(offset: number, length: number): Range; getValueInRange(range: Range, eol: EndOfLinePreference): string; + createSnapshot(preserveBOM: boolean): ITextSnapshot; getValueLengthInRange(range: Range, eol: EndOfLinePreference): number; + getLength(): number; getLineCount(): number; getLinesContent(): string[]; getLineContent(lineNumber: number): string; @@ -1087,7 +1098,7 @@ export interface ITextBuffer { getLineFirstNonWhitespaceColumn(lineNumber: number): number; getLineLastNonWhitespaceColumn(lineNumber: number): number; - setEOL(newEOL: string): void; + setEOL(newEOL: '\r\n' | '\n'): void; applyEdits(rawOperations: IIdentifiedSingleEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult; } @@ -1098,7 +1109,6 @@ export class ApplyEditsResult { constructor( public readonly reverseEdits: IIdentifiedSingleEditOperation[], - public readonly rawChanges: ModelRawChange[], public readonly changes: IInternalModelContentChange[], public readonly trimAutoWhitespaceLineNumbers: number[] ) { } @@ -1110,7 +1120,6 @@ export class ApplyEditsResult { */ export interface IInternalModelContentChange extends IModelContentChange { range: Range; - lines: string[]; rangeOffset: number; forceMoveMarkers: boolean; } diff --git a/src/vs/editor/common/model/chunksTextBuffer/bufferPiece.ts b/src/vs/editor/common/model/chunksTextBuffer/bufferPiece.ts new file mode 100644 index 00000000000..53063409aea --- /dev/null +++ b/src/vs/editor/common/model/chunksTextBuffer/bufferPiece.ts @@ -0,0 +1,323 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { CharCode } from 'vs/base/common/charCode'; + +export class LeafOffsetLenEdit { + constructor( + public readonly start: number, + public readonly length: number, + public readonly text: string + ) { } +} + +export class BufferPiece { + private readonly _str: string; + public get text(): string { return this._str; } + + private readonly _lineStarts: Uint32Array; + + constructor(str: string, lineStarts: Uint32Array = null) { + this._str = str; + if (lineStarts === null) { + this._lineStarts = createLineStartsFast(str); + } else { + this._lineStarts = lineStarts; + } + } + + public length(): number { + return this._str.length; + } + + public newLineCount(): number { + return this._lineStarts.length; + } + + public lineStartFor(relativeLineIndex: number): number { + return this._lineStarts[relativeLineIndex]; + } + + public charCodeAt(index: number): number { + return this._str.charCodeAt(index); + } + + public substr(from: number, length: number): string { + return this._str.substr(from, length); + } + + public findLineStartBeforeOffset(offset: number): number { + if (this._lineStarts.length === 0 || offset < this._lineStarts[0]) { + return -1; + } + + let low = 0, high = this._lineStarts.length - 1; + + while (low < high) { + let mid = low + Math.ceil((high - low) / 2); + let lineStart = this._lineStarts[mid]; + + if (offset === lineStart) { + return mid; + } else if (offset < lineStart) { + high = mid - 1; + } else { + low = mid; + } + } + + return low; + } + + public findLineFirstNonWhitespaceIndex(searchStartOffset: number): number { + for (let i = searchStartOffset, len = this._str.length; i < len; i++) { + const chCode = this._str.charCodeAt(i); + if (chCode === CharCode.CarriageReturn || chCode === CharCode.LineFeed) { + // Reached EOL + return -2; + } + if (chCode !== CharCode.Space && chCode !== CharCode.Tab) { + return i; + } + } + return -1; + } + + public findLineLastNonWhitespaceIndex(searchStartOffset: number): number { + for (let i = searchStartOffset - 1; i >= 0; i--) { + const chCode = this._str.charCodeAt(i); + if (chCode === CharCode.CarriageReturn || chCode === CharCode.LineFeed) { + // Reached EOL + return -2; + } + if (chCode !== CharCode.Space && chCode !== CharCode.Tab) { + return i; + } + } + return -1; + } + + public static normalizeEOL(target: BufferPiece, eol: '\r\n' | '\n'): BufferPiece { + return new BufferPiece(target._str.replace(/\r\n|\r|\n/g, eol)); + } + + public static deleteLastChar(target: BufferPiece): BufferPiece { + const targetCharsLength = target.length(); + const targetLineStartsLength = target.newLineCount(); + const targetLineStarts = target._lineStarts; + + let newLineStartsLength; + if (targetLineStartsLength > 0 && targetLineStarts[targetLineStartsLength - 1] === targetCharsLength) { + newLineStartsLength = targetLineStartsLength - 1; + } else { + newLineStartsLength = targetLineStartsLength; + } + + let newLineStarts = new Uint32Array(newLineStartsLength); + newLineStarts.set(targetLineStarts); + + return new BufferPiece( + target._str.substr(0, targetCharsLength - 1), + newLineStarts + ); + } + + public static insertFirstChar(target: BufferPiece, character: number): BufferPiece { + const targetLineStartsLength = target.newLineCount(); + const targetLineStarts = target._lineStarts; + const insertLineStart = ((character === CharCode.CarriageReturn && (targetLineStartsLength === 0 || targetLineStarts[0] !== 1 || target.charCodeAt(0) !== CharCode.LineFeed)) || (character === CharCode.LineFeed)); + + const newLineStartsLength = (insertLineStart ? targetLineStartsLength + 1 : targetLineStartsLength); + let newLineStarts = new Uint32Array(newLineStartsLength); + + if (insertLineStart) { + newLineStarts[0] = 1; + for (let i = 0; i < targetLineStartsLength; i++) { + newLineStarts[i + 1] = targetLineStarts[i] + 1; + } + } else { + for (let i = 0; i < targetLineStartsLength; i++) { + newLineStarts[i] = targetLineStarts[i] + 1; + } + } + + return new BufferPiece( + String.fromCharCode(character) + target._str, + newLineStarts + ); + } + + public static join(first: BufferPiece, second: BufferPiece): BufferPiece { + const firstCharsLength = first._str.length; + + const firstLineStartsLength = first._lineStarts.length; + const secondLineStartsLength = second._lineStarts.length; + + const firstLineStarts = first._lineStarts; + const secondLineStarts = second._lineStarts; + + const newLineStartsLength = firstLineStartsLength + secondLineStartsLength; + let newLineStarts = new Uint32Array(newLineStartsLength); + newLineStarts.set(firstLineStarts, 0); + for (let i = 0; i < secondLineStartsLength; i++) { + newLineStarts[i + firstLineStartsLength] = secondLineStarts[i] + firstCharsLength; + } + + return new BufferPiece(first._str + second._str, newLineStarts); + } + + public static replaceOffsetLen(target: BufferPiece, edits: LeafOffsetLenEdit[], idealLeafLength: number, maxLeafLength: number, result: BufferPiece[]): void { + const editsSize = edits.length; + const originalCharsLength = target.length(); + if (editsSize === 1 && edits[0].text.length === 0 && edits[0].start === 0 && edits[0].length === originalCharsLength) { + // special case => deleting everything + return; + } + + let pieces: string[] = new Array(2 * editsSize + 1); + let originalFromIndex = 0; + let piecesTextLength = 0; + for (let i = 0; i < editsSize; i++) { + const edit = edits[i]; + + const originalText = target._str.substr(originalFromIndex, edit.start - originalFromIndex); + pieces[2 * i] = originalText; + piecesTextLength += originalText.length; + + originalFromIndex = edit.start + edit.length; + pieces[2 * i + 1] = edit.text; + piecesTextLength += edit.text.length; + } + + // maintain the chars that survive to the right of the last edit + let text = target._str.substr(originalFromIndex, originalCharsLength - originalFromIndex); + pieces[2 * editsSize] = text; + piecesTextLength += text.length; + + let targetDataLength = piecesTextLength > maxLeafLength ? idealLeafLength : piecesTextLength; + let targetDataOffset = 0; + + let data: string = ''; + + for (let pieceIndex = 0, pieceCount = pieces.length; pieceIndex < pieceCount; pieceIndex++) { + const pieceText = pieces[pieceIndex]; + const pieceLength = pieceText.length; + if (pieceLength === 0) { + continue; + } + + let pieceOffset = 0; + while (pieceOffset < pieceLength) { + if (targetDataOffset >= targetDataLength) { + result.push(new BufferPiece(data)); + targetDataLength = piecesTextLength > maxLeafLength ? idealLeafLength : piecesTextLength; + targetDataOffset = 0; + data = ''; + } + + let writingCnt = min(pieceLength - pieceOffset, targetDataLength - targetDataOffset); + data += pieceText.substr(pieceOffset, writingCnt); + pieceOffset += writingCnt; + targetDataOffset += writingCnt; + piecesTextLength -= writingCnt; + + // check that the buffer piece does not end in a \r or high surrogate + if (targetDataOffset === targetDataLength && piecesTextLength > 0) { + const lastChar = data.charCodeAt(targetDataLength - 1); + if (lastChar === CharCode.CarriageReturn || (0xD800 <= lastChar && lastChar <= 0xDBFF)) { + // move lastChar over to next buffer piece + targetDataLength -= 1; + pieceOffset -= 1; + targetDataOffset -= 1; + piecesTextLength += 1; + data = data.substr(0, data.length - 1); + } + } + } + } + + result.push(new BufferPiece(data)); + } +} + +function min(a: number, b: number): number { + return (a < b ? a : b); +} + +export function createUint32Array(arr: number[]): Uint32Array { + let r = new Uint32Array(arr.length); + r.set(arr, 0); + return r; +} + +export class LineStarts { + constructor( + public readonly lineStarts: Uint32Array, + public readonly cr: number, + public readonly lf: number, + public readonly crlf: number, + public readonly isBasicASCII: boolean + ) { } +} + +export function createLineStartsFast(str: string): Uint32Array { + let r: number[] = [], rLength = 0; + for (let i = 0, len = str.length; i < len; i++) { + const chr = str.charCodeAt(i); + + if (chr === CharCode.CarriageReturn) { + if (i + 1 < len && str.charCodeAt(i + 1) === CharCode.LineFeed) { + // \r\n... case + r[rLength++] = i + 2; + i++; // skip \n + } else { + // \r... case + r[rLength++] = i + 1; + } + } else if (chr === CharCode.LineFeed) { + r[rLength++] = i + 1; + } + } + return createUint32Array(r); +} + +export function createLineStarts(r: number[], str: string): LineStarts { + r.length = 0; + + let rLength = 0; + let cr = 0, lf = 0, crlf = 0; + let isBasicASCII = true; + for (let i = 0, len = str.length; i < len; i++) { + const chr = str.charCodeAt(i); + + if (chr === CharCode.CarriageReturn) { + if (i + 1 < len && str.charCodeAt(i + 1) === CharCode.LineFeed) { + // \r\n... case + crlf++; + r[rLength++] = i + 2; + i++; // skip \n + } else { + cr++; + // \r... case + r[rLength++] = i + 1; + } + } else if (chr === CharCode.LineFeed) { + lf++; + r[rLength++] = i + 1; + } else { + if (isBasicASCII) { + if (chr !== CharCode.Tab && (chr < 32 || chr > 126)) { + isBasicASCII = false; + } + } + } + } + + const result = new LineStarts(createUint32Array(r), cr, lf, crlf, isBasicASCII); + r.length = 0; + + return result; +} diff --git a/src/vs/editor/common/model/chunksTextBuffer/chunksTextBuffer.ts b/src/vs/editor/common/model/chunksTextBuffer/chunksTextBuffer.ts new file mode 100644 index 00000000000..046f3387ea5 --- /dev/null +++ b/src/vs/editor/common/model/chunksTextBuffer/chunksTextBuffer.ts @@ -0,0 +1,1526 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { CharCode } from 'vs/base/common/charCode'; +import { ITextBuffer, EndOfLinePreference, IIdentifiedSingleEditOperation, ApplyEditsResult, ISingleEditOperationIdentifier, IInternalModelContentChange } from 'vs/editor/common/model'; +import { BufferPiece, LeafOffsetLenEdit } from 'vs/editor/common/model/chunksTextBuffer/bufferPiece'; +import { Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; +import * as strings from 'vs/base/common/strings'; +import { ITextSnapshot } from 'vs/platform/files/common/files'; + +export interface IValidatedEditOperation { + sortIndex: number; + identifier: ISingleEditOperationIdentifier; + range: Range; + rangeOffset: number; + rangeLength: number; + lines: string[]; + forceMoveMarkers: boolean; + isAutoWhitespaceEdit: boolean; +} + +export class ChunksTextBuffer implements ITextBuffer { + + private _BOM: string; + private _actual: Buffer; + private _mightContainRTL: boolean; + private _mightContainNonBasicASCII: boolean; + + constructor(pieces: BufferPiece[], _averageChunkSize: number, BOM: string, eol: '\r\n' | '\n', containsRTL: boolean, isBasicASCII: boolean) { + this._BOM = BOM; + const averageChunkSize = Math.floor(Math.min(65536.0, Math.max(128.0, _averageChunkSize))); + const delta = Math.floor(averageChunkSize / 3); + const min = averageChunkSize - delta; + const max = 2 * min; + this._actual = new Buffer(pieces, min, max, eol); + this._mightContainRTL = containsRTL; + this._mightContainNonBasicASCII = !isBasicASCII; + } + + equals(other: ITextBuffer): boolean { + if (!(other instanceof ChunksTextBuffer)) { + return false; + } + return this._actual.equals(other._actual); + } + mightContainRTL(): boolean { + return this._mightContainRTL; + } + mightContainNonBasicASCII(): boolean { + return this._mightContainNonBasicASCII; + } + getBOM(): string { + return this._BOM; + } + getEOL(): string { + return this._actual.getEOL(); + } + getOffsetAt(lineNumber: number, column: number): number { + return this._actual.convertPositionToOffset(lineNumber, column); + } + getPositionAt(offset: number): Position { + return this._actual.convertOffsetToPosition(offset); + } + getRangeAt(offset: number, length: number): Range { + return this._actual.convertOffsetLenToRange(offset, length); + } + getValueInRange(range: Range, eol: EndOfLinePreference): string { + if (range.isEmpty()) { + return ''; + } + + const text = this._actual.getValueInRange(range); + switch (eol) { + case EndOfLinePreference.TextDefined: + return text; + case EndOfLinePreference.LF: + if (this.getEOL() === '\n') { + return text; + } else { + return text.replace(/\r\n/g, '\n'); + } + case EndOfLinePreference.CRLF: + if (this.getEOL() === '\r\n') { + return text; + } else { + return text.replace(/\n/g, '\r\n'); + } + } + return null; + } + + public createSnapshot(preserveBOM: boolean): ITextSnapshot { + return this._actual.createSnapshot(preserveBOM ? this._BOM : ''); + } + + getValueLengthInRange(range: Range, eol: EndOfLinePreference): number { + if (range.isEmpty()) { + return 0; + } + const eolCount = range.endLineNumber - range.startLineNumber; + const result = this._actual.getValueLengthInRange(range); + switch (eol) { + case EndOfLinePreference.TextDefined: + return result; + case EndOfLinePreference.LF: + if (this.getEOL() === '\n') { + return result; + } else { + return result - eolCount; // \r\n => \n + } + case EndOfLinePreference.CRLF: + if (this.getEOL() === '\r\n') { + return result; + } else { + return result + eolCount; // \n => \r\n + } + } + return 0; + } + + public getLength(): number { + return this._actual.getLength(); + } + + getLineCount(): number { + return this._actual.getLineCount(); + } + + getLinesContent(): string[] { + return this._actual.getLinesContent(); + } + + getLineContent(lineNumber: number): string { + return this._actual.getLineContent(lineNumber); + } + + getLineCharCode(lineNumber: number, index: number): number { + return this._actual.getLineCharCode(lineNumber, index); + } + + getLineLength(lineNumber: number): number { + return this._actual.getLineLength(lineNumber); + } + + getLineFirstNonWhitespaceColumn(lineNumber: number): number { + const result = this._actual.getLineFirstNonWhitespaceIndex(lineNumber); + if (result === -1) { + return 0; + } + return result + 1; + } + getLineLastNonWhitespaceColumn(lineNumber: number): number { + const result = this._actual.getLineLastNonWhitespaceIndex(lineNumber); + if (result === -1) { + return 0; + } + return result + 1; + } + setEOL(newEOL: '\r\n' | '\n'): void { + if (this.getEOL() === newEOL) { + // nothing to do... + return; + } + this._actual.setEOL(newEOL); + } + + private static _sortOpsAscending(a: IValidatedEditOperation, b: IValidatedEditOperation): number { + let r = Range.compareRangesUsingEnds(a.range, b.range); + if (r === 0) { + return a.sortIndex - b.sortIndex; + } + return r; + } + + private static _sortOpsDescending(a: IValidatedEditOperation, b: IValidatedEditOperation): number { + let r = Range.compareRangesUsingEnds(a.range, b.range); + if (r === 0) { + return b.sortIndex - a.sortIndex; + } + return -r; + } + + applyEdits(rawOperations: IIdentifiedSingleEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult { + if (rawOperations.length === 0) { + return new ApplyEditsResult([], [], []); + } + + let mightContainRTL = this._mightContainRTL; + let mightContainNonBasicASCII = this._mightContainNonBasicASCII; + let canReduceOperations = true; + + let operations: IValidatedEditOperation[] = []; + for (let i = 0; i < rawOperations.length; i++) { + let op = rawOperations[i]; + if (canReduceOperations && op._isTracked) { + canReduceOperations = false; + } + let validatedRange = op.range; + if (!mightContainRTL && op.text) { + // check if the new inserted text contains RTL + mightContainRTL = strings.containsRTL(op.text); + } + if (!mightContainNonBasicASCII && op.text) { + mightContainNonBasicASCII = !strings.isBasicASCII(op.text); + } + operations[i] = { + sortIndex: i, + identifier: op.identifier || null, + range: validatedRange, + rangeOffset: this.getOffsetAt(validatedRange.startLineNumber, validatedRange.startColumn), + rangeLength: this.getValueLengthInRange(validatedRange, EndOfLinePreference.TextDefined), + lines: op.text ? op.text.split(/\r\n|\r|\n/) : null, + forceMoveMarkers: op.forceMoveMarkers || false, + isAutoWhitespaceEdit: op.isAutoWhitespaceEdit || false + }; + } + + // Sort operations ascending + operations.sort(ChunksTextBuffer._sortOpsAscending); + + for (let i = 0, count = operations.length - 1; i < count; i++) { + let rangeEnd = operations[i].range.getEndPosition(); + let nextRangeStart = operations[i + 1].range.getStartPosition(); + + if (nextRangeStart.isBefore(rangeEnd)) { + // overlapping ranges + throw new Error('Overlapping ranges are not allowed!'); + } + } + + if (canReduceOperations) { + operations = this._reduceOperations(operations); + } + + // Delta encode operations + let reverseRanges = ChunksTextBuffer._getInverseEditRanges(operations); + let newTrimAutoWhitespaceCandidates: { lineNumber: number, oldContent: string }[] = []; + + for (let i = 0; i < operations.length; i++) { + let op = operations[i]; + let reverseRange = reverseRanges[i]; + + if (recordTrimAutoWhitespace && op.isAutoWhitespaceEdit && op.range.isEmpty()) { + // Record already the future line numbers that might be auto whitespace removal candidates on next edit + for (let lineNumber = reverseRange.startLineNumber; lineNumber <= reverseRange.endLineNumber; lineNumber++) { + let currentLineContent = ''; + if (lineNumber === reverseRange.startLineNumber) { + currentLineContent = this.getLineContent(op.range.startLineNumber); + if (strings.firstNonWhitespaceIndex(currentLineContent) !== -1) { + continue; + } + } + newTrimAutoWhitespaceCandidates.push({ lineNumber: lineNumber, oldContent: currentLineContent }); + } + } + } + + let reverseOperations: IIdentifiedSingleEditOperation[] = []; + for (let i = 0; i < operations.length; i++) { + let op = operations[i]; + let reverseRange = reverseRanges[i]; + + reverseOperations[i] = { + identifier: op.identifier, + range: reverseRange, + text: this.getValueInRange(op.range, EndOfLinePreference.TextDefined), + forceMoveMarkers: op.forceMoveMarkers + }; + } + + this._mightContainRTL = mightContainRTL; + this._mightContainNonBasicASCII = mightContainNonBasicASCII; + + const contentChanges = this._doApplyEdits(operations); + + let trimAutoWhitespaceLineNumbers: number[] = null; + if (recordTrimAutoWhitespace && newTrimAutoWhitespaceCandidates.length > 0) { + // sort line numbers auto whitespace removal candidates for next edit descending + newTrimAutoWhitespaceCandidates.sort((a, b) => b.lineNumber - a.lineNumber); + + trimAutoWhitespaceLineNumbers = []; + for (let i = 0, len = newTrimAutoWhitespaceCandidates.length; i < len; i++) { + let lineNumber = newTrimAutoWhitespaceCandidates[i].lineNumber; + if (i > 0 && newTrimAutoWhitespaceCandidates[i - 1].lineNumber === lineNumber) { + // Do not have the same line number twice + continue; + } + + let prevContent = newTrimAutoWhitespaceCandidates[i].oldContent; + let lineContent = this.getLineContent(lineNumber); + + if (lineContent.length === 0 || lineContent === prevContent || strings.firstNonWhitespaceIndex(lineContent) !== -1) { + continue; + } + + trimAutoWhitespaceLineNumbers.push(lineNumber); + } + } + + return new ApplyEditsResult( + reverseOperations, + contentChanges, + trimAutoWhitespaceLineNumbers + ); + } + + /** + * Transform operations such that they represent the same logic edit, + * but that they also do not cause OOM crashes. + */ + private _reduceOperations(operations: IValidatedEditOperation[]): IValidatedEditOperation[] { + if (operations.length < 1000) { + // We know from empirical testing that a thousand edits work fine regardless of their shape. + return operations; + } + + // At one point, due to how events are emitted and how each operation is handled, + // some operations can trigger a high ammount of temporary string allocations, + // that will immediately get edited again. + // e.g. a formatter inserting ridiculous ammounts of \n on a model with a single line + // Therefore, the strategy is to collapse all the operations into a huge single edit operation + return [this._toSingleEditOperation(operations)]; + } + + _toSingleEditOperation(operations: IValidatedEditOperation[]): IValidatedEditOperation { + let forceMoveMarkers = false, + firstEditRange = operations[0].range, + lastEditRange = operations[operations.length - 1].range, + entireEditRange = new Range(firstEditRange.startLineNumber, firstEditRange.startColumn, lastEditRange.endLineNumber, lastEditRange.endColumn), + lastEndLineNumber = firstEditRange.startLineNumber, + lastEndColumn = firstEditRange.startColumn, + result: string[] = []; + + for (let i = 0, len = operations.length; i < len; i++) { + let operation = operations[i], + range = operation.range; + + forceMoveMarkers = forceMoveMarkers || operation.forceMoveMarkers; + + // (1) -- Push old text + for (let lineNumber = lastEndLineNumber; lineNumber < range.startLineNumber; lineNumber++) { + if (lineNumber === lastEndLineNumber) { + result.push(this.getLineContent(lineNumber).substring(lastEndColumn - 1)); + } else { + result.push('\n'); + result.push(this.getLineContent(lineNumber)); + } + } + + if (range.startLineNumber === lastEndLineNumber) { + result.push(this.getLineContent(range.startLineNumber).substring(lastEndColumn - 1, range.startColumn - 1)); + } else { + result.push('\n'); + result.push(this.getLineContent(range.startLineNumber).substring(0, range.startColumn - 1)); + } + + // (2) -- Push new text + if (operation.lines) { + for (let j = 0, lenJ = operation.lines.length; j < lenJ; j++) { + if (j !== 0) { + result.push('\n'); + } + result.push(operation.lines[j]); + } + } + + lastEndLineNumber = operation.range.endLineNumber; + lastEndColumn = operation.range.endColumn; + } + + return { + sortIndex: 0, + identifier: operations[0].identifier, + range: entireEditRange, + rangeOffset: this.getOffsetAt(entireEditRange.startLineNumber, entireEditRange.startColumn), + rangeLength: this.getValueLengthInRange(entireEditRange, EndOfLinePreference.TextDefined), + lines: result.join('').split('\n'), + forceMoveMarkers: forceMoveMarkers, + isAutoWhitespaceEdit: false + }; + } + + private _doApplyEdits(operations: IValidatedEditOperation[]): IInternalModelContentChange[] { + + // Sort operations descending + operations.sort(ChunksTextBuffer._sortOpsDescending); + + let contentChanges: IInternalModelContentChange[] = []; + let edits: OffsetLenEdit[] = []; + + for (let i = 0, len = operations.length; i < len; i++) { + const op = operations[i]; + + const text = (op.lines ? op.lines.join(this.getEOL()) : ''); + edits[i] = new OffsetLenEdit(op.sortIndex, op.rangeOffset, op.rangeLength, text); + + const startLineNumber = op.range.startLineNumber; + const startColumn = op.range.startColumn; + const endLineNumber = op.range.endLineNumber; + const endColumn = op.range.endColumn; + + if (startLineNumber === endLineNumber && startColumn === endColumn && (!op.lines || op.lines.length === 0)) { + // no-op + continue; + } + + contentChanges.push({ + range: op.range, + rangeLength: op.rangeLength, + text: text, + rangeOffset: op.rangeOffset, + forceMoveMarkers: op.forceMoveMarkers + }); + } + + this._actual.replaceOffsetLen(edits); + + return contentChanges; + } + + /** + * Assumes `operations` are validated and sorted ascending + */ + public static _getInverseEditRanges(operations: IValidatedEditOperation[]): Range[] { + let result: Range[] = []; + + let prevOpEndLineNumber: number; + let prevOpEndColumn: number; + let prevOp: IValidatedEditOperation = null; + for (let i = 0, len = operations.length; i < len; i++) { + let op = operations[i]; + + let startLineNumber: number; + let startColumn: number; + + if (prevOp) { + if (prevOp.range.endLineNumber === op.range.startLineNumber) { + startLineNumber = prevOpEndLineNumber; + startColumn = prevOpEndColumn + (op.range.startColumn - prevOp.range.endColumn); + } else { + startLineNumber = prevOpEndLineNumber + (op.range.startLineNumber - prevOp.range.endLineNumber); + startColumn = op.range.startColumn; + } + } else { + startLineNumber = op.range.startLineNumber; + startColumn = op.range.startColumn; + } + + let resultRange: Range; + + if (op.lines && op.lines.length > 0) { + // the operation inserts something + let lineCount = op.lines.length; + let firstLine = op.lines[0]; + let lastLine = op.lines[lineCount - 1]; + + if (lineCount === 1) { + // single line insert + resultRange = new Range(startLineNumber, startColumn, startLineNumber, startColumn + firstLine.length); + } else { + // multi line insert + resultRange = new Range(startLineNumber, startColumn, startLineNumber + lineCount - 1, lastLine.length + 1); + } + } else { + // There is nothing to insert + resultRange = new Range(startLineNumber, startColumn, startLineNumber, startColumn); + } + + prevOpEndLineNumber = resultRange.endLineNumber; + prevOpEndColumn = resultRange.endColumn; + + result.push(resultRange); + prevOp = op; + } + + return result; + } +} + + +class BufferNodes { + + public length: Uint32Array; + public newLineCount: Uint32Array; + + constructor(count: number) { + this.length = new Uint32Array(count); + this.newLineCount = new Uint32Array(count); + } + +} + +class BufferCursor { + constructor( + public offset: number, + public leafIndex: number, + public leafStartOffset: number, + public leafStartNewLineCount: number + ) { } + + public set(offset: number, leafIndex: number, leafStartOffset: number, leafStartNewLineCount: number) { + this.offset = offset; + this.leafIndex = leafIndex; + this.leafStartOffset = leafStartOffset; + this.leafStartNewLineCount = leafStartNewLineCount; + } +} + +class OffsetLenEdit { + constructor( + public readonly initialIndex: number, + public readonly offset: number, + public length: number, + public text: string + ) { } +} + +class InternalOffsetLenEdit { + constructor( + public readonly startLeafIndex: number, + public readonly startInnerOffset: number, + public readonly endLeafIndex: number, + public readonly endInnerOffset: number, + public text: string + ) { } +} + +class LeafReplacement { + constructor( + public readonly startLeafIndex: number, + public readonly endLeafIndex: number, + public readonly replacements: BufferPiece[] + ) { } +} + +const BUFFER_CURSOR_POOL_SIZE = 10; +const BufferCursorPool = new class { + private _pool: BufferCursor[]; + private _len: number; + + constructor() { + this._pool = []; + for (let i = 0; i < BUFFER_CURSOR_POOL_SIZE; i++) { + this._pool[i] = new BufferCursor(0, 0, 0, 0); + } + this._len = this._pool.length; + } + + public put(cursor: BufferCursor): void { + if (this._len > this._pool.length) { + // oh, well + return; + } + this._pool[this._len++] = cursor; + } + + public take(): BufferCursor { + if (this._len === 0) { + // oh, well + console.log(`insufficient BufferCursor pool`); + return new BufferCursor(0, 0, 0, 0); + } + const result = this._pool[this._len - 1]; + this._pool[this._len--] = null; + return result; + } +}; + +class BufferSnapshot implements ITextSnapshot { + + private readonly _pieces: BufferPiece[]; + private readonly _piecesLength: number; + private readonly _BOM: string; + private _piecesIndex: number; + + constructor(pieces: BufferPiece[], BOM: string) { + this._pieces = pieces; + this._piecesLength = this._pieces.length; + this._BOM = BOM; + this._piecesIndex = 0; + } + + public read(): string { + if (this._piecesIndex >= this._piecesLength) { + return null; + } + + let result: string = null; + if (this._piecesIndex === 0) { + result = this._BOM + this._pieces[this._piecesIndex].text; + } else { + result = this._pieces[this._piecesIndex].text; + } + + this._piecesIndex++; + return result; + } +} + +class Buffer { + + private _minLeafLength: number; + private _maxLeafLength: number; + private _idealLeafLength: number; + + private _eol: '\r\n' | '\n'; + private _eolLength: number; + + private _leafs: BufferPiece[]; + private _nodes: BufferNodes; + private _nodesCount: number; + private _leafsStart: number; + private _leafsEnd: number; + + constructor(pieces: BufferPiece[], minLeafLength: number, maxLeafLength: number, eol: '\r\n' | '\n') { + if (!(2 * minLeafLength >= maxLeafLength)) { + throw new Error(`assertion violation`); + } + + this._minLeafLength = minLeafLength; + this._maxLeafLength = maxLeafLength; + this._idealLeafLength = (minLeafLength + maxLeafLength) >>> 1; + + this._eol = eol; + this._eolLength = this._eol.length; + + this._leafs = pieces; + this._nodes = null; + this._nodesCount = 0; + this._leafsStart = 0; + this._leafsEnd = 0; + + this._rebuildNodes(); + } + + equals(other: Buffer): boolean { + return Buffer.equals(this, other); + } + + private static equals(a: Buffer, b: Buffer): boolean { + const aLength = a.getLength(); + const bLength = b.getLength(); + if (aLength !== bLength) { + return false; + } + if (a.getLineCount() !== b.getLineCount()) { + return false; + } + + let remaining = aLength; + let aLeafIndex = -1, aLeaf = null, aLeafLength = 0, aLeafRemaining = 0; + let bLeafIndex = -1, bLeaf = null, bLeafLength = 0, bLeafRemaining = 0; + + while (remaining > 0) { + if (aLeafRemaining === 0) { + aLeafIndex++; + aLeaf = a._leafs[aLeafIndex]; + aLeafLength = aLeaf.length(); + aLeafRemaining = aLeafLength; + } + + if (bLeafRemaining === 0) { + bLeafIndex++; + bLeaf = b._leafs[bLeafIndex]; + bLeafLength = bLeaf.length(); + bLeafRemaining = bLeafLength; + } + + let consuming = Math.min(aLeafRemaining, bLeafRemaining); + + let aStr = aLeaf.substr(aLeafLength - aLeafRemaining, consuming); + let bStr = bLeaf.substr(bLeafLength - bLeafRemaining, consuming); + + if (aStr !== bStr) { + return false; + } + + remaining -= consuming; + aLeafRemaining -= consuming; + bLeafRemaining -= consuming; + } + + return true; + } + + public getEOL(): string { + return this._eol; + } + + private _rebuildNodes() { + const leafsCount = this._leafs.length; + + this._nodesCount = (1 << log2(leafsCount)); + this._leafsStart = this._nodesCount; + this._leafsEnd = this._leafsStart + leafsCount; + + this._nodes = new BufferNodes(this._nodesCount); + for (let i = this._nodesCount - 1; i >= 1; i--) { + this._updateSingleNode(i); + } + } + + private _updateSingleNode(nodeIndex: number): void { + const left = LEFT_CHILD(nodeIndex); + const right = RIGHT_CHILD(nodeIndex); + + let length = 0; + let newLineCount = 0; + + if (this.IS_NODE(left)) { + length += this._nodes.length[left]; + newLineCount += this._nodes.newLineCount[left]; + } else if (this.IS_LEAF(left)) { + const leaf = this._leafs[this.NODE_TO_LEAF_INDEX(left)]; + length += leaf.length(); + newLineCount += leaf.newLineCount(); + } + + if (this.IS_NODE(right)) { + length += this._nodes.length[right]; + newLineCount += this._nodes.newLineCount[right]; + } else if (this.IS_LEAF(right)) { + const leaf = this._leafs[this.NODE_TO_LEAF_INDEX(right)]; + length += leaf.length(); + newLineCount += leaf.newLineCount(); + } + + this._nodes.length[nodeIndex] = length; + this._nodes.newLineCount[nodeIndex] = newLineCount; + } + + private _findOffset(offset: number, result: BufferCursor): boolean { + if (offset > this._nodes.length[1]) { + return false; + } + + let it = 1; + let searchOffset = offset; + let leafStartOffset = 0; + let leafStartNewLineCount = 0; + while (!this.IS_LEAF(it)) { + const left = LEFT_CHILD(it); + const right = RIGHT_CHILD(it); + + let leftNewLineCount = 0; + let leftLength = 0; + if (this.IS_NODE(left)) { + leftNewLineCount = this._nodes.newLineCount[left]; + leftLength = this._nodes.length[left]; + } else if (this.IS_LEAF(left)) { + const leaf = this._leafs[this.NODE_TO_LEAF_INDEX(left)]; + leftNewLineCount = leaf.newLineCount(); + leftLength = leaf.length(); + } + + let rightLength = 0; + if (this.IS_NODE(right)) { + rightLength += this._nodes.length[right]; + } else if (this.IS_LEAF(right)) { + rightLength += this._leafs[this.NODE_TO_LEAF_INDEX(right)].length(); + } + + if (searchOffset < leftLength || rightLength === 0) { + // go left + it = left; + } else { + // go right + searchOffset -= leftLength; + leafStartOffset += leftLength; + leafStartNewLineCount += leftNewLineCount; + it = right; + } + } + it = this.NODE_TO_LEAF_INDEX(it); + + result.set(offset, it, leafStartOffset, leafStartNewLineCount); + return true; + } + + private _findOffsetCloseAfter(offset: number, start: BufferCursor, result: BufferCursor): boolean { + if (offset > this._nodes.length[1]) { + return false; + } + + let innerOffset = offset - start.leafStartOffset; + const leafsCount = this._leafs.length; + + let leafIndex = start.leafIndex; + let leafStartOffset = start.leafStartOffset; + let leafStartNewLineCount = start.leafStartNewLineCount; + + while (true) { + const leaf = this._leafs[leafIndex]; + + if (innerOffset < leaf.length() || (innerOffset === leaf.length() && leafIndex + 1 === leafsCount)) { + result.set(offset, leafIndex, leafStartOffset, leafStartNewLineCount); + return true; + } + + leafIndex++; + + if (leafIndex >= leafsCount) { + result.set(offset, leafIndex, leafStartOffset, leafStartNewLineCount); + return true; + } + + leafStartOffset += leaf.length(); + leafStartNewLineCount += leaf.newLineCount(); + innerOffset -= leaf.length(); + } + } + + private _findLineStart(lineNumber: number, result: BufferCursor): boolean { + let lineIndex = lineNumber - 1; + if (lineIndex < 0 || lineIndex > this._nodes.newLineCount[1]) { + result.set(0, 0, 0, 0); + return false; + } + + let it = 1; + let leafStartOffset = 0; + let leafStartNewLineCount = 0; + while (!this.IS_LEAF(it)) { + const left = LEFT_CHILD(it); + const right = RIGHT_CHILD(it); + + let leftNewLineCount = 0; + let leftLength = 0; + if (this.IS_NODE(left)) { + leftNewLineCount = this._nodes.newLineCount[left]; + leftLength = this._nodes.length[left]; + } else if (this.IS_LEAF(left)) { + const leaf = this._leafs[this.NODE_TO_LEAF_INDEX(left)]; + leftNewLineCount = leaf.newLineCount(); + leftLength = leaf.length(); + } + + if (lineIndex <= leftNewLineCount) { + // go left + it = left; + continue; + } + + // go right + lineIndex -= leftNewLineCount; + leafStartOffset += leftLength; + leafStartNewLineCount += leftNewLineCount; + it = right; + } + it = this.NODE_TO_LEAF_INDEX(it); + + const innerLineStartOffset = (lineIndex === 0 ? 0 : this._leafs[it].lineStartFor(lineIndex - 1)); + + result.set(leafStartOffset + innerLineStartOffset, it, leafStartOffset, leafStartNewLineCount); + return true; + } + + private _findLineEnd(start: BufferCursor, lineNumber: number, result: BufferCursor): void { + let innerLineIndex = lineNumber - 1 - start.leafStartNewLineCount; + const leafsCount = this._leafs.length; + + let leafIndex = start.leafIndex; + let leafStartOffset = start.leafStartOffset; + let leafStartNewLineCount = start.leafStartNewLineCount; + while (true) { + const leaf = this._leafs[leafIndex]; + + if (innerLineIndex < leaf.newLineCount()) { + const lineEndOffset = this._leafs[leafIndex].lineStartFor(innerLineIndex); + result.set(leafStartOffset + lineEndOffset, leafIndex, leafStartOffset, leafStartNewLineCount); + return; + } + + leafIndex++; + + if (leafIndex >= leafsCount) { + result.set(leafStartOffset + leaf.length(), leafIndex - 1, leafStartOffset, leafStartNewLineCount); + return; + } + + leafStartOffset += leaf.length(); + leafStartNewLineCount += leaf.newLineCount(); + innerLineIndex = 0; + } + } + + private _findLine(lineNumber: number, start: BufferCursor, end: BufferCursor): boolean { + if (!this._findLineStart(lineNumber, start)) { + return false; + } + + this._findLineEnd(start, lineNumber, end); + return true; + } + + public getLength(): number { + return this._nodes.length[1]; + } + + public getLineCount(): number { + return this._nodes.newLineCount[1] + 1; + } + + public getLineContent(lineNumber: number): string { + const start = BufferCursorPool.take(); + const end = BufferCursorPool.take(); + + if (!this._findLine(lineNumber, start, end)) { + BufferCursorPool.put(start); + BufferCursorPool.put(end); + throw new Error(`Line not found`); + } + + let result: string; + if (lineNumber === this.getLineCount()) { + // last line is not trailed by an eol + result = this.extractString(start, end.offset - start.offset); + } else { + result = this.extractString(start, end.offset - start.offset - this._eolLength); + } + + BufferCursorPool.put(start); + BufferCursorPool.put(end); + return result; + } + + public getLineCharCode(lineNumber: number, index: number): number { + const start = BufferCursorPool.take(); + + if (!this._findLineStart(lineNumber, start)) { + BufferCursorPool.put(start); + throw new Error(`Line not found`); + } + + const tmp = BufferCursorPool.take(); + this._findOffsetCloseAfter(start.offset + index, start, tmp); + const result = this._leafs[tmp.leafIndex].charCodeAt(tmp.offset - tmp.leafStartNewLineCount); + BufferCursorPool.put(tmp); + + BufferCursorPool.put(start); + return result; + } + + public getLineLength(lineNumber: number): number { + const start = BufferCursorPool.take(); + const end = BufferCursorPool.take(); + + if (!this._findLine(lineNumber, start, end)) { + BufferCursorPool.put(start); + BufferCursorPool.put(end); + throw new Error(`Line not found`); + } + + let result: number; + if (lineNumber === this.getLineCount()) { + // last line is not trailed by an eol + result = end.offset - start.offset; + } else { + result = end.offset - start.offset - this._eolLength; + } + + BufferCursorPool.put(start); + BufferCursorPool.put(end); + return result; + } + + public getLineFirstNonWhitespaceIndex(lineNumber: number): number { + const start = BufferCursorPool.take(); + + if (!this._findLineStart(lineNumber, start)) { + BufferCursorPool.put(start); + throw new Error(`Line not found`); + } + + let leafIndex = start.leafIndex; + let searchStartOffset = start.offset - start.leafStartOffset; + BufferCursorPool.put(start); + + const leafsCount = this._leafs.length; + let totalDelta = 0; + while (true) { + const leaf = this._leafs[leafIndex]; + + const leafResult = leaf.findLineFirstNonWhitespaceIndex(searchStartOffset); + if (leafResult === -2) { + // reached EOL + return -1; + } + if (leafResult !== -1) { + return (leafResult - searchStartOffset) + totalDelta; + } + + leafIndex++; + + if (leafIndex >= leafsCount) { + return -1; + } + + totalDelta += (leaf.length() - searchStartOffset); + searchStartOffset = 0; + } + } + + public getLineLastNonWhitespaceIndex(lineNumber: number): number { + const start = BufferCursorPool.take(); + const end = BufferCursorPool.take(); + + if (!this._findLineStart(lineNumber, start)) { + BufferCursorPool.put(start); + BufferCursorPool.put(end); + throw new Error(`Line not found`); + } + + this._findLineEnd(start, lineNumber, end); + + const startOffset = start.offset; + const endOffset = end.offset; + let leafIndex = end.leafIndex; + let searchStartOffset = end.offset - end.leafStartOffset - this._eolLength; + + BufferCursorPool.put(start); + BufferCursorPool.put(end); + + let totalDelta = 0; + while (true) { + const leaf = this._leafs[leafIndex]; + + const leafResult = leaf.findLineLastNonWhitespaceIndex(searchStartOffset); + if (leafResult === -2) { + // reached EOL + return -1; + } + if (leafResult !== -1) { + const delta = (searchStartOffset - 1 - leafResult); + const absoluteOffset = (endOffset - this._eolLength) - delta - totalDelta; + return absoluteOffset - startOffset; + } + + leafIndex--; + + if (leafIndex < 0) { + return -1; + } + + totalDelta += searchStartOffset; + searchStartOffset = leaf.length(); + } + } + + public getLinesContent(): string[] { + let result: string[] = new Array(this.getLineCount()); + let resultIndex = 0; + + let currentLine = ''; + for (let leafIndex = 0, leafsCount = this._leafs.length; leafIndex < leafsCount; leafIndex++) { + const leaf = this._leafs[leafIndex]; + const leafNewLineCount = leaf.newLineCount(); + + if (leafNewLineCount === 0) { + // special case => push entire leaf text + currentLine += leaf.text; + continue; + } + + let leafSubstrOffset = 0; + for (let newLineIndex = 0; newLineIndex < leafNewLineCount; newLineIndex++) { + const newLineStart = leaf.lineStartFor(newLineIndex); + currentLine += leaf.substr(leafSubstrOffset, newLineStart - leafSubstrOffset - this._eolLength); + result[resultIndex++] = currentLine; + + currentLine = ''; + leafSubstrOffset = newLineStart; + } + currentLine += leaf.substr(leafSubstrOffset, leaf.length()); + } + result[resultIndex++] = currentLine; + + return result; + } + + public extractString(start: BufferCursor, len: number): string { + if (!(start.offset + len <= this._nodes.length[1])) { + throw new Error(`assertion violation`); + } + + let innerLeafOffset = start.offset - start.leafStartOffset; + let leafIndex = start.leafIndex; + let res = ''; + while (len > 0) { + const leaf = this._leafs[leafIndex]; + const cnt = Math.min(len, leaf.length() - innerLeafOffset); + res += leaf.substr(innerLeafOffset, cnt); + + len -= cnt; + innerLeafOffset = 0; + + if (len === 0) { + break; + } + + leafIndex++; + } + return res; + } + + private _getOffsetAt(lineNumber: number, column: number, result: BufferCursor): boolean { + const lineStart = BufferCursorPool.take(); + + if (!this._findLineStart(lineNumber, lineStart)) { + BufferCursorPool.put(lineStart); + return false; + } + + const startOffset = lineStart.offset + column - 1; + if (!this._findOffsetCloseAfter(startOffset, lineStart, result)) { + BufferCursorPool.put(lineStart); + return false; + } + + BufferCursorPool.put(lineStart); + return true; + } + + public convertPositionToOffset(lineNumber: number, column: number): number { + const r = BufferCursorPool.take(); + + if (!this._findLineStart(lineNumber, r)) { + BufferCursorPool.put(r); + throw new Error(`Position not found`); + } + + const result = r.offset + column - 1; + + BufferCursorPool.put(r); + return result; + } + + /** + * returns `lineNumber` + */ + private _findLineStartBeforeOffsetInLeaf(offset: number, leafIndex: number, leafStartOffset: number, leafStartNewLineCount: number, result: BufferCursor): number { + const leaf = this._leafs[leafIndex]; + const lineStartIndex = leaf.findLineStartBeforeOffset(offset - leafStartOffset); + const lineStartOffset = leafStartOffset + leaf.lineStartFor(lineStartIndex); + + result.set(lineStartOffset, leafIndex, leafStartOffset, leafStartNewLineCount); + return leafStartNewLineCount + lineStartIndex + 2; + } + + /** + * returns `lineNumber`. + */ + private _findLineStartBeforeOffset(offset: number, location: BufferCursor, result: BufferCursor): number { + + let leafIndex = location.leafIndex; + let leafStartOffset = location.leafStartOffset; + let leafStartNewLineCount = location.leafStartNewLineCount; + while (true) { + const leaf = this._leafs[leafIndex]; + + if (leaf.newLineCount() >= 1 && leaf.lineStartFor(0) + leafStartOffset <= offset) { + // must be in this leaf + return this._findLineStartBeforeOffsetInLeaf(offset, leafIndex, leafStartOffset, leafStartNewLineCount, result); + } + + // continue looking in previous leaf + leafIndex--; + + if (leafIndex < 0) { + result.set(0, 0, 0, 0); + return 1; + } + + leafStartOffset -= this._leafs[leafIndex].length(); + leafStartNewLineCount -= this._leafs[leafIndex].newLineCount(); + } + } + + public convertOffsetToPosition(offset: number): Position { + const r = BufferCursorPool.take(); + const lineStart = BufferCursorPool.take(); + + if (!this._findOffset(offset, r)) { + BufferCursorPool.put(r); + BufferCursorPool.put(lineStart); + throw new Error(`Offset not found`); + } + + const lineNumber = this._findLineStartBeforeOffset(offset, r, lineStart); + const column = offset - lineStart.offset + 1; + + BufferCursorPool.put(r); + BufferCursorPool.put(lineStart); + + return new Position(lineNumber, column); + } + + public convertOffsetLenToRange(offset: number, len: number): Range { + const r = BufferCursorPool.take(); + const lineStart = BufferCursorPool.take(); + + if (!this._findOffset(offset, r)) { + BufferCursorPool.put(r); + BufferCursorPool.put(lineStart); + throw new Error(`Offset not found`); + } + const startLineNumber = this._findLineStartBeforeOffset(offset, r, lineStart); + const startColumn = offset - lineStart.offset + 1; + + if (!this._findOffset(offset + len, r)) { + BufferCursorPool.put(r); + BufferCursorPool.put(lineStart); + throw new Error(`Offset not found`); + } + const endLineNumber = this._findLineStartBeforeOffset(offset + len, r, lineStart); + const endColumn = offset + len - lineStart.offset + 1; + + BufferCursorPool.put(r); + BufferCursorPool.put(lineStart); + + return new Range(startLineNumber, startColumn, endLineNumber, endColumn); + } + + public getValueInRange(range: Range): string { + const start = BufferCursorPool.take(); + + if (!this._getOffsetAt(range.startLineNumber, range.startColumn, start)) { + BufferCursorPool.put(start); + throw new Error(`Line not found`); + } + + const endOffset = this.convertPositionToOffset(range.endLineNumber, range.endColumn); + const result = this.extractString(start, endOffset - start.offset); + + BufferCursorPool.put(start); + return result; + } + + public createSnapshot(BOM: string): ITextSnapshot { + return new BufferSnapshot(this._leafs, BOM); + } + + public getValueLengthInRange(range: Range): number { + const startOffset = this.convertPositionToOffset(range.startLineNumber, range.startColumn); + const endOffset = this.convertPositionToOffset(range.endLineNumber, range.endColumn); + return endOffset - startOffset; + } + + //#region Editing + + private _mergeAdjacentEdits(edits: OffsetLenEdit[]): OffsetLenEdit[] { + // Check if we must merge adjacent edits + let merged: OffsetLenEdit[] = [], mergedLength = 0; + let prev = edits[0]; + for (let i = 1, len = edits.length; i < len; i++) { + const curr = edits[i]; + if (prev.offset + prev.length === curr.offset) { + // merge into `prev` + prev.length = prev.length + curr.length; + prev.text = prev.text + curr.text; + } else { + merged[mergedLength++] = prev; + prev = curr; + } + } + merged[mergedLength++] = prev; + + return merged; + } + + private _resolveEdits(edits: OffsetLenEdit[]): InternalOffsetLenEdit[] { + edits = this._mergeAdjacentEdits(edits); + + let result: InternalOffsetLenEdit[] = []; + let tmp = new BufferCursor(0, 0, 0, 0); + let tmp2 = new BufferCursor(0, 0, 0, 0); + for (let i = 0, len = edits.length; i < len; i++) { + const edit = edits[i]; + + let text = edit.text; + + this._findOffset(edit.offset, tmp); + let startLeafIndex = tmp.leafIndex; + let startInnerOffset = tmp.offset - tmp.leafStartOffset; + if (startInnerOffset > 0) { + const startLeaf = this._leafs[startLeafIndex]; + const charBefore = startLeaf.charCodeAt(startInnerOffset - 1); + if (charBefore === CharCode.CarriageReturn) { + // include the replacement of \r in the edit + text = '\r' + text; + + this._findOffsetCloseAfter(edit.offset - 1, tmp, tmp2); + startLeafIndex = tmp2.leafIndex; + startInnerOffset = tmp2.offset - tmp2.leafStartOffset; + // this._findOffset(edit.offset - 1, tmp); + // startLeafIndex = tmp.leafIndex; + // startInnerOffset = tmp.offset - tmp.leafStartOffset; + } + } + + this._findOffset(edit.offset + edit.length, tmp); + let endLeafIndex = tmp.leafIndex; + let endInnerOffset = tmp.offset - tmp.leafStartOffset; + const endLeaf = this._leafs[endLeafIndex]; + if (endInnerOffset < endLeaf.length()) { + const charAfter = endLeaf.charCodeAt(endInnerOffset); + if (charAfter === CharCode.LineFeed) { + // include the replacement of \n in the edit + text = text + '\n'; + + this._findOffsetCloseAfter(edit.offset + edit.length + 1, tmp, tmp2); + endLeafIndex = tmp2.leafIndex; + endInnerOffset = tmp2.offset - tmp2.leafStartOffset; + // this._findOffset(edit.offset + edit.length + 1, tmp); + // endLeafIndex = tmp.leafIndex; + // endInnerOffset = tmp.offset - tmp.leafStartOffset; + } + } + + result[i] = new InternalOffsetLenEdit( + startLeafIndex, startInnerOffset, + endLeafIndex, endInnerOffset, + text + ); + } + + return result; + } + + private _pushLeafReplacement(startLeafIndex: number, endLeafIndex: number, replacements: LeafReplacement[]): LeafReplacement { + const res = new LeafReplacement(startLeafIndex, endLeafIndex, []); + replacements.push(res); + return res; + } + + private _flushLeafEdits(accumulatedLeafIndex: number, accumulatedLeafEdits: LeafOffsetLenEdit[], replacements: LeafReplacement[]): void { + if (accumulatedLeafEdits.length > 0) { + const rep = this._pushLeafReplacement(accumulatedLeafIndex, accumulatedLeafIndex, replacements); + BufferPiece.replaceOffsetLen(this._leafs[accumulatedLeafIndex], accumulatedLeafEdits, this._idealLeafLength, this._maxLeafLength, rep.replacements); + } + accumulatedLeafEdits.length = 0; + } + + private _pushLeafEdits(start: number, length: number, text: string, accumulatedLeafEdits: LeafOffsetLenEdit[]): void { + if (length !== 0 || text.length !== 0) { + accumulatedLeafEdits.push(new LeafOffsetLenEdit(start, length, text)); + } + } + + private _appendLeaf(leaf: BufferPiece, leafs: BufferPiece[], prevLeaf: BufferPiece): BufferPiece { + if (prevLeaf === null) { + leafs.push(leaf); + prevLeaf = leaf; + return prevLeaf; + } + + let prevLeafLength = prevLeaf.length(); + let currLeafLength = leaf.length(); + + if ((prevLeafLength < this._minLeafLength || currLeafLength < this._minLeafLength) && prevLeafLength + currLeafLength <= this._maxLeafLength) { + const joinedLeaf = BufferPiece.join(prevLeaf, leaf); + leafs[leafs.length - 1] = joinedLeaf; + prevLeaf = joinedLeaf; + return prevLeaf; + } + + const lastChar = prevLeaf.charCodeAt(prevLeafLength - 1); + const firstChar = leaf.charCodeAt(0); + + if ( + (lastChar >= 0xd800 && lastChar <= 0xdbff) || (lastChar === CharCode.CarriageReturn && firstChar === CharCode.LineFeed) + ) { + const modifiedPrevLeaf = BufferPiece.deleteLastChar(prevLeaf); + leafs[leafs.length - 1] = modifiedPrevLeaf; + + const modifiedLeaf = BufferPiece.insertFirstChar(leaf, lastChar); + leaf = modifiedLeaf; + } + + leafs.push(leaf); + prevLeaf = leaf; + return prevLeaf; + } + + private static _compareEdits(a: OffsetLenEdit, b: OffsetLenEdit): number { + if (a.offset === b.offset) { + if (a.length === b.length) { + return (a.initialIndex - b.initialIndex); + } + return (a.length - b.length); + } + return a.offset - b.offset; + } + + public replaceOffsetLen(_edits: OffsetLenEdit[]): void { + _edits.sort(Buffer._compareEdits); + + const initialLeafLength = this._leafs.length; + const edits = this._resolveEdits(_edits); + + let accumulatedLeafIndex = 0; + let accumulatedLeafEdits: LeafOffsetLenEdit[] = []; + let replacements: LeafReplacement[] = []; + + for (let i = 0, len = edits.length; i < len; i++) { + const edit = edits[i]; + + const startLeafIndex = edit.startLeafIndex; + const endLeafIndex = edit.endLeafIndex; + + if (startLeafIndex !== accumulatedLeafIndex) { + this._flushLeafEdits(accumulatedLeafIndex, accumulatedLeafEdits, replacements); + accumulatedLeafIndex = startLeafIndex; + } + + const leafEditStart = edit.startInnerOffset; + const leafEditEnd = (startLeafIndex === endLeafIndex ? edit.endInnerOffset : this._leafs[startLeafIndex].length()); + this._pushLeafEdits(leafEditStart, leafEditEnd - leafEditStart, edit.text, accumulatedLeafEdits); + + if (startLeafIndex < endLeafIndex) { + this._flushLeafEdits(accumulatedLeafIndex, accumulatedLeafEdits, replacements); + accumulatedLeafIndex = endLeafIndex; + + // delete leafs in the middle + if (startLeafIndex + 1 < endLeafIndex) { + this._pushLeafReplacement(startLeafIndex + 1, endLeafIndex - 1, replacements); + } + + // delete on last leaf + const leafEditStart = 0; + const leafEditEnd = edit.endInnerOffset; + this._pushLeafEdits(leafEditStart, leafEditEnd - leafEditStart, '', accumulatedLeafEdits); + } + } + this._flushLeafEdits(accumulatedLeafIndex, accumulatedLeafEdits, replacements); + + let leafs: BufferPiece[] = []; + let leafIndex = 0; + let prevLeaf: BufferPiece = null; + + for (let i = 0, len = replacements.length; i < len; i++) { + const replaceStartLeafIndex = replacements[i].startLeafIndex; + const replaceEndLeafIndex = replacements[i].endLeafIndex; + const innerLeafs = replacements[i].replacements; + + // add leafs to the left of this replace op. + while (leafIndex < replaceStartLeafIndex) { + prevLeaf = this._appendLeaf(this._leafs[leafIndex], leafs, prevLeaf); + leafIndex++; + } + + // delete leafs that get replaced. + while (leafIndex <= replaceEndLeafIndex) { + leafIndex++; + } + + // add new leafs. + for (let j = 0, lenJ = innerLeafs.length; j < lenJ; j++) { + prevLeaf = this._appendLeaf(innerLeafs[j], leafs, prevLeaf); + } + } + + // add remaining leafs to the right of the last replacement. + while (leafIndex < initialLeafLength) { + prevLeaf = this._appendLeaf(this._leafs[leafIndex], leafs, prevLeaf); + leafIndex++; + } + + if (leafs.length === 0) { + // don't leave behind an empty leafs array + leafs.push(new BufferPiece('')); + } + + this._leafs = leafs; + this._rebuildNodes(); + } + + public setEOL(newEOL: '\r\n' | '\n'): void { + let leafs: BufferPiece[] = []; + for (let i = 0, len = this._leafs.length; i < len; i++) { + leafs[i] = BufferPiece.normalizeEOL(this._leafs[i], newEOL); + } + this._leafs = leafs; + this._rebuildNodes(); + this._eol = newEOL; + this._eolLength = this._eol.length; + } + + //#endregion + + private IS_NODE(i: number): boolean { + return (i < this._nodesCount); + } + private IS_LEAF(i: number): boolean { + return (i >= this._leafsStart && i < this._leafsEnd); + } + private NODE_TO_LEAF_INDEX(i: number): number { + return (i - this._leafsStart); + } + // private LEAF_TO_NODE_INDEX(i: number): number { + // return (i + this._leafsStart); + // } +} + +function log2(n: number): number { + let v = 1; + for (let pow = 1; ; pow++) { + v = v << 1; + if (v >= n) { + return pow; + } + } + // return -1; +} + +function LEFT_CHILD(i: number): number { + return (i << 1); +} + +function RIGHT_CHILD(i: number): number { + return (i << 1) + 1; +} diff --git a/src/vs/editor/common/model/chunksTextBuffer/chunksTextBufferBuilder.ts b/src/vs/editor/common/model/chunksTextBuffer/chunksTextBufferBuilder.ts new file mode 100644 index 00000000000..12eaf167b28 --- /dev/null +++ b/src/vs/editor/common/model/chunksTextBuffer/chunksTextBufferBuilder.ts @@ -0,0 +1,186 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as strings from 'vs/base/common/strings'; +import { ITextBufferBuilder, ITextBufferFactory, ITextBuffer, DefaultEndOfLine } from 'vs/editor/common/model'; +import { BufferPiece, createLineStarts } from 'vs/editor/common/model/chunksTextBuffer/bufferPiece'; +import { ChunksTextBuffer } from 'vs/editor/common/model/chunksTextBuffer/chunksTextBuffer'; +import { CharCode } from 'vs/base/common/charCode'; + +export class TextBufferFactory implements ITextBufferFactory { + + constructor( + private readonly _pieces: BufferPiece[], + private readonly _averageChunkSize: number, + private readonly _BOM: string, + private readonly _cr: number, + private readonly _lf: number, + private readonly _crlf: number, + private readonly _containsRTL: boolean, + private readonly _isBasicASCII: boolean, + ) { + } + + /** + * if text source is empty or with precisely one line, returns null. No end of line is detected. + * if text source contains more lines ending with '\r\n', returns '\r\n'. + * Otherwise returns '\n'. More lines end with '\n'. + */ + private _getEOL(defaultEOL: DefaultEndOfLine): '\r\n' | '\n' { + const totalEOLCount = this._cr + this._lf + this._crlf; + const totalCRCount = this._cr + this._crlf; + if (totalEOLCount === 0) { + // This is an empty file or a file with precisely one line + return (defaultEOL === DefaultEndOfLine.LF ? '\n' : '\r\n'); + } + if (totalCRCount > totalEOLCount / 2) { + // More than half of the file contains \r\n ending lines + return '\r\n'; + } + // At least one line more ends in \n + return '\n'; + } + + public create(defaultEOL: DefaultEndOfLine): ITextBuffer { + const eol = this._getEOL(defaultEOL); + let pieces = this._pieces; + + if ( + (eol === '\r\n' && (this._cr > 0 || this._lf > 0)) + || (eol === '\n' && (this._cr > 0 || this._crlf > 0)) + ) { + // Normalize pieces + for (let i = 0, len = pieces.length; i < len; i++) { + pieces[i] = BufferPiece.normalizeEOL(pieces[i], eol); + } + } + return new ChunksTextBuffer(pieces, this._averageChunkSize, this._BOM, eol, this._containsRTL, this._isBasicASCII); + } + + public getFirstLineText(lengthLimit: number): string { + const firstPiece = this._pieces[0]; + if (firstPiece.newLineCount() === 0) { + return firstPiece.substr(0, lengthLimit); + } + + const firstEOLOffset = firstPiece.lineStartFor(0); + return firstPiece.substr(0, Math.min(lengthLimit, firstEOLOffset)); + } +} + +export class ChunksTextBufferBuilder implements ITextBufferBuilder { + + private _rawPieces: BufferPiece[]; + private _hasPreviousChar: boolean; + private _previousChar: number; + private _averageChunkSize: number; + private _tmpLineStarts: number[]; + + private BOM: string; + private cr: number; + private lf: number; + private crlf: number; + private containsRTL: boolean; + private isBasicASCII: boolean; + + constructor() { + this._rawPieces = []; + this._hasPreviousChar = false; + this._previousChar = 0; + this._averageChunkSize = 0; + this._tmpLineStarts = []; + + this.BOM = ''; + this.cr = 0; + this.lf = 0; + this.crlf = 0; + this.containsRTL = false; + this.isBasicASCII = true; + } + + public acceptChunk(chunk: string): void { + if (chunk.length === 0) { + return; + } + + if (this._rawPieces.length === 0) { + if (strings.startsWithUTF8BOM(chunk)) { + this.BOM = strings.UTF8_BOM_CHARACTER; + chunk = chunk.substr(1); + } + } + + this._averageChunkSize = (this._averageChunkSize * this._rawPieces.length + chunk.length) / (this._rawPieces.length + 1); + + const lastChar = chunk.charCodeAt(chunk.length - 1); + if (lastChar === CharCode.CarriageReturn || (lastChar >= 0xd800 && lastChar <= 0xdbff)) { + // last character is \r or a high surrogate => keep it back + this._acceptChunk1(chunk.substr(0, chunk.length - 1), false); + this._hasPreviousChar = true; + this._previousChar = lastChar; + } else { + this._acceptChunk1(chunk, false); + this._hasPreviousChar = false; + this._previousChar = lastChar; + } + } + + private _acceptChunk1(chunk: string, allowEmptyStrings: boolean): void { + if (!allowEmptyStrings && chunk.length === 0) { + // Nothing to do + return; + } + + if (this._hasPreviousChar) { + this._acceptChunk2(chunk + String.fromCharCode(this._previousChar)); + } else { + this._acceptChunk2(chunk); + } + } + + private _acceptChunk2(chunk: string): void { + const lineStarts = createLineStarts(this._tmpLineStarts, chunk); + + this._rawPieces.push(new BufferPiece(chunk, lineStarts.lineStarts)); + this.cr += lineStarts.cr; + this.lf += lineStarts.lf; + this.crlf += lineStarts.crlf; + + if (this.isBasicASCII) { + this.isBasicASCII = lineStarts.isBasicASCII; + } + if (!this.isBasicASCII && !this.containsRTL) { + // No need to check if is basic ASCII + this.containsRTL = strings.containsRTL(chunk); + } + } + + public finish(): TextBufferFactory { + this._finish(); + return new TextBufferFactory(this._rawPieces, this._averageChunkSize, this.BOM, this.cr, this.lf, this.crlf, this.containsRTL, this.isBasicASCII); + } + + private _finish(): void { + if (this._rawPieces.length === 0) { + // no chunks => forcefully go through accept chunk + this._acceptChunk1('', true); + return; + } + + if (this._hasPreviousChar) { + this._hasPreviousChar = false; + + // recreate last chunk + const lastPiece = this._rawPieces[this._rawPieces.length - 1]; + const tmp = new BufferPiece(String.fromCharCode(this._previousChar)); + const newLastPiece = BufferPiece.join(lastPiece, tmp); + this._rawPieces[this._rawPieces.length - 1] = newLastPiece; + if (this._previousChar === CharCode.CarriageReturn) { + this.cr++; + } + } + } +} diff --git a/src/vs/editor/common/model/linesTextBuffer/linesTextBuffer.ts b/src/vs/editor/common/model/linesTextBuffer/linesTextBuffer.ts index 09cafe2246c..0d03ecd90a0 100644 --- a/src/vs/editor/common/model/linesTextBuffer/linesTextBuffer.ts +++ b/src/vs/editor/common/model/linesTextBuffer/linesTextBuffer.ts @@ -9,8 +9,8 @@ import { Position } from 'vs/editor/common/core/position'; import * as strings from 'vs/base/common/strings'; import * as arrays from 'vs/base/common/arrays'; import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer'; -import { ModelRawChange, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/model/textModelEvents'; import { ISingleEditOperationIdentifier, IIdentifiedSingleEditOperation, EndOfLinePreference, ITextBuffer, ApplyEditsResult, IInternalModelContentChange } from 'vs/editor/common/model'; +import { ITextSnapshot } from 'vs/platform/files/common/files'; export interface IValidatedEditOperation { sortIndex: number; @@ -49,6 +49,45 @@ export interface ITextSource { readonly isBasicASCII: boolean; } +class LinesTextBufferSnapshot implements ITextSnapshot { + + private readonly _lines: string[]; + private readonly _linesLength: number; + private readonly _eol: string; + private readonly _bom: string; + private _lineIndex: number; + + constructor(lines: string[], eol: string, bom: string) { + this._lines = lines; + this._linesLength = this._lines.length; + this._eol = eol; + this._bom = bom; + this._lineIndex = 0; + } + + public read(): string { + if (this._lineIndex >= this._linesLength) { + return null; + } + + let result: string = null; + + if (this._lineIndex === 0) { + result = this._bom + this._lines[this._lineIndex]; + } else { + result = this._lines[this._lineIndex]; + } + + this._lineIndex++; + + if (this._lineIndex < this._linesLength) { + result += this._eol; + } + + return result; + } +} + export class LinesTextBuffer implements ITextBuffer { private _lines: string[]; @@ -177,6 +216,10 @@ export class LinesTextBuffer implements ITextBuffer { return resultLines.join(lineEnding); } + public createSnapshot(preserveBOM: boolean): ITextSnapshot { + return new LinesTextBufferSnapshot(this._lines.slice(0), this._EOL, preserveBOM ? this._BOM : ''); + } + public getValueLengthInRange(range: Range, eol: EndOfLinePreference): number { if (range.isEmpty()) { return 0; @@ -199,6 +242,10 @@ export class LinesTextBuffer implements ITextBuffer { return this._lines.slice(0); } + public getLength(): number { + return this._lineStarts.getTotalValue(); + } + public getLineContent(lineNumber: number): string { return this._lines[lineNumber - 1]; } @@ -229,7 +276,7 @@ export class LinesTextBuffer implements ITextBuffer { //#region Editing - public setEOL(newEOL: string): void { + public setEOL(newEOL: '\r\n' | '\n'): void { this._EOL = newEOL; this._constructLineStarts(); } @@ -252,7 +299,7 @@ export class LinesTextBuffer implements ITextBuffer { public applyEdits(rawOperations: IIdentifiedSingleEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult { if (rawOperations.length === 0) { - return new ApplyEditsResult([], [], [], []); + return new ApplyEditsResult([], [], []); } let mightContainRTL = this._mightContainRTL; @@ -341,7 +388,7 @@ export class LinesTextBuffer implements ITextBuffer { this._mightContainRTL = mightContainRTL; this._mightContainNonBasicASCII = mightContainNonBasicASCII; - const [rawContentChanges, contentChanges] = this._doApplyEdits(operations); + const contentChanges = this._doApplyEdits(operations); let trimAutoWhitespaceLineNumbers: number[] = null; if (recordTrimAutoWhitespace && newTrimAutoWhitespaceCandidates.length > 0) { @@ -369,7 +416,6 @@ export class LinesTextBuffer implements ITextBuffer { return new ApplyEditsResult( reverseOperations, - rawContentChanges, contentChanges, trimAutoWhitespaceLineNumbers ); @@ -451,18 +497,16 @@ export class LinesTextBuffer implements ITextBuffer { }; } - private _setLineContent(lineNumber: number, content: string, rawContentChanges: ModelRawChange[]): void { + private _setLineContent(lineNumber: number, content: string): void { this._lines[lineNumber - 1] = content; this._lineStarts.changeValue(lineNumber - 1, content.length + this._EOL.length); - rawContentChanges.push(new ModelRawLineChanged(lineNumber, content)); } - private _doApplyEdits(operations: IValidatedEditOperation[]): [ModelRawChange[], IInternalModelContentChange[]] { + private _doApplyEdits(operations: IValidatedEditOperation[]): IInternalModelContentChange[] { // Sort operations descending operations.sort(LinesTextBuffer._sortOpsDescending); - let rawContentChanges: ModelRawChange[] = []; let contentChanges: IInternalModelContentChange[] = []; for (let i = 0, len = operations.length; i < len; i++) { @@ -497,7 +541,7 @@ export class LinesTextBuffer implements ITextBuffer { ); } - this._setLineContent(editLineNumber, editText, rawContentChanges); + this._setLineContent(editLineNumber, editText); } if (editingLinesCnt < deletingLinesCnt) { @@ -507,12 +551,10 @@ export class LinesTextBuffer implements ITextBuffer { const endLineRemains = this._lines[endLineNumber - 1].substring(endColumn - 1); // Reconstruct first line - this._setLineContent(spliceStartLineNumber, this._lines[spliceStartLineNumber - 1] + endLineRemains, rawContentChanges); + this._setLineContent(spliceStartLineNumber, this._lines[spliceStartLineNumber - 1] + endLineRemains); this._lines.splice(spliceStartLineNumber, endLineNumber - spliceStartLineNumber); this._lineStarts.removeValues(spliceStartLineNumber, endLineNumber - spliceStartLineNumber); - - rawContentChanges.push(new ModelRawLinesDeleted(spliceStartLineNumber + 1, endLineNumber)); } if (editingLinesCnt < insertingLinesCnt) { @@ -527,7 +569,7 @@ export class LinesTextBuffer implements ITextBuffer { // Split last line const leftoverLine = this._lines[spliceLineNumber - 1].substring(spliceColumn - 1); - this._setLineContent(spliceLineNumber, this._lines[spliceLineNumber - 1].substring(0, spliceColumn - 1), rawContentChanges); + this._setLineContent(spliceLineNumber, this._lines[spliceLineNumber - 1].substring(0, spliceColumn - 1)); // Lines in the middle let newLines: string[] = new Array(insertingLinesCnt - editingLinesCnt); @@ -540,8 +582,6 @@ export class LinesTextBuffer implements ITextBuffer { newLinesLengths[newLines.length - 1] += leftoverLine.length; this._lines = arrays.arrayInsert(this._lines, startLineNumber + editingLinesCnt, newLines); this._lineStarts.insertValues(startLineNumber + editingLinesCnt, newLinesLengths); - - rawContentChanges.push(new ModelRawLinesInserted(spliceLineNumber + 1, startLineNumber + insertingLinesCnt, newLines)); } const contentChangeRange = new Range(startLineNumber, startColumn, endLineNumber, endColumn); @@ -550,13 +590,12 @@ export class LinesTextBuffer implements ITextBuffer { range: contentChangeRange, rangeLength: op.rangeLength, text: text, - lines: op.lines, rangeOffset: op.rangeOffset, forceMoveMarkers: op.forceMoveMarkers }); } - return [rawContentChanges, contentChanges]; + return contentChanges; } /** diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts new file mode 100644 index 00000000000..9c4b974dd11 --- /dev/null +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts @@ -0,0 +1,1300 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { Position } from 'vs/editor/common/core/position'; +import { CharCode } from 'vs/base/common/charCode'; +import { Range } from 'vs/editor/common/core/range'; +import { ITextSnapshot } from 'vs/platform/files/common/files'; +import { leftest, righttest, updateTreeMetadata, rbDelete, fixInsert, NodeColor, SENTINEL, TreeNode } from 'vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase'; + +// const lfRegex = new RegExp(/\r\n|\r|\n/g); + +export function createUintArray(arr: number[]): Uint32Array | Uint16Array { + let r; + if (arr[arr.length - 1] < 65536) { + r = new Uint16Array(arr.length); + } else { + r = new Uint32Array(arr.length); + } + r.set(arr, 0); + return r; +} + +export class LineStarts { + constructor( + public readonly lineStarts: Uint32Array | Uint16Array | number[], + public readonly cr: number, + public readonly lf: number, + public readonly crlf: number, + public readonly isBasicASCII: boolean + ) { } +} + +export function createLineStartsFast(str: string, readonly: boolean = true): Uint32Array | number[] { + let r: number[] = [0], rLength = 1; + + for (let i = 0, len = str.length; i < len; i++) { + const chr = str.charCodeAt(i); + + if (chr === CharCode.CarriageReturn) { + if (i + 1 < len && str.charCodeAt(i + 1) === CharCode.LineFeed) { + // \r\n... case + r[rLength++] = i + 2; + i++; // skip \n + } else { + // \r... case + r[rLength++] = i + 1; + } + } else if (chr === CharCode.LineFeed) { + r[rLength++] = i + 1; + } + } + if (readonly) { + return createUintArray(r); + } else { + return r; + } +} + +export function createLineStarts(r: number[], str: string): LineStarts { + r.length = 0; + r[0] = 0; + let rLength = 1; + let cr = 0, lf = 0, crlf = 0; + let isBasicASCII = true; + for (let i = 0, len = str.length; i < len; i++) { + const chr = str.charCodeAt(i); + + if (chr === CharCode.CarriageReturn) { + if (i + 1 < len && str.charCodeAt(i + 1) === CharCode.LineFeed) { + // \r\n... case + crlf++; + r[rLength++] = i + 2; + i++; // skip \n + } else { + cr++; + // \r... case + r[rLength++] = i + 1; + } + } else if (chr === CharCode.LineFeed) { + lf++; + r[rLength++] = i + 1; + } else { + if (isBasicASCII) { + if (chr !== CharCode.Tab && (chr < 32 || chr > 126)) { + isBasicASCII = false; + } + } + } + } + const result = new LineStarts(createUintArray(r), cr, lf, crlf, isBasicASCII); + r.length = 0; + + return result; +} + +export interface NodePosition { + /** + * Piece Index + */ + node: TreeNode; + /** + * remainer in current piece. + */ + remainder: number; + /** + * node start offset in document. + */ + nodeStartOffset: number; +} + +export interface BufferCursor { + /** + * Line number in current buffer + */ + line: number; + /** + * Column number in current buffer + */ + column: number; +} + +export class Piece { + bufferIndex: number; + start: BufferCursor; + end: BufferCursor; + length: number; + lineFeedCnt: number; + + constructor(bufferIndex: number, start: BufferCursor, end: BufferCursor, lineFeedCnt: number, length: number) { + this.bufferIndex = bufferIndex; + this.start = start; + this.end = end; + this.lineFeedCnt = lineFeedCnt; + this.length = length; + } +} + +export class StringBuffer { + buffer: string; + lineStarts: Uint32Array | Uint16Array | number[]; + + constructor(buffer: string, lineStarts: Uint32Array | Uint16Array | number[]) { + this.buffer = buffer; + this.lineStarts = lineStarts; + } +} + +/** + * Readonly snapshot for piece tree. + * In a real multiple thread environment, to make snapshot reading always work correctly, we need to + * 1. Make TreeNode.piece immutable, then reading and writing can run in parallel. + * 2. TreeNode/Buffers normalization should not happen during snapshot reading. + */ +class PieceTreeSnapshot implements ITextSnapshot { + private _nodes: TreeNode[]; // pieces/tree nodes in order + private _index: number; + private _tree: PieceTreeBase; + private _BOM: string; + + constructor(tree: PieceTreeBase, BOM: string) { + this._nodes = []; + this._tree = tree; + this._BOM = BOM; + tree.iterate(tree.root, node => { + this._nodes.push(node); + return true; + }); + this._index = 0; + } + + read(): string { + if (this._index > this._nodes.length - 1) { + return null; + } + + if (this._index === 0) { + return this._BOM + this._tree.getNodeContent(this._nodes[this._index++]); + } + return this._tree.getNodeContent(this._nodes[this._index++]); + } +} + +export class PieceTreeBase { + root: TreeNode; + protected _buffers: StringBuffer[]; // 0 is change buffer, others are readonly original buffer. + protected _lineCnt: number; + protected _length: number; + private _lastChangeBufferPos: BufferCursor; + private _lastNodePosition: NodePosition; + + constructor(chunks: StringBuffer[]) { + this.create(chunks); + } + + create(chunks: StringBuffer[]) { + this._buffers = [ + new StringBuffer('', [0]) + ]; + this._lastChangeBufferPos = { line: 0, column: 0 }; + this._lastNodePosition = null; + this.root = SENTINEL; + this._lineCnt = 1; + this._length = 0; + + let lastNode: TreeNode = null; + for (let i = 0, len = chunks.length; i < len; i++) { + if (chunks[i].buffer.length > 0) { + if (!chunks[i].lineStarts) { + chunks[i].lineStarts = createLineStartsFast(chunks[i].buffer); + } + + let piece = new Piece( + i + 1, + { line: 0, column: 0 }, + { line: chunks[i].lineStarts.length - 1, column: chunks[i].buffer.length - chunks[i].lineStarts[chunks[i].lineStarts.length - 1] }, + chunks[i].lineStarts.length - 1, + chunks[i].buffer.length + ); + this._buffers.push(chunks[i]); + lastNode = this.rbInsertRight(lastNode, piece); + } + } + + this.computeBufferMetadata(); + + } + + normalizeEOL(eol: '\r\n' | '\n') { + let averageBufferSize = 65536; + let min = averageBufferSize - Math.floor(averageBufferSize / 3); + let max = min * 2; + + let tempChunk = ''; + let tempChunkLen = 0; + let chunks: StringBuffer[] = []; + + this.iterate(this.root, node => { + let str = this.getNodeContent(node); + let len = str.length; + if (tempChunkLen <= min || tempChunkLen + len < max) { + tempChunk += str; + tempChunkLen += len; + return true; + } + + // flush anyways + let text = tempChunk.replace(/\r\n|\r|\n/g, eol); + chunks.push(new StringBuffer(text, createLineStartsFast(text))); + tempChunk = str; + tempChunkLen = len; + return true; + }); + + if (tempChunkLen > 0) { + let text = tempChunk.replace(/\r\n|\r|\n/g, eol); + chunks.push(new StringBuffer(text, createLineStartsFast(text))); + } + + this.create(chunks); + } + + // #region Buffer API + public createSnapshot(BOM: string): ITextSnapshot { + return new PieceTreeSnapshot(this, BOM); + } + + public equal(other: PieceTreeBase): boolean { + if (this.getLength() !== other.getLength()) { + return false; + } + if (this.getLineCount() !== other.getLineCount()) { + return false; + } + + let offset = 0; + let ret = this.iterate(this.root, node => { + let str = this.getNodeContent(node); + let len = str.length; + let startPosition = other.nodeAt(offset); + let endPosition = other.nodeAt(offset + len); + let val = other.getValueInRange2(startPosition, endPosition); + + return str === val; + }); + + return ret; + } + + public getOffsetAt(lineNumber: number, column: number): number { + let leftLen = 0; // inorder + + let x = this.root; + + while (x !== SENTINEL) { + if (x.left !== SENTINEL && x.lf_left + 1 >= lineNumber) { + x = x.left; + } else if (x.lf_left + x.piece.lineFeedCnt + 1 >= lineNumber) { + leftLen += x.size_left; + // lineNumber >= 2 + let accumualtedValInCurrentIndex = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2); + return leftLen += accumualtedValInCurrentIndex + column - 1; + } else { + lineNumber -= x.lf_left + x.piece.lineFeedCnt; + leftLen += x.size_left + x.piece.length; + x = x.right; + } + } + + return leftLen; + } + + public getPositionAt(offset: number): Position { + offset = Math.floor(offset); + offset = Math.max(0, offset); + + let x = this.root; + let lfCnt = 0; + let originalOffset = offset; + + while (x !== SENTINEL) { + if (x.size_left !== 0 && x.size_left >= offset) { + x = x.left; + } else if (x.size_left + x.piece.length >= offset) { + let out = this.getIndexOf(x, offset - x.size_left); + + lfCnt += x.lf_left + out.index; + + if (out.index === 0) { + let lineStartOffset = this.getOffsetAt(lfCnt + 1, 1); + let column = originalOffset - lineStartOffset; + return new Position(lfCnt + 1, column + 1); + } + + return new Position(lfCnt + 1, out.remainder + 1); + } else { + offset -= x.size_left + x.piece.length; + lfCnt += x.lf_left + x.piece.lineFeedCnt; + + if (x.right === SENTINEL) { + // last node + let lineStartOffset = this.getOffsetAt(lfCnt + 1, 1); + let column = originalOffset - offset - lineStartOffset; + return new Position(lfCnt + 1, column + 1); + } else { + x = x.right; + } + } + } + + return new Position(1, 1); + } + + public getValueInRange(range: Range): string { + if (range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn) { + return ''; + } + + let startPosition = this.nodeAt2(new Position(range.startLineNumber, range.startColumn)); + let endPosition = this.nodeAt2(new Position(range.endLineNumber, range.endColumn)); + + return this.getValueInRange2(startPosition, endPosition); + } + + public getValueInRange2(startPosition: NodePosition, endPosition: NodePosition): string { + if (startPosition.node === endPosition.node) { + let node = startPosition.node; + let buffer = this._buffers[node.piece.bufferIndex].buffer; + let startOffset = this.offsetInBuffer(node.piece.bufferIndex, node.piece.start); + return buffer.substring(startOffset + startPosition.remainder, startOffset + endPosition.remainder); + } + + let x = startPosition.node; + let buffer = this._buffers[x.piece.bufferIndex].buffer; + let startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start); + let ret = buffer.substring(startOffset + startPosition.remainder, startOffset + x.piece.length); + + x = x.next(); + while (x !== SENTINEL) { + let buffer = this._buffers[x.piece.bufferIndex].buffer; + let startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start); + + if (x === endPosition.node) { + ret += buffer.substring(startOffset, startOffset + endPosition.remainder); + break; + } else { + ret += buffer.substr(startOffset, x.piece.length); + } + + x = x.next(); + } + + return ret; + } + + public getLinesContent(): string[] { + return this.getContentOfSubTree(this.root).split(/\r\n|\r|\n/); + } + + public getLength(): number { + return this._length; + } + + public getLineCount(): number { + return this._lineCnt; + } + + public getLineContent(lineNumber): string { + return this.getLineRawContent(lineNumber).replace(/(\r\n|\r|\n)$/, ''); + } + + public getLineCharCode(lineNumber: number, index: number): number { + let nodePos = this.nodeAt2(new Position(lineNumber, index + 1)); + let buffer = this._buffers[nodePos.node.piece.bufferIndex]; + let startOffset = this.offsetInBuffer(nodePos.node.piece.bufferIndex, nodePos.node.piece.start); + let targetOffset = startOffset + index; + + return buffer.buffer.charCodeAt(targetOffset); + } + + // #endregion + + // #region Piece Table + insert(offset: number, value: string): void { + if (this.root !== SENTINEL) { + let { node, remainder, nodeStartOffset } = this.nodeAt(offset); + let piece = node.piece; + let bufferIndex = piece.bufferIndex; + let insertPosInBuffer = this.positionInBuffer(node, remainder); + if (node.piece.bufferIndex === 0 && + piece.end.line === this._lastChangeBufferPos.line && + piece.end.column === this._lastChangeBufferPos.column && + (nodeStartOffset + piece.length === offset) + ) { + // changed buffer + this.appendToNode(node, value); + this.computeBufferMetadata(); + this._lastNodePosition = { node, remainder, nodeStartOffset }; + return; + } + + if (nodeStartOffset === offset) { + this.insertContentToNodeLeft(value, node); + } else if (nodeStartOffset + node.piece.length > offset) { + // we are inserting into the middle of a node. + let nodesToDel = []; + let newRightPiece = new Piece( + piece.bufferIndex, + insertPosInBuffer, + piece.end, + this.getLineFeedCnt(piece.bufferIndex, insertPosInBuffer, piece.end), + this.offsetInBuffer(bufferIndex, piece.end) - this.offsetInBuffer(bufferIndex, insertPosInBuffer) + ); + + if (this.endWithCR(value)) { + let headOfRight = this.nodeCharCodeAt(node, remainder); + + if (headOfRight === 10 /** \n */) { + let newStart: BufferCursor = { line: newRightPiece.start.line + 1, column: 0 }; + newRightPiece.start = newStart; + newRightPiece.length -= 1; + newRightPiece.lineFeedCnt = this.getLineFeedCnt(newRightPiece.bufferIndex, newRightPiece.start, newRightPiece.end); // @todo, we can optimize + value += '\n'; + } + } + + // reuse node for content before insertion point. + if (this.startWithLF(value)) { + let tailOfLeft = this.nodeCharCodeAt(node, remainder - 1); + if (tailOfLeft === 13 /** \r */) { + let previousPos = this.positionInBuffer(node, remainder - 1); + this.deleteNodeTail(node, previousPos); + value = '\r' + value; + + if (node.piece.length === 0) { + nodesToDel.push(node); + } + } else { + this.deleteNodeTail(node, insertPosInBuffer); + } + } else { + this.deleteNodeTail(node, insertPosInBuffer); + } + + let newPiece = this.createNewPiece(value); + if (newRightPiece.length > 0) { + this.rbInsertRight(node, newRightPiece); + } + this.rbInsertRight(node, newPiece); + this.deleteNodes(nodesToDel); + } else { + this.insertContentToNodeRight(value, node); + } + } else { + // insert new node + let piece = this.createNewPiece(value); + this.rbInsertLeft(null, piece); + } + + // todo, this is too brutal. Total line feed count should be updated the same way as lf_left. + this.computeBufferMetadata(); + } + + delete(offset: number, cnt: number): void { + if (cnt <= 0 || this.root === SENTINEL) { + return; + } + + let startPosition = this.nodeAt(offset); + let endPosition = this.nodeAt(offset + cnt); + let startNode = startPosition.node; + let endNode = endPosition.node; + + if (startNode === endNode) { + let startSplitPosInBuffer = this.positionInBuffer(startNode, startPosition.remainder); + let endSplitPosInBuffer = this.positionInBuffer(startNode, endPosition.remainder); + + if (startPosition.nodeStartOffset === offset) { + if (cnt === startNode.piece.length) { // delete node + let next = startNode.next(); + rbDelete(this, startNode); + this.validateCRLFWithPrevNode(next); + this.computeBufferMetadata(); + return; + } + this.deleteNodeHead(startNode, endSplitPosInBuffer); + this.validateCRLFWithPrevNode(startNode); + this.computeBufferMetadata(); + return; + } + + if (startPosition.nodeStartOffset + startNode.piece.length === offset + cnt) { + this.deleteNodeTail(startNode, startSplitPosInBuffer); + this.validateCRLFWithNextNode(startNode); + this.computeBufferMetadata(); + return; + } + + // delete content in the middle, this node will be splitted to nodes + this.shrinkNode(startNode, startSplitPosInBuffer, endSplitPosInBuffer); + this.computeBufferMetadata(); + return; + } + + let nodesToDel = []; + + let startSplitPosInBuffer = this.positionInBuffer(startNode, startPosition.remainder); + this.deleteNodeTail(startNode, startSplitPosInBuffer); + if (startNode.piece.length === 0) { + nodesToDel.push(startNode); + } + + // update last touched node + let endSplitPosInBuffer = this.positionInBuffer(endNode, endPosition.remainder); + this.deleteNodeHead(endNode, endSplitPosInBuffer); + if (endNode.piece.length === 0) { + nodesToDel.push(endNode); + } + + // delete nodes in between + let secondNode = startNode.next(); + for (let node = secondNode; node !== SENTINEL && node !== endNode; node = node.next()) { + nodesToDel.push(node); + } + + let prev = startNode.piece.length === 0 ? startNode.prev() : startNode; + this.deleteNodes(nodesToDel); + this.validateCRLFWithNextNode(prev); + this.computeBufferMetadata(); + } + + insertContentToNodeLeft(value: string, node: TreeNode) { + // we are inserting content to the beginning of node + let nodesToDel = []; + if (this.endWithCR(value) && this.startWithLF(node)) { + // move `\n` to new node. + + let piece = node.piece; + let newStart: BufferCursor = { line: piece.start.line + 1, column: 0 }; + piece.start = newStart; + piece.lineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, piece.start, piece.end); // @todo, we can optimize + piece.length -= 1; + + value += '\n'; + updateTreeMetadata(this, node, -1, -1); + + if (node.piece.length === 0) { + nodesToDel.push(node); + } + } + + let newPiece = this.createNewPiece(value); + let newNode = this.rbInsertLeft(node, newPiece); + this.validateCRLFWithPrevNode(newNode); + this.deleteNodes(nodesToDel); + } + + insertContentToNodeRight(value: string, node: TreeNode) { + // we are inserting to the right of this node. + if (this.adjustCarriageReturnFromNext(value, node)) { + // move \n to the new node. + value += '\n'; + } + + let newPiece = this.createNewPiece(value); + let newNode = this.rbInsertRight(node, newPiece); + this.validateCRLFWithPrevNode(newNode); + } + + positionInBuffer(node: TreeNode, remainder: number): BufferCursor { + let piece = node.piece; + let bufferIndex = node.piece.bufferIndex; + let lineStarts = this._buffers[bufferIndex].lineStarts; + + let startOffset = lineStarts[piece.start.line] + piece.start.column; + + let offset = startOffset + remainder; + + // binary search offset between startOffset and endOffset + let low = piece.start.line; + let high = piece.end.line; + + let mid: number; + let midStop: number; + let midStart: number; + + while (low <= high) { + mid = low + ((high - low) / 2) | 0; + midStart = lineStarts[mid]; + + if (mid === high) { + break; + } + + midStop = lineStarts[mid + 1]; + + if (offset < midStart) { + high = mid - 1; + } else if (offset >= midStop) { + low = mid + 1; + } else { + break; + } + } + + return { + line: mid, + column: offset - midStart + }; + } + + getLineFeedCnt(bufferIndex: number, start: BufferCursor, end: BufferCursor): number { + // we don't need to worry about start: abc\r|\n, or abc|\r, or abc|\n, or abc|\r\n doesn't change the fact that, there is one line break after start. + // now let's take care of end: abc\r|\n, if end is in between \r and \n, we need to add line feed count by 1 + if (end.column === 0) { + return end.line - start.line; + } + + let lineStarts = this._buffers[bufferIndex].lineStarts; + if (end.line === lineStarts.length - 1) { // it means, there is no \n after end, otherwise, there will be one more lineStart. + return end.line - start.line; + } + + let nextLineStartOffset = lineStarts[end.line + 1]; + let endOffset = lineStarts[end.line] + end.column; + if (nextLineStartOffset > endOffset + 1) { // there are more than 1 character after end, which means it can't be \n + return end.line - start.line; + } + // endOffset + 1 === nextLineStartOffset + // character at endOffset is \n, so we check the character before first + // if character at endOffset is \r, end.column is 0 and we can't get here. + let previousCharOffset = endOffset - 1; // end.column > 0 so it's okay. + let buffer = this._buffers[bufferIndex].buffer; + + if (buffer.charCodeAt(previousCharOffset) === 13) { + return end.line - start.line + 1; + } else { + return end.line - start.line; + } + } + + offsetInBuffer(bufferIndex: number, cursor: BufferCursor): number { + let lineStarts = this._buffers[bufferIndex].lineStarts; + return lineStarts[cursor.line] + cursor.column; + } + + deleteNodes(nodes: TreeNode[]): void { + for (let i = 0; i < nodes.length; i++) { + rbDelete(this, nodes[i]); + } + } + + createNewPiece(text: string): Piece { + let startOffset = this._buffers[0].buffer.length; + const lineStarts = createLineStartsFast(text, false); + + let start = this._lastChangeBufferPos; + if (this._buffers[0].lineStarts[this._buffers[0].lineStarts.length - 1] === startOffset + && startOffset !== 0 + && this.startWithLF(text) + && this.endWithCR(this._buffers[0].buffer) // todo, we can check this._lastChangeBufferPos's column as it's the last one + ) { + this._lastChangeBufferPos = { line: this._lastChangeBufferPos.line, column: this._lastChangeBufferPos.column + 1 }; + start = this._lastChangeBufferPos; + + for (let i = 0; i < lineStarts.length; i++) { + lineStarts[i] += startOffset + 1; + } + (this._buffers[0].lineStarts).push(...lineStarts.slice(1)); + this._buffers[0].buffer += '_' + text; + startOffset += 1; + } else { + for (let i = 0; i < lineStarts.length; i++) { + lineStarts[i] += startOffset; + } + (this._buffers[0].lineStarts).push(...lineStarts.slice(1)); + this._buffers[0].buffer += text; + } + + const endOffset = this._buffers[0].buffer.length; + let endIndex = this._buffers[0].lineStarts.length - 1; + let endColumn = endOffset - this._buffers[0].lineStarts[endIndex]; + let endPos = { line: endIndex, column: endColumn }; + let newPiece = new Piece( + 0, + start, + endPos, + this.getLineFeedCnt(0, start, endPos), // @todo, optimize + endOffset - startOffset + ); + this._lastChangeBufferPos = endPos; + return newPiece; + } + + getLinesRawContent(): string { + return this.getContentOfSubTree(this.root); + } + + getLineRawContent(lineNumber: number): string { + let x = this.root; + + let ret = ''; + while (x !== SENTINEL) { + if (x.left !== SENTINEL && x.lf_left >= lineNumber - 1) { + x = x.left; + } else if (x.lf_left + x.piece.lineFeedCnt > lineNumber - 1) { + let prevAccumualtedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2); + let accumualtedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 1); + let buffer = this._buffers[x.piece.bufferIndex].buffer; + let startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start); + return buffer.substring(startOffset + prevAccumualtedValue, startOffset + accumualtedValue); + } else if (x.lf_left + x.piece.lineFeedCnt === lineNumber - 1) { + let prevAccumualtedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2); + let buffer = this._buffers[x.piece.bufferIndex].buffer; + let startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start); + + ret = buffer.substring(startOffset + prevAccumualtedValue, startOffset + x.piece.length); + break; + } else { + lineNumber -= x.lf_left + x.piece.lineFeedCnt; + x = x.right; + } + } + + // search in order, to find the node contains end column + x = x.next(); + while (x !== SENTINEL) { + let buffer = this._buffers[x.piece.bufferIndex].buffer; + + if (x.piece.lineFeedCnt > 0) { + let accumualtedValue = this.getAccumulatedValue(x, 0); + let startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start); + + ret += buffer.substring(startOffset, startOffset + accumualtedValue); + return ret; + } else { + let startOffset = this.offsetInBuffer(x.piece.bufferIndex, x.piece.start); + ret += buffer.substr(startOffset, x.piece.length); + } + + x = x.next(); + } + + return ret; + } + + computeBufferMetadata() { + let x = this.root; + + let lfCnt = 1; + let len = 0; + + while (x !== SENTINEL) { + lfCnt += x.lf_left + x.piece.lineFeedCnt; + len += x.size_left + x.piece.length; + x = x.right; + } + + this._lineCnt = lfCnt; + this._length = len; + } + + // #region node operations + getIndexOf(node: TreeNode, accumulatedValue: number): { index: number, remainder: number } { + let piece = node.piece; + let pos = this.positionInBuffer(node, accumulatedValue); + let lineCnt = pos.line - piece.start.line; + + if (this.offsetInBuffer(piece.bufferIndex, piece.end) - this.offsetInBuffer(piece.bufferIndex, piece.start) === accumulatedValue) { + // we are checking the end of this node, so a CRLF check is necessary. + let realLineCnt = this.getLineFeedCnt(node.piece.bufferIndex, piece.start, pos); + if (realLineCnt !== lineCnt) { + // aha yes, CRLF + return { index: realLineCnt, remainder: 0 }; + } + } + + return { index: lineCnt, remainder: pos.column }; + } + + getAccumulatedValue(node: TreeNode, index: number) { + if (index < 0) { + return 0; + } + let piece = node.piece; + let lineStarts = this._buffers[piece.bufferIndex].lineStarts; + let expectedLineStartIndex = piece.start.line + index + 1; + if (expectedLineStartIndex > piece.end.line) { + return lineStarts[piece.end.line] + piece.end.column - lineStarts[piece.start.line] - piece.start.column; + } else { + return lineStarts[expectedLineStartIndex] - lineStarts[piece.start.line] - piece.start.column; + } + } + + deleteNodeTail(node: TreeNode, pos: BufferCursor) { + let piece = node.piece; + let originalLFCnt = piece.lineFeedCnt; + let originalEndOffset = this.offsetInBuffer(piece.bufferIndex, piece.end); + piece.end = pos; + let newEndOffset = this.offsetInBuffer(piece.bufferIndex, piece.end); + piece.lineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, piece.start, piece.end); + let lf_delta = piece.lineFeedCnt - originalLFCnt; + let size_delta = newEndOffset - originalEndOffset; + piece.length += size_delta; + updateTreeMetadata(this, node, size_delta, lf_delta); + } + + deleteNodeHead(node: TreeNode, pos: BufferCursor) { + let piece = node.piece; + let originalLFCnt = piece.lineFeedCnt; + let originalStartOffset = this.offsetInBuffer(piece.bufferIndex, piece.start); + + piece.start = pos; + piece.lineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, piece.start, piece.end); // @todo, maybe we can optimize this case as we just change start. + let newStartOffset = this.offsetInBuffer(piece.bufferIndex, piece.start); + let lf_delta = piece.lineFeedCnt - originalLFCnt; + let size_delta = originalStartOffset - newStartOffset; + piece.length += size_delta; + updateTreeMetadata(this, node, size_delta, lf_delta); + } + + shrinkNode(node: TreeNode, start: BufferCursor, end: BufferCursor) { + let piece = node.piece; + let originalStartPos = piece.start; + let originalEndPos = piece.end; + + // old piece, originalStartPos, start + let oldLength = piece.length; + let oldLFCnt = piece.lineFeedCnt; + piece.end = start; + piece.lineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, piece.start, piece.end); + let newLength = this.offsetInBuffer(piece.bufferIndex, start) - this.offsetInBuffer(piece.bufferIndex, originalStartPos); + let newLFCnt = piece.lineFeedCnt; + piece.length = newLength; + updateTreeMetadata(this, node, newLength - oldLength, newLFCnt - oldLFCnt); + + // new right piece, end, originalEndPos + let newPiece = new Piece( + piece.bufferIndex, + end, + originalEndPos, + this.getLineFeedCnt(piece.bufferIndex, end, originalEndPos), + this.offsetInBuffer(piece.bufferIndex, originalEndPos) - this.offsetInBuffer(piece.bufferIndex, end) + ); + + let newNode = this.rbInsertRight(node, newPiece); + this.validateCRLFWithPrevNode(newNode); + } + + appendToNode(node: TreeNode, value: string): void { + if (this.adjustCarriageReturnFromNext(value, node)) { + value += '\n'; + } + + let hitCRLF = this.startWithLF(value) && this.endWithCR(node); + const startOffset = this._buffers[0].buffer.length; + this._buffers[0].buffer += value; + const lineStarts = createLineStartsFast(value, false); + for (let i = 0; i < lineStarts.length; i++) { + lineStarts[i] += startOffset; + } + if (hitCRLF) { + let prevStartOffset = this._buffers[0].lineStarts[this._buffers[0].lineStarts.length - 2]; + (this._buffers[0].lineStarts).pop(); + // _lastChangeBufferPos is already wrong + this._lastChangeBufferPos = { line: this._lastChangeBufferPos.line - 1, column: startOffset - prevStartOffset }; + } + (this._buffers[0].lineStarts).push(...lineStarts.slice(1)); + let endIndex = this._buffers[0].lineStarts.length - 1; + let endColumn = this._buffers[0].buffer.length - this._buffers[0].lineStarts[endIndex]; + let endPos = { line: endIndex, column: endColumn }; + node.piece.end = endPos; + node.piece.length += value.length; + let oldLineFeedCnt = node.piece.lineFeedCnt; + let newLineFeedCnt = this.getLineFeedCnt(0, node.piece.start, endPos); + node.piece.lineFeedCnt = newLineFeedCnt; + let lf_delta = newLineFeedCnt - oldLineFeedCnt; + this._lastChangeBufferPos = endPos; + updateTreeMetadata(this, node, value.length, lf_delta); + } + + readNodePositionFromCache(offset: number): NodePosition { + if (!this._lastNodePosition) { + return null; + } + + if (this._lastNodePosition.node.parent === null) { + this._lastNodePosition = null; + return null; + } + + if (this._lastNodePosition.nodeStartOffset > offset || this._lastNodePosition.nodeStartOffset + this._lastNodePosition.node.piece.length < offset) { + return null; + } + + return { + node: this._lastNodePosition.node, + remainder: offset - this._lastNodePosition.nodeStartOffset, + nodeStartOffset: this._lastNodePosition.nodeStartOffset + }; + } + + nodeAt(offset: number): NodePosition { + let cachedNodePosition = this.readNodePositionFromCache(offset); + if (cachedNodePosition) { + return cachedNodePosition; + } + + let x = this.root; + let nodeStartOffset = 0; + + while (x !== SENTINEL) { + if (x.size_left > offset) { + x = x.left; + } else if (x.size_left + x.piece.length >= offset) { + nodeStartOffset += x.size_left; + return { + node: x, + remainder: offset - x.size_left, + nodeStartOffset + }; + } else { + offset -= x.size_left + x.piece.length; + nodeStartOffset += x.size_left + x.piece.length; + x = x.right; + } + } + + return null; + } + + nodeAt2(position: Position): NodePosition { + let x = this.root; + let lineNumber = position.lineNumber; + let column = position.column; + let nodeStartOffset = 0; + + while (x !== SENTINEL) { + if (x.left !== SENTINEL && x.lf_left >= lineNumber - 1) { + x = x.left; + } else if (x.lf_left + x.piece.lineFeedCnt > lineNumber - 1) { + let prevAccumualtedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2); + let accumualtedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 1); + nodeStartOffset += x.size_left; + + return { + node: x, + remainder: Math.min(prevAccumualtedValue + column - 1, accumualtedValue), + nodeStartOffset + }; + } else if (x.lf_left + x.piece.lineFeedCnt === lineNumber - 1) { + let prevAccumualtedValue = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2); + if (prevAccumualtedValue + column - 1 <= x.piece.length) { + return { + node: x, + remainder: prevAccumualtedValue + column - 1, + nodeStartOffset + }; + } else { + column -= x.piece.length - prevAccumualtedValue; + break; + } + } else { + lineNumber -= x.lf_left + x.piece.lineFeedCnt; + nodeStartOffset += x.size_left + x.piece.length; + x = x.right; + } + } + + // search in order, to find the node contains position.column + x = x.next(); + while (x !== SENTINEL) { + + if (x.piece.lineFeedCnt > 0) { + let accumualtedValue = this.getAccumulatedValue(x, 0); + let nodeStartOffset = this.offsetOfNode(x); + return { + node: x, + remainder: Math.min(column - 1, accumualtedValue), + nodeStartOffset + }; + } else { + if (x.piece.length >= column - 1) { + let nodeStartOffset = this.offsetOfNode(x); + return { + node: x, + remainder: column - 1, + nodeStartOffset + }; + } else { + column -= x.piece.length; + } + } + + x = x.next(); + } + + return null; + } + + nodeCharCodeAt(node: TreeNode, offset: number): number { + if (node.piece.lineFeedCnt < 1) { + return -1; + } + let buffer = this._buffers[node.piece.bufferIndex]; + let newOffset = this.offsetInBuffer(node.piece.bufferIndex, node.piece.start) + offset; + return buffer.buffer.charCodeAt(newOffset); + } + + offsetOfNode(node: TreeNode): number { + if (!node) { + return 0; + } + let pos = node.size_left; + while (node !== this.root) { + if (node.parent.right === node) { + pos += node.parent.size_left + node.parent.piece.length; + } + + node = node.parent; + } + + return pos; + } + + // #endregion + + // #region CRLF + startWithLF(val: string | TreeNode): boolean { + if (typeof val === 'string') { + return val.charCodeAt(0) === 10; + } + + if (val === SENTINEL || val.piece.lineFeedCnt === 0) { + return false; + } + + let piece = val.piece; + let lineStarts = this._buffers[piece.bufferIndex].lineStarts; + let line = piece.start.line; + let startOffset = lineStarts[line] + piece.start.column; + if (line === lineStarts.length - 1) { + // last line, so there is no line feed at the end of this line + return false; + } + let nextLineOffset = lineStarts[line + 1]; + if (nextLineOffset > startOffset + 1) { + return false; + } + return this._buffers[piece.bufferIndex].buffer.charCodeAt(startOffset) === 10; + } + + endWithCR(val: string | TreeNode): boolean { + if (typeof val === 'string') { + return val.charCodeAt(val.length - 1) === 13; + } + + if (val === SENTINEL || val.piece.lineFeedCnt === 0) { + return false; + } + + return this.nodeCharCodeAt(val, val.piece.length - 1) === 13; + } + + validateCRLFWithPrevNode(nextNode: TreeNode) { + if (this.startWithLF(nextNode)) { + let node = nextNode.prev(); + if (this.endWithCR(node)) { + this.fixCRLF(node, nextNode); + } + } + } + + validateCRLFWithNextNode(node: TreeNode) { + if (this.endWithCR(node)) { + let nextNode = node.next(); + if (this.startWithLF(nextNode)) { + this.fixCRLF(node, nextNode); + } + } + } + + fixCRLF(prev: TreeNode, next: TreeNode) { + let nodesToDel = []; + // update node + let lineStarts = this._buffers[prev.piece.bufferIndex].lineStarts; + if (prev.piece.end.column === 0) { + // it means, last line ends with \r, not \r\n + let newEnd: BufferCursor = { line: prev.piece.end.line - 1, column: lineStarts[prev.piece.end.line] - lineStarts[prev.piece.end.line - 1] - 1 }; + prev.piece.end = newEnd; + } else { + // \r\n + let newEnd: BufferCursor = { line: prev.piece.end.line, column: prev.piece.end.column - 1 }; + prev.piece.end = newEnd; + } + + prev.piece.length -= 1; + prev.piece.lineFeedCnt -= 1; + + updateTreeMetadata(this, prev, - 1, -1); + if (prev.piece.length === 0) { + nodesToDel.push(prev); + } + + // update nextNode + let newStart: BufferCursor = { line: next.piece.start.line + 1, column: 0 }; + next.piece.start = newStart; + next.piece.length -= 1; + next.piece.lineFeedCnt = this.getLineFeedCnt(next.piece.bufferIndex, next.piece.start, next.piece.end); // @todo, we can optimize + // } + + updateTreeMetadata(this, next, - 1, -1); + if (next.piece.length === 0) { + nodesToDel.push(next); + } + + // create new piece which contains \r\n + let piece = this.createNewPiece('\r\n'); + this.rbInsertRight(prev, piece); + // delete empty nodes + + for (let i = 0; i < nodesToDel.length; i++) { + rbDelete(this, nodesToDel[i]); + } + } + + adjustCarriageReturnFromNext(value: string, node: TreeNode): boolean { + if (this.endWithCR(value)) { + let nextNode = node.next(); + if (this.startWithLF(nextNode)) { + // move `\n` forward + value += '\n'; + + if (nextNode.piece.length === 1) { + rbDelete(this, nextNode); + } else { + + let piece = nextNode.piece; + let newStart: BufferCursor = { line: piece.start.line + 1, column: 0 }; + piece.start = newStart; + piece.length -= 1; + piece.lineFeedCnt = this.getLineFeedCnt(piece.bufferIndex, piece.start, piece.end); // @todo, we can optimize + updateTreeMetadata(this, nextNode, -1, -1); + } + return true; + } + } + + return false; + } + + // #endregion + + // #endregion + + // #region Tree operations + iterate(node: TreeNode, callback: (node: TreeNode) => boolean): boolean { + if (node === SENTINEL) { + return callback(SENTINEL); + } + + let leftRet = this.iterate(node.left, callback); + if (!leftRet) { + return leftRet; + } + + return callback(node) && this.iterate(node.right, callback); + } + + getNodeContent(node: TreeNode) { + if (node === SENTINEL) { + return ''; + } + let buffer = this._buffers[node.piece.bufferIndex]; + let currentContent; + let piece = node.piece; + let startOffset = this.offsetInBuffer(piece.bufferIndex, piece.start); + let endOffset = this.offsetInBuffer(piece.bufferIndex, piece.end); + currentContent = buffer.buffer.substring(startOffset, endOffset); + return currentContent; + } + + /** + * node node + * / \ / \ + * a b <---- a b + * / + * z + */ + rbInsertRight(node: TreeNode, p: Piece): TreeNode { + let z = new TreeNode(p, NodeColor.Red); + z.left = SENTINEL; + z.right = SENTINEL; + z.parent = SENTINEL; + z.size_left = 0; + z.lf_left = 0; + + let x = this.root; + if (x === SENTINEL) { + this.root = z; + z.color = NodeColor.Black; + } else if (node.right === SENTINEL) { + node.right = z; + z.parent = node; + } else { + let nextNode = leftest(node.right); + nextNode.left = z; + z.parent = nextNode; + } + + fixInsert(this, z); + return z; + } + + /** + * node node + * / \ / \ + * a b ----> a b + * \ + * z + */ + rbInsertLeft(node: TreeNode, p: Piece): TreeNode { + let z = new TreeNode(p, NodeColor.Red); + z.left = SENTINEL; + z.right = SENTINEL; + z.parent = SENTINEL; + z.size_left = 0; + z.lf_left = 0; + + let x = this.root; + if (x === SENTINEL) { + this.root = z; + z.color = NodeColor.Black; + } else if (node.left === SENTINEL) { + node.left = z; + z.parent = node; + } else { + let prevNode = righttest(node.left); // a + prevNode.right = z; + z.parent = prevNode; + } + + fixInsert(this, z); + return z; + } + + getContentOfSubTree(node: TreeNode): string { + let str = ''; + + this.iterate(node, node => { + str += this.getNodeContent(node); + return true; + }); + + return str; + } + // #endregion +} diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts new file mode 100644 index 00000000000..f8505567923 --- /dev/null +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.ts @@ -0,0 +1,504 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { Range } from 'vs/editor/common/core/range'; +import { Position } from 'vs/editor/common/core/position'; +import * as strings from 'vs/base/common/strings'; +import { IValidatedEditOperation } from 'vs/editor/common/model/linesTextBuffer/linesTextBuffer'; +import { PieceTreeBase, StringBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase'; +import { IIdentifiedSingleEditOperation, EndOfLinePreference, ITextBuffer, ApplyEditsResult, IInternalModelContentChange } from 'vs/editor/common/model'; +import { ITextSnapshot } from 'vs/platform/files/common/files'; + +export class PieceTreeTextBuffer implements ITextBuffer { + private _pieceTree: PieceTreeBase; + private _BOM: string; + private _EOL: string; + private _EOLLength: number; + private _mightContainRTL: boolean; + private _mightContainNonBasicASCII: boolean; + + constructor(chunks: StringBuffer[], BOM: string, eol: '\r\n' | '\n', containsRTL: boolean, isBasicASCII: boolean) { + this._BOM = BOM; + this._EOL = eol; + this._EOLLength = this._EOL.length; + this._mightContainNonBasicASCII = !isBasicASCII; + this._mightContainRTL = containsRTL; + this._pieceTree = new PieceTreeBase(chunks); + } + + // #region TextBuffer + public equals(other: ITextBuffer): boolean { + if (!(other instanceof PieceTreeTextBuffer)) { + return false; + } + if (this._BOM !== other._BOM) { + return false; + } + if (this._EOL !== other._EOL) { + return false; + } + return this._pieceTree.equal(other._pieceTree); + } + public mightContainRTL(): boolean { + return this._mightContainRTL; + } + public mightContainNonBasicASCII(): boolean { + return this._mightContainNonBasicASCII; + } + public getBOM(): string { + return this._BOM; + } + public getEOL(): string { + return this._EOL; + } + + public createSnapshot(preserveBOM: boolean): ITextSnapshot { + return this._pieceTree.createSnapshot(preserveBOM ? this._BOM : ''); + } + + public getOffsetAt(lineNumber: number, column: number): number { + return this._pieceTree.getOffsetAt(lineNumber, column); + } + + public getPositionAt(offset: number): Position { + return this._pieceTree.getPositionAt(offset); + } + + public getRangeAt(start: number, length: number): Range { + let end = start + length; + const startPosition = this.getPositionAt(start); + const endPosition = this.getPositionAt(end); + return new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column); + } + + public getValueInRange(range: Range, eol: EndOfLinePreference = EndOfLinePreference.TextDefined): string { + if (range.isEmpty()) { + return ''; + } + + const lineEnding = this._getEndOfLine(eol); + const text = this._pieceTree.getValueInRange(range); + return text.replace(/\r\n|\r|\n/g, lineEnding); + } + + public getValueLengthInRange(range: Range, eol: EndOfLinePreference = EndOfLinePreference.TextDefined): number { + if (range.isEmpty()) { + return 0; + } + + if (range.startLineNumber === range.endLineNumber) { + return (range.endColumn - range.startColumn); + } + + let startOffset = this.getOffsetAt(range.startLineNumber, range.startColumn); + let endOffset = this.getOffsetAt(range.endLineNumber, range.endColumn); + return endOffset - startOffset; + } + + public getLength(): number { + return this._pieceTree.getLength(); + } + + public getLineCount(): number { + return this._pieceTree.getLineCount(); + } + + public getLinesContent(): string[] { + return this._pieceTree.getLinesContent(); + } + + public getLineContent(lineNumber: number): string { + return this._pieceTree.getLineContent(lineNumber); + } + + public getLineCharCode(lineNumber: number, index: number): number { + return this._pieceTree.getLineCharCode(lineNumber, index); + } + + public getLineLength(lineNumber: number): number { + if (lineNumber === this.getLineCount()) { + let startOffset = this.getOffsetAt(lineNumber, 1); + return this.getLength() - startOffset; + } + return this.getOffsetAt(lineNumber + 1, 1) - this.getOffsetAt(lineNumber, 1) - this._EOLLength; + } + + public getLineMinColumn(lineNumber: number): number { + return 1; + } + + public getLineMaxColumn(lineNumber: number): number { + return this.getLineLength(lineNumber) + 1; + } + + public getLineFirstNonWhitespaceColumn(lineNumber: number): number { + const result = strings.firstNonWhitespaceIndex(this.getLineContent(lineNumber)); + if (result === -1) { + return 0; + } + return result + 1; + } + + public getLineLastNonWhitespaceColumn(lineNumber: number): number { + const result = strings.lastNonWhitespaceIndex(this.getLineContent(lineNumber)); + if (result === -1) { + return 0; + } + return result + 2; + } + + private _getEndOfLine(eol: EndOfLinePreference): string { + switch (eol) { + case EndOfLinePreference.LF: + return '\n'; + case EndOfLinePreference.CRLF: + return '\r\n'; + case EndOfLinePreference.TextDefined: + return this.getEOL(); + } + throw new Error('Unknown EOL preference'); + } + + public setEOL(newEOL: '\r\n' | '\n'): void { + this._EOL = newEOL; + this._EOLLength = this._EOL.length; + this._pieceTree.normalizeEOL(newEOL); + } + + public applyEdits(rawOperations: IIdentifiedSingleEditOperation[], recordTrimAutoWhitespace: boolean): ApplyEditsResult { + let mightContainRTL = this._mightContainRTL; + let mightContainNonBasicASCII = this._mightContainNonBasicASCII; + let canReduceOperations = true; + + let operations: IValidatedEditOperation[] = []; + for (let i = 0; i < rawOperations.length; i++) { + let op = rawOperations[i]; + if (canReduceOperations && op._isTracked) { + canReduceOperations = false; + } + let validatedRange = op.range; + if (!mightContainRTL && op.text) { + // check if the new inserted text contains RTL + mightContainRTL = strings.containsRTL(op.text); + } + if (!mightContainNonBasicASCII && op.text) { + mightContainNonBasicASCII = !strings.isBasicASCII(op.text); + } + operations[i] = { + sortIndex: i, + identifier: op.identifier, + range: validatedRange, + rangeOffset: this.getOffsetAt(validatedRange.startLineNumber, validatedRange.startColumn), + rangeLength: this.getValueLengthInRange(validatedRange), + lines: op.text ? op.text.split(/\r\n|\r|\n/) : null, + forceMoveMarkers: op.forceMoveMarkers, + isAutoWhitespaceEdit: op.isAutoWhitespaceEdit || false + }; + } + + // Sort operations ascending + operations.sort(PieceTreeTextBuffer._sortOpsAscending); + + for (let i = 0, count = operations.length - 1; i < count; i++) { + let rangeEnd = operations[i].range.getEndPosition(); + let nextRangeStart = operations[i + 1].range.getStartPosition(); + + if (nextRangeStart.isBefore(rangeEnd)) { + // overlapping ranges + throw new Error('Overlapping ranges are not allowed!'); + } + } + + if (canReduceOperations) { + operations = this._reduceOperations(operations); + } + + // Delta encode operations + let reverseRanges = PieceTreeTextBuffer._getInverseEditRanges(operations); + let newTrimAutoWhitespaceCandidates: { lineNumber: number, oldContent: string }[] = []; + + for (let i = 0; i < operations.length; i++) { + let op = operations[i]; + let reverseRange = reverseRanges[i]; + + if (recordTrimAutoWhitespace && op.isAutoWhitespaceEdit && op.range.isEmpty()) { + // Record already the future line numbers that might be auto whitespace removal candidates on next edit + for (let lineNumber = reverseRange.startLineNumber; lineNumber <= reverseRange.endLineNumber; lineNumber++) { + let currentLineContent = ''; + if (lineNumber === reverseRange.startLineNumber) { + currentLineContent = this.getLineContent(op.range.startLineNumber); + if (strings.firstNonWhitespaceIndex(currentLineContent) !== -1) { + continue; + } + } + newTrimAutoWhitespaceCandidates.push({ lineNumber: lineNumber, oldContent: currentLineContent }); + } + } + } + + let reverseOperations: IIdentifiedSingleEditOperation[] = []; + for (let i = 0; i < operations.length; i++) { + let op = operations[i]; + let reverseRange = reverseRanges[i]; + + reverseOperations[i] = { + identifier: op.identifier, + range: reverseRange, + text: this.getValueInRange(op.range), + forceMoveMarkers: op.forceMoveMarkers + }; + } + + this._mightContainRTL = mightContainRTL; + this._mightContainNonBasicASCII = mightContainNonBasicASCII; + + const contentChanges = this._doApplyEdits(operations); + + let trimAutoWhitespaceLineNumbers: number[] = null; + if (recordTrimAutoWhitespace && newTrimAutoWhitespaceCandidates.length > 0) { + // sort line numbers auto whitespace removal candidates for next edit descending + newTrimAutoWhitespaceCandidates.sort((a, b) => b.lineNumber - a.lineNumber); + + trimAutoWhitespaceLineNumbers = []; + for (let i = 0, len = newTrimAutoWhitespaceCandidates.length; i < len; i++) { + let lineNumber = newTrimAutoWhitespaceCandidates[i].lineNumber; + if (i > 0 && newTrimAutoWhitespaceCandidates[i - 1].lineNumber === lineNumber) { + // Do not have the same line number twice + continue; + } + + let prevContent = newTrimAutoWhitespaceCandidates[i].oldContent; + let lineContent = this.getLineContent(lineNumber); + + if (lineContent.length === 0 || lineContent === prevContent || strings.firstNonWhitespaceIndex(lineContent) !== -1) { + continue; + } + + trimAutoWhitespaceLineNumbers.push(lineNumber); + } + } + + return new ApplyEditsResult( + reverseOperations, + contentChanges, + trimAutoWhitespaceLineNumbers + ); + } + + /** + * Transform operations such that they represent the same logic edit, + * but that they also do not cause OOM crashes. + */ + private _reduceOperations(operations: IValidatedEditOperation[]): IValidatedEditOperation[] { + if (operations.length < 1000) { + // We know from empirical testing that a thousand edits work fine regardless of their shape. + return operations; + } + + // At one point, due to how events are emitted and how each operation is handled, + // some operations can trigger a high ammount of temporary string allocations, + // that will immediately get edited again. + // e.g. a formatter inserting ridiculous ammounts of \n on a model with a single line + // Therefore, the strategy is to collapse all the operations into a huge single edit operation + return [this._toSingleEditOperation(operations)]; + } + + _toSingleEditOperation(operations: IValidatedEditOperation[]): IValidatedEditOperation { + let forceMoveMarkers = false, + firstEditRange = operations[0].range, + lastEditRange = operations[operations.length - 1].range, + entireEditRange = new Range(firstEditRange.startLineNumber, firstEditRange.startColumn, lastEditRange.endLineNumber, lastEditRange.endColumn), + lastEndLineNumber = firstEditRange.startLineNumber, + lastEndColumn = firstEditRange.startColumn, + result: string[] = []; + + for (let i = 0, len = operations.length; i < len; i++) { + let operation = operations[i], + range = operation.range; + + forceMoveMarkers = forceMoveMarkers || operation.forceMoveMarkers; + + // (1) -- Push old text + for (let lineNumber = lastEndLineNumber; lineNumber < range.startLineNumber; lineNumber++) { + if (lineNumber === lastEndLineNumber) { + result.push(this.getLineContent(lineNumber).substring(lastEndColumn - 1)); + } else { + result.push('\n'); + result.push(this.getLineContent(lineNumber)); + } + } + + if (range.startLineNumber === lastEndLineNumber) { + result.push(this.getLineContent(range.startLineNumber).substring(lastEndColumn - 1, range.startColumn - 1)); + } else { + result.push('\n'); + result.push(this.getLineContent(range.startLineNumber).substring(0, range.startColumn - 1)); + } + + // (2) -- Push new text + if (operation.lines) { + for (let j = 0, lenJ = operation.lines.length; j < lenJ; j++) { + if (j !== 0) { + result.push('\n'); + } + result.push(operation.lines[j]); + } + } + + lastEndLineNumber = operation.range.endLineNumber; + lastEndColumn = operation.range.endColumn; + } + + return { + sortIndex: 0, + identifier: operations[0].identifier, + range: entireEditRange, + rangeOffset: this.getOffsetAt(entireEditRange.startLineNumber, entireEditRange.startColumn), + rangeLength: this.getValueLengthInRange(entireEditRange, EndOfLinePreference.TextDefined), + lines: result.join('').split('\n'), + forceMoveMarkers: forceMoveMarkers, + isAutoWhitespaceEdit: false + }; + } + + private _doApplyEdits(operations: IValidatedEditOperation[]): IInternalModelContentChange[] { + operations.sort(PieceTreeTextBuffer._sortOpsDescending); + + let contentChanges: IInternalModelContentChange[] = []; + + // operations are from bottom to top + for (let i = 0; i < operations.length; i++) { + let op = operations[i]; + + const startLineNumber = op.range.startLineNumber; + const startColumn = op.range.startColumn; + const endLineNumber = op.range.endLineNumber; + const endColumn = op.range.endColumn; + + if (startLineNumber === endLineNumber && startColumn === endColumn && (!op.lines || op.lines.length === 0)) { + // no-op + continue; + } + + const deletingLinesCnt = endLineNumber - startLineNumber; + const insertingLinesCnt = (op.lines ? op.lines.length - 1 : 0); + const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt); + + const text = (op.lines ? op.lines.join(this.getEOL()) : ''); + + if (text) { + // replacement + this._pieceTree.delete(op.rangeOffset, op.rangeLength); + this._pieceTree.insert(op.rangeOffset, text); + + } else { + // deletion + this._pieceTree.delete(op.rangeOffset, op.rangeLength); + } + + if (editingLinesCnt < insertingLinesCnt) { + let newLinesContent: string[] = []; + for (let j = editingLinesCnt + 1; j <= insertingLinesCnt; j++) { + newLinesContent.push(op.lines[j]); + } + + newLinesContent[newLinesContent.length - 1] = this.getLineContent(startLineNumber + insertingLinesCnt - 1); + } + + const contentChangeRange = new Range(startLineNumber, startColumn, endLineNumber, endColumn); + contentChanges.push({ + range: contentChangeRange, + rangeLength: op.rangeLength, + text: text, + rangeOffset: op.rangeOffset, + forceMoveMarkers: op.forceMoveMarkers + }); + } + return contentChanges; + } + + // #endregion + + // #region helper + // testing purpose. + public getPieceTree(): PieceTreeBase { + return this._pieceTree; + } + /** + * Assumes `operations` are validated and sorted ascending + */ + public static _getInverseEditRanges(operations: IValidatedEditOperation[]): Range[] { + let result: Range[] = []; + + let prevOpEndLineNumber: number; + let prevOpEndColumn: number; + let prevOp: IValidatedEditOperation = null; + for (let i = 0, len = operations.length; i < len; i++) { + let op = operations[i]; + + let startLineNumber: number; + let startColumn: number; + + if (prevOp) { + if (prevOp.range.endLineNumber === op.range.startLineNumber) { + startLineNumber = prevOpEndLineNumber; + startColumn = prevOpEndColumn + (op.range.startColumn - prevOp.range.endColumn); + } else { + startLineNumber = prevOpEndLineNumber + (op.range.startLineNumber - prevOp.range.endLineNumber); + startColumn = op.range.startColumn; + } + } else { + startLineNumber = op.range.startLineNumber; + startColumn = op.range.startColumn; + } + + let resultRange: Range; + + if (op.lines && op.lines.length > 0) { + // the operation inserts something + let lineCount = op.lines.length; + let firstLine = op.lines[0]; + let lastLine = op.lines[lineCount - 1]; + + if (lineCount === 1) { + // single line insert + resultRange = new Range(startLineNumber, startColumn, startLineNumber, startColumn + firstLine.length); + } else { + // multi line insert + resultRange = new Range(startLineNumber, startColumn, startLineNumber + lineCount - 1, lastLine.length + 1); + } + } else { + // There is nothing to insert + resultRange = new Range(startLineNumber, startColumn, startLineNumber, startColumn); + } + + prevOpEndLineNumber = resultRange.endLineNumber; + prevOpEndColumn = resultRange.endColumn; + + result.push(resultRange); + prevOp = op; + } + + return result; + } + + private static _sortOpsAscending(a: IValidatedEditOperation, b: IValidatedEditOperation): number { + let r = Range.compareRangesUsingEnds(a.range, b.range); + if (r === 0) { + return a.sortIndex - b.sortIndex; + } + return r; + } + + private static _sortOpsDescending(a: IValidatedEditOperation, b: IValidatedEditOperation): number { + let r = Range.compareRangesUsingEnds(a.range, b.range); + if (r === 0) { + return b.sortIndex - a.sortIndex; + } + return -r; + } + // #endregion +} diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts new file mode 100644 index 00000000000..ab46a6892b3 --- /dev/null +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder.ts @@ -0,0 +1,180 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as strings from 'vs/base/common/strings'; +import { ITextBufferBuilder, DefaultEndOfLine, ITextBufferFactory, ITextBuffer } from 'vs/editor/common/model'; +import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer'; +import { StringBuffer, createLineStarts, createLineStartsFast } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase'; +import { CharCode } from 'vs/base/common/charCode'; + +export class PieceTreeTextBufferFactory implements ITextBufferFactory { + + constructor( + private readonly _chunks: StringBuffer[], + private readonly _bom: string, + private readonly _cr: number, + private readonly _lf: number, + private readonly _crlf: number, + private readonly _containsRTL: boolean, + private readonly _isBasicASCII: boolean, + private readonly _normalizeEOL: boolean + ) { } + + private _getEOL(defaultEOL: DefaultEndOfLine): '\r\n' | '\n' { + const totalEOLCount = this._cr + this._lf + this._crlf; + const totalCRCount = this._cr + this._crlf; + if (totalEOLCount === 0) { + // This is an empty file or a file with precisely one line + return (defaultEOL === DefaultEndOfLine.LF ? '\n' : '\r\n'); + } + if (totalCRCount > totalEOLCount / 2) { + // More than half of the file contains \r\n ending lines + return '\r\n'; + } + // At least one line more ends in \n + return '\n'; + } + + public create(defaultEOL: DefaultEndOfLine): ITextBuffer { + const eol = this._getEOL(defaultEOL); + let chunks = this._chunks; + + if (this._normalizeEOL && + ((eol === '\r\n' && (this._cr > 0 || this._lf > 0)) + || (eol === '\n' && (this._cr > 0 || this._crlf > 0))) + ) { + // Normalize pieces + for (let i = 0, len = chunks.length; i < len; i++) { + let str = chunks[i].buffer.replace(/\r\n|\r|\n/g, eol); + let newLineStart = createLineStartsFast(str); + chunks[i] = new StringBuffer(str, newLineStart); + } + } + + return new PieceTreeTextBuffer(chunks, this._bom, eol, this._containsRTL, this._isBasicASCII); + } + + public getFirstLineText(lengthLimit: number): string { + return this._chunks[0].buffer.substr(0, 100).split(/\r\n|\r|\n/)[0]; + } +} + +export class PieceTreeTextBufferBuilder implements ITextBufferBuilder { + private chunks: StringBuffer[]; + private BOM: string; + + private _hasPreviousChar: boolean; + private _previousChar: number; + private _tmpLineStarts: number[]; + + private cr: number; + private lf: number; + private crlf: number; + private containsRTL: boolean; + private isBasicASCII: boolean; + + constructor() { + this.chunks = []; + this.BOM = ''; + + this._hasPreviousChar = false; + this._previousChar = 0; + this._tmpLineStarts = []; + + this.cr = 0; + this.lf = 0; + this.crlf = 0; + this.containsRTL = false; + this.isBasicASCII = true; + } + + public acceptChunk(chunk: string): void { + if (chunk.length === 0) { + return; + } + + if (this.chunks.length === 0) { + if (strings.startsWithUTF8BOM(chunk)) { + this.BOM = strings.UTF8_BOM_CHARACTER; + chunk = chunk.substr(1); + } + } + + const lastChar = chunk.charCodeAt(chunk.length - 1); + if (lastChar === CharCode.CarriageReturn || (lastChar >= 0xd800 && lastChar <= 0xdbff)) { + // last character is \r or a high surrogate => keep it back + this._acceptChunk1(chunk.substr(0, chunk.length - 1), false); + this._hasPreviousChar = true; + this._previousChar = lastChar; + } else { + this._acceptChunk1(chunk, false); + this._hasPreviousChar = false; + this._previousChar = lastChar; + } + } + + private _acceptChunk1(chunk: string, allowEmptyStrings: boolean): void { + if (!allowEmptyStrings && chunk.length === 0) { + // Nothing to do + return; + } + + if (this._hasPreviousChar) { + this._acceptChunk2(String.fromCharCode(this._previousChar) + chunk); + } else { + this._acceptChunk2(chunk); + } + } + + private _acceptChunk2(chunk: string): void { + const lineStarts = createLineStarts(this._tmpLineStarts, chunk); + + this.chunks.push(new StringBuffer(chunk, lineStarts.lineStarts)); + this.cr += lineStarts.cr; + this.lf += lineStarts.lf; + this.crlf += lineStarts.crlf; + + if (this.isBasicASCII) { + this.isBasicASCII = lineStarts.isBasicASCII; + } + if (!this.isBasicASCII && !this.containsRTL) { + // No need to check if is basic ASCII + this.containsRTL = strings.containsRTL(chunk); + } + } + + public finish(normalizeEOL: boolean = true): PieceTreeTextBufferFactory { + this._finish(); + return new PieceTreeTextBufferFactory( + this.chunks, + this.BOM, + this.cr, + this.lf, + this.crlf, + this.containsRTL, + this.isBasicASCII, + normalizeEOL + ); + } + + private _finish(): void { + if (this.chunks.length === 0) { + this._acceptChunk1('', true); + } + + if (this._hasPreviousChar) { + this._hasPreviousChar = false; + // recreate last chunk + let lastChunk = this.chunks[this.chunks.length - 1]; + lastChunk.buffer += String.fromCharCode(this._previousChar); + let newLineStarts = createLineStartsFast(lastChunk.buffer); + lastChunk.lineStarts = newLineStarts; + if (this._previousChar === CharCode.CarriageReturn) { + this.cr++; + } + } + } +} diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.ts new file mode 100644 index 00000000000..84417b947cd --- /dev/null +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase.ts @@ -0,0 +1,427 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { Piece, PieceTreeBase } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase'; + +export class TreeNode { + parent: TreeNode; + left: TreeNode; + right: TreeNode; + color: NodeColor; + + // Piece + piece: Piece; + size_left: number; // size of the left subtree (not inorder) + lf_left: number; // line feeds cnt in the left subtree (not in order) + + constructor(piece: Piece, color: NodeColor) { + this.piece = piece; + this.color = color; + this.size_left = 0; + this.lf_left = 0; + this.parent = null; + this.left = null; + this.right = null; + } + + public next(): TreeNode { + if (this.right !== SENTINEL) { + return leftest(this.right); + } + + let node: TreeNode = this; + + while (node.parent !== SENTINEL) { + if (node.parent.left === node) { + break; + } + + node = node.parent; + } + + if (node.parent === SENTINEL) { + return SENTINEL; + } else { + return node.parent; + } + } + + public prev(): TreeNode { + if (this.left !== SENTINEL) { + return righttest(this.left); + } + + let node: TreeNode = this; + + while (node.parent !== SENTINEL) { + if (node.parent.right === node) { + break; + } + + node = node.parent; + } + + if (node.parent === SENTINEL) { + return SENTINEL; + } else { + return node.parent; + } + } + + public detach(): void { + this.parent = null; + this.left = null; + this.right = null; + } +} + +export const SENTINEL: TreeNode = new TreeNode(null, NodeColor.Black); +SENTINEL.parent = SENTINEL; +SENTINEL.left = SENTINEL; +SENTINEL.right = SENTINEL; +SENTINEL.color = NodeColor.Black; + +export const enum NodeColor { + Black = 0, + Red = 1, +} + +export function leftest(node: TreeNode): TreeNode { + while (node.left !== SENTINEL) { + node = node.left; + } + return node; +} + +export function righttest(node: TreeNode): TreeNode { + while (node.right !== SENTINEL) { + node = node.right; + } + return node; +} + +export function calculateSize(node: TreeNode): number { + if (node === SENTINEL) { + return 0; + } + + return node.size_left + node.piece.length + calculateSize(node.right); +} + +export function calculateLF(node: TreeNode): number { + if (node === SENTINEL) { + return 0; + } + + return node.lf_left + node.piece.lineFeedCnt + calculateLF(node.right); +} + +export function resetSentinel(): void { + SENTINEL.parent = SENTINEL; +} + +export function leftRotate(tree: PieceTreeBase, x: TreeNode) { + let y = x.right; + + // fix size_left + y.size_left += x.size_left + (x.piece ? x.piece.length : 0); + y.lf_left += x.lf_left + (x.piece ? x.piece.lineFeedCnt : 0); + x.right = y.left; + + if (y.left !== SENTINEL) { + y.left.parent = x; + } + y.parent = x.parent; + if (x.parent === SENTINEL) { + tree.root = y; + } else if (x.parent.left === x) { + x.parent.left = y; + } else { + x.parent.right = y; + } + y.left = x; + x.parent = y; +} + +export function rightRotate(tree: PieceTreeBase, y: TreeNode) { + let x = y.left; + y.left = x.right; + if (x.right !== SENTINEL) { + x.right.parent = y; + } + x.parent = y.parent; + + // fix size_left + y.size_left -= x.size_left + (x.piece ? x.piece.length : 0); + y.lf_left -= x.lf_left + (x.piece ? x.piece.lineFeedCnt : 0); + + if (y.parent === SENTINEL) { + tree.root = x; + } else if (y === y.parent.right) { + y.parent.right = x; + } else { + y.parent.left = x; + } + + x.right = y; + y.parent = x; +} + +export function rbDelete(tree: PieceTreeBase, z: TreeNode) { + let x: TreeNode; + let y: TreeNode; + + if (z.left === SENTINEL) { + y = z; + x = y.right; + } else if (z.right === SENTINEL) { + y = z; + x = y.left; + } else { + y = leftest(z.right); + x = y.right; + } + + if (y === tree.root) { + tree.root = x; + + // if x is null, we are removing the only node + x.color = NodeColor.Black; + z.detach(); + resetSentinel(); + tree.root.parent = SENTINEL; + + return; + } + + let yWasRed = (y.color === NodeColor.Red); + + if (y === y.parent.left) { + y.parent.left = x; + } else { + y.parent.right = x; + } + + if (y === z) { + x.parent = y.parent; + recomputeTreeMetadata(tree, x); + } else { + if (y.parent === z) { + x.parent = y; + } else { + x.parent = y.parent; + } + + // as we make changes to x's hierarchy, update size_left of subtree first + recomputeTreeMetadata(tree, x); + + y.left = z.left; + y.right = z.right; + y.parent = z.parent; + y.color = z.color; + + if (z === tree.root) { + tree.root = y; + } else { + if (z === z.parent.left) { + z.parent.left = y; + } else { + z.parent.right = y; + } + } + + if (y.left !== SENTINEL) { + y.left.parent = y; + } + if (y.right !== SENTINEL) { + y.right.parent = y; + } + // update metadata + // we replace z with y, so in this sub tree, the length change is z.item.length + y.size_left = z.size_left; + y.lf_left = z.lf_left; + recomputeTreeMetadata(tree, y); + } + + z.detach(); + + if (x.parent.left === x) { + let newSizeLeft = calculateSize(x); + let newLFLeft = calculateLF(x); + if (newSizeLeft !== x.parent.size_left || newLFLeft !== x.parent.lf_left) { + let delta = newSizeLeft - x.parent.size_left; + let lf_delta = newLFLeft - x.parent.lf_left; + x.parent.size_left = newSizeLeft; + x.parent.lf_left = newLFLeft; + updateTreeMetadata(tree, x.parent, delta, lf_delta); + } + } + + recomputeTreeMetadata(tree, x.parent); + + if (yWasRed) { + resetSentinel(); + return; + } + + // RB-DELETE-FIXUP + let w: TreeNode; + while (x !== tree.root && x.color === NodeColor.Black) { + if (x === x.parent.left) { + w = x.parent.right; + + if (w.color === NodeColor.Red) { + w.color = NodeColor.Black; + x.parent.color = NodeColor.Red; + leftRotate(tree, x.parent); + w = x.parent.right; + } + + if (w.left.color === NodeColor.Black && w.right.color === NodeColor.Black) { + w.color = NodeColor.Red; + x = x.parent; + } else { + if (w.right.color === NodeColor.Black) { + w.left.color = NodeColor.Black; + w.color = NodeColor.Red; + rightRotate(tree, w); + w = x.parent.right; + } + + w.color = x.parent.color; + x.parent.color = NodeColor.Black; + w.right.color = NodeColor.Black; + leftRotate(tree, x.parent); + x = tree.root; + } + } else { + w = x.parent.left; + + if (w.color === NodeColor.Red) { + w.color = NodeColor.Black; + x.parent.color = NodeColor.Red; + rightRotate(tree, x.parent); + w = x.parent.left; + } + + if (w.left.color === NodeColor.Black && w.right.color === NodeColor.Black) { + w.color = NodeColor.Red; + x = x.parent; + + } else { + if (w.left.color === NodeColor.Black) { + w.right.color = NodeColor.Black; + w.color = NodeColor.Red; + leftRotate(tree, w); + w = x.parent.left; + } + + w.color = x.parent.color; + x.parent.color = NodeColor.Black; + w.left.color = NodeColor.Black; + rightRotate(tree, x.parent); + x = tree.root; + } + } + } + x.color = NodeColor.Black; + resetSentinel(); +} + +export function fixInsert(tree: PieceTreeBase, x: TreeNode) { + recomputeTreeMetadata(tree, x); + + while (x !== tree.root && x.parent.color === NodeColor.Red) { + if (x.parent === x.parent.parent.left) { + const y = x.parent.parent.right; + + if (y.color === NodeColor.Red) { + x.parent.color = NodeColor.Black; + y.color = NodeColor.Black; + x.parent.parent.color = NodeColor.Red; + x = x.parent.parent; + } else { + if (x === x.parent.right) { + x = x.parent; + leftRotate(tree, x); + } + + x.parent.color = NodeColor.Black; + x.parent.parent.color = NodeColor.Red; + rightRotate(tree, x.parent.parent); + } + } else { + const y = x.parent.parent.left; + + if (y.color === NodeColor.Red) { + x.parent.color = NodeColor.Black; + y.color = NodeColor.Black; + x.parent.parent.color = NodeColor.Red; + x = x.parent.parent; + } else { + if (x === x.parent.left) { + x = x.parent; + rightRotate(tree, x); + } + x.parent.color = NodeColor.Black; + x.parent.parent.color = NodeColor.Red; + leftRotate(tree, x.parent.parent); + } + } + } + + tree.root.color = NodeColor.Black; +} + +export function updateTreeMetadata(tree: PieceTreeBase, x: TreeNode, delta: number, lineFeedCntDelta: number): void { + // node length change or line feed count change + while (x !== tree.root && x !== SENTINEL) { + if (x.parent.left === x) { + x.parent.size_left += delta; + x.parent.lf_left += lineFeedCntDelta; + } + + x = x.parent; + } +} + +export function recomputeTreeMetadata(tree: PieceTreeBase, x: TreeNode) { + let delta = 0; + let lf_delta = 0; + if (x === tree.root) { + return; + } + + if (delta === 0) { + // go upwards till the node whose left subtree is changed. + while (x !== tree.root && x === x.parent.right) { + x = x.parent; + } + + if (x === tree.root) { + // well, it means we add a node to the end (inorder) + return; + } + + // x is the node whose right subtree is changed. + x = x.parent; + + delta = calculateSize(x.left) - x.size_left; + lf_delta = calculateLF(x.left) - x.lf_left; + x.size_left += delta; + x.lf_left += lf_delta; + } + + // go upwards till root. O(logN) + while (x !== tree.root && (delta !== 0 || lf_delta !== 0)) { + if (x.parent.left === x) { + x.parent.size_left += delta; + x.parent.lf_left += lf_delta; + } + + x = x.parent; + } +} diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index dff56a1a7a8..90e95ac7bb7 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -11,7 +11,7 @@ import { LanguageIdentifier, TokenizationRegistry, LanguageId } from 'vs/editor/ import { EditStack } from 'vs/editor/common/model/editStack'; import { Range, IRange } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; -import { ModelRawContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelOptionsChangedEvent, IModelContentChangedEvent, InternalModelContentChangeEvent, ModelRawFlush, ModelRawEOLChanged } from 'vs/editor/common/model/textModelEvents'; +import { ModelRawContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelTokensChangedEvent, IModelOptionsChangedEvent, IModelContentChangedEvent, InternalModelContentChangeEvent, ModelRawFlush, ModelRawEOLChanged, ModelRawChange, ModelRawLineChanged, ModelRawLinesDeleted, ModelRawLinesInserted } from 'vs/editor/common/model/textModelEvents'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IMarkdownString } from 'vs/base/common/htmlContent'; import * as strings from 'vs/base/common/strings'; @@ -32,11 +32,22 @@ import { guessIndentation } from 'vs/editor/common/model/indentationGuesser'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions'; import { TextModelSearch, SearchParams } from 'vs/editor/common/model/textModelSearch'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IStringStream } from 'vs/platform/files/common/files'; +import { IStringStream, ITextSnapshot } from 'vs/platform/files/common/files'; import { LinesTextBufferBuilder } from 'vs/editor/common/model/linesTextBuffer/linesTextBufferBuilder'; +import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; +import { ChunksTextBufferBuilder } from 'vs/editor/common/model/chunksTextBuffer/chunksTextBufferBuilder'; // Here is the master switch for the text buffer implementation: +const USE_PIECE_TREE_IMPLEMENTATION = false; +const USE_CHUNKS_TEXT_BUFFER = false; + function createTextBufferBuilder() { + if (USE_PIECE_TREE_IMPLEMENTATION) { + return new PieceTreeTextBufferBuilder(); + } + if (USE_CHUNKS_TEXT_BUFFER) { + return new ChunksTextBufferBuilder(); + } return new LinesTextBufferBuilder(); } @@ -96,6 +107,48 @@ function singleLetter(result: number): string { const LIMIT_FIND_COUNT = 999; export const LONG_LINE_BOUNDARY = 10000; +class TextModelSnapshot implements ITextSnapshot { + + private readonly _source: ITextSnapshot; + private _eos: boolean; + + constructor(source: ITextSnapshot) { + this._source = source; + this._eos = false; + } + + public read(): string { + if (this._eos) { + return null; + } + + let result: string[] = [], resultCnt = 0, resultLength = 0; + + do { + let tmp = this._source.read(); + + if (tmp === null) { + // end-of-stream + this._eos = true; + if (resultCnt === 0) { + return null; + } else { + return result.join(''); + } + } + + if (tmp.length > 0) { + result[resultCnt++] = tmp; + resultLength += tmp.length; + } + + if (resultLength >= 64 * 1024) { + return result.join(''); + } + } while (true); + } +} + export class TextModel extends Disposable implements model.ITextModel { private static readonly MODEL_SYNC_LIMIT = 50 * 1024 * 1024; // 50 MB @@ -488,6 +541,10 @@ export class TextModel extends Disposable implements model.ITextModel { public isDominatedByLongLines(): boolean { this._assertNotDisposed(); + if (this.isTooLargeForTokenization()) { + // Cannot word wrap huge files anyways, so it doesn't really matter + return false; + } let smallLineCharCount = 0; let longLineCharCount = 0; @@ -630,8 +687,9 @@ export class TextModel extends Disposable implements model.ITextModel { return this._buffer.getOffsetAt(position.lineNumber, position.column); } - public getPositionAt(offset: number): Position { + public getPositionAt(rawOffset: number): Position { this._assertNotDisposed(); + let offset = (Math.min(this._buffer.getLength(), Math.max(0, rawOffset))); return this._buffer.getPositionAt(offset); } @@ -660,6 +718,10 @@ export class TextModel extends Disposable implements model.ITextModel { return fullModelValue; } + public createSnapshot(preserveBOM: boolean = false): ITextSnapshot { + return new TextModelSnapshot(this._buffer.createSnapshot(preserveBOM)); + } + public getValueLength(eol?: model.EndOfLinePreference, preserveBOM: boolean = false): number { this._assertNotDisposed(); const fullModelRange = this.getFullModelRange(); @@ -890,7 +952,8 @@ export class TextModel extends Disposable implements model.ITextModel { public modifyPosition(rawPosition: IPosition, offset: number): Position { this._assertNotDisposed(); - return this.getPositionAt(this.getOffsetAt(rawPosition) + offset); + let candidate = this.getOffsetAt(rawPosition) + offset; + return this.getPositionAt(Math.min(this._buffer.getLength(), Math.max(0, candidate))); } public getFullModelRange(): Range { @@ -1033,21 +1096,94 @@ export class TextModel extends Disposable implements model.ITextModel { } } + private static _eolCount(text: string): [number, number] { + let eolCount = 0; + let firstLineLength = 0; + for (let i = 0, len = text.length; i < len; i++) { + const chr = text.charCodeAt(i); + + if (chr === CharCode.CarriageReturn) { + if (eolCount === 0) { + firstLineLength = i; + } + eolCount++; + if (i + 1 < len && text.charCodeAt(i + 1) === CharCode.LineFeed) { + // \r\n... case + i++; // skip \n + } else { + // \r... case + } + } else if (chr === CharCode.LineFeed) { + if (eolCount === 0) { + firstLineLength = i; + } + eolCount++; + } + } + if (eolCount === 0) { + firstLineLength = text.length; + } + return [eolCount, firstLineLength]; + } + private _applyEdits(rawOperations: model.IIdentifiedSingleEditOperation[]): model.IIdentifiedSingleEditOperation[] { for (let i = 0, len = rawOperations.length; i < len; i++) { rawOperations[i].range = this.validateRange(rawOperations[i].range); } + + const oldLineCount = this._buffer.getLineCount(); const result = this._buffer.applyEdits(rawOperations, this._options.trimAutoWhitespace); - const rawContentChanges = result.rawChanges; + const newLineCount = this._buffer.getLineCount(); + const contentChanges = result.changes; this._trimAutoWhitespaceLines = result.trimAutoWhitespaceLineNumbers; - if (rawContentChanges.length !== 0 || contentChanges.length !== 0) { + if (contentChanges.length !== 0) { + let rawContentChanges: ModelRawChange[] = []; + + let lineCount = oldLineCount; for (let i = 0, len = contentChanges.length; i < len; i++) { - const contentChange = contentChanges[i]; - this._tokens.applyEdits(contentChange.range, contentChange.lines); + const change = contentChanges[i]; + const [eolCount, firstLineLength] = TextModel._eolCount(change.text); + this._tokens.applyEdits(change.range, eolCount, firstLineLength); this._onDidChangeDecorations.fire(); - this._decorationsTree.acceptReplace(contentChange.rangeOffset, contentChange.rangeLength, contentChange.text.length, contentChange.forceMoveMarkers); + this._decorationsTree.acceptReplace(change.rangeOffset, change.rangeLength, change.text.length, change.forceMoveMarkers); + + const startLineNumber = change.range.startLineNumber; + const endLineNumber = change.range.endLineNumber; + + const deletingLinesCnt = endLineNumber - startLineNumber; + const insertingLinesCnt = eolCount; + const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt); + + const changeLineCountDelta = (insertingLinesCnt - deletingLinesCnt); + + for (let j = editingLinesCnt; j >= 0; j--) { + const editLineNumber = startLineNumber + j; + const currentEditLineNumber = newLineCount - lineCount - changeLineCountDelta + editLineNumber; + rawContentChanges.push(new ModelRawLineChanged(editLineNumber, this.getLineContent(currentEditLineNumber))); + } + + if (editingLinesCnt < deletingLinesCnt) { + // Must delete some lines + const spliceStartLineNumber = startLineNumber + editingLinesCnt; + rawContentChanges.push(new ModelRawLinesDeleted(spliceStartLineNumber + 1, endLineNumber)); + } + + if (editingLinesCnt < insertingLinesCnt) { + // Must insert some lines + const spliceLineNumber = startLineNumber + editingLinesCnt; + const cnt = insertingLinesCnt - editingLinesCnt; + const fromLineNumber = newLineCount - lineCount - cnt + spliceLineNumber + 1; + let newLines: string[] = []; + for (let i = 0; i < cnt; i++) { + let lineNumber = fromLineNumber + i; + newLines[lineNumber - fromLineNumber] = this.getLineContent(lineNumber); + } + rawContentChanges.push(new ModelRawLinesInserted(spliceLineNumber + 1, startLineNumber + insertingLinesCnt, newLines)); + } + + lineCount += changeLineCountDelta; } this._increaseVersionId(); diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index e190d4337bb..bc0a715dda9 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -285,34 +285,18 @@ export class ModelLinesTokens { //#region Editing - // TODO: simplify - public applyEdits(range: Range, lines: string[]): void { + public applyEdits(range: Range, eolCount: number, firstLineLength: number): void { const deletingLinesCnt = range.endLineNumber - range.startLineNumber; - const insertingLinesCnt = (lines ? lines.length - 1 : 0); + const insertingLinesCnt = eolCount; const editingLinesCnt = Math.min(deletingLinesCnt, insertingLinesCnt); - // Iterating descending to overlap with previous op - // in case there are common lines being edited in both for (let j = editingLinesCnt; j >= 0; j--) { - const editLineNumber = range.startLineNumber + j; - this.invalidateLine(editLineNumber - 1); - } - - if (editingLinesCnt < deletingLinesCnt) { - // Must delete some lines - const spliceStartLineNumber = range.startLineNumber + editingLinesCnt; - this.invalidateLine(spliceStartLineNumber - 1); - } - - if (editingLinesCnt < insertingLinesCnt) { - // Must insert some lines - const spliceLineNumber = range.startLineNumber + editingLinesCnt; - this.invalidateLine(spliceLineNumber - 1); + this.invalidateLine(range.startLineNumber + j - 1); } this._acceptDeleteRange(range); - this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), lines); + this._acceptInsertText(new Position(range.startLineNumber, range.startColumn), eolCount, firstLineLength); } private _acceptDeleteRange(range: Range): void { @@ -350,9 +334,9 @@ export class ModelLinesTokens { this._tokens.splice(range.startLineNumber, range.endLineNumber - range.startLineNumber); } - private _acceptInsertText(position: Position, insertLines: string[]): void { + private _acceptInsertText(position: Position, eolCount: number, firstLineLength: number): void { - if (!insertLines || insertLines.length === 0) { + if (eolCount === 0 && firstLineLength === 0) { // Nothing to insert return; } @@ -362,18 +346,18 @@ export class ModelLinesTokens { return; } - if (insertLines.length === 1) { + if (eolCount === 0) { // Inserting text on one line - this._tokens[lineIndex].insert(position.column - 1, insertLines[0].length); + this._tokens[lineIndex].insert(position.column - 1, firstLineLength); return; } const line = this._tokens[lineIndex]; line.deleteEnding(position.column - 1); - line.insert(position.column - 1, insertLines[0].length); + line.insert(position.column - 1, firstLineLength); - let insert: ModelLineTokens[] = new Array(insertLines.length - 1); - for (let i = insertLines.length - 2; i >= 0; i--) { + let insert: ModelLineTokens[] = new Array(eolCount); + for (let i = eolCount - 1; i >= 0; i--) { insert[i] = new ModelLineTokens(null); } this._tokens = arrays.arrayInsert(this._tokens, position.lineNumber, insert); diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index e822789ab01..df5ca43c975 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -315,7 +315,8 @@ export interface ISuggestResult { */ export enum SuggestTriggerKind { Invoke = 0, - TriggerCharacter = 1 + TriggerCharacter = 1, + TriggerForIncompleteCompletions = 2 } /** diff --git a/src/vs/editor/common/view/editorColorRegistry.ts b/src/vs/editor/common/view/editorColorRegistry.ts index 3fae633c29b..939a99c1d13 100644 --- a/src/vs/editor/common/view/editorColorRegistry.ts +++ b/src/vs/editor/common/view/editorColorRegistry.ts @@ -13,7 +13,7 @@ import { Color, RGBA } from 'vs/base/common/color'; */ export const editorLineHighlight = registerColor('editor.lineHighlightBackground', { dark: null, light: null, hc: null }, nls.localize('lineHighlight', 'Background color for the highlight of line at the cursor position.')); export const editorLineHighlightBorder = registerColor('editor.lineHighlightBorder', { dark: '#282828', light: '#eeeeee', hc: '#f38518' }, nls.localize('lineHighlightBorderBox', 'Background color for the border around the line at the cursor position.')); -export const editorRangeHighlight = registerColor('editor.rangeHighlightBackground', { dark: '#ffffff0b', light: '#fdff0033', hc: null }, nls.localize('rangeHighlight', 'Background color of highlighted ranges, like by quick open and find features.')); +export const editorRangeHighlight = registerColor('editor.rangeHighlightBackground', { dark: '#ffffff0b', light: '#fdff0033', hc: null }, nls.localize('rangeHighlight', 'Background color of highlighted ranges, like by quick open and find features. The color must not be opaque to not hide underlying decorations.'), true); export const editorCursorForeground = registerColor('editorCursor.foreground', { dark: '#AEAFAD', light: Color.black, hc: Color.white }, nls.localize('caret', 'Color of the editor cursor.')); export const editorCursorBackground = registerColor('editorCursor.background', null, nls.localize('editorCursorBackground', 'The background color of the editor cursor. Allows customizing the color of a character overlapped by a block cursor.')); export const editorWhitespaces = registerColor('editorWhitespace.foreground', { dark: '#e3e4e229', light: '#33333333', hc: '#e3e4e229' }, nls.localize('editorWhitespaces', 'Color of whitespace characters in the editor.')); diff --git a/src/vs/editor/common/viewModel/splitLinesCollection.ts b/src/vs/editor/common/viewModel/splitLinesCollection.ts index 9855eda6939..24009cea46a 100644 --- a/src/vs/editor/common/viewModel/splitLinesCollection.ts +++ b/src/vs/editor/common/viewModel/splitLinesCollection.ts @@ -403,6 +403,7 @@ export class SplitLinesCollection implements IViewModelLinesCollection { insertPrefixSumValues[i] = outputLineCount; } + // TODO@Alex: use arrays.arrayInsert this.lines = this.lines.slice(0, fromLineNumber - 1).concat(insertLines).concat(this.lines.slice(fromLineNumber - 1)); this.prefixSumComputer.insertValues(fromLineNumber - 1, insertPrefixSumValues); diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index 283801a2d60..d898a618ca4 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -101,7 +101,7 @@ export class FoldingController implements IEditorContribution { */ public saveViewState(): { collapsedRegions?: CollapseMemento, lineCount?: number } { let model = this.editor.getModel(); - if (!model || !this._isEnabled) { + if (!model || !this._isEnabled || model.isTooLargeForTokenization()) { return {}; } return { collapsedRegions: this.foldingModel.getMemento(), lineCount: model.getLineCount() }; @@ -112,7 +112,7 @@ export class FoldingController implements IEditorContribution { */ public restoreViewState(state: { collapsedRegions?: CollapseMemento, lineCount?: number }): void { let model = this.editor.getModel(); - if (!model || !this._isEnabled) { + if (!model || !this._isEnabled || model.isTooLargeForTokenization()) { return; } if (!state || !state.collapsedRegions || state.lineCount !== model.getLineCount()) { @@ -133,7 +133,8 @@ export class FoldingController implements IEditorContribution { this.localToDispose = dispose(this.localToDispose); let model = this.editor.getModel(); - if (!this._isEnabled || !model) { + if (!this._isEnabled || !model || model.isTooLargeForTokenization()) { + // huge files get no view model, so they cannot support hidden areas return; } diff --git a/src/vs/editor/contrib/goToDeclaration/goToDeclarationCommands.ts b/src/vs/editor/contrib/goToDeclaration/goToDeclarationCommands.ts index 94f46987882..d27eebcc428 100644 --- a/src/vs/editor/contrib/goToDeclaration/goToDeclarationCommands.ts +++ b/src/vs/editor/contrib/goToDeclaration/goToDeclarationCommands.ts @@ -151,7 +151,7 @@ export class DefinitionAction extends EditorAction { resource: uri, options: { selection: Range.collapseToStart(range), - revealIfVisible: !sideBySide, + revealIfVisible: true, revealInCenterIfOutsideViewport: true } }, sideBySide).then(editor => { diff --git a/src/vs/editor/contrib/gotoError/gotoError.ts b/src/vs/editor/contrib/gotoError/gotoError.ts index f60bc6af83d..9efd2151ada 100644 --- a/src/vs/editor/contrib/gotoError/gotoError.ts +++ b/src/vs/editor/contrib/gotoError/gotoError.ts @@ -494,7 +494,7 @@ class NextMarkerAction extends MarkerNavigationAction { constructor() { super(true, { id: 'editor.action.marker.next', - label: nls.localize('markerAction.next.label', "Go to Next Error or Warning"), + label: nls.localize('markerAction.next.label', "Go to Next Problem (Error, Warning, Info)"), alias: 'Go to Next Error or Warning', precondition: EditorContextKeys.writable, kbOpts: { @@ -509,7 +509,7 @@ class PrevMarkerAction extends MarkerNavigationAction { constructor() { super(false, { id: 'editor.action.marker.prev', - label: nls.localize('markerAction.previous.label', "Go to Previous Error or Warning"), + label: nls.localize('markerAction.previous.label', "Go to Previous Problem (Error, Warning, Info)"), alias: 'Go to Previous Error or Warning', precondition: EditorContextKeys.writable, kbOpts: { diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index d0b9b18ac3f..136e54c22a8 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -251,7 +251,7 @@ class Controller extends DefaultController { } var result = super.onClick(tree, element, event); - if (event.ctrlKey || event.metaKey) { + if (event.ctrlKey || event.metaKey || event.altKey) { this._onDidOpenToSide.fire(element); } else if (event.detail === 2) { this._onDidSelect.fire(element); @@ -578,7 +578,7 @@ export class ReferenceWidget extends PeekViewWidget { if (this._preview && this._preview.getModel()) { this._onDidSelectReference.fire({ element: this._getFocusedReference(), - kind: e.ctrlKey || e.metaKey ? 'side' : 'open', + kind: e.ctrlKey || e.metaKey || e.altKey ? 'side' : 'open', source: 'title' }); } @@ -745,7 +745,7 @@ export class ReferenceWidget extends PeekViewWidget { if (event.detail === 2) { this._onDidSelectReference.fire({ element: { uri: this._getFocusedReference().uri, range: target.range }, - kind: (event.ctrlKey || event.metaKey) ? 'side' : 'open', + kind: (event.ctrlKey || event.metaKey || event.altKey) ? 'side' : 'open', source: 'editor' }); } diff --git a/src/vs/editor/contrib/snippet/snippetSession.ts b/src/vs/editor/contrib/snippet/snippetSession.ts index af22d663d0b..30a06931cd7 100644 --- a/src/vs/editor/contrib/snippet/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/snippetSession.ts @@ -15,7 +15,7 @@ import { Range } from 'vs/editor/common/core/range'; import { IPosition } from 'vs/editor/common/core/position'; import { groupBy } from 'vs/base/common/arrays'; import { dispose } from 'vs/base/common/lifecycle'; -import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver } from './snippetVariables'; +import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver, TimeBasedVariableResolver } from './snippetVariables'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -318,7 +318,8 @@ export class SnippetSession { .resolveVariables(new CompositeSnippetVariableResolver([ modelBasedVariableResolver, new ClipboardBasedVariableResolver(clipboardService, idx, indexedSelections.length), - new SelectionBasedVariableResolver(model, selection) + new SelectionBasedVariableResolver(model, selection), + new TimeBasedVariableResolver ])); const offset = model.getOffsetAt(start) + delta; diff --git a/src/vs/editor/contrib/snippet/snippetVariables.ts b/src/vs/editor/contrib/snippet/snippetVariables.ts index f3b77a67181..9ca69afdfa4 100644 --- a/src/vs/editor/contrib/snippet/snippetVariables.ts +++ b/src/vs/editor/contrib/snippet/snippetVariables.ts @@ -9,10 +9,17 @@ import { basename, dirname } from 'vs/base/common/paths'; import { ITextModel } from 'vs/editor/common/model'; import { Selection } from 'vs/editor/common/core/selection'; import { VariableResolver, Variable, Text } from 'vs/editor/contrib/snippet/snippetParser'; -import { getLeadingWhitespace, commonPrefixLength, isFalsyOrWhitespace } from 'vs/base/common/strings'; +import { getLeadingWhitespace, commonPrefixLength, isFalsyOrWhitespace, pad } from 'vs/base/common/strings'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; export const KnownSnippetVariableNames = Object.freeze({ + 'CURRENT_YEAR': true, + 'CURRENT_YEAR_SHORT': true, + 'CURRENT_MONTH': true, + 'CURRENT_DATE': true, + 'CURRENT_HOUR': true, + 'CURRENT_MINUTE': true, + 'CURRENT_SECOND': true, 'SELECTION': true, 'CLIPBOARD': true, 'TM_SELECTED_TEXT': true, @@ -170,3 +177,28 @@ export class ClipboardBasedVariableResolver implements VariableResolver { } } } + +export class TimeBasedVariableResolver implements VariableResolver { + + resolve(variable: Variable): string { + const { name } = variable; + + if (name === 'CURRENT_YEAR') { + return String(new Date().getFullYear()); + } else if (name === 'CURRENT_YEAR_SHORT') { + return String(new Date().getFullYear()).slice(-2); + } else if (name === 'CURRENT_MONTH') { + return pad((new Date().getMonth().valueOf() + 1), 2); + } else if (name === 'CURRENT_DATE') { + return pad(new Date().getDate().valueOf(), 2); + } else if (name === 'CURRENT_HOUR') { + return pad(new Date().getHours().valueOf(), 2); + } else if (name === 'CURRENT_MINUTE') { + return pad(new Date().getMinutes().valueOf(), 2); + } else if (name === 'CURRENT_SECOND') { + return pad(new Date().getSeconds().valueOf(), 2); + } + + return undefined; + } +} diff --git a/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts b/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts index 704173368f7..7eb0f74f147 100644 --- a/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts @@ -8,7 +8,7 @@ import * as assert from 'assert'; import { isWindows } from 'vs/base/common/platform'; import URI from 'vs/base/common/uri'; import { Selection } from 'vs/editor/common/core/selection'; -import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver } from 'vs/editor/contrib/snippet/snippetVariables'; +import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver, TimeBasedVariableResolver } from 'vs/editor/contrib/snippet/snippetVariables'; import { SnippetParser, Variable, VariableResolver } from 'vs/editor/contrib/snippet/snippetParser'; import { TextModel } from 'vs/editor/common/model/textModel'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -261,4 +261,25 @@ suite('Snippet Variables Resolver', function () { resolver = new ClipboardBasedVariableResolver(clipboardService, 0, 2); assertVariableResolve(resolver, 'CLIPBOARD', 'line1'); }); + + + function assertVariableResolve3(resolver: VariableResolver, varName: string) { + const snippet = new SnippetParser().parse(`$${varName}`); + const variable = snippet.children[0]; + + assert.equal(variable.resolve(resolver), true, `${varName} failed to resolve`); + } + + test('Add time variables for snippets #41631', function () { + + const resolver = new TimeBasedVariableResolver; + + assertVariableResolve3(resolver, 'CURRENT_YEAR'); + assertVariableResolve3(resolver, 'CURRENT_YEAR_SHORT'); + assertVariableResolve3(resolver, 'CURRENT_MONTH'); + assertVariableResolve3(resolver, 'CURRENT_DATE'); + assertVariableResolve3(resolver, 'CURRENT_HOUR'); + assertVariableResolve3(resolver, 'CURRENT_MINUTE'); + assertVariableResolve3(resolver, 'CURRENT_SECOND'); + }); }); diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index 7d7013aaa1a..e3eed8c4310 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -25,7 +25,7 @@ import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2 import { Context as SuggestContext } from './suggest'; import { SuggestModel, State } from './suggestModel'; import { ICompletionItem } from './completionModel'; -import { SuggestWidget } from './suggestWidget'; +import { SuggestWidget, ISelectedSuggestion } from './suggestWidget'; import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { SuggestMemories } from 'vs/editor/contrib/suggest/suggestMemory'; @@ -34,9 +34,9 @@ class AcceptOnCharacterOracle { private _disposables: IDisposable[] = []; private _activeAcceptCharacters = new Set(); - private _activeItem: ICompletionItem; + private _activeItem: ISelectedSuggestion; - constructor(editor: ICodeEditor, widget: SuggestWidget, accept: (item: ICompletionItem) => any) { + constructor(editor: ICodeEditor, widget: SuggestWidget, accept: (selected: ISelectedSuggestion) => any) { this._disposables.push(widget.onDidShow(() => this._onItem(widget.getFocusedItem()))); this._disposables.push(widget.onDidFocus(this._onItem, this)); @@ -52,14 +52,14 @@ class AcceptOnCharacterOracle { })); } - private _onItem(item: ICompletionItem): void { - if (!item || isFalsyOrEmpty(item.suggestion.commitCharacters)) { + private _onItem(selected: ISelectedSuggestion): void { + if (!selected || isFalsyOrEmpty(selected.item.suggestion.commitCharacters)) { this.reset(); return; } - this._activeItem = item; + this._activeItem = selected; this._activeAcceptCharacters.clear(); - for (const ch of item.suggestion.commitCharacters) { + for (const ch of selected.item.suggestion.commitCharacters) { if (ch.length > 0) { this._activeAcceptCharacters.add(ch[0]); } @@ -148,7 +148,7 @@ export class SuggestController implements IEditorContribution { ); let makesTextEdit = SuggestContext.MakesTextEdit.bindTo(this._contextKeyService); - this._toDispose.push(this._widget.onDidFocus(item => { + this._toDispose.push(this._widget.onDidFocus(({ item }) => { const position = this._editor.getPosition(); const startColumn = item.position.column - item.suggestion.overwriteBefore; @@ -193,13 +193,13 @@ export class SuggestController implements IEditorContribution { } } - protected _onDidSelectItem(item: ICompletionItem): void { - if (!item) { + protected _onDidSelectItem(event: ISelectedSuggestion): void { + if (!event || !event.item) { this._model.cancel(); return; } - const { suggestion, position } = item; + const { suggestion, position } = event.item; const editorColumn = this._editor.getPosition().column; const columnDelta = editorColumn - position.column; @@ -209,8 +209,12 @@ export class SuggestController implements IEditorContribution { this._editor.pushUndoStop(); } - // remember this word for future invocations - this._memory.remember(this._editor.getModel().getLanguageIdentifier(), item); + // remember this suggestion for future invocations + // when it wasn't the first suggestion but from the group + // of top suggestions (cons -> const, console, constructor) + if (event.model.items[0].score === event.item.score) { + this._memory.remember(this._editor.getModel().getLanguageIdentifier(), event.item); + } let { insertText } = suggestion; if (suggestion.snippetType !== 'textmate') { @@ -237,7 +241,7 @@ export class SuggestController implements IEditorContribution { this._model.cancel(); } - this._alertCompletionItem(item); + this._alertCompletionItem(event.item); } private _alertCompletionItem({ suggestion }: ICompletionItem): void { diff --git a/src/vs/editor/contrib/suggest/suggestMemory.ts b/src/vs/editor/contrib/suggest/suggestMemory.ts index 1d4c32c0281..46a02a46e85 100644 --- a/src/vs/editor/contrib/suggest/suggestMemory.ts +++ b/src/vs/editor/contrib/suggest/suggestMemory.ts @@ -79,7 +79,23 @@ export class SuggestMemory { } select(items: ICompletionItem[], last: ICompletionItem): number { + + if (items.length === 0) { + return -1; + } + + const topScore = items[0].score; + for (let i = 0; i < items.length; i++) { + + if (topScore !== items[i].score) { + // we only take a look at the bucket + // of top matches, hence we return + // as soon as we see an item that + // hasn't the top score anymore + return -1; + } + if (items[i] === last) { // prefer the last selected item when // there is one diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index 9ae1b480474..b597301e9c8 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -11,7 +11,7 @@ import Event, { Emitter } from 'vs/base/common/event'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; import { ITextModel, IWordAtPosition } from 'vs/editor/common/model'; -import { ISuggestSupport, SuggestRegistry, StandardTokenType, SuggestTriggerKind } from 'vs/editor/common/modes'; +import { ISuggestSupport, SuggestRegistry, StandardTokenType, SuggestTriggerKind, SuggestContext } from 'vs/editor/common/modes'; import { Position } from 'vs/editor/common/core/position'; import { provideSuggestionItems, getSuggestionComparator, ISuggestionItem } from './suggest'; import { CompletionModel } from './completionModel'; @@ -347,13 +347,23 @@ export class SuggestModel implements IDisposable { // Capture context when request was sent this._context = ctx; + // Build context for request + let suggestCtx: SuggestContext; + if (context.triggerCharacter) { + suggestCtx = { + triggerKind: SuggestTriggerKind.TriggerCharacter, + triggerCharacter: context.triggerCharacter + }; + } else if (onlyFrom && onlyFrom.length) { + suggestCtx = { triggerKind: SuggestTriggerKind.TriggerForIncompleteCompletions }; + } else { + suggestCtx = { triggerKind: SuggestTriggerKind.Invoke }; + } + this._requestPromise = provideSuggestionItems(model, this._editor.getPosition(), this._editor.getConfiguration().contribInfo.snippetSuggestions, onlyFrom, - { - triggerCharacter: context.triggerCharacter, - triggerKind: context.triggerCharacter ? SuggestTriggerKind.TriggerCharacter : SuggestTriggerKind.Invoke - } + suggestCtx ).then(items => { this._requestPromise = null; diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 1742ab97781..6624f1ca547 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -335,6 +335,12 @@ class SuggestionDetails { } } +export interface ISelectedSuggestion { + item: ICompletionItem; + index: number; + model: CompletionModel; +} + export class SuggestWidget implements IContentWidget, IDelegate, IDisposable { private static ID: string = 'editor.widget.suggestWidget'; @@ -368,14 +374,14 @@ export class SuggestWidget implements IContentWidget, IDelegate private showTimeout: TPromise; private toDispose: IDisposable[]; - private onDidSelectEmitter = new Emitter(); - private onDidFocusEmitter = new Emitter(); + private onDidSelectEmitter = new Emitter(); + private onDidFocusEmitter = new Emitter(); private onDidHideEmitter = new Emitter(); private onDidShowEmitter = new Emitter(); - readonly onDidSelect: Event = this.onDidSelectEmitter.event; - readonly onDidFocus: Event = this.onDidFocusEmitter.event; + readonly onDidSelect: Event = this.onDidSelectEmitter.event; + readonly onDidFocus: Event = this.onDidFocusEmitter.event; readonly onDidHide: Event = this.onDidHideEmitter.event; readonly onDidShow: Event = this.onDidShowEmitter.event; @@ -499,13 +505,12 @@ export class SuggestWidget implements IContentWidget, IDelegate } const item = e.elements[0]; + const index = e.indexes[0]; item.resolve().then(() => { - this.onDidSelectEmitter.fire(item); + this.onDidSelectEmitter.fire({ item, index, model: this.completionModel }); + alert(nls.localize('suggestionAriaAccepted', "{0}, accepted", item.suggestion.label)); + this.editor.focus(); }); - - alert(nls.localize('suggestionAriaAccepted', "{0}, accepted", item.suggestion.label)); - - this.editor.focus(); } private _getSuggestionAriaAlertLabel(item: ICompletionItem): string { @@ -613,7 +618,7 @@ export class SuggestWidget implements IContentWidget, IDelegate .then(() => this.currentSuggestionDetails = null); // emit an event - this.onDidFocusEmitter.fire(item); + this.onDidFocusEmitter.fire({ item, index, model: this.completionModel }); } private setState(state: State): void { @@ -838,12 +843,16 @@ export class SuggestWidget implements IContentWidget, IDelegate } } - getFocusedItem(): ICompletionItem { + getFocusedItem(): ISelectedSuggestion { if (this.state !== State.Hidden && this.state !== State.Empty && this.state !== State.Loading) { - return this.list.getFocusedElements()[0]; + return { + item: this.list.getFocusedElements()[0], + index: this.list.getFocus()[0], + model: this.completionModel + }; } return undefined; } diff --git a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts index e50fd6a7731..e1c3d114de8 100644 --- a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts +++ b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts @@ -25,6 +25,7 @@ import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands'; import { SuggestController } from 'vs/editor/contrib/suggest/suggestController'; import { IStorageService, NullStorageService } from 'vs/platform/storage/common/storage'; import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; +import { ISelectedSuggestion } from 'vs/editor/contrib/suggest/suggestWidget'; function createMockEditor(model: TextModel): TestCodeEditor { const contextKeyService = new MockContextKeyService(); @@ -590,7 +591,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { return withOracle(async (sugget, editor) => { class TestCtrl extends SuggestController { - _onDidSelectItem(item) { + _onDidSelectItem(item: ISelectedSuggestion) { super._onDidSelectItem(item); } } @@ -606,7 +607,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { const [first] = event.completionModel.items; assert.equal(first.suggestion.label, 'bar'); - ctrl._onDidSelectItem(first); + ctrl._onDidSelectItem({ item: first, index: 0, model: event.completionModel }); }); assert.equal( diff --git a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts index e438ed06ee4..02875a72eab 100644 --- a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts @@ -27,8 +27,8 @@ import { firstIndex } from 'vs/base/common/arrays'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ITextModel, TrackedRangeStickiness, OverviewRulerLane, IModelDeltaDecoration } from 'vs/editor/common/model'; -export const editorWordHighlight = registerColor('editor.wordHighlightBackground', { dark: '#575757B8', light: '#57575740', hc: null }, nls.localize('wordHighlight', 'Background color of a symbol during read-access, like reading a variable.')); -export const editorWordHighlightStrong = registerColor('editor.wordHighlightStrongBackground', { dark: '#004972B8', light: '#0e639c40', hc: null }, nls.localize('wordHighlightStrong', 'Background color of a symbol during write-access, like writing to a variable.')); +export const editorWordHighlight = registerColor('editor.wordHighlightBackground', { dark: '#575757B8', light: '#57575740', hc: null }, nls.localize('wordHighlight', 'Background color of a symbol during read-access, like reading a variable. The color must not be opaque to not hide underlying decorations.'), true); +export const editorWordHighlightStrong = registerColor('editor.wordHighlightStrongBackground', { dark: '#004972B8', light: '#0e639c40', hc: null }, nls.localize('wordHighlightStrong', 'Background color of a symbol during write-access, like writing to a variable. The color must not be opaque to not hide underlying decorations.'), true); export const overviewRulerWordHighlightForeground = registerColor('editorOverviewRuler.wordHighlightForeground', { dark: '#A0A0A0', light: '#A0A0A0', hc: '#A0A0A0' }, nls.localize('overviewRulerWordHighlightForeground', 'Overview ruler marker color for symbol highlights.')); export const overviewRulerWordHighlightStrongForeground = registerColor('editorOverviewRuler.wordHighlightStrongForeground', { dark: '#C0A0C0', light: '#C0A0C0', hc: '#C0A0C0' }, nls.localize('overviewRulerWordHighlightStrongForeground', 'Overview ruler marker color for write-access symbol highlights.')); diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 1ccd43194a1..87e6d2d6ea6 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -1852,6 +1852,36 @@ suite('Editor Controller - Regression tests', () => { assertCursor(cursor, new Selection(1, 12, 1, 12)); }); }); + + test('issue #41573 - delete across multiple lines does not shrink the selection when word wraps', () => { + const model = TextModel.createFromString([ + 'Authorization: \'Bearer pHKRfCTFSnGxs6akKlb9ddIXcca0sIUSZJutPHYqz7vEeHdMTMh0SGN0IGU3a0n59DXjTLRsj5EJ2u33qLNIFi9fk5XF8pK39PndLYUZhPt4QvHGLScgSkK0L4gwzkzMloTQPpKhqiikiIOvyNNSpd2o8j29NnOmdTUOKi9DVt74PD2ohKxyOrWZ6oZprTkb3eKajcpnS0LABKfaw2rmv4\',' + ].join('\n')); + const config = new TestConfiguration({ + wordWrap: 'wordWrapColumn', + wordWrapColumn: 100 + }); + const viewModel = new ViewModel(0, config, model, null); + const cursor = new Cursor(config, model, viewModel); + + console.log(viewModel.getLineCount()); + + moveTo(cursor, 1, 43, false); + moveTo(cursor, 1, 147, true); + assertCursor(cursor, new Selection(1, 43, 1, 147)); + + model.applyEdits([{ + range: new Range(1, 1, 1, 43), + text: '' + }]); + + assertCursor(cursor, new Selection(1, 1, 1, 105)); + + cursor.dispose(); + viewModel.dispose(); + config.dispose(); + model.dispose(); + }); }); suite('Editor Controller - Cursor Configuration', () => { diff --git a/src/vs/editor/test/common/model/benchmark/benchmarkUtils.ts b/src/vs/editor/test/common/model/benchmark/benchmarkUtils.ts new file mode 100644 index 00000000000..f466e4d21c8 --- /dev/null +++ b/src/vs/editor/test/common/model/benchmark/benchmarkUtils.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ITextBufferBuilder, ITextBufferFactory, ITextBuffer, DefaultEndOfLine } from 'vs/editor/common/model'; +import { LinesTextBufferBuilder } from 'vs/editor/common/model/linesTextBuffer/linesTextBufferBuilder'; +import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; +import { ChunksTextBufferBuilder } from 'vs/editor/common/model/chunksTextBuffer/chunksTextBufferBuilder'; + +export function doBenchmark(id: string, ts: T[], fn: (t: T) => void) { + let columns: string[] = [id]; + for (let i = 0; i < ts.length; i++) { + var start = process.hrtime(); + fn(ts[i]); + var diff = process.hrtime(start); + columns.push(`${(diff[0] * 1000 + diff[1] / 1000000).toFixed(3)} ms`); + } + console.log('|' + columns.join('\t|') + '|'); +} + +export interface IBenchmark { + name: string; + /** + * Before each cycle, this function will be called to create TextBufferFactory + */ + buildBuffer: (textBufferBuilder: ITextBufferBuilder) => ITextBufferFactory; + /** + * Before each cycle, this function will be called to do pre-work for text buffer. + * This will be called onece `buildBuffer` is finished. + */ + preCycle: (textBuffer: ITextBuffer) => void; + /** + * The function we are benchmarking + */ + fn: (textBuffer: ITextBuffer) => void; +} + +export class BenchmarkSuite { + name: string; + iterations: number; + benchmarks: IBenchmark[]; + + constructor(suiteOptions: { name: string, iterations: number }) { + this.name = suiteOptions.name; + this.iterations = suiteOptions.iterations; + this.benchmarks = []; + } + + add(benchmark: IBenchmark) { + this.benchmarks.push(benchmark); + } + + run() { + console.log(`|${this.name}\t|line buffer\t|piece table\t|edcore\t`); + console.log('|---|---|---|---|'); + for (let i = 0; i < this.benchmarks.length; i++) { + let benchmark = this.benchmarks[i]; + let columns: string[] = [benchmark.name]; + [new LinesTextBufferBuilder(), new PieceTreeTextBufferBuilder(), new ChunksTextBufferBuilder()].forEach((builder: ITextBufferBuilder) => { + let timeDiffTotal = 0.0; + for (let j = 0; j < this.iterations; j++) { + let factory = benchmark.buildBuffer(builder); + let buffer = factory.create(DefaultEndOfLine.LF); + benchmark.preCycle(buffer); + var start = process.hrtime(); + benchmark.fn(buffer); + var diff = process.hrtime(start); + timeDiffTotal += (diff[0] * 1000 * 1000 + diff[1] / 1000); + } + columns.push(`${(timeDiffTotal / 1000 / this.iterations).toFixed(3)} ms`); + }); + console.log('|' + columns.join('\t|') + '|'); + } + console.log('\n'); + } +} diff --git a/src/vs/editor/test/common/model/benchmark/bootstrap.js b/src/vs/editor/test/common/model/benchmark/bootstrap.js new file mode 100644 index 00000000000..a93aabeb980 --- /dev/null +++ b/src/vs/editor/test/common/model/benchmark/bootstrap.js @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +require('../../../../../../bootstrap-amd').bootstrap('vs/editor/test/common/model/benchmark/entry'); \ No newline at end of file diff --git a/src/vs/editor/test/common/model/benchmark/entry.ts b/src/vs/editor/test/common/model/benchmark/entry.ts new file mode 100644 index 00000000000..e1b4221dd66 --- /dev/null +++ b/src/vs/editor/test/common/model/benchmark/entry.ts @@ -0,0 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import 'vs/editor/test/common/model/benchmark/modelbuilder.benchmark'; +import 'vs/editor/test/common/model/benchmark/operations.benchmark'; +import 'vs/editor/test/common/model/benchmark/searchNReplace.benchmark'; \ No newline at end of file diff --git a/src/vs/editor/test/common/model/benchmark/modelbuilder.benchmark.ts b/src/vs/editor/test/common/model/benchmark/modelbuilder.benchmark.ts new file mode 100644 index 00000000000..41445a17df9 --- /dev/null +++ b/src/vs/editor/test/common/model/benchmark/modelbuilder.benchmark.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { LinesTextBufferBuilder } from 'vs/editor/common/model/linesTextBuffer/linesTextBufferBuilder'; +import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; +import { ITextBufferBuilder } from 'vs/editor/common/model'; +import { generateRandomChunkWithLF } from 'vs/editor/test/common/model/linesTextBuffer/textBufferAutoTestUtils'; +import { doBenchmark } from 'vs/editor/test/common/model/benchmark/benchmarkUtils'; + +let linesTextBufferBuilder = new LinesTextBufferBuilder(); +let pieceTreeTextBufferBuilder = new PieceTreeTextBufferBuilder(); +let chunks = []; + +for (let i = 0; i < 100; i++) { + chunks.push(generateRandomChunkWithLF(16 * 1000, 64 * 1000)); +} + +let modelBuildBenchmark = function (id: string, builders: ITextBufferBuilder[], chunkCnt: number) { + doBenchmark(id, builders, builder => { + for (let i = 0, len = Math.min(chunkCnt, chunks.length); i < len; i++) { + builder.acceptChunk(chunks[i]); + } + builder.finish(); + }); +}; + +console.log(`|model builder\t|line buffer\t|piece table\t|`); +console.log('|---|---|---|'); +for (let i of [10, 100]) { + modelBuildBenchmark(`${i} random chunks`, [linesTextBufferBuilder, pieceTreeTextBufferBuilder], i); +} diff --git a/src/vs/editor/test/common/model/benchmark/operations.benchmark.ts b/src/vs/editor/test/common/model/benchmark/operations.benchmark.ts new file mode 100644 index 00000000000..5a83e5f29e9 --- /dev/null +++ b/src/vs/editor/test/common/model/benchmark/operations.benchmark.ts @@ -0,0 +1,139 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ITextBufferBuilder, EndOfLinePreference } from 'vs/editor/common/model'; +import { BenchmarkSuite } from 'vs/editor/test/common/model/benchmark/benchmarkUtils'; +import { generateRandomChunkWithLF, generateRandomEdits, generateSequentialInserts, getRandomInt } from 'vs/editor/test/common/model/linesTextBuffer/textBufferAutoTestUtils'; +import { Range } from 'vs/editor/common/core/range'; + +let fileSizes = [1, 1000, 64 * 1000, 32 * 1000 * 1000]; +let editTypes = [ + { + id: 'random edits', + generateEdits: generateRandomEdits + }, + { + id: 'sequential inserts', + generateEdits: generateSequentialInserts + } +]; + +for (let fileSize of fileSizes) { + let chunks = []; + + let chunkCnt = Math.floor(fileSize / (64 * 1000)); + if (chunkCnt === 0) { + chunks.push(generateRandomChunkWithLF(fileSize, fileSize)); + } else { + let chunk = generateRandomChunkWithLF(64 * 1000, 64 * 1000); + // try to avoid OOM + for (let j = 0; j < chunkCnt; j++) { + chunks.push(Buffer.from(chunk + j).toString()); + } + } + + for (let editType of editTypes) { + const edits = editType.generateEdits(chunks, 1000); + + let editsSuite = new BenchmarkSuite({ + name: `File Size: ${fileSize}Byte, ${editType.id}`, + iterations: 10 + }); + + for (let i of [10, 100, 1000]) { + editsSuite.add({ + name: `apply ${i} edits`, + buildBuffer: (textBufferBuilder: ITextBufferBuilder) => { + chunks.forEach(ck => textBufferBuilder.acceptChunk(ck)); + return textBufferBuilder.finish(); + }, + preCycle: (textBuffer) => { + return textBuffer; + }, + fn: (textBuffer) => { + // for line model, this loop doesn't reflect the real situation. + for (let k = 0; k < edits.length && k < i; k++) { + textBuffer.applyEdits([edits[k]], false); + } + } + }); + + editsSuite.add({ + name: `Read all lines after ${i} edits`, + buildBuffer: (textBufferBuilder: ITextBufferBuilder) => { + chunks.forEach(ck => textBufferBuilder.acceptChunk(ck)); + return textBufferBuilder.finish(); + }, + preCycle: (textBuffer) => { + for (let k = 0; k < edits.length && k < i; k++) { + textBuffer.applyEdits([edits[k]], false); + } + return textBuffer; + }, + fn: (textBuffer) => { + for (let j = 0, len = textBuffer.getLineCount(); j < len; j++) { + var str = textBuffer.getLineContent(j + 1); + let firstChar = str.charCodeAt(0); + let lastChar = str.charCodeAt(str.length - 1); + firstChar = firstChar - lastChar; + lastChar = firstChar + lastChar; + firstChar = lastChar - firstChar; + } + } + }); + + editsSuite.add({ + name: `Read 10 random windows after ${i} edits`, + buildBuffer: (textBufferBuilder: ITextBufferBuilder) => { + chunks.forEach(ck => textBufferBuilder.acceptChunk(ck)); + return textBufferBuilder.finish(); + }, + preCycle: (textBuffer) => { + for (let k = 0; k < edits.length && k < i; k++) { + textBuffer.applyEdits([edits[k]], false); + } + return textBuffer; + }, + fn: (textBuffer) => { + for (let i = 0; i < 10; i++) { + let minLine = 1; + let maxLine = textBuffer.getLineCount(); + let startLine = getRandomInt(minLine, Math.max(minLine, maxLine - 100)); + let endLine = Math.min(maxLine, startLine + 100); + for (let j = startLine; j < endLine; j++) { + var str = textBuffer.getLineContent(j + 1); + let firstChar = str.charCodeAt(0); + let lastChar = str.charCodeAt(str.length - 1); + firstChar = firstChar - lastChar; + lastChar = firstChar + lastChar; + firstChar = lastChar - firstChar; + } + } + } + }); + + editsSuite.add({ + name: `save file after ${i} edits`, + buildBuffer: (textBufferBuilder: ITextBufferBuilder) => { + chunks.forEach(ck => textBufferBuilder.acceptChunk(ck)); + return textBufferBuilder.finish(); + }, + preCycle: (textBuffer) => { + for (let k = 0; k < edits.length && k < i; k++) { + textBuffer.applyEdits([edits[k]], false); + } + return textBuffer; + }, + fn: (textBuffer) => { + const lineCount = textBuffer.getLineCount(); + const fullModelRange = new Range(1, 1, lineCount, textBuffer.getLineLength(lineCount) + 1); + textBuffer.getValueInRange(fullModelRange, EndOfLinePreference.LF); + } + }); + } + + editsSuite.run(); + } +} \ No newline at end of file diff --git a/src/vs/editor/test/common/model/benchmark/searchNReplace.benchmark.ts b/src/vs/editor/test/common/model/benchmark/searchNReplace.benchmark.ts new file mode 100644 index 00000000000..6c4667ca0fa --- /dev/null +++ b/src/vs/editor/test/common/model/benchmark/searchNReplace.benchmark.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { ITextBufferBuilder } from 'vs/editor/common/model'; +import { generateRandomReplaces, generateRandomChunkWithLF } from 'vs/editor/test/common/model/linesTextBuffer/textBufferAutoTestUtils'; +import { BenchmarkSuite } from 'vs/editor/test/common/model/benchmark/benchmarkUtils'; + +let fileSizes = [1, 1000, 64 * 1000, 32 * 1000 * 1000]; + +for (let fileSize of fileSizes) { + let chunks = []; + + let chunkCnt = Math.floor(fileSize / (64 * 1000)); + if (chunkCnt === 0) { + chunks.push(generateRandomChunkWithLF(fileSize, fileSize)); + } else { + let chunk = generateRandomChunkWithLF(64 * 1000, 64 * 1000); + // try to avoid OOM + for (let j = 0; j < chunkCnt; j++) { + chunks.push(Buffer.from(chunk + j).toString()); + } + } + + let replaceSuite = new BenchmarkSuite({ + name: `File Size: ${fileSize}Byte`, + iterations: 10 + }); + + let edits = generateRandomReplaces(chunks, 500, 5, 10); + + for (let i of [10, 100, 500]) { + replaceSuite.add({ + name: `replace ${i} occurrences`, + buildBuffer: (textBufferBuilder: ITextBufferBuilder) => { + chunks.forEach(ck => textBufferBuilder.acceptChunk(ck)); + return textBufferBuilder.finish(); + }, + preCycle: (textBuffer) => { + return textBuffer; + }, + fn: (textBuffer) => { + textBuffer.applyEdits(edits.slice(0, i), false); + } + }); + } + + replaceSuite.run(); +} \ No newline at end of file diff --git a/src/vs/editor/test/common/model/chunksTextBuffer/bufferPiece.test.ts b/src/vs/editor/test/common/model/chunksTextBuffer/bufferPiece.test.ts new file mode 100644 index 00000000000..a6cc8f6f22d --- /dev/null +++ b/src/vs/editor/test/common/model/chunksTextBuffer/bufferPiece.test.ts @@ -0,0 +1,61 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as assert from 'assert'; +import { BufferPiece } from 'vs/editor/common/model/chunksTextBuffer/bufferPiece'; + +suite('BufferPiece', () => { + test('findLineStartBeforeOffset', () => { + let piece = new BufferPiece([ + 'Line1\r\n', + 'l2\n', + 'another\r', + 'and\r\n', + 'finally\n', + 'last' + ].join('')); + + assert.equal(piece.length(), 35); + assert.deepEqual(piece.findLineStartBeforeOffset(0), -1); + assert.deepEqual(piece.findLineStartBeforeOffset(1), -1); + assert.deepEqual(piece.findLineStartBeforeOffset(2), -1); + assert.deepEqual(piece.findLineStartBeforeOffset(3), -1); + assert.deepEqual(piece.findLineStartBeforeOffset(4), -1); + assert.deepEqual(piece.findLineStartBeforeOffset(5), -1); + assert.deepEqual(piece.findLineStartBeforeOffset(6), -1); + assert.deepEqual(piece.findLineStartBeforeOffset(7), 0); + assert.deepEqual(piece.findLineStartBeforeOffset(8), 0); + assert.deepEqual(piece.findLineStartBeforeOffset(9), 0); + assert.deepEqual(piece.findLineStartBeforeOffset(10), 1); + assert.deepEqual(piece.findLineStartBeforeOffset(11), 1); + assert.deepEqual(piece.findLineStartBeforeOffset(12), 1); + assert.deepEqual(piece.findLineStartBeforeOffset(13), 1); + assert.deepEqual(piece.findLineStartBeforeOffset(14), 1); + assert.deepEqual(piece.findLineStartBeforeOffset(15), 1); + assert.deepEqual(piece.findLineStartBeforeOffset(16), 1); + assert.deepEqual(piece.findLineStartBeforeOffset(17), 1); + assert.deepEqual(piece.findLineStartBeforeOffset(18), 2); + assert.deepEqual(piece.findLineStartBeforeOffset(19), 2); + assert.deepEqual(piece.findLineStartBeforeOffset(20), 2); + assert.deepEqual(piece.findLineStartBeforeOffset(21), 2); + assert.deepEqual(piece.findLineStartBeforeOffset(22), 2); + assert.deepEqual(piece.findLineStartBeforeOffset(23), 3); + assert.deepEqual(piece.findLineStartBeforeOffset(24), 3); + assert.deepEqual(piece.findLineStartBeforeOffset(25), 3); + assert.deepEqual(piece.findLineStartBeforeOffset(26), 3); + assert.deepEqual(piece.findLineStartBeforeOffset(27), 3); + assert.deepEqual(piece.findLineStartBeforeOffset(28), 3); + assert.deepEqual(piece.findLineStartBeforeOffset(29), 3); + assert.deepEqual(piece.findLineStartBeforeOffset(30), 3); + assert.deepEqual(piece.findLineStartBeforeOffset(31), 4); + assert.deepEqual(piece.findLineStartBeforeOffset(32), 4); + assert.deepEqual(piece.findLineStartBeforeOffset(33), 4); + assert.deepEqual(piece.findLineStartBeforeOffset(34), 4); + assert.deepEqual(piece.findLineStartBeforeOffset(35), 4); + assert.deepEqual(piece.findLineStartBeforeOffset(36), 4); + }); +}); diff --git a/src/vs/editor/test/common/model/linesTextBuffer/linesTextBufferBuilderAuto.test.ts b/src/vs/editor/test/common/model/linesTextBuffer/linesTextBufferBuilderAuto.test.ts index 9b1c70f96b1..8d7119d2077 100644 --- a/src/vs/editor/test/common/model/linesTextBuffer/linesTextBufferBuilderAuto.test.ts +++ b/src/vs/editor/test/common/model/linesTextBuffer/linesTextBufferBuilderAuto.test.ts @@ -5,7 +5,7 @@ 'use strict'; import { testModelBuilder } from './linesTextBufferBuilder.test'; -import { CharCode } from 'vs/base/common/charCode'; +import { getRandomInt, getRandomEOLSequence, getRandomString } from 'vs/editor/test/common/model/linesTextBuffer/textBufferAutoTestUtils'; const GENERATE_TESTS = false; @@ -21,30 +21,6 @@ suite('ModelBuilder Auto Tests', () => { }); -function getRandomInt(min: number, max: number): number { - return Math.floor(Math.random() * (max - min + 1)) + min; -} - -function getRandomEOLSequence(): string { - let rnd = getRandomInt(1, 3); - if (rnd === 1) { - return '\n'; - } - if (rnd === 2) { - return '\r'; - } - return '\r\n'; -} - -function getRandomString(minLength: number, maxLength: number): string { - let length = getRandomInt(minLength, maxLength); - let r = ''; - for (let i = 0; i < length; i++) { - r += String.fromCharCode(getRandomInt(CharCode.a, CharCode.z)); - } - return r; -} - function generateRandomFile(): string { let lineCount = getRandomInt(1, 10); let mixedEOLSequence = getRandomInt(1, 2) === 1 ? true : false; diff --git a/src/vs/editor/test/common/model/linesTextBuffer/textBufferAutoTestUtils.ts b/src/vs/editor/test/common/model/linesTextBuffer/textBufferAutoTestUtils.ts new file mode 100644 index 00000000000..b43de70c81b --- /dev/null +++ b/src/vs/editor/test/common/model/linesTextBuffer/textBufferAutoTestUtils.ts @@ -0,0 +1,170 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { CharCode } from 'vs/base/common/charCode'; +import { IIdentifiedSingleEditOperation, DefaultEndOfLine, ITextBufferBuilder, ITextBuffer } from 'vs/editor/common/model'; +import { Range } from 'vs/editor/common/core/range'; + +export function getRandomInt(min: number, max: number): number { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +export function getRandomEOLSequence(): string { + let rnd = getRandomInt(1, 3); + if (rnd === 1) { + return '\n'; + } + if (rnd === 2) { + return '\r'; + } + return '\r\n'; +} + +export function getRandomString(minLength: number, maxLength: number): string { + let length = getRandomInt(minLength, maxLength); + let r = ''; + for (let i = 0; i < length; i++) { + r += String.fromCharCode(getRandomInt(CharCode.a, CharCode.z)); + } + return r; +} + +export function generateRandomEdits(chunks: string[], editCnt: number): IIdentifiedSingleEditOperation[] { + let lines = []; + for (let i = 0; i < chunks.length; i++) { + let newLines = chunks[i].split(/\r\n|\r|\n/); + if (lines.length === 0) { + lines.push(...newLines); + } else { + newLines[0] = lines[lines.length - 1] + newLines[0]; + lines.splice(lines.length - 1, 1, ...newLines); + } + } + + let ops: IIdentifiedSingleEditOperation[] = []; + + for (let i = 0; i < editCnt; i++) { + let line = getRandomInt(1, lines.length); + let startColumn = getRandomInt(1, Math.max(lines[line - 1].length, 1)); + let endColumn = getRandomInt(startColumn, Math.max(lines[line - 1].length, startColumn)); + let text: string = ''; + if (Math.random() < .5) { + text = getRandomString(5, 10); + } + + ops.push({ + text: text, + range: new Range(line, startColumn, line, endColumn) + }); + lines[line - 1] = lines[line - 1].substring(0, startColumn - 1) + text + lines[line - 1].substring(endColumn - 1); + } + + return ops; +} + +export function generateSequentialInserts(chunks: string[], editCnt: number): IIdentifiedSingleEditOperation[] { + let lines = []; + for (let i = 0; i < chunks.length; i++) { + let newLines = chunks[i].split(/\r\n|\r|\n/); + if (lines.length === 0) { + lines.push(...newLines); + } else { + newLines[0] = lines[lines.length - 1] + newLines[0]; + lines.splice(lines.length - 1, 1, ...newLines); + } + } + + let ops: IIdentifiedSingleEditOperation[] = []; + + for (let i = 0; i < editCnt; i++) { + let line = lines.length; + let column = lines[line - 1].length + 1; + let text: string = ''; + if (Math.random() < .5) { + text = '\n'; + lines.push(''); + } else { + text = getRandomString(1, 2); + lines[line - 1] += text; + } + + ops.push({ + text: text, + range: new Range(line, column, line, column) + }); + } + + return ops; +} + +export function generateRandomReplaces(chunks: string[], editCnt: number, searchStringLen: number, replaceStringLen: number): IIdentifiedSingleEditOperation[] { + let lines = []; + for (let i = 0; i < chunks.length; i++) { + let newLines = chunks[i].split(/\r\n|\r|\n/); + if (lines.length === 0) { + lines.push(...newLines); + } else { + newLines[0] = lines[lines.length - 1] + newLines[0]; + lines.splice(lines.length - 1, 1, ...newLines); + } + } + + let ops: IIdentifiedSingleEditOperation[] = []; + let chunkSize = Math.max(1, Math.floor(lines.length / editCnt)); + let chunkCnt = Math.floor(lines.length / chunkSize); + let replaceString = getRandomString(replaceStringLen, replaceStringLen); + + let previousChunksLength = 0; + for (let i = 0; i < chunkCnt; i++) { + let startLine = previousChunksLength + 1; + let endLine = previousChunksLength + chunkSize; + let line = getRandomInt(startLine, endLine); + let maxColumn = lines[line - 1].length + 1; + let startColumn = getRandomInt(1, maxColumn); + let endColumn = Math.min(maxColumn, startColumn + searchStringLen); + + ops.push({ + text: replaceString, + range: new Range(line, startColumn, line, endColumn) + }); + previousChunksLength = endLine; + } + + return ops; +} + +export function createMockText(lineCount: number, minColumn: number, maxColumn: number) { + let fixedEOL = getRandomEOLSequence(); + let lines: string[] = []; + for (let i = 0; i < lineCount; i++) { + if (i !== 0) { + lines.push(fixedEOL); + } + lines.push(getRandomString(minColumn, maxColumn)); + } + return lines.join(''); +} + +export function createMockBuffer(str: string, bufferBuilder: ITextBufferBuilder): ITextBuffer { + bufferBuilder.acceptChunk(str); + let bufferFactory = bufferBuilder.finish(); + let buffer = bufferFactory.create(DefaultEndOfLine.LF); + return buffer; +} + +export function generateRandomChunkWithLF(minLength: number, maxLength: number): string { + let length = getRandomInt(minLength, maxLength); + let r = ''; + for (let i = 0; i < length; i++) { + let randomI = getRandomInt(0, CharCode.z - CharCode.a + 1); + if (randomI === 0 && Math.random() < 0.3) { + r += '\n'; + } else { + r += String.fromCharCode(randomI + CharCode.a - 1); + } + } + return r; +} \ No newline at end of file diff --git a/src/vs/editor/test/common/model/model.test.ts b/src/vs/editor/test/common/model/model.test.ts index 92b7e5b714a..e610caa3ddf 100644 --- a/src/vs/editor/test/common/model/model.test.ts +++ b/src/vs/editor/test/common/model/model.test.ts @@ -129,7 +129,6 @@ suite('Editor Model - Model', () => { thisModel.applyEdits([EditOperation.insert(new Position(1, 3), ' new line\nNo longer')]); assert.deepEqual(e, new ModelRawContentChangedEvent( [ - new ModelRawLineChanged(1, 'My new line First Line'), new ModelRawLineChanged(1, 'My new line'), new ModelRawLinesInserted(2, 2, ['No longer First Line']), ], @@ -245,7 +244,6 @@ suite('Editor Model - Model', () => { thisModel.applyEdits([EditOperation.delete(new Range(1, 4, 2, 6))]); assert.deepEqual(e, new ModelRawContentChangedEvent( [ - new ModelRawLineChanged(1, 'My '), new ModelRawLineChanged(1, 'My Second Line'), new ModelRawLinesDeleted(2, 2), ], @@ -266,7 +264,6 @@ suite('Editor Model - Model', () => { thisModel.applyEdits([EditOperation.delete(new Range(1, 4, 3, 5))]); assert.deepEqual(e, new ModelRawContentChangedEvent( [ - new ModelRawLineChanged(1, 'My '), new ModelRawLineChanged(1, 'My Third Line'), new ModelRawLinesDeleted(2, 3), ], diff --git a/src/vs/editor/test/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.test.ts b/src/vs/editor/test/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.test.ts new file mode 100644 index 00000000000..83eaf75bde0 --- /dev/null +++ b/src/vs/editor/test/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer.test.ts @@ -0,0 +1,1520 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as assert from 'assert'; +import { Position } from 'vs/editor/common/core/position'; +import { Range } from 'vs/editor/common/core/range'; +import { PieceTreeTextBufferBuilder } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder'; +import { DefaultEndOfLine } from 'vs/editor/common/model'; +import { PieceTreeBase } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase'; +import { SENTINEL, NodeColor, TreeNode } from 'vs/editor/common/model/pieceTreeTextBuffer/rbTreeBase'; +import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer'; + +const alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n'; + +function randomChar() { + return alphabet[randomInt(alphabet.length)]; +} + +function randomInt(bound: number) { + return Math.floor(Math.random() * bound); +} + +function randomStr(len: number) { + if (len === null) { + len = 10; + } + return (function () { + var j, ref, results; + results = []; + for ( + j = 1, ref = len; + 1 <= ref ? j < ref : j > ref; + 1 <= ref ? j++ : j-- + ) { + results.push(randomChar()); + } + return results; + })().join(''); +} + +function trimLineFeed(text: string): string { + if (text.length === 0) { + return text; + } + + if (text.length === 1) { + if ( + text.charCodeAt(text.length - 1) === 10 || + text.charCodeAt(text.length - 1) === 13 + ) { + return ''; + } + return text; + } + + if (text.charCodeAt(text.length - 1) === 10) { + if (text.charCodeAt(text.length - 2) === 13) { + return text.slice(0, -2); + } + return text.slice(0, -1); + } + + if (text.charCodeAt(text.length - 1) === 13) { + return text.slice(0, -1); + } + + return text; +} + +//#region Assertion + +function testLinesContent(str: string, pieceTable: PieceTreeBase) { + let lines = str.split(/\r\n|\r|\n/); + assert.equal(pieceTable.getLineCount(), lines.length); + assert.equal(pieceTable.getLinesRawContent(), str); + for (let i = 0; i < lines.length; i++) { + assert.equal(pieceTable.getLineContent(i + 1), lines[i]); + assert.equal( + trimLineFeed( + pieceTable.getValueInRange( + new Range( + i + 1, + 1, + i + 1, + lines[i].length + (i === lines.length - 1 ? 1 : 2) + ) + ) + ), + lines[i] + ); + } +} + +function testLineStarts(str: string, pieceTable: PieceTreeBase) { + let lineStarts = [0]; + + // Reset regex to search from the beginning + let _regex = new RegExp(/\r\n|\r|\n/g); + _regex.lastIndex = 0; + let prevMatchStartIndex = -1; + let prevMatchLength = 0; + + let m: RegExpExecArray; + do { + if (prevMatchStartIndex + prevMatchLength === str.length) { + // Reached the end of the line + break; + } + + m = _regex.exec(str); + if (!m) { + break; + } + + const matchStartIndex = m.index; + const matchLength = m[0].length; + + if ( + matchStartIndex === prevMatchStartIndex && + matchLength === prevMatchLength + ) { + // Exit early if the regex matches the same range twice + break; + } + + prevMatchStartIndex = matchStartIndex; + prevMatchLength = matchLength; + + lineStarts.push(matchStartIndex + matchLength); + } while (m); + + for (let i = 0; i < lineStarts.length; i++) { + assert.deepEqual( + pieceTable.getPositionAt(lineStarts[i]), + new Position(i + 1, 1) + ); + assert.equal(pieceTable.getOffsetAt(i + 1, 1), lineStarts[i]); + } + + for (let i = 1; i < lineStarts.length; i++) { + let pos = pieceTable.getPositionAt(lineStarts[i] - 1); + assert.equal( + pieceTable.getOffsetAt(pos.lineNumber, pos.column), + lineStarts[i] - 1 + ); + } +} + +function createTextBuffer(val: string[], normalizeEOL: boolean = true): PieceTreeBase { + let bufferBuilder = new PieceTreeTextBufferBuilder(); + for (let i = 0; i < val.length; i++) { + bufferBuilder.acceptChunk(val[i]); + } + let factory = bufferBuilder.finish(normalizeEOL); + return (factory.create(DefaultEndOfLine.LF)).getPieceTree(); +} + +function assertTreeInvariants(T: PieceTreeBase): void { + assert(SENTINEL.color === NodeColor.Black); + assert(SENTINEL.parent === SENTINEL); + assert(SENTINEL.left === SENTINEL); + assert(SENTINEL.right === SENTINEL); + assert(SENTINEL.size_left === 0); + assert(SENTINEL.lf_left === 0); + assertValidTree(T); +} + +function depth(n: TreeNode): number { + if (n === SENTINEL) { + // The leafs are black + return 1; + } + assert(depth(n.left) === depth(n.right)); + return (n.color === NodeColor.Black ? 1 : 0) + depth(n.left); +} + +function assertValidNode(n: TreeNode): { size: number, lf_cnt: number } { + if (n === SENTINEL) { + return { size: 0, lf_cnt: 0 }; + } + + let l = n.left; + let r = n.right; + + if (n.color === NodeColor.Red) { + assert(l.color === NodeColor.Black); + assert(r.color === NodeColor.Black); + } + + let actualLeft = assertValidNode(l); + assert(actualLeft.lf_cnt === n.lf_left); + assert(actualLeft.size === n.size_left); + let actualRight = assertValidNode(r); + + return { size: n.size_left + n.piece.length + actualRight.size, lf_cnt: n.lf_left + n.piece.lineFeedCnt + actualRight.lf_cnt }; +} + +function assertValidTree(T: PieceTreeBase): void { + if (T.root === SENTINEL) { + return; + } + assert(T.root.color === NodeColor.Black); + assert(depth(T.root.left) === depth(T.root.right)); + assertValidNode(T.root); +} + +//#endregion + +suite('inserts and deletes', () => { + test('basic insert/delete', () => { + let pieceTable = createTextBuffer([ + 'This is a document with some text.' + ]); + + pieceTable.insert(34, 'This is some more text to insert at offset 34.'); + assert.equal( + pieceTable.getLinesRawContent(), + 'This is a document with some text.This is some more text to insert at offset 34.' + ); + pieceTable.delete(42, 5); + assert.equal( + pieceTable.getLinesRawContent(), + 'This is a document with some text.This is more text to insert at offset 34.' + ); + assertTreeInvariants(pieceTable); + }); + + test('more inserts', () => { + let pt = createTextBuffer(['']); + + pt.insert(0, 'AAA'); + assert.equal(pt.getLinesRawContent(), 'AAA'); + pt.insert(0, 'BBB'); + assert.equal(pt.getLinesRawContent(), 'BBBAAA'); + pt.insert(6, 'CCC'); + assert.equal(pt.getLinesRawContent(), 'BBBAAACCC'); + pt.insert(5, 'DDD'); + assert.equal(pt.getLinesRawContent(), 'BBBAADDDACCC'); + assertTreeInvariants(pt); + }); + + test('more deletes', () => { + let pt = createTextBuffer(['012345678']); + pt.delete(8, 1); + assert.equal(pt.getLinesRawContent(), '01234567'); + pt.delete(0, 1); + assert.equal(pt.getLinesRawContent(), '1234567'); + pt.delete(5, 1); + assert.equal(pt.getLinesRawContent(), '123457'); + pt.delete(5, 1); + assert.equal(pt.getLinesRawContent(), '12345'); + pt.delete(0, 5); + assert.equal(pt.getLinesRawContent(), ''); + assertTreeInvariants(pt); + }); + + test('random test 1', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'ceLPHmFzvCtFeHkCBej '); + str = str.substring(0, 0) + 'ceLPHmFzvCtFeHkCBej ' + str.substring(0); + assert.equal(pieceTable.getLinesRawContent(), str); + pieceTable.insert(8, 'gDCEfNYiBUNkSwtvB K '); + str = str.substring(0, 8) + 'gDCEfNYiBUNkSwtvB K ' + str.substring(8); + assert.equal(pieceTable.getLinesRawContent(), str); + pieceTable.insert(38, 'cyNcHxjNPPoehBJldLS '); + str = str.substring(0, 38) + 'cyNcHxjNPPoehBJldLS ' + str.substring(38); + assert.equal(pieceTable.getLinesRawContent(), str); + pieceTable.insert(59, 'ejMx\nOTgWlbpeDExjOk '); + str = str.substring(0, 59) + 'ejMx\nOTgWlbpeDExjOk ' + str.substring(59); + + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + + test('random test 2', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'VgPG '); + str = str.substring(0, 0) + 'VgPG ' + str.substring(0); + pieceTable.insert(2, 'DdWF '); + str = str.substring(0, 2) + 'DdWF ' + str.substring(2); + pieceTable.insert(0, 'hUJc '); + str = str.substring(0, 0) + 'hUJc ' + str.substring(0); + pieceTable.insert(8, 'lQEq '); + str = str.substring(0, 8) + 'lQEq ' + str.substring(8); + pieceTable.insert(10, 'Gbtp '); + str = str.substring(0, 10) + 'Gbtp ' + str.substring(10); + + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + + test('random test 3', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'gYSz'); + str = str.substring(0, 0) + 'gYSz' + str.substring(0); + pieceTable.insert(1, 'mDQe'); + str = str.substring(0, 1) + 'mDQe' + str.substring(1); + pieceTable.insert(1, 'DTMQ'); + str = str.substring(0, 1) + 'DTMQ' + str.substring(1); + pieceTable.insert(2, 'GGZB'); + str = str.substring(0, 2) + 'GGZB' + str.substring(2); + pieceTable.insert(12, 'wXpq'); + str = str.substring(0, 12) + 'wXpq' + str.substring(12); + assert.equal(pieceTable.getLinesRawContent(), str); + }); + + test('random delete 1', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + + pieceTable.insert(0, 'vfb'); + str = str.substring(0, 0) + 'vfb' + str.substring(0); + assert.equal(pieceTable.getLinesRawContent(), str); + pieceTable.insert(0, 'zRq'); + str = str.substring(0, 0) + 'zRq' + str.substring(0); + assert.equal(pieceTable.getLinesRawContent(), str); + + pieceTable.delete(5, 1); + str = str.substring(0, 5) + str.substring(5 + 1); + assert.equal(pieceTable.getLinesRawContent(), str); + + pieceTable.insert(1, 'UNw'); + str = str.substring(0, 1) + 'UNw' + str.substring(1); + assert.equal(pieceTable.getLinesRawContent(), str); + + pieceTable.delete(4, 3); + str = str.substring(0, 4) + str.substring(4 + 3); + assert.equal(pieceTable.getLinesRawContent(), str); + + pieceTable.delete(1, 4); + str = str.substring(0, 1) + str.substring(1 + 4); + assert.equal(pieceTable.getLinesRawContent(), str); + + pieceTable.delete(0, 1); + str = str.substring(0, 0) + str.substring(0 + 1); + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + + test('random delete 2', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + + pieceTable.insert(0, 'IDT'); + str = str.substring(0, 0) + 'IDT' + str.substring(0); + pieceTable.insert(3, 'wwA'); + str = str.substring(0, 3) + 'wwA' + str.substring(3); + pieceTable.insert(3, 'Gnr'); + str = str.substring(0, 3) + 'Gnr' + str.substring(3); + pieceTable.delete(6, 3); + str = str.substring(0, 6) + str.substring(6 + 3); + pieceTable.insert(4, 'eHp'); + str = str.substring(0, 4) + 'eHp' + str.substring(4); + pieceTable.insert(1, 'UAi'); + str = str.substring(0, 1) + 'UAi' + str.substring(1); + pieceTable.insert(2, 'FrR'); + str = str.substring(0, 2) + 'FrR' + str.substring(2); + pieceTable.delete(6, 7); + str = str.substring(0, 6) + str.substring(6 + 7); + pieceTable.delete(3, 5); + str = str.substring(0, 3) + str.substring(3 + 5); + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + + test('random delete 3', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'PqM'); + str = str.substring(0, 0) + 'PqM' + str.substring(0); + pieceTable.delete(1, 2); + str = str.substring(0, 1) + str.substring(1 + 2); + pieceTable.insert(1, 'zLc'); + str = str.substring(0, 1) + 'zLc' + str.substring(1); + pieceTable.insert(0, 'MEX'); + str = str.substring(0, 0) + 'MEX' + str.substring(0); + pieceTable.insert(0, 'jZh'); + str = str.substring(0, 0) + 'jZh' + str.substring(0); + pieceTable.insert(8, 'GwQ'); + str = str.substring(0, 8) + 'GwQ' + str.substring(8); + pieceTable.delete(5, 6); + str = str.substring(0, 5) + str.substring(5 + 6); + pieceTable.insert(4, 'ktw'); + str = str.substring(0, 4) + 'ktw' + str.substring(4); + pieceTable.insert(5, 'GVu'); + str = str.substring(0, 5) + 'GVu' + str.substring(5); + pieceTable.insert(9, 'jdm'); + str = str.substring(0, 9) + 'jdm' + str.substring(9); + pieceTable.insert(15, 'na\n'); + str = str.substring(0, 15) + 'na\n' + str.substring(15); + pieceTable.delete(5, 8); + str = str.substring(0, 5) + str.substring(5 + 8); + pieceTable.delete(3, 4); + str = str.substring(0, 3) + str.substring(3 + 4); + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + + test('random insert/delete \\r bug 1', () => { + let str = 'a'; + let pieceTable = createTextBuffer(['a']); + pieceTable.delete(0, 1); + str = str.substring(0, 0) + str.substring(0 + 1); + pieceTable.insert(0, '\r\r\n\n'); + str = str.substring(0, 0) + '\r\r\n\n' + str.substring(0); + pieceTable.delete(3, 1); + str = str.substring(0, 3) + str.substring(3 + 1); + pieceTable.insert(2, '\n\n\ra'); + str = str.substring(0, 2) + '\n\n\ra' + str.substring(2); + pieceTable.delete(4, 3); + str = str.substring(0, 4) + str.substring(4 + 3); + pieceTable.insert(2, '\na\r\r'); + str = str.substring(0, 2) + '\na\r\r' + str.substring(2); + pieceTable.insert(6, '\ra\n\n'); + str = str.substring(0, 6) + '\ra\n\n' + str.substring(6); + pieceTable.insert(0, 'aa\n\n'); + str = str.substring(0, 0) + 'aa\n\n' + str.substring(0); + pieceTable.insert(5, '\n\na\r'); + str = str.substring(0, 5) + '\n\na\r' + str.substring(5); + + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + + test('random insert/delete \\r bug 2', () => { + let str = 'a'; + let pieceTable = createTextBuffer(['a']); + pieceTable.insert(1, '\naa\r'); + str = str.substring(0, 1) + '\naa\r' + str.substring(1); + pieceTable.delete(0, 4); + str = str.substring(0, 0) + str.substring(0 + 4); + pieceTable.insert(1, '\r\r\na'); + str = str.substring(0, 1) + '\r\r\na' + str.substring(1); + pieceTable.insert(2, '\n\r\ra'); + str = str.substring(0, 2) + '\n\r\ra' + str.substring(2); + pieceTable.delete(4, 1); + str = str.substring(0, 4) + str.substring(4 + 1); + pieceTable.insert(8, '\r\n\r\r'); + str = str.substring(0, 8) + '\r\n\r\r' + str.substring(8); + pieceTable.insert(7, '\n\n\na'); + str = str.substring(0, 7) + '\n\n\na' + str.substring(7); + pieceTable.insert(13, 'a\n\na'); + str = str.substring(0, 13) + 'a\n\na' + str.substring(13); + pieceTable.delete(17, 3); + str = str.substring(0, 17) + str.substring(17 + 3); + pieceTable.insert(2, 'a\ra\n'); + str = str.substring(0, 2) + 'a\ra\n' + str.substring(2); + + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + + test('random insert/delete \\r bug 3', () => { + let str = 'a'; + let pieceTable = createTextBuffer(['a']); + pieceTable.insert(0, '\r\na\r'); + str = str.substring(0, 0) + '\r\na\r' + str.substring(0); + pieceTable.delete(2, 3); + str = str.substring(0, 2) + str.substring(2 + 3); + pieceTable.insert(2, 'a\r\n\r'); + str = str.substring(0, 2) + 'a\r\n\r' + str.substring(2); + pieceTable.delete(4, 2); + str = str.substring(0, 4) + str.substring(4 + 2); + pieceTable.insert(4, 'a\n\r\n'); + str = str.substring(0, 4) + 'a\n\r\n' + str.substring(4); + pieceTable.insert(1, 'aa\n\r'); + str = str.substring(0, 1) + 'aa\n\r' + str.substring(1); + pieceTable.insert(7, '\na\r\n'); + str = str.substring(0, 7) + '\na\r\n' + str.substring(7); + pieceTable.insert(5, '\n\na\r'); + str = str.substring(0, 5) + '\n\na\r' + str.substring(5); + pieceTable.insert(10, '\r\r\n\r'); + str = str.substring(0, 10) + '\r\r\n\r' + str.substring(10); + assert.equal(pieceTable.getLinesRawContent(), str); + pieceTable.delete(21, 3); + str = str.substring(0, 21) + str.substring(21 + 3); + + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + + test('random insert/delete \\r bug 4s', () => { + let str = 'a'; + let pieceTable = createTextBuffer(['a']); + pieceTable.delete(0, 1); + str = str.substring(0, 0) + str.substring(0 + 1); + pieceTable.insert(0, '\naaa'); + str = str.substring(0, 0) + '\naaa' + str.substring(0); + pieceTable.insert(2, '\n\naa'); + str = str.substring(0, 2) + '\n\naa' + str.substring(2); + pieceTable.delete(1, 4); + str = str.substring(0, 1) + str.substring(1 + 4); + pieceTable.delete(3, 1); + str = str.substring(0, 3) + str.substring(3 + 1); + pieceTable.delete(1, 2); + str = str.substring(0, 1) + str.substring(1 + 2); + pieceTable.delete(0, 1); + str = str.substring(0, 0) + str.substring(0 + 1); + pieceTable.insert(0, 'a\n\n\r'); + str = str.substring(0, 0) + 'a\n\n\r' + str.substring(0); + pieceTable.insert(2, 'aa\r\n'); + str = str.substring(0, 2) + 'aa\r\n' + str.substring(2); + pieceTable.insert(3, 'a\naa'); + str = str.substring(0, 3) + 'a\naa' + str.substring(3); + + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); + test('random insert/delete \\r bug 5', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, '\n\n\n\r'); + str = str.substring(0, 0) + '\n\n\n\r' + str.substring(0); + pieceTable.insert(1, '\n\n\n\r'); + str = str.substring(0, 1) + '\n\n\n\r' + str.substring(1); + pieceTable.insert(2, '\n\r\r\r'); + str = str.substring(0, 2) + '\n\r\r\r' + str.substring(2); + pieceTable.insert(8, '\n\r\n\r'); + str = str.substring(0, 8) + '\n\r\n\r' + str.substring(8); + pieceTable.delete(5, 2); + str = str.substring(0, 5) + str.substring(5 + 2); + pieceTable.insert(4, '\n\r\r\r'); + str = str.substring(0, 4) + '\n\r\r\r' + str.substring(4); + pieceTable.insert(8, '\n\n\n\r'); + str = str.substring(0, 8) + '\n\n\n\r' + str.substring(8); + pieceTable.delete(0, 7); + str = str.substring(0, 0) + str.substring(0 + 7); + pieceTable.insert(1, '\r\n\r\r'); + str = str.substring(0, 1) + '\r\n\r\r' + str.substring(1); + pieceTable.insert(15, '\n\r\r\r'); + str = str.substring(0, 15) + '\n\r\r\r' + str.substring(15); + + assert.equal(pieceTable.getLinesRawContent(), str); + assertTreeInvariants(pieceTable); + }); +}); + +suite('prefix sum for line feed', () => { + test('basic', () => { + let pieceTable = createTextBuffer(['1\n2\n3\n4']); + + assert.equal(pieceTable.getLineCount(), 4); + assert.deepEqual(pieceTable.getPositionAt(0), new Position(1, 1)); + assert.deepEqual(pieceTable.getPositionAt(1), new Position(1, 2)); + assert.deepEqual(pieceTable.getPositionAt(2), new Position(2, 1)); + assert.deepEqual(pieceTable.getPositionAt(3), new Position(2, 2)); + assert.deepEqual(pieceTable.getPositionAt(4), new Position(3, 1)); + assert.deepEqual(pieceTable.getPositionAt(5), new Position(3, 2)); + assert.deepEqual(pieceTable.getPositionAt(6), new Position(4, 1)); + + assert.equal(pieceTable.getOffsetAt(1, 1), 0); + assert.equal(pieceTable.getOffsetAt(1, 2), 1); + assert.equal(pieceTable.getOffsetAt(2, 1), 2); + assert.equal(pieceTable.getOffsetAt(2, 2), 3); + assert.equal(pieceTable.getOffsetAt(3, 1), 4); + assert.equal(pieceTable.getOffsetAt(3, 2), 5); + assert.equal(pieceTable.getOffsetAt(4, 1), 6); + assertTreeInvariants(pieceTable); + }); + + test('append', () => { + let pieceTable = createTextBuffer(['a\nb\nc\nde']); + pieceTable.insert(8, 'fh\ni\njk'); + + assert.equal(pieceTable.getLineCount(), 6); + assert.deepEqual(pieceTable.getPositionAt(9), new Position(4, 4)); + assert.equal(pieceTable.getOffsetAt(1, 1), 0); + assertTreeInvariants(pieceTable); + }); + + test('insert', () => { + let pieceTable = createTextBuffer(['a\nb\nc\nde']); + pieceTable.insert(7, 'fh\ni\njk'); + + assert.equal(pieceTable.getLineCount(), 6); + assert.deepEqual(pieceTable.getPositionAt(6), new Position(4, 1)); + assert.deepEqual(pieceTable.getPositionAt(7), new Position(4, 2)); + assert.deepEqual(pieceTable.getPositionAt(8), new Position(4, 3)); + assert.deepEqual(pieceTable.getPositionAt(9), new Position(4, 4)); + assert.deepEqual(pieceTable.getPositionAt(12), new Position(6, 1)); + assert.deepEqual(pieceTable.getPositionAt(13), new Position(6, 2)); + assert.deepEqual(pieceTable.getPositionAt(14), new Position(6, 3)); + + assert.equal(pieceTable.getOffsetAt(4, 1), 6); + assert.equal(pieceTable.getOffsetAt(4, 2), 7); + assert.equal(pieceTable.getOffsetAt(4, 3), 8); + assert.equal(pieceTable.getOffsetAt(4, 4), 9); + assert.equal(pieceTable.getOffsetAt(6, 1), 12); + assert.equal(pieceTable.getOffsetAt(6, 2), 13); + assert.equal(pieceTable.getOffsetAt(6, 3), 14); + assertTreeInvariants(pieceTable); + }); + + test('delete', () => { + let pieceTable = createTextBuffer(['a\nb\nc\ndefh\ni\njk']); + pieceTable.delete(7, 2); + + assert.equal(pieceTable.getLinesRawContent(), 'a\nb\nc\ndh\ni\njk'); + assert.equal(pieceTable.getLineCount(), 6); + assert.deepEqual(pieceTable.getPositionAt(6), new Position(4, 1)); + assert.deepEqual(pieceTable.getPositionAt(7), new Position(4, 2)); + assert.deepEqual(pieceTable.getPositionAt(8), new Position(4, 3)); + assert.deepEqual(pieceTable.getPositionAt(9), new Position(5, 1)); + assert.deepEqual(pieceTable.getPositionAt(11), new Position(6, 1)); + assert.deepEqual(pieceTable.getPositionAt(12), new Position(6, 2)); + assert.deepEqual(pieceTable.getPositionAt(13), new Position(6, 3)); + + assert.equal(pieceTable.getOffsetAt(4, 1), 6); + assert.equal(pieceTable.getOffsetAt(4, 2), 7); + assert.equal(pieceTable.getOffsetAt(4, 3), 8); + assert.equal(pieceTable.getOffsetAt(5, 1), 9); + assert.equal(pieceTable.getOffsetAt(6, 1), 11); + assert.equal(pieceTable.getOffsetAt(6, 2), 12); + assert.equal(pieceTable.getOffsetAt(6, 3), 13); + assertTreeInvariants(pieceTable); + }); + + test('add+delete 1', () => { + let pieceTable = createTextBuffer(['a\nb\nc\nde']); + pieceTable.insert(8, 'fh\ni\njk'); + pieceTable.delete(7, 2); + + assert.equal(pieceTable.getLinesRawContent(), 'a\nb\nc\ndh\ni\njk'); + assert.equal(pieceTable.getLineCount(), 6); + assert.deepEqual(pieceTable.getPositionAt(6), new Position(4, 1)); + assert.deepEqual(pieceTable.getPositionAt(7), new Position(4, 2)); + assert.deepEqual(pieceTable.getPositionAt(8), new Position(4, 3)); + assert.deepEqual(pieceTable.getPositionAt(9), new Position(5, 1)); + assert.deepEqual(pieceTable.getPositionAt(11), new Position(6, 1)); + assert.deepEqual(pieceTable.getPositionAt(12), new Position(6, 2)); + assert.deepEqual(pieceTable.getPositionAt(13), new Position(6, 3)); + + assert.equal(pieceTable.getOffsetAt(4, 1), 6); + assert.equal(pieceTable.getOffsetAt(4, 2), 7); + assert.equal(pieceTable.getOffsetAt(4, 3), 8); + assert.equal(pieceTable.getOffsetAt(5, 1), 9); + assert.equal(pieceTable.getOffsetAt(6, 1), 11); + assert.equal(pieceTable.getOffsetAt(6, 2), 12); + assert.equal(pieceTable.getOffsetAt(6, 3), 13); + assertTreeInvariants(pieceTable); + }); + + test('insert random bug 1: prefixSumComputer.removeValues(start, cnt) cnt is 1 based.', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, ' ZX \n Z\nZ\n YZ\nY\nZXX '); + str = + str.substring(0, 0) + + ' ZX \n Z\nZ\n YZ\nY\nZXX ' + + str.substring(0); + pieceTable.insert(14, 'X ZZ\nYZZYZXXY Y XY\n '); + str = + str.substring(0, 14) + 'X ZZ\nYZZYZXXY Y XY\n ' + str.substring(14); + + assert.equal(pieceTable.getLinesRawContent(), str); + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('insert random bug 2: prefixSumComputer initialize does not do deep copy of UInt32Array.', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'ZYZ\nYY XY\nX \nZ Y \nZ '); + str = + str.substring(0, 0) + 'ZYZ\nYY XY\nX \nZ Y \nZ ' + str.substring(0); + pieceTable.insert(3, 'XXY \n\nY Y YYY ZYXY '); + str = str.substring(0, 3) + 'XXY \n\nY Y YYY ZYXY ' + str.substring(3); + + assert.equal(pieceTable.getLinesRawContent(), str); + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('delete random bug 1: I forgot to update the lineFeedCnt when deletion is on one single piece.', () => { + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'ba\na\nca\nba\ncbab\ncaa '); + pieceTable.insert(13, 'cca\naabb\ncac\nccc\nab '); + pieceTable.delete(5, 8); + pieceTable.delete(30, 2); + pieceTable.insert(24, 'cbbacccbac\nbaaab\n\nc '); + pieceTable.delete(29, 3); + pieceTable.delete(23, 9); + pieceTable.delete(21, 5); + pieceTable.delete(30, 3); + pieceTable.insert(3, 'cb\nac\nc\n\nacc\nbb\nb\nc '); + pieceTable.delete(19, 5); + pieceTable.insert(18, '\nbb\n\nacbc\ncbb\nc\nbb\n '); + pieceTable.insert(65, 'cbccbac\nbc\n\nccabba\n '); + pieceTable.insert(77, 'a\ncacb\n\nac\n\n\n\n\nabab '); + pieceTable.delete(30, 9); + pieceTable.insert(45, 'b\n\nc\nba\n\nbbbba\n\naa\n '); + pieceTable.insert(82, 'ab\nbb\ncabacab\ncbc\na '); + pieceTable.delete(123, 9); + pieceTable.delete(71, 2); + pieceTable.insert(33, 'acaa\nacb\n\naa\n\nc\n\n\n\n '); + + let str = pieceTable.getLinesRawContent(); + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('delete random bug rb tree 1', () => { + let str = ''; + let pieceTable = createTextBuffer([str]); + pieceTable.insert(0, 'YXXZ\n\nYY\n'); + str = str.substring(0, 0) + 'YXXZ\n\nYY\n' + str.substring(0); + pieceTable.delete(0, 5); + str = str.substring(0, 0) + str.substring(0 + 5); + pieceTable.insert(0, 'ZXYY\nX\nZ\n'); + str = str.substring(0, 0) + 'ZXYY\nX\nZ\n' + str.substring(0); + pieceTable.insert(10, '\nXY\nYXYXY'); + str = str.substring(0, 10) + '\nXY\nYXYXY' + str.substring(10); + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('delete random bug rb tree 2', () => { + let str = ''; + let pieceTable = createTextBuffer([str]); + pieceTable.insert(0, 'YXXZ\n\nYY\n'); + str = str.substring(0, 0) + 'YXXZ\n\nYY\n' + str.substring(0); + pieceTable.insert(0, 'ZXYY\nX\nZ\n'); + str = str.substring(0, 0) + 'ZXYY\nX\nZ\n' + str.substring(0); + pieceTable.insert(10, '\nXY\nYXYXY'); + str = str.substring(0, 10) + '\nXY\nYXYXY' + str.substring(10); + pieceTable.insert(8, 'YZXY\nZ\nYX'); + str = str.substring(0, 8) + 'YZXY\nZ\nYX' + str.substring(8); + pieceTable.insert(12, 'XX\nXXYXYZ'); + str = str.substring(0, 12) + 'XX\nXXYXYZ' + str.substring(12); + pieceTable.delete(0, 4); + str = str.substring(0, 0) + str.substring(0 + 4); + + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('delete random bug rb tree 3', () => { + let str = ''; + let pieceTable = createTextBuffer([str]); + pieceTable.insert(0, 'YXXZ\n\nYY\n'); + str = str.substring(0, 0) + 'YXXZ\n\nYY\n' + str.substring(0); + pieceTable.delete(7, 2); + str = str.substring(0, 7) + str.substring(7 + 2); + pieceTable.delete(6, 1); + str = str.substring(0, 6) + str.substring(6 + 1); + pieceTable.delete(0, 5); + str = str.substring(0, 0) + str.substring(0 + 5); + pieceTable.insert(0, 'ZXYY\nX\nZ\n'); + str = str.substring(0, 0) + 'ZXYY\nX\nZ\n' + str.substring(0); + pieceTable.insert(10, '\nXY\nYXYXY'); + str = str.substring(0, 10) + '\nXY\nYXYXY' + str.substring(10); + pieceTable.insert(8, 'YZXY\nZ\nYX'); + str = str.substring(0, 8) + 'YZXY\nZ\nYX' + str.substring(8); + pieceTable.insert(12, 'XX\nXXYXYZ'); + str = str.substring(0, 12) + 'XX\nXXYXYZ' + str.substring(12); + pieceTable.delete(0, 4); + str = str.substring(0, 0) + str.substring(0 + 4); + pieceTable.delete(30, 3); + str = str.substring(0, 30) + str.substring(30 + 3); + + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); +}); + +suite('offset 2 position', () => { + test('random tests bug 1', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'huuyYzUfKOENwGgZLqn '); + str = str.substring(0, 0) + 'huuyYzUfKOENwGgZLqn ' + str.substring(0); + pieceTable.delete(18, 2); + str = str.substring(0, 18) + str.substring(18 + 2); + pieceTable.delete(3, 1); + str = str.substring(0, 3) + str.substring(3 + 1); + pieceTable.delete(12, 4); + str = str.substring(0, 12) + str.substring(12 + 4); + pieceTable.insert(3, 'hMbnVEdTSdhLlPevXKF '); + str = str.substring(0, 3) + 'hMbnVEdTSdhLlPevXKF ' + str.substring(3); + pieceTable.delete(22, 8); + str = str.substring(0, 22) + str.substring(22 + 8); + pieceTable.insert(4, 'S umSnYrqOmOAV\nEbZJ '); + str = str.substring(0, 4) + 'S umSnYrqOmOAV\nEbZJ ' + str.substring(4); + + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); +}); + +suite('get text in range', () => { + test('getContentInRange', () => { + let pieceTable = createTextBuffer(['a\nb\nc\nde']); + pieceTable.insert(8, 'fh\ni\njk'); + pieceTable.delete(7, 2); + // 'a\nb\nc\ndh\ni\njk' + + assert.equal(pieceTable.getValueInRange(new Range(1, 1, 1, 3)), 'a\n'); + assert.equal(pieceTable.getValueInRange(new Range(2, 1, 2, 3)), 'b\n'); + assert.equal(pieceTable.getValueInRange(new Range(3, 1, 3, 3)), 'c\n'); + assert.equal(pieceTable.getValueInRange(new Range(4, 1, 4, 4)), 'dh\n'); + assert.equal(pieceTable.getValueInRange(new Range(5, 1, 5, 3)), 'i\n'); + assert.equal(pieceTable.getValueInRange(new Range(6, 1, 6, 3)), 'jk'); + assertTreeInvariants(pieceTable); + }); + + test('random test value in range', () => { + let str = ''; + let pieceTable = createTextBuffer([str]); + + pieceTable.insert(0, 'ZXXY'); + str = str.substring(0, 0) + 'ZXXY' + str.substring(0); + pieceTable.insert(1, 'XZZY'); + str = str.substring(0, 1) + 'XZZY' + str.substring(1); + pieceTable.insert(5, '\nX\n\n'); + str = str.substring(0, 5) + '\nX\n\n' + str.substring(5); + pieceTable.insert(3, '\nXX\n'); + str = str.substring(0, 3) + '\nXX\n' + str.substring(3); + pieceTable.insert(12, 'YYYX'); + str = str.substring(0, 12) + 'YYYX' + str.substring(12); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + test('random test value in range exception', () => { + let str = ''; + let pieceTable = createTextBuffer([str]); + + pieceTable.insert(0, 'XZ\nZ'); + str = str.substring(0, 0) + 'XZ\nZ' + str.substring(0); + pieceTable.delete(0, 3); + str = str.substring(0, 0) + str.substring(0 + 3); + pieceTable.delete(0, 1); + str = str.substring(0, 0) + str.substring(0 + 1); + pieceTable.insert(0, 'ZYX\n'); + str = str.substring(0, 0) + 'ZYX\n' + str.substring(0); + pieceTable.delete(0, 4); + str = str.substring(0, 0) + str.substring(0 + 4); + + pieceTable.getValueInRange(new Range(1, 1, 1, 1)); + assertTreeInvariants(pieceTable); + }); + + test('random tests bug 1', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'huuyYzUfKOENwGgZLqn '); + str = str.substring(0, 0) + 'huuyYzUfKOENwGgZLqn ' + str.substring(0); + pieceTable.delete(18, 2); + str = str.substring(0, 18) + str.substring(18 + 2); + pieceTable.delete(3, 1); + str = str.substring(0, 3) + str.substring(3 + 1); + pieceTable.delete(12, 4); + str = str.substring(0, 12) + str.substring(12 + 4); + pieceTable.insert(3, 'hMbnVEdTSdhLlPevXKF '); + str = str.substring(0, 3) + 'hMbnVEdTSdhLlPevXKF ' + str.substring(3); + pieceTable.delete(22, 8); + str = str.substring(0, 22) + str.substring(22 + 8); + pieceTable.insert(4, 'S umSnYrqOmOAV\nEbZJ '); + str = str.substring(0, 4) + 'S umSnYrqOmOAV\nEbZJ ' + str.substring(4); + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random tests bug 2', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'xfouRDZwdAHjVXJAMV\n '); + str = str.substring(0, 0) + 'xfouRDZwdAHjVXJAMV\n ' + str.substring(0); + pieceTable.insert(16, 'dBGndxpFZBEAIKykYYx '); + str = str.substring(0, 16) + 'dBGndxpFZBEAIKykYYx ' + str.substring(16); + pieceTable.delete(7, 6); + str = str.substring(0, 7) + str.substring(7 + 6); + pieceTable.delete(9, 7); + str = str.substring(0, 9) + str.substring(9 + 7); + pieceTable.delete(17, 6); + str = str.substring(0, 17) + str.substring(17 + 6); + pieceTable.delete(0, 4); + str = str.substring(0, 0) + str.substring(0 + 4); + pieceTable.insert(9, 'qvEFXCNvVkWgvykahYt '); + str = str.substring(0, 9) + 'qvEFXCNvVkWgvykahYt ' + str.substring(9); + pieceTable.delete(4, 6); + str = str.substring(0, 4) + str.substring(4 + 6); + pieceTable.insert(11, 'OcSChUYT\nzPEBOpsGmR '); + str = + str.substring(0, 11) + 'OcSChUYT\nzPEBOpsGmR ' + str.substring(11); + pieceTable.insert(15, 'KJCozaXTvkE\nxnqAeTz '); + str = + str.substring(0, 15) + 'KJCozaXTvkE\nxnqAeTz ' + str.substring(15); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('get line content', () => { + let pieceTable = createTextBuffer(['1']); + assert.equal(pieceTable.getLineRawContent(1), '1'); + pieceTable.insert(1, '2'); + assert.equal(pieceTable.getLineRawContent(1), '12'); + assertTreeInvariants(pieceTable); + }); + + test('get line content basic', () => { + let pieceTable = createTextBuffer(['1\n2\n3\n4']); + assert.equal(pieceTable.getLineRawContent(1), '1\n'); + assert.equal(pieceTable.getLineRawContent(2), '2\n'); + assert.equal(pieceTable.getLineRawContent(3), '3\n'); + assert.equal(pieceTable.getLineRawContent(4), '4'); + assertTreeInvariants(pieceTable); + }); + + test('get line content after inserts/deletes', () => { + let pieceTable = createTextBuffer(['a\nb\nc\nde']); + pieceTable.insert(8, 'fh\ni\njk'); + pieceTable.delete(7, 2); + // 'a\nb\nc\ndh\ni\njk' + + assert.equal(pieceTable.getLineRawContent(1), 'a\n'); + assert.equal(pieceTable.getLineRawContent(2), 'b\n'); + assert.equal(pieceTable.getLineRawContent(3), 'c\n'); + assert.equal(pieceTable.getLineRawContent(4), 'dh\n'); + assert.equal(pieceTable.getLineRawContent(5), 'i\n'); + assert.equal(pieceTable.getLineRawContent(6), 'jk'); + assertTreeInvariants(pieceTable); + }); + + test('random 1', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + + pieceTable.insert(0, 'J eNnDzQpnlWyjmUu\ny '); + str = str.substring(0, 0) + 'J eNnDzQpnlWyjmUu\ny ' + str.substring(0); + pieceTable.insert(0, 'QPEeRAQmRwlJqtZSWhQ '); + str = str.substring(0, 0) + 'QPEeRAQmRwlJqtZSWhQ ' + str.substring(0); + pieceTable.delete(5, 1); + str = str.substring(0, 5) + str.substring(5 + 1); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random 2', () => { + let str = ''; + let pieceTable = createTextBuffer(['']); + pieceTable.insert(0, 'DZoQ tglPCRHMltejRI '); + str = str.substring(0, 0) + 'DZoQ tglPCRHMltejRI ' + str.substring(0); + pieceTable.insert(10, 'JRXiyYqJ qqdcmbfkKX '); + str = str.substring(0, 10) + 'JRXiyYqJ qqdcmbfkKX ' + str.substring(10); + pieceTable.delete(16, 3); + str = str.substring(0, 16) + str.substring(16 + 3); + pieceTable.delete(25, 1); + str = str.substring(0, 25) + str.substring(25 + 1); + pieceTable.insert(18, 'vH\nNlvfqQJPm\nSFkhMc '); + str = + str.substring(0, 18) + 'vH\nNlvfqQJPm\nSFkhMc ' + str.substring(18); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); +}); + +suite('CRLF', () => { + test('delete CR in CRLF 1', () => { + let pieceTable = createTextBuffer([''], false); + pieceTable.insert(0, 'a\r\nb'); + pieceTable.delete(0, 2); + + assert.equal(pieceTable.getLineCount(), 2); + assertTreeInvariants(pieceTable); + }); + + test('delete CR in CRLF 2', () => { + let pieceTable = createTextBuffer([''], false); + pieceTable.insert(0, 'a\r\nb'); + pieceTable.delete(2, 2); + + assert.equal(pieceTable.getLineCount(), 2); + assertTreeInvariants(pieceTable); + }); + + test('random bug 1', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + pieceTable.insert(0, '\n\n\r\r'); + str = str.substring(0, 0) + '\n\n\r\r' + str.substring(0); + pieceTable.insert(1, '\r\n\r\n'); + str = str.substring(0, 1) + '\r\n\r\n' + str.substring(1); + pieceTable.delete(5, 3); + str = str.substring(0, 5) + str.substring(5 + 3); + pieceTable.delete(2, 3); + str = str.substring(0, 2) + str.substring(2 + 3); + + let lines = str.split(/\r\n|\r|\n/); + assert.equal(pieceTable.getLineCount(), lines.length); + assertTreeInvariants(pieceTable); + }); + test('random bug 2', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, '\n\r\n\r'); + str = str.substring(0, 0) + '\n\r\n\r' + str.substring(0); + pieceTable.insert(2, '\n\r\r\r'); + str = str.substring(0, 2) + '\n\r\r\r' + str.substring(2); + pieceTable.delete(4, 1); + str = str.substring(0, 4) + str.substring(4 + 1); + + let lines = str.split(/\r\n|\r|\n/); + assert.equal(pieceTable.getLineCount(), lines.length); + assertTreeInvariants(pieceTable); + }); + test('random bug 3', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, '\n\n\n\r'); + str = str.substring(0, 0) + '\n\n\n\r' + str.substring(0); + pieceTable.delete(2, 2); + str = str.substring(0, 2) + str.substring(2 + 2); + pieceTable.delete(0, 2); + str = str.substring(0, 0) + str.substring(0 + 2); + pieceTable.insert(0, '\r\r\r\r'); + str = str.substring(0, 0) + '\r\r\r\r' + str.substring(0); + pieceTable.insert(2, '\r\n\r\r'); + str = str.substring(0, 2) + '\r\n\r\r' + str.substring(2); + pieceTable.insert(3, '\r\r\r\n'); + str = str.substring(0, 3) + '\r\r\r\n' + str.substring(3); + + let lines = str.split(/\r\n|\r|\n/); + assert.equal(pieceTable.getLineCount(), lines.length); + assertTreeInvariants(pieceTable); + }); + test('random bug 4', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, '\n\n\n\n'); + str = str.substring(0, 0) + '\n\n\n\n' + str.substring(0); + pieceTable.delete(3, 1); + str = str.substring(0, 3) + str.substring(3 + 1); + pieceTable.insert(1, '\r\r\r\r'); + str = str.substring(0, 1) + '\r\r\r\r' + str.substring(1); + pieceTable.insert(6, '\r\n\n\r'); + str = str.substring(0, 6) + '\r\n\n\r' + str.substring(6); + pieceTable.delete(5, 3); + str = str.substring(0, 5) + str.substring(5 + 3); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + test('random bug 5', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, '\n\n\n\n'); + str = str.substring(0, 0) + '\n\n\n\n' + str.substring(0); + pieceTable.delete(3, 1); + str = str.substring(0, 3) + str.substring(3 + 1); + pieceTable.insert(0, '\n\r\r\n'); + str = str.substring(0, 0) + '\n\r\r\n' + str.substring(0); + pieceTable.insert(4, '\n\r\r\n'); + str = str.substring(0, 4) + '\n\r\r\n' + str.substring(4); + pieceTable.delete(4, 3); + str = str.substring(0, 4) + str.substring(4 + 3); + pieceTable.insert(5, '\r\r\n\r'); + str = str.substring(0, 5) + '\r\r\n\r' + str.substring(5); + pieceTable.insert(12, '\n\n\n\r'); + str = str.substring(0, 12) + '\n\n\n\r' + str.substring(12); + pieceTable.insert(5, '\r\r\r\n'); + str = str.substring(0, 5) + '\r\r\r\n' + str.substring(5); + pieceTable.insert(20, '\n\n\r\n'); + str = str.substring(0, 20) + '\n\n\r\n' + str.substring(20); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + test('random bug 6', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, '\n\r\r\n'); + str = str.substring(0, 0) + '\n\r\r\n' + str.substring(0); + pieceTable.insert(4, '\r\n\n\r'); + str = str.substring(0, 4) + '\r\n\n\r' + str.substring(4); + pieceTable.insert(3, '\r\n\n\n'); + str = str.substring(0, 3) + '\r\n\n\n' + str.substring(3); + pieceTable.delete(4, 8); + str = str.substring(0, 4) + str.substring(4 + 8); + pieceTable.insert(4, '\r\n\n\r'); + str = str.substring(0, 4) + '\r\n\n\r' + str.substring(4); + pieceTable.insert(0, '\r\n\n\r'); + str = str.substring(0, 0) + '\r\n\n\r' + str.substring(0); + pieceTable.delete(4, 0); + str = str.substring(0, 4) + str.substring(4 + 0); + pieceTable.delete(8, 4); + str = str.substring(0, 8) + str.substring(8 + 4); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + test('random bug 8', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, '\r\n\n\r'); + str = str.substring(0, 0) + '\r\n\n\r' + str.substring(0); + pieceTable.delete(1, 0); + str = str.substring(0, 1) + str.substring(1 + 0); + pieceTable.insert(3, '\n\n\n\r'); + str = str.substring(0, 3) + '\n\n\n\r' + str.substring(3); + pieceTable.insert(7, '\n\n\r\n'); + str = str.substring(0, 7) + '\n\n\r\n' + str.substring(7); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + test('random bug 7', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, '\r\r\n\n'); + str = str.substring(0, 0) + '\r\r\n\n' + str.substring(0); + pieceTable.insert(4, '\r\n\n\r'); + str = str.substring(0, 4) + '\r\n\n\r' + str.substring(4); + pieceTable.insert(7, '\n\r\r\r'); + str = str.substring(0, 7) + '\n\r\r\r' + str.substring(7); + pieceTable.insert(11, '\n\n\r\n'); + str = str.substring(0, 11) + '\n\n\r\n' + str.substring(11); + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random bug 10', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, 'qneW'); + str = str.substring(0, 0) + 'qneW' + str.substring(0); + pieceTable.insert(0, 'YhIl'); + str = str.substring(0, 0) + 'YhIl' + str.substring(0); + pieceTable.insert(0, 'qdsm'); + str = str.substring(0, 0) + 'qdsm' + str.substring(0); + pieceTable.delete(7, 0); + str = str.substring(0, 7) + str.substring(7 + 0); + pieceTable.insert(12, 'iiPv'); + str = str.substring(0, 12) + 'iiPv' + str.substring(12); + pieceTable.insert(9, 'V\rSA'); + str = str.substring(0, 9) + 'V\rSA' + str.substring(9); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random bug 9', () => { + let str = ''; + let pieceTable = createTextBuffer([''], false); + + pieceTable.insert(0, '\n\n\n\n'); + str = str.substring(0, 0) + '\n\n\n\n' + str.substring(0); + pieceTable.insert(3, '\n\r\n\r'); + str = str.substring(0, 3) + '\n\r\n\r' + str.substring(3); + pieceTable.insert(2, '\n\r\n\n'); + str = str.substring(0, 2) + '\n\r\n\n' + str.substring(2); + pieceTable.insert(0, '\n\n\r\r'); + str = str.substring(0, 0) + '\n\n\r\r' + str.substring(0); + pieceTable.insert(3, '\r\r\r\r'); + str = str.substring(0, 3) + '\r\r\r\r' + str.substring(3); + pieceTable.insert(3, '\n\n\r\r'); + str = str.substring(0, 3) + '\n\n\r\r' + str.substring(3); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); +}); + +suite('centralized lineStarts with CRLF', () => { + test('delete CR in CRLF 1', () => { + let pieceTable = createTextBuffer(['a\r\nb'], false); + pieceTable.delete(2, 2); + assert.equal(pieceTable.getLineCount(), 2); + assertTreeInvariants(pieceTable); + }); + test('delete CR in CRLF 2', () => { + let pieceTable = createTextBuffer(['a\r\nb']); + pieceTable.delete(0, 2); + + assert.equal(pieceTable.getLineCount(), 2); + assertTreeInvariants(pieceTable); + }); + + test('random bug 1', () => { + let str = '\n\n\r\r'; + let pieceTable = createTextBuffer(['\n\n\r\r'], false); + pieceTable.insert(1, '\r\n\r\n'); + str = str.substring(0, 1) + '\r\n\r\n' + str.substring(1); + pieceTable.delete(5, 3); + str = str.substring(0, 5) + str.substring(5 + 3); + pieceTable.delete(2, 3); + str = str.substring(0, 2) + str.substring(2 + 3); + + let lines = str.split(/\r\n|\r|\n/); + assert.equal(pieceTable.getLineCount(), lines.length); + assertTreeInvariants(pieceTable); + }); + test('random bug 2', () => { + let str = '\n\r\n\r'; + let pieceTable = createTextBuffer(['\n\r\n\r'], false); + + pieceTable.insert(2, '\n\r\r\r'); + str = str.substring(0, 2) + '\n\r\r\r' + str.substring(2); + pieceTable.delete(4, 1); + str = str.substring(0, 4) + str.substring(4 + 1); + + let lines = str.split(/\r\n|\r|\n/); + assert.equal(pieceTable.getLineCount(), lines.length); + assertTreeInvariants(pieceTable); + }); + + test('random bug 3', () => { + let str = '\n\n\n\r'; + let pieceTable = createTextBuffer(['\n\n\n\r'], false); + + pieceTable.delete(2, 2); + str = str.substring(0, 2) + str.substring(2 + 2); + pieceTable.delete(0, 2); + str = str.substring(0, 0) + str.substring(0 + 2); + pieceTable.insert(0, '\r\r\r\r'); + str = str.substring(0, 0) + '\r\r\r\r' + str.substring(0); + pieceTable.insert(2, '\r\n\r\r'); + str = str.substring(0, 2) + '\r\n\r\r' + str.substring(2); + pieceTable.insert(3, '\r\r\r\n'); + str = str.substring(0, 3) + '\r\r\r\n' + str.substring(3); + + let lines = str.split(/\r\n|\r|\n/); + assert.equal(pieceTable.getLineCount(), lines.length); + assertTreeInvariants(pieceTable); + }); + + test('random bug 4', () => { + let str = '\n\n\n\n'; + let pieceTable = createTextBuffer(['\n\n\n\n'], false); + + pieceTable.delete(3, 1); + str = str.substring(0, 3) + str.substring(3 + 1); + pieceTable.insert(1, '\r\r\r\r'); + str = str.substring(0, 1) + '\r\r\r\r' + str.substring(1); + pieceTable.insert(6, '\r\n\n\r'); + str = str.substring(0, 6) + '\r\n\n\r' + str.substring(6); + pieceTable.delete(5, 3); + str = str.substring(0, 5) + str.substring(5 + 3); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random bug 5', () => { + let str = '\n\n\n\n'; + let pieceTable = createTextBuffer(['\n\n\n\n'], false); + + pieceTable.delete(3, 1); + str = str.substring(0, 3) + str.substring(3 + 1); + pieceTable.insert(0, '\n\r\r\n'); + str = str.substring(0, 0) + '\n\r\r\n' + str.substring(0); + pieceTable.insert(4, '\n\r\r\n'); + str = str.substring(0, 4) + '\n\r\r\n' + str.substring(4); + pieceTable.delete(4, 3); + str = str.substring(0, 4) + str.substring(4 + 3); + pieceTable.insert(5, '\r\r\n\r'); + str = str.substring(0, 5) + '\r\r\n\r' + str.substring(5); + pieceTable.insert(12, '\n\n\n\r'); + str = str.substring(0, 12) + '\n\n\n\r' + str.substring(12); + pieceTable.insert(5, '\r\r\r\n'); + str = str.substring(0, 5) + '\r\r\r\n' + str.substring(5); + pieceTable.insert(20, '\n\n\r\n'); + str = str.substring(0, 20) + '\n\n\r\n' + str.substring(20); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random bug 6', () => { + let str = '\n\r\r\n'; + let pieceTable = createTextBuffer(['\n\r\r\n'], false); + + pieceTable.insert(4, '\r\n\n\r'); + str = str.substring(0, 4) + '\r\n\n\r' + str.substring(4); + pieceTable.insert(3, '\r\n\n\n'); + str = str.substring(0, 3) + '\r\n\n\n' + str.substring(3); + pieceTable.delete(4, 8); + str = str.substring(0, 4) + str.substring(4 + 8); + pieceTable.insert(4, '\r\n\n\r'); + str = str.substring(0, 4) + '\r\n\n\r' + str.substring(4); + pieceTable.insert(0, '\r\n\n\r'); + str = str.substring(0, 0) + '\r\n\n\r' + str.substring(0); + pieceTable.delete(4, 0); + str = str.substring(0, 4) + str.substring(4 + 0); + pieceTable.delete(8, 4); + str = str.substring(0, 8) + str.substring(8 + 4); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random bug 7', () => { + let str = '\r\n\n\r'; + let pieceTable = createTextBuffer(['\r\n\n\r'], false); + + pieceTable.delete(1, 0); + str = str.substring(0, 1) + str.substring(1 + 0); + pieceTable.insert(3, '\n\n\n\r'); + str = str.substring(0, 3) + '\n\n\n\r' + str.substring(3); + pieceTable.insert(7, '\n\n\r\n'); + str = str.substring(0, 7) + '\n\n\r\n' + str.substring(7); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random bug 8', () => { + let str = '\r\r\n\n'; + let pieceTable = createTextBuffer(['\r\r\n\n'], false); + + pieceTable.insert(4, '\r\n\n\r'); + str = str.substring(0, 4) + '\r\n\n\r' + str.substring(4); + pieceTable.insert(7, '\n\r\r\r'); + str = str.substring(0, 7) + '\n\r\r\r' + str.substring(7); + pieceTable.insert(11, '\n\n\r\n'); + str = str.substring(0, 11) + '\n\n\r\n' + str.substring(11); + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random bug 9', () => { + let str = 'qneW'; + let pieceTable = createTextBuffer(['qneW'], false); + + pieceTable.insert(0, 'YhIl'); + str = str.substring(0, 0) + 'YhIl' + str.substring(0); + pieceTable.insert(0, 'qdsm'); + str = str.substring(0, 0) + 'qdsm' + str.substring(0); + pieceTable.delete(7, 0); + str = str.substring(0, 7) + str.substring(7 + 0); + pieceTable.insert(12, 'iiPv'); + str = str.substring(0, 12) + 'iiPv' + str.substring(12); + pieceTable.insert(9, 'V\rSA'); + str = str.substring(0, 9) + 'V\rSA' + str.substring(9); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random bug 10', () => { + let str = '\n\n\n\n'; + let pieceTable = createTextBuffer(['\n\n\n\n'], false); + + pieceTable.insert(3, '\n\r\n\r'); + str = str.substring(0, 3) + '\n\r\n\r' + str.substring(3); + pieceTable.insert(2, '\n\r\n\n'); + str = str.substring(0, 2) + '\n\r\n\n' + str.substring(2); + pieceTable.insert(0, '\n\n\r\r'); + str = str.substring(0, 0) + '\n\n\r\r' + str.substring(0); + pieceTable.insert(3, '\r\r\r\r'); + str = str.substring(0, 3) + '\r\r\r\r' + str.substring(3); + pieceTable.insert(3, '\n\n\r\r'); + str = str.substring(0, 3) + '\n\n\r\r' + str.substring(3); + + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random chunk bug 1', () => { + let pieceTable = createTextBuffer(['\n\r\r\n\n\n\r\n\r'], false); + let str = '\n\r\r\n\n\n\r\n\r'; + pieceTable.delete(0, 2); + str = str.substring(0, 0) + str.substring(0 + 2); + pieceTable.insert(1, '\r\r\n\n'); + str = str.substring(0, 1) + '\r\r\n\n' + str.substring(1); + pieceTable.insert(7, '\r\r\r\r'); + str = str.substring(0, 7) + '\r\r\r\r' + str.substring(7); + + assert.equal(pieceTable.getLinesRawContent(), str); + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random chunk bug 2', () => { + let pieceTable = createTextBuffer([ + '\n\r\n\n\n\r\n\r\n\r\r\n\n\n\r\r\n\r\n' + ], false); + let str = '\n\r\n\n\n\r\n\r\n\r\r\n\n\n\r\r\n\r\n'; + pieceTable.insert(16, '\r\n\r\r'); + str = str.substring(0, 16) + '\r\n\r\r' + str.substring(16); + pieceTable.insert(13, '\n\n\r\r'); + str = str.substring(0, 13) + '\n\n\r\r' + str.substring(13); + pieceTable.insert(19, '\n\n\r\n'); + str = str.substring(0, 19) + '\n\n\r\n' + str.substring(19); + pieceTable.delete(5, 0); + str = str.substring(0, 5) + str.substring(5 + 0); + pieceTable.delete(11, 2); + str = str.substring(0, 11) + str.substring(11 + 2); + + assert.equal(pieceTable.getLinesRawContent(), str); + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random chunk bug 3', () => { + let pieceTable = createTextBuffer(['\r\n\n\n\n\n\n\r\n'], false); + let str = '\r\n\n\n\n\n\n\r\n'; + pieceTable.insert(4, '\n\n\r\n\r\r\n\n\r'); + str = str.substring(0, 4) + '\n\n\r\n\r\r\n\n\r' + str.substring(4); + pieceTable.delete(4, 4); + str = str.substring(0, 4) + str.substring(4 + 4); + pieceTable.insert(11, '\r\n\r\n\n\r\r\n\n'); + str = str.substring(0, 11) + '\r\n\r\n\n\r\r\n\n' + str.substring(11); + pieceTable.delete(1, 2); + str = str.substring(0, 1) + str.substring(1 + 2); + + assert.equal(pieceTable.getLinesRawContent(), str); + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random chunk bug 4', () => { + let pieceTable = createTextBuffer(['\n\r\n\r'], false); + let str = '\n\r\n\r'; + pieceTable.insert(4, '\n\n\r\n'); + str = str.substring(0, 4) + '\n\n\r\n' + str.substring(4); + pieceTable.insert(3, '\r\n\n\n'); + str = str.substring(0, 3) + '\r\n\n\n' + str.substring(3); + + assert.equal(pieceTable.getLinesRawContent(), str); + testLineStarts(str, pieceTable); + assertTreeInvariants(pieceTable); + }); +}); + +suite('random is unsupervised', () => { + test('random insert delete', () => { + let str = ''; + let pieceTable = createTextBuffer([str], false); + + for (let i = 0; i < 1000; i++) { + if (Math.random() < 0.6) { + // insert + let text = randomStr(100); + let pos = randomInt(str.length + 1); + pieceTable.insert(pos, text); + str = str.substring(0, pos) + text + str.substring(pos); + } else { + // delete + let pos = randomInt(str.length); + let length = Math.min( + str.length - pos, + Math.floor(Math.random() * 10) + ); + pieceTable.delete(pos, length); + str = str.substring(0, pos) + str.substring(pos + length); + } + } + + assert.equal(pieceTable.getLinesRawContent(), str); + + testLineStarts(str, pieceTable); + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); + + test('random chunks', () => { + let chunks = []; + for (let i = 0; i < 5; i++) { + chunks.push(randomStr(1000)); + } + + let pieceTable = createTextBuffer(chunks, false); + let str = chunks.join(''); + + for (let i = 0; i < 1000; i++) { + if (Math.random() < 0.6) { + // insert + let text = randomStr(100); + let pos = randomInt(str.length + 1); + pieceTable.insert(pos, text); + str = str.substring(0, pos) + text + str.substring(pos); + } else { + // delete + let pos = randomInt(str.length); + let length = Math.min( + str.length - pos, + Math.floor(Math.random() * 10) + ); + pieceTable.delete(pos, length); + str = str.substring(0, pos) + str.substring(pos + length); + } + } + + assert.equal(pieceTable.getLinesRawContent(), str); + testLineStarts(str, pieceTable); + testLinesContent(str, pieceTable); + assertTreeInvariants(pieceTable); + }); +}); + +suite('buffer api', () => { + test('equal', () => { + let a = createTextBuffer(['abc']); + let b = createTextBuffer(['ab', 'c']); + let c = createTextBuffer(['abd']); + let d = createTextBuffer(['abcd']); + + assert(a.equal(b)); + assert(!a.equal(c)); + assert(!a.equal(d)); + }); +}); \ No newline at end of file diff --git a/src/vs/editor/test/common/model/textModel.test.ts b/src/vs/editor/test/common/model/textModel.test.ts index 323ca9886b3..a99bde0f438 100644 --- a/src/vs/editor/test/common/model/textModel.test.ts +++ b/src/vs/editor/test/common/model/textModel.test.ts @@ -9,6 +9,7 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel'; import { DefaultEndOfLine } from 'vs/editor/common/model'; +import { UTF8_BOM_CHARACTER } from 'vs/base/common/strings'; function testGuessIndentation(defaultInsertSpaces: boolean, defaultTabSize: number, expectedInsertSpaces: boolean, expectedTabSize: number, text: string[], msg?: string): void { var m = TextModel.createFromString( @@ -763,6 +764,66 @@ suite('Editor Model - TextModel', () => { model.dispose(); }); + + test('getLineFirstNonWhitespaceColumn', () => { + let model = TextModel.createFromString([ + 'asd', + ' asd', + '\tasd', + ' asd', + '\t\tasd', + ' ', + ' ', + '\t', + '\t\t', + ' \tasd', + '', + '' + ].join('\n')); + + assert.equal(model.getLineFirstNonWhitespaceColumn(1), 1, '1'); + assert.equal(model.getLineFirstNonWhitespaceColumn(2), 2, '2'); + assert.equal(model.getLineFirstNonWhitespaceColumn(3), 2, '3'); + assert.equal(model.getLineFirstNonWhitespaceColumn(4), 3, '4'); + assert.equal(model.getLineFirstNonWhitespaceColumn(5), 3, '5'); + assert.equal(model.getLineFirstNonWhitespaceColumn(6), 0, '6'); + assert.equal(model.getLineFirstNonWhitespaceColumn(7), 0, '7'); + assert.equal(model.getLineFirstNonWhitespaceColumn(8), 0, '8'); + assert.equal(model.getLineFirstNonWhitespaceColumn(9), 0, '9'); + assert.equal(model.getLineFirstNonWhitespaceColumn(10), 4, '10'); + assert.equal(model.getLineFirstNonWhitespaceColumn(11), 0, '11'); + assert.equal(model.getLineFirstNonWhitespaceColumn(12), 0, '12'); + }); + + test('getLineLastNonWhitespaceColumn', () => { + let model = TextModel.createFromString([ + 'asd', + 'asd ', + 'asd\t', + 'asd ', + 'asd\t\t', + ' ', + ' ', + '\t', + '\t\t', + 'asd \t', + '', + '' + ].join('\n')); + + assert.equal(model.getLineLastNonWhitespaceColumn(1), 4, '1'); + assert.equal(model.getLineLastNonWhitespaceColumn(2), 4, '2'); + assert.equal(model.getLineLastNonWhitespaceColumn(3), 4, '3'); + assert.equal(model.getLineLastNonWhitespaceColumn(4), 4, '4'); + assert.equal(model.getLineLastNonWhitespaceColumn(5), 4, '5'); + assert.equal(model.getLineLastNonWhitespaceColumn(6), 0, '6'); + assert.equal(model.getLineLastNonWhitespaceColumn(7), 0, '7'); + assert.equal(model.getLineLastNonWhitespaceColumn(8), 0, '8'); + assert.equal(model.getLineLastNonWhitespaceColumn(9), 0, '9'); + assert.equal(model.getLineLastNonWhitespaceColumn(10), 4, '10'); + assert.equal(model.getLineLastNonWhitespaceColumn(11), 0, '11'); + assert.equal(model.getLineLastNonWhitespaceColumn(12), 0, '12'); + }); }); suite('TextModel.mightContainRTL', () => { @@ -792,3 +853,60 @@ suite('TextModel.mightContainRTL', () => { }); }); + +suite('TextModel.createSnapshot', () => { + + test('empty file', () => { + let model = TextModel.createFromString(''); + let snapshot = model.createSnapshot(); + assert.equal(snapshot.read(), null); + model.dispose(); + }); + + test('file with BOM', () => { + let model = TextModel.createFromString(UTF8_BOM_CHARACTER + 'Hello'); + assert.equal(model.getLineContent(1), 'Hello'); + let snapshot = model.createSnapshot(true); + assert.equal(snapshot.read(), UTF8_BOM_CHARACTER + 'Hello'); + assert.equal(snapshot.read(), null); + model.dispose(); + }); + + test('regular file', () => { + let model = TextModel.createFromString('My First Line\n\t\tMy Second Line\n Third Line\n\n1'); + let snapshot = model.createSnapshot(); + assert.equal(snapshot.read(), 'My First Line\n\t\tMy Second Line\n Third Line\n\n1'); + assert.equal(snapshot.read(), null); + model.dispose(); + }); + + test('large file', () => { + let lines: string[] = []; + for (let i = 0; i < 1000; i++) { + lines[i] = 'Just some text that is a bit long such that it can consume some memory'; + } + const text = lines.join('\n'); + + let model = TextModel.createFromString(text); + let snapshot = model.createSnapshot(); + let actual = ''; + + // 70999 length => at most 2 read calls are necessary + let tmp1 = snapshot.read(); + assert.ok(tmp1); + actual += tmp1; + + let tmp2 = snapshot.read(); + if (tmp2 === null) { + // all good + } else { + actual += tmp2; + assert.equal(snapshot.read(), null); + } + + assert.equal(actual, text); + + model.dispose(); + }); + +}); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index ea436add39c..3af00b08fe9 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4487,6 +4487,7 @@ declare module monaco.languages { export enum SuggestTriggerKind { Invoke = 0, TriggerCharacter = 1, + TriggerForIncompleteCompletions = 2, } export interface CodeAction { diff --git a/src/vs/platform/editor/common/editor.ts b/src/vs/platform/editor/common/editor.ts index 98d63a1977b..5e1f5db95db 100644 --- a/src/vs/platform/editor/common/editor.ts +++ b/src/vs/platform/editor/common/editor.ts @@ -269,12 +269,16 @@ export interface IEditorOptions { forceOpen?: boolean; /** - * Will reveal the editor if it is already opened and visible in any of the opened editor groups. + * Will reveal the editor if it is already opened and visible in any of the opened editor groups. Note + * that this option is just a hint that might be ignored if the user wants to open an editor explicitly + * to the side of another one. */ revealIfVisible?: boolean; /** - * Will reveal the editor if it is already opened (even when not visible) in any of the opened editor groups. + * Will reveal the editor if it is already opened (even when not visible) in any of the opened editor groups. Note + * that this option is just a hint that might be ignored if the user wants to open an editor explicitly + * to the side of another one. */ revealIfOpened?: boolean; diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 7c6ed230677..3296b628490 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -9,9 +9,11 @@ import { LogLevel } from 'vs/platform/log/common/log'; export interface ParsedArgs { [arg: string]: any; _: string[]; + _urls?: string[]; help?: boolean; version?: boolean; status?: boolean; + issue?: boolean; wait?: boolean; waitMarkerFilePath?: string; diff?: boolean; @@ -42,10 +44,11 @@ export interface ParsedArgs { 'install-extension'?: string | string[]; 'uninstall-extension'?: string | string[]; 'enable-proposed-api'?: string | string[]; - 'open-url'?: string | string[]; + 'open-url'?: boolean; 'skip-getting-started'?: boolean; 'skip-release-notes'?: boolean; 'sticky-quickopen'?: boolean; + 'disable-restore-windows'?: boolean; 'disable-telemetry'?: boolean; 'export-default-configuration'?: string; 'install-source'?: string; @@ -54,6 +57,7 @@ export interface ParsedArgs { 'skip-add-to-recently-opened'?: boolean; 'file-write'?: boolean; 'file-chmod'?: boolean; + 'upload-logs'?: boolean; } export const IEnvironmentService = createDecorator('environmentService'); diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 627e7cdc920..fade5e83e1a 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -26,7 +26,6 @@ const options: minimist.Opts = { 'debugBrkPluginHost', 'debugSearch', 'debugBrkSearch', - 'open-url', 'enable-proposed-api', 'export-default-configuration', 'install-source' @@ -41,6 +40,7 @@ const options: minimist.Opts = { 'new-window', 'unity-launch', 'reuse-window', + 'open-url', 'performance', 'prof-startup', 'verbose', @@ -49,16 +49,19 @@ const options: minimist.Opts = { 'list-extensions', 'show-versions', 'nolazy', + 'issue', 'skip-getting-started', 'skip-release-notes', 'sticky-quickopen', + 'disable-restore-windows', 'disable-telemetry', 'disable-updates', 'disable-crash-reporter', 'skip-add-to-recently-opened', 'status', 'file-write', - 'file-chmod' + 'file-chmod', + 'upload-logs' ], alias: { add: 'a', @@ -71,6 +74,7 @@ const options: minimist.Opts = { 'new-window': 'n', 'reuse-window': 'r', performance: 'p', + 'issue': 'i', 'disable-extensions': 'disableExtensions', 'extensions-dir': 'extensionHomePath', 'debugPluginHost': 'inspect-extensions', @@ -162,7 +166,9 @@ const troubleshootingHelp: { [name: string]: string; } = { '--disable-extensions': localize('disableExtensions', "Disable all installed extensions."), '--inspect-extensions': localize('inspect-extensions', "Allow debugging and profiling of extensions. Check the developer tools for the connection uri."), '--inspect-brk-extensions': localize('inspect-brk-extensions', "Allow debugging and profiling of extensions with the extension host being paused after start. Check the developer tools for the connection uri."), - '--disable-gpu': localize('disableGPU', "Disable GPU hardware acceleration.") + '--disable-gpu': localize('disableGPU', "Disable GPU hardware acceleration."), + '--upload-logs': localize('uploadLogs', "Uploads logs from current session to a secure endpoint."), + '-i, --issue': localize('issue', "Report an issue."), }; export function formatOptions(options: { [name: string]: string; }, columns: number): string { diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index b5e01b791cc..f50aa30396f 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -184,6 +184,7 @@ export class EnvironmentService implements IEnvironmentService { get performance(): boolean { return this._args.performance; } get status(): boolean { return this._args.status; } + get issue(): boolean { return this._args.issue; } @memoize get mainIPCHandle(): string { return getIPCHandle(this.userDataPath, 'main'); } diff --git a/src/vs/platform/extensionManagement/common/extensionEnablementService.ts b/src/vs/platform/extensionManagement/common/extensionEnablementService.ts index 1f475504c98..990894ef862 100644 --- a/src/vs/platform/extensionManagement/common/extensionEnablementService.ts +++ b/src/vs/platform/extensionManagement/common/extensionEnablementService.ts @@ -8,7 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { distinct, coalesce } from 'vs/base/common/arrays'; import Event, { Emitter } from 'vs/base/common/event'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { IExtensionManagementService, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionIdentifier, EnablementState } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, DidUninstallExtensionEvent, IExtensionEnablementService, IExtensionIdentifier, EnablementState, ILocalExtension, isIExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement'; import { adoptToGalleryExtensionId, getIdFromLocalExtensionId, areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; @@ -77,13 +77,19 @@ export class ExtensionEnablementService implements IExtensionEnablementService { return EnablementState.Enabled; } - canChangeEnablement(): boolean { - return !this.environmentService.disableExtensions; + canChangeEnablement(extension: ILocalExtension): boolean { + return !this.environmentService.disableExtensions && !(extension.manifest && extension.manifest.contributes && extension.manifest.contributes.locales && extension.manifest.contributes.locales.length); } - setEnablement(identifier: IExtensionIdentifier, newState: EnablementState): TPromise { - if (this.environmentService.disableExtensions) { - return TPromise.wrap(false); + setEnablement(arg: ILocalExtension | IExtensionIdentifier, newState: EnablementState): TPromise { + let identifier; + if (isIExtensionIdentifier(arg)) { + identifier = arg; + } else { + if (!this.canChangeEnablement(arg)) { + return TPromise.wrap(false); + } + identifier = { id: getIdFromLocalExtensionId(arg.identifier.id), uuid: arg.identifier.uuid }; } const workspace = newState === EnablementState.WorkspaceDisabled || newState === EnablementState.WorkspaceEnabled; diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index ca36e02bff8..28f19aa05df 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -85,6 +85,11 @@ export interface IColor { defaults: { light: string, dark: string, highContrast: string }; } +export interface ILocale { + locale: string; + path: string; +} + export interface IExtensionContributions { commands?: ICommand[]; configuration?: IConfiguration; @@ -98,7 +103,8 @@ export interface IExtensionContributions { themes?: ITheme[]; iconThemes?: ITheme[]; views?: { [location: string]: IView[] }; - colors: IColor[]; + colors?: IColor[]; + locales?: ILocale[]; } export interface IExtensionManifest { @@ -136,6 +142,13 @@ export interface IGalleryExtensionAssets { repository: IGalleryExtensionAsset; } +export function isIExtensionIdentifier(thing: any): thing is IExtensionIdentifier { + return thing + && typeof thing === 'object' + && typeof thing.id === 'string' + && (!thing.uuid || typeof thing.uuid === 'string'); +} + export interface IExtensionIdentifier { id: string; uuid?: string; @@ -295,7 +308,7 @@ export interface IExtensionEnablementService { /** * Returns `true` if the enablement can be changed. */ - canChangeEnablement(): boolean; + canChangeEnablement(extension: ILocalExtension): boolean; /** * Returns `true` if the given extension identifier is enabled. @@ -311,6 +324,10 @@ export interface IExtensionEnablementService { * * Throws error if enablement is requested for workspace and there is no workspace */ + setEnablement(extension: ILocalExtension, state: EnablementState): TPromise; + /** + * TODO: @Sandy. Use setEnablement(extension: ILocalExtension, state: EnablementState): TPromise. Use one model for extension management and runtime + */ setEnablement(identifier: IExtensionIdentifier, state: EnablementState): TPromise; migrateToIdentifiers(installed: IExtensionIdentifier[]): void; diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index f3752b10161..84ab67e438e 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -10,7 +10,7 @@ import * as path from 'path'; import * as pfs from 'vs/base/node/pfs'; import * as errors from 'vs/base/common/errors'; import { assign } from 'vs/base/common/objects'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { flatten, distinct } from 'vs/base/common/arrays'; import { extract, buffer } from 'vs/base/node/zip'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -45,6 +45,8 @@ const INSTALL_ERROR_GALLERY = 'gallery'; const INSTALL_ERROR_LOCAL = 'local'; const INSTALL_ERROR_EXTRACTING = 'extracting'; const INSTALL_ERROR_DELETING = 'deleting'; +const INSTALL_ERROR_READING_EXTENSION_FROM_DISK = 'readingExtension'; +const INSTALL_ERROR_SAVING_METADATA = 'savingMetadata'; const INSTALL_ERROR_UNKNOWN = 'unknown'; export class ExtensionManagementError extends Error { @@ -105,14 +107,16 @@ export class ExtensionManagementService implements IExtensionManagementService { private uninstalledFileLimiter: Limiter; private disposables: IDisposable[] = []; - private _onInstallExtension = new Emitter(); - onInstallExtension: Event = this._onInstallExtension.event; + private readonly _onInstallExtension = new Emitter(); + readonly onInstallExtension: Event = this._onInstallExtension.event; - private _onDidInstallExtension = new Emitter(); - onDidInstallExtension: Event = this._onDidInstallExtension.event; + private readonly _onDidInstallExtension = new Emitter(); + readonly onDidInstallExtension: Event = this._onDidInstallExtension.event; - private _onUninstallExtension = new Emitter(); - onUninstallExtension: Event = this._onUninstallExtension.event; + private readonly _onUninstallExtension = new Emitter(); + readonly onUninstallExtension: Event = this._onUninstallExtension.event; + + private readonly installingExtensions: Map> = new Map>(); private _onDidUninstallExtension = new Emitter(); onDidUninstallExtension: Event = this._onDidUninstallExtension.event; @@ -127,6 +131,7 @@ export class ExtensionManagementService implements IExtensionManagementService { this.uninstalledPath = path.join(this.extensionsPath, '.obsolete'); this.userDataPath = environmentService.userDataPath; this.uninstalledFileLimiter = new Limiter(1); + this.disposables.push(toDisposable(() => this.installingExtensions.clear())); } private deleteExtensionsManifestCache(): void { @@ -257,9 +262,18 @@ export class ExtensionManagementService implements IExtensionManagementService { } private downloadAndInstallExtensions(extensions: IGalleryExtension[]): TPromise { - return TPromise.join(extensions.map(extensionToInstall => this.downloadInstallableExtension(extensionToInstall) - .then(installableExtension => this.installExtension(installableExtension)) - )).then(null, errors => this.rollback(extensions).then(() => TPromise.wrapError(errors), () => TPromise.wrapError(errors))); + return TPromise.join(extensions.map(extensionToInstall => this.downloadAndInstallExtension(extensionToInstall))) + .then(null, errors => this.rollback(extensions).then(() => TPromise.wrapError(errors), () => TPromise.wrapError(errors))); + } + + private downloadAndInstallExtension(extension: IGalleryExtension): TPromise { + let installingExtension = this.installingExtensions.get(extension.identifier.id); + if (!installingExtension) { + installingExtension = this.downloadInstallableExtension(extension).then(installableExtension => this.installExtension(installableExtension)); + this.installingExtensions.set(extension.identifier.id, installingExtension); + installingExtension.then(local => { this.installingExtensions.delete(extension.identifier.id); return local; }, e => { this.installingExtensions.delete(extension.identifier.id); return TPromise.wrapError(e); }); + } + return installingExtension; } private downloadInstallableExtension(extension: IGalleryExtension): TPromise { @@ -396,7 +410,7 @@ export class ExtensionManagementService implements IExtensionManagementService { () => { this.logService.info(`Extracted extension to ${extensionPath}:`, id); return TPromise.join([readManifest(extensionPath), pfs.readdir(extensionPath)]) - .then(null, e => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_LOCAL))); + .then(null, e => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_READING_EXTENSION_FROM_DISK))); }, e => TPromise.wrapError(new ExtensionManagementError(e.message, INSTALL_ERROR_EXTRACTING))) .then(([{ manifest }, children]) => { @@ -414,7 +428,7 @@ export class ExtensionManagementService implements IExtensionManagementService { .then(() => { this.logService.info(`Updated metadata of the extension:`, id); return local; - }, e => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_LOCAL))); + }, e => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_SAVING_METADATA))); }); }, e => TPromise.wrapError(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_DELETING))); } diff --git a/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts b/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts index 93bfae02c16..4ccb6691229 100644 --- a/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts +++ b/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; -import { IExtensionManagementService, IExtensionEnablementService, DidUninstallExtensionEvent, EnablementState } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, IExtensionEnablementService, DidUninstallExtensionEvent, EnablementState, IExtensionContributions, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { Emitter } from 'vs/base/common/event'; @@ -39,7 +39,7 @@ export class TestExtensionEnablementService extends ExtensionEnablementService { } public reset(): TPromise { - return this.getDisabledExtensions().then(extensions => extensions.forEach(d => this.setEnablement(d, EnablementState.Enabled))); + return this.getDisabledExtensions().then(extensions => extensions.forEach(d => this.setEnablement(aLocalExtension(d.id), EnablementState.Enabled))); } } @@ -52,7 +52,7 @@ suite('ExtensionEnablementService Test', () => { setup(() => { instantiationService = new TestInstantiationService(); - instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event, }); + instantiationService.stub(IExtensionManagementService, { onDidUninstallExtension: didUninstallEvent.event }); testObject = new TestExtensionEnablementService(instantiationService); }); @@ -65,7 +65,7 @@ suite('ExtensionEnablementService Test', () => { }); test('test when no extensions are disabled for workspace when there is no workspace', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) .then(() => { instantiationService.stub(IWorkspaceContextService, 'getWorkbenchState', WorkbenchState.EMPTY); return testObject.getDisabledExtensions().then(extensions => assert.deepEqual([], extensions)); @@ -73,255 +73,268 @@ suite('ExtensionEnablementService Test', () => { }); test('test disable an extension globally', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([{ id: 'pub.a' }], extensions)); }); test('test disable an extension globally should return truthy promise', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) .then(value => assert.ok(value)); }); test('test disable an extension globally triggers the change event', () => { const target = sinon.spy(); testObject.onEnablementChanged(target); - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => assert.ok(target.calledWithExactly({ id: 'pub.a' }))); + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => assert.ok(target.calledWithExactly({ id: 'pub.a', uuid: void 0 }))); }); test('test disable an extension globally again should return a falsy promise', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) .then(value => assert.ok(!value)); }); test('test state of globally disabled extension', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.Disabled)); }); test('test state of globally enabled extension', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Enabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.Enabled)); }); test('test disable an extension for workspace', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([{ id: 'pub.a' }], extensions)); }); test('test disable an extension for workspace returns a truthy promise', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) .then(value => assert.ok(value)); }); test('test disable an extension for workspace again should return a falsy promise', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)) .then(value => assert.ok(!value)); }); test('test state of workspace disabled extension', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.WorkspaceDisabled)); }); test('test state of workspace and globally disabled extension', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.WorkspaceDisabled)); }); test('test state of workspace enabled extension', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.WorkspaceEnabled)); }); test('test state of globally disabled and workspace enabled extension', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.WorkspaceEnabled)); }); test('test state of an extension when disabled for workspace from workspace enabled', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled)) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.WorkspaceDisabled)); }); test('test state of an extension when disabled globally from workspace enabled', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled)) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.Disabled)); }); test('test state of an extension when disabled globally from workspace disabled', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.Disabled)); }); test('test state of an extension when enabled globally from workspace enabled', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Enabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled)) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.Enabled)); }); test('test state of an extension when enabled globally from workspace disabled', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Enabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled)) .then(() => assert.equal(testObject.getEnablementState({ id: 'pub.a' }), EnablementState.Enabled)); }); test('test disable an extension for workspace and then globally', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([{ id: 'pub.a' }], extensions)); }); test('test disable an extension for workspace and then globally return a truthy promise', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) .then(value => assert.ok(value)); }); test('test disable an extension for workspace and then globally trigger the change event', () => { const target = sinon.spy(); - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) .then(() => testObject.onEnablementChanged(target)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) - .then(() => assert.ok(target.calledWithExactly({ id: 'pub.a' }))); + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) + .then(() => assert.ok(target.calledWithExactly({ id: 'pub.a', uuid: void 0 }))); }); test('test disable an extension globally and then for workspace', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([{ id: 'pub.a' }], extensions)); }); test('test disable an extension globally and then for workspace return a truthy promise', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)) .then(value => assert.ok(value)); }); test('test disable an extension globally and then for workspace triggers the change event', () => { const target = sinon.spy(); - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) .then(() => testObject.onEnablementChanged(target)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled)) - .then(() => assert.ok(target.calledWithExactly({ id: 'pub.a' }))); + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled)) + .then(() => assert.ok(target.calledWithExactly({ id: 'pub.a', uuid: void 0 }))); }); test('test disable an extension for workspace when there is no workspace throws error', (done) => { instantiationService.stub(IWorkspaceContextService, 'getWorkbenchState', WorkbenchState.EMPTY); - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) .then(() => assert.fail('should throw an error'), error => assert.ok(error)) .then(done, done); }); test('test enable an extension globally', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Enabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled)) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([], extensions)); }); test('test enable an extension globally return truthy promise', (done) => { - testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Enabled)) + testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled)) .then(value => assert.ok(value)) .then(done, done); }); test('test enable an extension globally triggers change event', (done) => { const target = sinon.spy(); - testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) + testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) .then(() => testObject.onEnablementChanged(target)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Enabled)) - .then(() => assert.ok(target.calledWithExactly({ id: 'pub.a' }))) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled)) + .then(() => assert.ok(target.calledWithExactly({ id: 'pub.a', uuid: void 0 }))) .then(done, done); }); test('test enable an extension globally when already enabled return falsy promise', (done) => { - testObject.setEnablement({ id: 'pub.a' }, EnablementState.Enabled) + testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled) .then(value => assert.ok(!value)) .then(done, done); }); test('test enable an extension for workspace', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled)) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([], extensions)); }); test('test enable an extension for workspace return truthy promise', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled)) .then(value => assert.ok(value)); }); test('test enable an extension for workspace triggers change event', () => { const target = sinon.spy(); - return testObject.setEnablement({ id: 'pub.b' }, EnablementState.WorkspaceDisabled) + return testObject.setEnablement(aLocalExtension('pub.b'), EnablementState.WorkspaceDisabled) .then(() => testObject.onEnablementChanged(target)) - .then(() => testObject.setEnablement({ id: 'pub.b' }, EnablementState.WorkspaceEnabled)) - .then(() => assert.ok(target.calledWithExactly({ id: 'pub.b' }))); + .then(() => testObject.setEnablement(aLocalExtension('pub.b'), EnablementState.WorkspaceEnabled)) + .then(() => assert.ok(target.calledWithExactly({ id: 'pub.b', uuid: void 0 }))); }); test('test enable an extension for workspace when already enabled return truthy promise', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled) .then(value => assert.ok(value)); }); test('test enable an extension for workspace when disabled in workspace and gloablly', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceEnabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceEnabled)) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([], extensions)); }); test('test enable an extension globally when disabled in workspace and gloablly', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Enabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Enabled)) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([], extensions)); }); test('test remove an extension from disablement list when uninstalled', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled)) .then(() => didUninstallEvent.fire({ identifier: { id: 'pub.a-1.0.0' } })) .then(() => testObject.getDisabledExtensions()) .then(extensions => assert.deepEqual([], extensions)); }); test('test isEnabled return false extension is disabled globally', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.Disabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.Disabled) .then(() => assert.ok(!testObject.isEnabled({ id: 'pub.a' }))); }); test('test isEnabled return false extension is disabled in workspace', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) .then(() => assert.ok(!testObject.isEnabled({ id: 'pub.a' }))); }); test('test isEnabled return true extension is not disabled', () => { - return testObject.setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled) - .then(() => testObject.setEnablement({ id: 'pub.c' }, EnablementState.Disabled)) + return testObject.setEnablement(aLocalExtension('pub.a'), EnablementState.WorkspaceDisabled) + .then(() => testObject.setEnablement(aLocalExtension('pub.c'), EnablementState.Disabled)) .then(() => assert.ok(testObject.isEnabled({ id: 'pub.b' }))); }); -}); \ No newline at end of file + + test('test canChangeEnablement return false for language packs', () => { + assert.equal(testObject.canChangeEnablement(aLocalExtension('pub.a', { locales: [{ locale: 'gr', path: 'somepath' }] })), false); + }); +}); + +function aLocalExtension(id: string, contributes?: IExtensionContributions): ILocalExtension { + return Object.create({ + identifier: { id }, + manifest: { + contributes + } + }); +} diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index ab62f52ccbe..af89c431ab6 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -409,12 +409,6 @@ export interface IFileStat extends IBaseStat { */ isDirectory: boolean; - /** - * Return {{true}} when this is a directory - * that is not empty. - */ - hasChildren: boolean; - /** * The children of the file stat or undefined if none. */ @@ -465,6 +459,15 @@ export interface IStringStream { on(event: string, callback: any): void; } +/** + * Text snapshot that works like an iterator. + * Will try to return chunks of roughly ~64KB size. + * Will return null when finished. + */ +export interface ITextSnapshot { + read(): string; +} + /** * Streamable content and meta information of a file. */ diff --git a/src/vs/platform/integrity/node/integrityServiceImpl.ts b/src/vs/platform/integrity/node/integrityServiceImpl.ts index 96798846b0b..63c7816a33c 100644 --- a/src/vs/platform/integrity/node/integrityServiceImpl.ts +++ b/src/vs/platform/integrity/node/integrityServiceImpl.ts @@ -97,7 +97,7 @@ export class IntegrityServiceImpl implements IIntegrityService { ); const dontShowAgainAction = new Action( 'integrity.dontShowAgain', - nls.localize('integrity.dontShowAgain', "Don't show again"), + nls.localize('integrity.dontShowAgain', "Don't Show Again"), null, true, () => { diff --git a/src/vs/platform/issue/common/issue.ts b/src/vs/platform/issue/common/issue.ts new file mode 100644 index 00000000000..5d43f4e5c4a --- /dev/null +++ b/src/vs/platform/issue/common/issue.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { TPromise } from 'vs/base/common/winjs.base'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const ID = 'issueService'; +export const IIssueService = createDecorator(ID); + +export interface IssueReporterStyles { + backgroundColor: string; + color: string; + textLinkColor: string; + inputBackground: string; + inputForeground: string; + inputBorder: string; + inputErrorBorder: string; + inputActiveBorder: string; + buttonBackground: string; + buttonForeground: string; + buttonHoverBackground: string; + zoomLevel: number; +} + +export interface IIssueService { + _serviceBrand: any; + openReporter(theme?: IssueReporterStyles): TPromise; +} \ No newline at end of file diff --git a/src/vs/platform/issue/common/issueIpc.ts b/src/vs/platform/issue/common/issueIpc.ts new file mode 100644 index 00000000000..f9f05c05ede --- /dev/null +++ b/src/vs/platform/issue/common/issueIpc.ts @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { TPromise } from 'vs/base/common/winjs.base'; +import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IIssueService, IssueReporterStyles } from './issue'; + +export interface IIssueChannel extends IChannel { + call(command: 'openIssueReporter', arg: IssueReporterStyles): TPromise; + call(command: 'getStatusInfo'): TPromise; + call(command: string, arg?: any): TPromise; +} + +export class IssueChannel implements IIssueChannel { + + constructor(private service: IIssueService) { } + + call(command: string, arg?: any): TPromise { + switch (command) { + case 'openIssueReporter': + return this.service.openReporter(arg); + } + return undefined; + } +} + +export class IssueChannelClient implements IIssueService { + + _serviceBrand: any; + + constructor(private channel: IIssueChannel) { } + + openReporter(theme: IssueReporterStyles): TPromise { + return this.channel.call('openIssueReporter', theme); + } +} \ No newline at end of file diff --git a/src/vs/platform/issue/electron-main/issueService.ts b/src/vs/platform/issue/electron-main/issueService.ts new file mode 100644 index 00000000000..26ba9c5f6bd --- /dev/null +++ b/src/vs/platform/issue/electron-main/issueService.ts @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { TPromise, Promise } from 'vs/base/common/winjs.base'; +import { IIssueService, IssueReporterStyles } from 'vs/platform/issue/common/issue'; +import { BrowserWindow, ipcMain } from 'electron'; +import { ILaunchService } from 'vs/code/electron-main/launch'; +import { buildDiagnostics, DiagnosticInfo } from 'vs/code/electron-main/diagnostics'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; + +export class IssueService implements IIssueService { + _serviceBrand: any; + _issueWindow: BrowserWindow; + + constructor( + private machineId: string, + @IEnvironmentService private environmentService: IEnvironmentService, + @ILaunchService private launchService: ILaunchService + ) { } + + openReporter(theme?: IssueReporterStyles): TPromise { + ipcMain.on('issueInfoRequest', event => { + this.getStatusInfo().then(msg => { + event.sender.send('issueInfoResponse', msg); + }); + }); + + // When launching from cli, no theme is provided. Match theme if passed from workbench. + if (theme) { + ipcMain.on('issueStyleRequest', event => { + event.sender.send('issueStyleResponse', theme); + }); + } + + this._issueWindow = new BrowserWindow({ + width: 800, + height: 900, + title: 'Issue Reporter', + alwaysOnTop: true + }); + + this._issueWindow.setMenuBarVisibility(false); // workaround for now, until a menu is implemented + + this._issueWindow.loadURL(this.getIssueReporterPath()); + + return TPromise.as(null); + } + + private getStatusInfo(): TPromise { + return new Promise((resolve, reject) => { + this.launchService.getMainProcessInfo().then(info => { + buildDiagnostics(info) + .then(diagnosticInfo => { + resolve(diagnosticInfo); + }) + .catch(err => { + reject(err); + }); + }); + }); + } + + private getIssueReporterPath() { + const config = { + appRoot: this.environmentService.appRoot, + nodeCachedDataDir: this.environmentService.nodeCachedDataDir, + windowId: this._issueWindow.id, + machineId: this.machineId + }; + return `${require.toUrl('vs/code/electron-browser/issue/issueReporter.html')}?config=${encodeURIComponent(JSON.stringify(config))}`; + } +} diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 96a170f3ac1..1bba7f047a6 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -5,7 +5,7 @@ 'use strict'; import { ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; -import { List, IListOptions } from 'vs/base/browser/ui/list/listWidget'; +import { List, IListCreationOptions } from 'vs/base/browser/ui/list/listWidget'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IDisposable, toDisposable, combinedDisposable, dispose } from 'vs/base/common/lifecycle'; import { IContextKeyService, IContextKey, RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -15,6 +15,11 @@ import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { attachListStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { InputFocusedContextKey } from 'vs/platform/workbench/common/contextkeys'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { mixin } from 'vs/base/common/objects'; +import { localize } from 'vs/nls'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; export type ListWidget = List | PagedList | ITree; @@ -74,6 +79,7 @@ export class ListService implements IListService { const RawWorkbenchListFocusContextKey = new RawContextKey('listFocus', true); export const WorkbenchListSupportsMultiSelectContextKey = new RawContextKey('listSupportsMultiselect', true); export const WorkbenchListFocusContextKey = ContextKeyExpr.and(RawWorkbenchListFocusContextKey, ContextKeyExpr.not(InputFocusedContextKey)); +export const WorkbenchListDoubleSelection = new RawContextKey('listDoubleSelection', false); export type Widget = List | PagedList | ITree; @@ -88,32 +94,49 @@ function createScopedContextKeyService(contextKeyService: IContextKeyService, wi return result; } +export const multiSelectModifierSettingKey = 'workbench.multiSelectModifier'; + +function useAltAsMultiSelectModifier(configurationService: IConfigurationService): { useAltAsMultiSelectModifier: boolean } { + return { useAltAsMultiSelectModifier: configurationService.getValue(multiSelectModifierSettingKey) === 'alt' }; +} + export class WorkbenchList extends List { readonly contextKeyService: IContextKeyService; - private disposable: IDisposable; + private listDoubleSelection: IContextKey; constructor( container: HTMLElement, delegate: IDelegate, renderers: IRenderer[], - options: IListOptions, + private options: IListCreationOptions, @IContextKeyService contextKeyService: IContextKeyService, @IListService listService: IListService, - @IThemeService themeService: IThemeService + @IThemeService themeService: IThemeService, + @IConfigurationService configurationService: IConfigurationService ) { - super(container, delegate, renderers, options); + super(container, delegate, renderers, mixin(options, useAltAsMultiSelectModifier(configurationService))); this.contextKeyService = createScopedContextKeyService(contextKeyService, this); + this.listDoubleSelection = WorkbenchListDoubleSelection.bindTo(this.contextKeyService); - this.disposable = combinedDisposable([ + this.disposables.push(combinedDisposable([ this.contextKeyService, (listService as ListService).register(this), attachListStyler(this, themeService) - ]); + ])); + this.disposables.push(this.onSelectionChange(() => { + const selection = this.getSelection(); + this.listDoubleSelection.set(selection && selection.length === 2); + })); + this.disposables.push(configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(multiSelectModifierSettingKey)) { + this.updateOptions(useAltAsMultiSelectModifier(configurationService)); + } + })); } - dispose(): void { - this.disposable.dispose(); + public get useAltAsMultiSelectModifier(): boolean { + return this.options.useAltAsMultiSelectModifier; } } @@ -126,18 +149,24 @@ export class WorkbenchPagedList extends PagedList { container: HTMLElement, delegate: IDelegate, renderers: IPagedRenderer[], - options: IListOptions, + options: IListCreationOptions, @IContextKeyService contextKeyService: IContextKeyService, @IListService listService: IListService, - @IThemeService themeService: IThemeService + @IThemeService themeService: IThemeService, + @IConfigurationService configurationService: IConfigurationService ) { - super(container, delegate, renderers, options); + super(container, delegate, renderers, mixin(options, useAltAsMultiSelectModifier(configurationService))); this.contextKeyService = createScopedContextKeyService(contextKeyService, this); this.disposable = combinedDisposable([ this.contextKeyService, (listService as ListService).register(this), - attachListStyler(this, themeService) + attachListStyler(this, themeService), + configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(multiSelectModifierSettingKey)) { + this.updateOptions(useAltAsMultiSelectModifier(configurationService)); + } + }) ]); } @@ -149,7 +178,8 @@ export class WorkbenchPagedList extends PagedList { export class WorkbenchTree extends Tree { readonly contextKeyService: IContextKeyService; - private disposables: IDisposable[] = []; + protected disposables: IDisposable[] = []; + private listDoubleSelection: IContextKey; constructor( container: HTMLElement, @@ -162,15 +192,47 @@ export class WorkbenchTree extends Tree { super(container, configuration, options); this.contextKeyService = createScopedContextKeyService(contextKeyService, this); + this.listDoubleSelection = WorkbenchListDoubleSelection.bindTo(this.contextKeyService); this.disposables.push( this.contextKeyService, (listService as ListService).register(this), attachListStyler(this, themeService) ); + this.disposables.push(this.onDidChangeSelection(() => { + const selection = this.getSelection(); + this.listDoubleSelection.set(selection && selection.length === 2); + })); } dispose(): void { this.disposables = dispose(this.disposables); } } + +const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); + +configurationRegistry.registerConfiguration({ + 'id': 'workbench', + 'order': 7, + 'title': localize('workbenchConfigurationTitle', "Workbench"), + 'type': 'object', + 'properties': { + 'workbench.multiSelectModifier': { + 'type': 'string', + 'enum': ['ctrlCmd', 'alt'], + 'enumDescriptions': [ + localize('multiSelectModifier.ctrlCmd', "Maps to `Control` on Windows and Linux and to `Command` on macOS."), + localize('multiSelectModifier.alt', "Maps to `Alt` on Windows and Linux and to `Option` on macOS.") + ], + 'default': 'ctrlCmd', + 'description': localize({ + key: 'multiSelectModifier', + comment: [ + '- `ctrlCmd` refers to a value the setting can take and should not be localized.', + '- `Control` and `Command` refer to the modifier keys Ctrl or Cmd on the keyboard and can be localized.' + ] + }, "The modifier to be used to add an item to a multi-selection with the mouse (for example in trees and lists, if supported). `ctrlCmd` maps to `Control` on Windows and Linux and to `Command` on macOS. The 'Open to Side' mouse gestures - if supported - will adapt such that they do not conflict with the multiselect modifier.") + } + } +}); \ No newline at end of file diff --git a/src/vs/platform/markers/common/problemMatcher.ts b/src/vs/platform/markers/common/problemMatcher.ts index 7268756d769..e6dd0d5bdbe 100644 --- a/src/vs/platform/markers/common/problemMatcher.ts +++ b/src/vs/platform/markers/common/problemMatcher.ts @@ -245,24 +245,28 @@ abstract class AbstractLineMatcher implements ILineMatcher { } protected getMarkerMatch(data: ProblemData): ProblemMatch { - let location = this.getLocation(data); - if (data.file && location && data.message) { - let marker: IMarkerData = { - severity: this.getSeverity(data), - startLineNumber: location.startLineNumber, - startColumn: location.startCharacter, - endLineNumber: location.startLineNumber, - endColumn: location.endCharacter, - message: data.message - }; - if (!Types.isUndefined(data.code)) { - marker.code = data.code; + try { + let location = this.getLocation(data); + if (data.file && location && data.message) { + let marker: IMarkerData = { + severity: this.getSeverity(data), + startLineNumber: location.startLineNumber, + startColumn: location.startCharacter, + endLineNumber: location.startLineNumber, + endColumn: location.endCharacter, + message: data.message + }; + if (!Types.isUndefined(data.code)) { + marker.code = data.code; + } + return { + description: this.matcher, + resource: this.getResource(data.file), + marker: marker + }; } - return { - description: this.matcher, - resource: this.getResource(data.file), - marker: marker - }; + } catch (err) { + console.error(`Failed to convert problem data into match: ${JSON.stringify(data)}`); } return undefined; } diff --git a/src/vs/platform/message/common/message.ts b/src/vs/platform/message/common/message.ts index 61ed328a213..4211798a0a9 100644 --- a/src/vs/platform/message/common/message.ts +++ b/src/vs/platform/message/common/message.ts @@ -5,6 +5,8 @@ 'use strict'; import nls = require('vs/nls'); +import uri from 'vs/base/common/uri'; +import paths = require('vs/base/common/paths'); import { TPromise } from 'vs/base/common/winjs.base'; import Severity from 'vs/base/common/severity'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; @@ -35,6 +37,24 @@ export const CancelAction = new Action('cancel.message', nls.localize('cancel', export const IMessageService = createDecorator('messageService'); +const MAX_CONFIRM_FILES = 10; +export function getConfirmMessage(start: string, resourcesToConfirm: uri[]): string { + const message = [start]; + message.push(''); + message.push(...resourcesToConfirm.slice(0, MAX_CONFIRM_FILES).map(r => paths.basename(r.fsPath))); + + if (resourcesToConfirm.length > MAX_CONFIRM_FILES) { + if (resourcesToConfirm.length - MAX_CONFIRM_FILES === 1) { + message.push(nls.localize('moreFile', "...1 additional file not shown")); + } else { + message.push(nls.localize('moreFiles', "...{0} additional files not shown", resourcesToConfirm.length - MAX_CONFIRM_FILES)); + } + } + + message.push(''); + return message.join('\n'); +} + export interface IConfirmationResult { confirmed: boolean; checkboxChecked?: boolean; diff --git a/src/vs/platform/node/product.ts b/src/vs/platform/node/product.ts index 68802e24d9b..00a76d6fc38 100644 --- a/src/vs/platform/node/product.ts +++ b/src/vs/platform/node/product.ts @@ -69,6 +69,7 @@ export interface IProductConfiguration { 'linux-x64': string; 'darwin': string; }; + logUploaderUrl: string; } export interface ISurveyData { diff --git a/src/vs/platform/progress/common/progress.ts b/src/vs/platform/progress/common/progress.ts index 97fc957c02b..100276698ea 100644 --- a/src/vs/platform/progress/common/progress.ts +++ b/src/vs/platform/progress/common/progress.ts @@ -64,7 +64,8 @@ export class Progress implements IProgress { export enum ProgressLocation { Scm = 1, - Window = 10, + Extensions = 2, + Window = 10 } export interface IProgressOptions { diff --git a/src/vs/platform/search/common/search.ts b/src/vs/platform/search/common/search.ts index 3090197c532..7fb3992feb1 100644 --- a/src/vs/platform/search/common/search.ts +++ b/src/vs/platform/search/common/search.ts @@ -112,13 +112,10 @@ export interface ILineMatch { export interface IProgress { total?: number; worked?: number; -} - -export interface ISearchLog { message?: string; } -export interface ISearchProgressItem extends IFileMatch, IProgress, ISearchLog { +export interface ISearchProgressItem extends IFileMatch, IProgress { // Marker interface to indicate the possible values for progress calls from the engine } diff --git a/src/vs/platform/storage/common/storageService.ts b/src/vs/platform/storage/common/storageService.ts index f891309651f..7cf9aa4f4ba 100644 --- a/src/vs/platform/storage/common/storageService.ts +++ b/src/vs/platform/storage/common/storageService.ts @@ -8,6 +8,7 @@ import types = require('vs/base/common/types'); import errors = require('vs/base/common/errors'); import strings = require('vs/base/common/strings'); import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import * as perf from 'vs/base/common/performance'; // Browser localStorage interface export interface IStorage { @@ -89,7 +90,9 @@ export class StorageService implements IStorageService { private cleanupWorkspaceScope(workspaceUid: number): void { // Get stored identifier from storage + perf.mark('willReadWorkspaceIdentifier'); const id = this.getInteger(StorageService.WORKSPACE_IDENTIFIER, StorageScope.WORKSPACE); + perf.mark('didReadWorkspaceIdentifier'); // If identifier differs, assume the workspace got recreated and thus clean all storage for this workspace if (types.isNumber(id) && workspaceUid !== id) { diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index a30413c4706..0c8fb6574b6 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -19,6 +19,7 @@ export interface ColorContribution { readonly id: ColorIdentifier; readonly description: string; readonly defaults: ColorDefaults; + readonly needsTransparency: boolean; } @@ -85,8 +86,8 @@ class ColorRegistry implements IColorRegistry { this.colorsById = {}; } - public registerColor(id: string, defaults: ColorDefaults, description: string): ColorIdentifier { - let colorContribution = { id, description, defaults }; + public registerColor(id: string, defaults: ColorDefaults, description: string, needsTransparency = false): ColorIdentifier { + let colorContribution = { id, description, defaults, needsTransparency }; this.colorsById[id] = colorContribution; this.colorSchema.properties[id] = { type: 'string', description, format: 'color-hex', default: '#ff0000' }; this.colorReferenceSchema.enum.push(id); @@ -133,8 +134,8 @@ class ColorRegistry implements IColorRegistry { const colorRegistry = new ColorRegistry(); platform.Registry.add(Extensions.ColorContribution, colorRegistry); -export function registerColor(id: string, defaults: ColorDefaults, description: string): ColorIdentifier { - return colorRegistry.registerColor(id, defaults, description); +export function registerColor(id: string, defaults: ColorDefaults, description: string, needsTransparency?: boolean): ColorIdentifier { + return colorRegistry.registerColor(id, defaults, description, needsTransparency); } export function getColorRegistry(): IColorRegistry { @@ -239,20 +240,20 @@ export const editorWidgetBorder = registerColor('editorWidget.border', { dark: ' */ export const editorSelectionBackground = registerColor('editor.selectionBackground', { light: '#ADD6FF', dark: '#264F78', hc: '#f3f518' }, nls.localize('editorSelectionBackground', "Color of the editor selection.")); export const editorSelectionForeground = registerColor('editor.selectionForeground', { light: null, dark: null, hc: '#000000' }, nls.localize('editorSelectionForeground', "Color of the selected text for high contrast.")); -export const editorInactiveSelection = registerColor('editor.inactiveSelectionBackground', { light: transparent(editorSelectionBackground, 0.5), dark: transparent(editorSelectionBackground, 0.5), hc: transparent(editorSelectionBackground, 0.5) }, nls.localize('editorInactiveSelection', "Color of the selection in an inactive editor.")); -export const editorSelectionHighlight = registerColor('editor.selectionHighlightBackground', { light: lessProminent(editorSelectionBackground, editorBackground, 0.3, 0.6), dark: lessProminent(editorSelectionBackground, editorBackground, 0.3, 0.6), hc: null }, nls.localize('editorSelectionHighlight', 'Color for regions with the same content as the selection.')); +export const editorInactiveSelection = registerColor('editor.inactiveSelectionBackground', { light: transparent(editorSelectionBackground, 0.5), dark: transparent(editorSelectionBackground, 0.5), hc: transparent(editorSelectionBackground, 0.5) }, nls.localize('editorInactiveSelection', "Color of the selection in an inactive editor. The color must not be opaque to not hide underlying decorations."), true); +export const editorSelectionHighlight = registerColor('editor.selectionHighlightBackground', { light: lessProminent(editorSelectionBackground, editorBackground, 0.3, 0.6), dark: lessProminent(editorSelectionBackground, editorBackground, 0.3, 0.6), hc: null }, nls.localize('editorSelectionHighlight', 'Color for regions with the same content as the selection. The color must not be opaque to not hide underlying decorations.'), true); /** * Editor find match colors. */ export const editorFindMatch = registerColor('editor.findMatchBackground', { light: '#A8AC94', dark: '#515C6A', hc: null }, nls.localize('editorFindMatch', "Color of the current search match.")); -export const editorFindMatchHighlight = registerColor('editor.findMatchHighlightBackground', { light: '#EA5C0055', dark: '#EA5C0055', hc: null }, nls.localize('findMatchHighlight', "Color of the other search matches.")); -export const editorFindRangeHighlight = registerColor('editor.findRangeHighlightBackground', { dark: '#3a3d4166', light: '#b4b4b44d', hc: null }, nls.localize('findRangeHighlight', "Color the range limiting the search.")); +export const editorFindMatchHighlight = registerColor('editor.findMatchHighlightBackground', { light: '#EA5C0055', dark: '#EA5C0055', hc: null }, nls.localize('findMatchHighlight', "Color of the other search matches. The color must not be opaque to not hide underlying decorations."), true); +export const editorFindRangeHighlight = registerColor('editor.findRangeHighlightBackground', { dark: '#3a3d4166', light: '#b4b4b44d', hc: null }, nls.localize('findRangeHighlight', "Color the range limiting the search. The color must not be opaque to not hide underlying decorations."), true); /** * Editor hover */ -export const editorHoverHighlight = registerColor('editor.hoverHighlightBackground', { light: '#ADD6FF26', dark: '#264f7840', hc: '#ADD6FF26' }, nls.localize('hoverHighlight', 'Highlight below the word for which a hover is shown.')); +export const editorHoverHighlight = registerColor('editor.hoverHighlightBackground', { light: '#ADD6FF26', dark: '#264f7840', hc: '#ADD6FF26' }, nls.localize('hoverHighlight', 'Highlight below the word for which a hover is shown. The color must not be opaque to not hide underlying decorations.'), true); export const editorHoverBackground = registerColor('editorHoverWidget.background', { light: editorWidgetBackground, dark: editorWidgetBackground, hc: editorWidgetBackground }, nls.localize('hoverBackground', 'Background color of the editor hover.')); export const editorHoverBorder = registerColor('editorHoverWidget.border', { light: editorWidgetBorder, dark: editorWidgetBorder, hc: editorWidgetBorder }, nls.localize('hoverBorder', 'Border color of the editor hover.')); @@ -284,12 +285,12 @@ const commonBaseColor = Color.fromHex('#606060').transparent(0.4); const contentTransparency = 0.4; const rulerTransparency = 1; -export const mergeCurrentHeaderBackground = registerColor('merge.currentHeaderBackground', { dark: currentBaseColor, light: currentBaseColor, hc: null }, nls.localize('mergeCurrentHeaderBackground', 'Current header background in inline merge-conflicts.')); -export const mergeCurrentContentBackground = registerColor('merge.currentContentBackground', { dark: transparent(mergeCurrentHeaderBackground, contentTransparency), light: transparent(mergeCurrentHeaderBackground, contentTransparency), hc: transparent(mergeCurrentHeaderBackground, contentTransparency) }, nls.localize('mergeCurrentContentBackground', 'Current content background in inline merge-conflicts.')); -export const mergeIncomingHeaderBackground = registerColor('merge.incomingHeaderBackground', { dark: incomingBaseColor, light: incomingBaseColor, hc: null }, nls.localize('mergeIncomingHeaderBackground', 'Incoming header background in inline merge-conflicts.')); -export const mergeIncomingContentBackground = registerColor('merge.incomingContentBackground', { dark: transparent(mergeIncomingHeaderBackground, contentTransparency), light: transparent(mergeIncomingHeaderBackground, contentTransparency), hc: transparent(mergeIncomingHeaderBackground, contentTransparency) }, nls.localize('mergeIncomingContentBackground', 'Incoming content background in inline merge-conflicts.')); -export const mergeCommonHeaderBackground = registerColor('merge.commonHeaderBackground', { dark: commonBaseColor, light: commonBaseColor, hc: null }, nls.localize('mergeCommonHeaderBackground', 'Common ancestor header background in inline merge-conflicts.')); -export const mergeCommonContentBackground = registerColor('merge.commonContentBackground', { dark: transparent(mergeCommonHeaderBackground, contentTransparency), light: transparent(mergeCommonHeaderBackground, contentTransparency), hc: transparent(mergeCommonHeaderBackground, contentTransparency) }, nls.localize('mergeCommonContentBackground', 'Common ancester content background in inline merge-conflicts.')); +export const mergeCurrentHeaderBackground = registerColor('merge.currentHeaderBackground', { dark: currentBaseColor, light: currentBaseColor, hc: null }, nls.localize('mergeCurrentHeaderBackground', 'Current header background in inline merge-conflicts. The color must not be opaque to not hide underlying decorations.'), true); +export const mergeCurrentContentBackground = registerColor('merge.currentContentBackground', { dark: transparent(mergeCurrentHeaderBackground, contentTransparency), light: transparent(mergeCurrentHeaderBackground, contentTransparency), hc: transparent(mergeCurrentHeaderBackground, contentTransparency) }, nls.localize('mergeCurrentContentBackground', 'Current content background in inline merge-conflicts. The color must not be opaque to not hide underlying decorations.'), true); +export const mergeIncomingHeaderBackground = registerColor('merge.incomingHeaderBackground', { dark: incomingBaseColor, light: incomingBaseColor, hc: null }, nls.localize('mergeIncomingHeaderBackground', 'Incoming header background in inline merge-conflicts. The color must not be opaque to not hide underlying decorations.'), true); +export const mergeIncomingContentBackground = registerColor('merge.incomingContentBackground', { dark: transparent(mergeIncomingHeaderBackground, contentTransparency), light: transparent(mergeIncomingHeaderBackground, contentTransparency), hc: transparent(mergeIncomingHeaderBackground, contentTransparency) }, nls.localize('mergeIncomingContentBackground', 'Incoming content background in inline merge-conflicts. The color must not be opaque to not hide underlying decorations.'), true); +export const mergeCommonHeaderBackground = registerColor('merge.commonHeaderBackground', { dark: commonBaseColor, light: commonBaseColor, hc: null }, nls.localize('mergeCommonHeaderBackground', 'Common ancestor header background in inline merge-conflicts. The color must not be opaque to not hide underlying decorations.'), true); +export const mergeCommonContentBackground = registerColor('merge.commonContentBackground', { dark: transparent(mergeCommonHeaderBackground, contentTransparency), light: transparent(mergeCommonHeaderBackground, contentTransparency), hc: transparent(mergeCommonHeaderBackground, contentTransparency) }, nls.localize('mergeCommonContentBackground', 'Common ancester content background in inline merge-conflicts. The color must not be opaque to not hide underlying decorations.'), true); export const mergeBorder = registerColor('merge.border', { dark: null, light: null, hc: '#C3DF6F' }, nls.localize('mergeBorder', 'Border color on headers and the splitter in inline merge-conflicts.')); diff --git a/src/vs/platform/url/electron-main/urlService.ts b/src/vs/platform/url/electron-main/urlService.ts index 5469274fb20..595d3b38c97 100644 --- a/src/vs/platform/url/electron-main/urlService.ts +++ b/src/vs/platform/url/electron-main/urlService.ts @@ -25,7 +25,7 @@ export class URLService implements IURLService { ...globalBuffer ]; - app.setAsDefaultProtocolClient(product.urlProtocol, process.execPath, ['--open-url']); + app.setAsDefaultProtocolClient(product.urlProtocol, process.execPath, ['--open-url', '--']); const rawOnOpenUrl = fromNodeEventEmitter(app, 'open-url', (event: Electron.Event, url: string) => ({ event, url })); diff --git a/src/vs/platform/windows/electron-browser/windowService.ts b/src/vs/platform/windows/electron-browser/windowService.ts index 677d4603464..8548cf17b9f 100644 --- a/src/vs/platform/windows/electron-browser/windowService.ts +++ b/src/vs/platform/windows/electron-browser/windowService.ts @@ -11,7 +11,6 @@ import { IWindowService, IWindowsService, INativeOpenDialogOptions, IEnterWorksp import { IRecentlyOpened } from 'vs/platform/history/common/history'; import { ICommandAction } from 'vs/platform/actions/common/actions'; import { IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; -import { ILogService } from 'vs/platform/log/common/log'; export class WindowService implements IWindowService { @@ -22,8 +21,7 @@ export class WindowService implements IWindowService { constructor( private windowId: number, private configuration: IWindowConfiguration, - @IWindowsService private windowsService: IWindowsService, - @ILogService private logService: ILogService // TODO@Ben remove logging when no longer needed + @IWindowsService private windowsService: IWindowsService ) { const onThisWindowFocus = mapEvent(filterEvent(windowsService.onWindowFocus, id => id === windowId), _ => true); const onThisWindowBlur = mapEvent(filterEvent(windowsService.onWindowBlur, id => id === windowId), _ => false); @@ -41,32 +39,24 @@ export class WindowService implements IWindowService { pickFileFolderAndOpen(options: INativeOpenDialogOptions): TPromise { options.windowId = this.windowId; - this.logService.info('pickFileFolderAndOpen: begin'); - return this.windowsService.pickFileFolderAndOpen(options); } pickFileAndOpen(options: INativeOpenDialogOptions): TPromise { options.windowId = this.windowId; - this.logService.info('pickFileAndOpen: begin'); - return this.windowsService.pickFileAndOpen(options); } pickFolderAndOpen(options: INativeOpenDialogOptions): TPromise { options.windowId = this.windowId; - this.logService.info('pickFolderAndOpen: begin'); - return this.windowsService.pickFolderAndOpen(options); } pickWorkspaceAndOpen(options: INativeOpenDialogOptions): TPromise { options.windowId = this.windowId; - this.logService.info('pickWorkspaceAndOpen: begin'); - return this.windowsService.pickWorkspaceAndOpen(options); } @@ -131,27 +121,15 @@ export class WindowService implements IWindowService { } showMessageBox(options: Electron.MessageBoxOptions): TPromise { - this.logService.info('showMessageBox begin: ', options); - return this.windowsService.showMessageBox(this.windowId, options).then(result => { - this.logService.info('showMessageBox closed, response: ', result); - return result; - }); + return this.windowsService.showMessageBox(this.windowId, options); } showSaveDialog(options: Electron.SaveDialogOptions): TPromise { - this.logService.info('showSaveDialog begin: ', options); - return this.windowsService.showSaveDialog(this.windowId, options).then(result => { - this.logService.info('showSaveDialog begin: ', result); - return result; - }); + return this.windowsService.showSaveDialog(this.windowId, options); } showOpenDialog(options: Electron.OpenDialogOptions): TPromise { - this.logService.info('showOpenDialog begin: ', options); - return this.windowsService.showOpenDialog(this.windowId, options).then(result => { - this.logService.info('showOpenDialog closed: ', result); - return result; - }); + return this.windowsService.showOpenDialog(this.windowId, options); } updateTouchBar(items: ICommandAction[][]): TPromise { diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 1529b850f59..0869f93c220 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -261,7 +261,7 @@ declare module 'vscode' { constructor(line: number, character: number); /** - * Check if `other` is before this position. + * Check if this position is before `other`. * * @param other A position. * @return `true` if position is on a smaller line @@ -270,7 +270,7 @@ declare module 'vscode' { isBefore(other: Position): boolean; /** - * Check if `other` is before or equal to this position. + * Check if this position is before or equal to `other`. * * @param other A position. * @return `true` if position is on a smaller line @@ -279,7 +279,7 @@ declare module 'vscode' { isBeforeOrEqual(other: Position): boolean; /** - * Check if `other` is after this position. + * Check if this position is after `other`. * * @param other A position. * @return `true` if position is on a greater line @@ -288,7 +288,7 @@ declare module 'vscode' { isAfter(other: Position): boolean; /** - * Check if `other` is after or equal to this position. + * Check if this position is after or equal to `other`. * * @param other A position. * @return `true` if position is on a greater line @@ -297,7 +297,7 @@ declare module 'vscode' { isAfterOrEqual(other: Position): boolean; /** - * Check if `other` equals this position. + * Check if this position is equal to `other`. * * @param other A position. * @return `true` if the line and character of the given position are equal to @@ -2948,7 +2948,7 @@ declare module 'vscode' { export class CompletionList { /** - * This list it not complete. Further typing should result in recomputing + * This list is not complete. Further typing should result in recomputing * this list. */ isIncomplete?: boolean; @@ -2978,7 +2978,11 @@ declare module 'vscode' { /** * Completion was triggered by a trigger character. */ - TriggerCharacter = 1 + TriggerCharacter = 1, + /** + * Completion was re-triggered as current completion list is incomplete + */ + TriggerForIncompleteCompletions = 2 } /** @@ -4999,15 +5003,30 @@ declare module 'vscode' { export class TreeItem { /** - * A human-readable string describing this item + * A human-readable string describing this item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri). */ - label: string; + label?: string; /** - * The icon path for the tree item + * Optional id for the tree item that has to be unique across tree. The id is used to preserve the selection and expansion state of the tree item. + * + * If not provided, an id is generated using the tree item's label. **Note** that when labels change, ids will change and that selection and expansion state cannot be kept stable anymore. + */ + id?: string; + + /** + * The icon path for the tree item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri). */ iconPath?: string | Uri | { light: string | Uri; dark: string | Uri }; + /** + * The [uri](#Uri) of the resource representing this item. + * + * Will be used to derive the [label](#TreeItem.label), when it is not provided. + * Will be used to derive the icon from current file icon theme, when [iconPath](#TreeItem.iconPath) is not provided. + */ + resourceUri?: Uri; + /** * The [command](#Command) which should be run when the tree item is selected. */ @@ -5043,6 +5062,12 @@ declare module 'vscode' { * @param collapsibleState [TreeItemCollapsibleState](#TreeItemCollapsibleState) of the tree item. Default is [TreeItemCollapsibleState.None](#TreeItemCollapsibleState.None) */ constructor(label: string, collapsibleState?: TreeItemCollapsibleState); + + /** + * @param resourceUri The [uri](#Uri) of the resource representing this item. + * @param collapsibleState [TreeItemCollapsibleState](#TreeItemCollapsibleState) of the tree item. Default is [TreeItemCollapsibleState.None](#TreeItemCollapsibleState.None) + */ + constructor(resourceUri: Uri, collapsibleState?: TreeItemCollapsibleState); } /** diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index ab8f16d446a..7cbea7b4289 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -83,13 +83,33 @@ declare module 'vscode' { type: FileType; } + export interface TextSearchQuery { + pattern: string; + isRegex?: boolean; + isCaseSensitive?: boolean; + isWordMatch?: boolean; + } + + export interface TextSearchOptions { + includes: GlobPattern[]; + excludes: GlobPattern[]; + } + + export interface TextSearchResult { + uri: Uri; + range: Range; + preview: { leading: string, matching: string, trailing: string }; + } + // todo@joh discover files etc // todo@joh CancellationToken everywhere + // todo@joh add open/close calls? export interface FileSystemProvider { readonly onDidChange?: Event; - readonly root: Uri; + // todo@joh - remove this + readonly root?: Uri; // more... // @@ -130,11 +150,13 @@ declare module 'vscode' { // create(resource: Uri): Thenable; // find files by names + // todo@joh, move into its own provider findFiles?(query: string, progress: Progress, token: CancellationToken): Thenable; + provideTextSearchResults?(query: TextSearchQuery, options: TextSearchOptions, progress: Progress, token: CancellationToken): Thenable; } export namespace workspace { - export function registerFileSystemProvider(authority: string, provider: FileSystemProvider): Disposable; + export function registerFileSystemProvider(scheme: string, provider: FileSystemProvider): Disposable; } export namespace window { diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 0ebf0e9893d..191ae51ea6d 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { forEach } from 'vs/base/common/collections'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; -import { ViewLocation, ViewsRegistry, IViewDescriptor } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewLocation, ViewsRegistry, IViewDescriptor } from 'vs/workbench/common/views'; import { TreeView } from 'vs/workbench/browser/parts/views/treeView'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { coalesce, } from 'vs/base/common/arrays'; diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts index 52d0da37382..7778851490a 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystem.ts @@ -6,20 +6,21 @@ import URI, { UriComponents } from 'vs/base/common/uri'; import { TPromise, PPromise } from 'vs/base/common/winjs.base'; -import { ExtHostContext, MainContext, IExtHostContext, MainThreadFileSystemShape, ExtHostFileSystemShape } from '../node/extHost.protocol'; +import { ExtHostContext, MainContext, IExtHostContext, MainThreadFileSystemShape, ExtHostFileSystemShape, IFileChangeDto } from '../node/extHost.protocol'; import { IFileService, IFileSystemProvider, IStat, IFileChange } from 'vs/platform/files/common/files'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import Event, { Emitter } from 'vs/base/common/event'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { IProgress } from 'vs/platform/progress/common/progress'; -import { ISearchResultProvider, ISearchQuery, ISearchComplete, ISearchProgressItem, QueryType, IFileMatch, ISearchService } from 'vs/platform/search/common/search'; +import { ISearchResultProvider, ISearchQuery, ISearchComplete, ISearchProgressItem, QueryType, IFileMatch, ISearchService, ILineMatch } from 'vs/platform/search/common/search'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { onUnexpectedError } from 'vs/base/common/errors'; +import { values } from 'vs/base/common/map'; +import { isFalsyOrEmpty } from 'vs/base/common/arrays'; @extHostNamedCustomer(MainContext.MainThreadFileSystem) export class MainThreadFileSystem implements MainThreadFileSystemShape { - private readonly _toDispose: IDisposable[] = []; private readonly _proxy: ExtHostFileSystemShape; private readonly _provider = new Map(); @@ -33,7 +34,8 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { } dispose(): void { - dispose(this._toDispose); + this._provider.forEach(value => dispose()); + this._provider.clear(); } $registerFileSystemProvider(handle: number, scheme: string): void { @@ -49,7 +51,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { this._workspaceEditingService.addFolders([{ uri: URI.revive(data) }], true).done(null, onUnexpectedError); } - $onFileSystemChange(handle: number, changes: IFileChange[]): void { + $onFileSystemChange(handle: number, changes: IFileChangeDto[]): void { this._provider.get(handle).$onFileSystemChange(changes); } @@ -59,8 +61,8 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { // --- search - $handleSearchProgress(handle: number, session: number, data: UriComponents): void { - this._provider.get(handle).handleSearchProgress(session, URI.revive(data)); + $handleFindMatch(handle: number, session, data: UriComponents | [UriComponents, ILineMatch]): void { + this._provider.get(handle).handleFindMatch(session, data); } } @@ -76,11 +78,25 @@ class FileReadOperation { } } +class SearchOperation { + + private static _idPool = 0; + + constructor( + readonly progress: (match: IFileMatch) => any, + readonly id: number = ++SearchOperation._idPool, + readonly matches = new Map() + ) { + // + } +} + class RemoteFileSystemProvider implements IFileSystemProvider, ISearchResultProvider { private readonly _onDidChange = new Emitter(); - private readonly _reads = new Map(); private readonly _registrations: IDisposable[]; + private readonly _reads = new Map(); + private readonly _searches = new Map(); readonly onDidChange: Event = this._onDidChange.event; @@ -88,12 +104,12 @@ class RemoteFileSystemProvider implements IFileSystemProvider, ISearchResultProv constructor( fileService: IFileService, searchService: ISearchService, - scheme: string, + private readonly _scheme: string, private readonly _handle: number, private readonly _proxy: ExtHostFileSystemShape ) { this._registrations = [ - fileService.registerProvider(scheme, this), + fileService.registerProvider(_scheme, this), searchService.registerSearchResultProvider(this), ]; } @@ -103,8 +119,12 @@ class RemoteFileSystemProvider implements IFileSystemProvider, ISearchResultProv this._onDidChange.dispose(); } - $onFileSystemChange(changes: IFileChange[]): void { - this._onDidChange.fire(changes); + $onFileSystemChange(changes: IFileChangeDto[]): void { + this._onDidChange.fire(changes.map(RemoteFileSystemProvider._createFileChange)); + } + + private static _createFileChange(dto: IFileChangeDto): IFileChange { + return { resource: URI.revive(dto.resource), type: dto.type }; } // --- forwarding calls @@ -118,7 +138,10 @@ class RemoteFileSystemProvider implements IFileSystemProvider, ISearchResultProv read(resource: URI, offset: number, count: number, progress: IProgress): TPromise { const read = new FileReadOperation(progress); this._reads.set(read.id, read); - return this._proxy.$read(this._handle, read.id, offset, count, resource); + return this._proxy.$read(this._handle, read.id, offset, count, resource).then(value => { + this._reads.delete(read.id); + return value; + }); } reportFileChunk(session: number, chunk: number[]): void { this._reads.get(session).progress.report(Buffer.from(chunk)); @@ -146,33 +169,58 @@ class RemoteFileSystemProvider implements IFileSystemProvider, ISearchResultProv // --- search - private _searches = new Map void>(); - private _searchesIdPool = 0; - search(query: ISearchQuery): PPromise { - if (query.type === QueryType.Text) { - return PPromise.as({ results: [], stats: undefined }); - } - const id = ++this._searchesIdPool; - const matches: IFileMatch[] = []; - return new PPromise((resolve, reject, report) => { - this._proxy.$findFiles(this._handle, id, query.filePattern).then(() => { - this._searches.delete(id); - resolve({ - results: matches, - stats: undefined - }); - }, reject); - this._searches.set(id, resource => { - const match: IFileMatch = { resource }; - matches.push(match); - report(match); + if (isFalsyOrEmpty(query.folderQueries)) { + return PPromise.as(undefined); + } + + let includes = { ...query.includePattern }; + let excludes = { ...query.excludePattern }; + + for (const folderQuery of query.folderQueries) { + if (folderQuery.folder.scheme === this._scheme) { + includes = { ...includes, ...folderQuery.includePattern }; + excludes = { ...excludes, ...folderQuery.excludePattern }; + } + } + + return new PPromise((resolve, reject, report) => { + + const search = new SearchOperation(report); + this._searches.set(search.id, search); + + const promise = query.type === QueryType.File + ? this._proxy.$findFiles(this._handle, search.id, query.filePattern) + : this._proxy.$provideTextSearchResults(this._handle, search.id, query.contentPattern, { excludes: Object.keys(excludes), includes: Object.keys(includes) }); + + promise.then(() => { + this._searches.delete(search.id); + resolve(({ results: values(search.matches), stats: undefined })); + }, err => { + this._searches.delete(search.id); + reject(err); }); }); } - handleSearchProgress(session: number, resource: URI): void { - this._searches.get(session)(resource); + handleFindMatch(session: number, dataOrUri: UriComponents | [UriComponents, ILineMatch]): void { + let resource: URI; + let match: ILineMatch; + + if (Array.isArray(dataOrUri)) { + resource = URI.revive(dataOrUri[0]); + match = dataOrUri[1]; + } else { + resource = URI.revive(dataOrUri); + } + + const { matches } = this._searches.get(session); + if (!matches.has(resource.toString())) { + matches.set(resource.toString(), { resource, lineMatches: [] }); + } + if (match) { + matches.get(resource.toString()).lineMatches.push(match); + } } } diff --git a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts index 5d0a02c34e3..07a61e0f3b8 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts @@ -26,6 +26,7 @@ import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerServ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IProgressService2, ProgressLocation } from 'vs/platform/progress/common/progress'; import { localize } from 'vs/nls'; +import { isFalsyOrEmpty } from 'vs/base/common/arrays'; export interface ISaveParticipantParticipant extends ISaveParticipant { // progressMessage: string; @@ -208,7 +209,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { }); }).then(edits => { - if (edits && versionNow === model.getVersionId()) { + if (!isFalsyOrEmpty(edits) && versionNow === model.getVersionId()) { const editor = findEditor(model, this._editorService); if (editor) { this._editsWithEditor(editor, edits); diff --git a/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts b/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts index e9730fb0ed4..67bd6438fe5 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts @@ -9,8 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { Disposable } from 'vs/base/common/lifecycle'; import { ExtHostContext, MainThreadTreeViewsShape, ExtHostTreeViewsShape, MainContext, IExtHostContext } from '../node/extHost.protocol'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; -import { ViewsRegistry } from 'vs/workbench/browser/parts/views/viewsRegistry'; -import { ITreeViewDataProvider, ITreeItem } from 'vs/workbench/common/views'; +import { ViewsRegistry, ITreeViewDataProvider, ITreeItem } from 'vs/workbench/common/views'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { assign } from 'vs/base/common/objects'; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index bd4337b59a1..4d6eb312357 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -51,7 +51,6 @@ import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions'; import { ProxyIdentifier } from 'vs/workbench/services/extensions/node/proxyIdentifier'; import { ExtHostDialogs } from 'vs/workbench/api/node/extHostDialogs'; import { ExtHostFileSystem } from 'vs/workbench/api/node/extHostFileSystem'; -import { FileChangeType, FileType } from 'vs/platform/files/common/files'; import { ExtHostDecorations } from 'vs/workbench/api/node/extHostDecorations'; import { toGlobPattern, toLanguageSelector } from 'vs/workbench/api/node/extHostTypeConverters'; import { ExtensionActivatedByAPI } from 'vs/workbench/api/node/extHostExtensionActivator'; @@ -107,8 +106,8 @@ export function createApiFactory( const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace)); rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); - const languageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics)); - const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol)); + const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics)); + const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures)); const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService()); const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol)); @@ -237,61 +236,61 @@ export function createApiFactory( return score(toLanguageSelector(selector), document.uri, document.languageId); }, registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider): vscode.Disposable { - return languageFeatures.registerCodeActionProvider(selector, provider); + return extHostLanguageFeatures.registerCodeActionProvider(selector, provider); }, registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable { - return languageFeatures.registerCodeLensProvider(selector, provider); + return extHostLanguageFeatures.registerCodeLensProvider(selector, provider); }, registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable { - return languageFeatures.registerDefinitionProvider(selector, provider); + return extHostLanguageFeatures.registerDefinitionProvider(selector, provider); }, registerImplementationProvider(selector: vscode.DocumentSelector, provider: vscode.ImplementationProvider): vscode.Disposable { - return languageFeatures.registerImplementationProvider(selector, provider); + return extHostLanguageFeatures.registerImplementationProvider(selector, provider); }, registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable { - return languageFeatures.registerTypeDefinitionProvider(selector, provider); + return extHostLanguageFeatures.registerTypeDefinitionProvider(selector, provider); }, registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable { - return languageFeatures.registerHoverProvider(selector, provider, extension.id); + return extHostLanguageFeatures.registerHoverProvider(selector, provider, extension.id); }, registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable { - return languageFeatures.registerDocumentHighlightProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentHighlightProvider(selector, provider); }, registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable { - return languageFeatures.registerReferenceProvider(selector, provider); + return extHostLanguageFeatures.registerReferenceProvider(selector, provider); }, registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable { - return languageFeatures.registerRenameProvider(selector, provider); + return extHostLanguageFeatures.registerRenameProvider(selector, provider); }, registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider): vscode.Disposable { - return languageFeatures.registerDocumentSymbolProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentSymbolProvider(selector, provider); }, registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable { - return languageFeatures.registerWorkspaceSymbolProvider(provider); + return extHostLanguageFeatures.registerWorkspaceSymbolProvider(provider); }, registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable { - return languageFeatures.registerDocumentFormattingEditProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentFormattingEditProvider(selector, provider); }, registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable { - return languageFeatures.registerDocumentRangeFormattingEditProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentRangeFormattingEditProvider(selector, provider); }, registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacters: string[]): vscode.Disposable { - return languageFeatures.registerOnTypeFormattingEditProvider(selector, provider, [firstTriggerCharacter].concat(moreTriggerCharacters)); + return extHostLanguageFeatures.registerOnTypeFormattingEditProvider(selector, provider, [firstTriggerCharacter].concat(moreTriggerCharacters)); }, registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, ...triggerCharacters: string[]): vscode.Disposable { - return languageFeatures.registerSignatureHelpProvider(selector, provider, triggerCharacters); + return extHostLanguageFeatures.registerSignatureHelpProvider(selector, provider, triggerCharacters); }, registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable { - return languageFeatures.registerCompletionItemProvider(selector, provider, triggerCharacters); + return extHostLanguageFeatures.registerCompletionItemProvider(selector, provider, triggerCharacters); }, registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable { - return languageFeatures.registerDocumentLinkProvider(selector, provider); + return extHostLanguageFeatures.registerDocumentLinkProvider(selector, provider); }, registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable { - return languageFeatures.registerColorProvider(selector, provider); + return extHostLanguageFeatures.registerColorProvider(selector, provider); }, setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => { - return languageFeatures.setLanguageConfiguration(language, configuration); + return extHostLanguageFeatures.setLanguageConfiguration(language, configuration); } }; @@ -616,9 +615,8 @@ export function createApiFactory( ConfigurationTarget: extHostTypes.ConfigurationTarget, RelativePattern: extHostTypes.RelativePattern, - // TODO@JOH,remote - FileChangeType: FileChangeType, - FileType: FileType + FileChangeType: extHostTypes.FileChangeType, + FileType: extHostTypes.FileType }; }; } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index dad2c493041..347ab9e9328 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -48,11 +48,12 @@ import { ITreeItem } from 'vs/workbench/common/views'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; import { IDisposable } from 'vs/base/common/lifecycle'; import { SerializedError } from 'vs/base/common/errors'; -import { IStat, IFileChange } from 'vs/platform/files/common/files'; +import { IStat, FileChangeType } from 'vs/platform/files/common/files'; import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { CommentRule, CharacterPair, EnterAction } from 'vs/editor/common/modes/languageConfiguration'; -import { ISingleEditOperation } from 'vs/editor/common/model'; +import { EndOfLineSequence, ISingleEditOperation } from 'vs/editor/common/model'; +import { ILineMatch, IPatternInfo } from 'vs/platform/search/common/search'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -353,15 +354,20 @@ export interface MainThreadWorkspaceShape extends IDisposable { $saveAll(includeUntitled?: boolean): Thenable; } +export interface IFileChangeDto { + resource: UriComponents; + type: FileChangeType; +} + export interface MainThreadFileSystemShape extends IDisposable { $registerFileSystemProvider(handle: number, scheme: string): void; $unregisterFileSystemProvider(handle: number): void; $onDidAddFileSystemRoot(root: UriComponents): void; - $onFileSystemChange(handle: number, resource: IFileChange[]): void; + $onFileSystemChange(handle: number, resource: IFileChangeDto[]): void; $reportFileChunk(handle: number, session: number, chunk: number[] | null): void; - $handleSearchProgress(handle: number, session: number, resource: UriComponents): void; + $handleFindMatch(handle: number, session, data: UriComponents | [UriComponents, ILineMatch]): void; } export interface MainThreadTaskShape extends IDisposable { @@ -531,6 +537,7 @@ export interface ExtHostFileSystemShape { $readdir(handle: number, resource: UriComponents): TPromise<[UriComponents, IStat][]>; $rmdir(handle: number, resource: UriComponents): TPromise; $findFiles(handle: number, session: number, query: string): TPromise; + $provideTextSearchResults(handle: number, session: number, pattern: IPatternInfo, options: { includes: string[], excludes: string[] }): TPromise; } export interface ExtHostExtensionServiceShape { diff --git a/src/vs/workbench/api/node/extHostApiCommands.ts b/src/vs/workbench/api/node/extHostApiCommands.ts index d29bab7425a..cc2e30d0f82 100644 --- a/src/vs/workbench/api/node/extHostApiCommands.ts +++ b/src/vs/workbench/api/node/extHostApiCommands.ts @@ -239,6 +239,15 @@ export class ExtHostApiCommands { { name: 'columnOrOptions', description: '(optional) Either the column in which to open or editor options, see vscode.TextDocumentShowOptions', constraint: v => v === void 0 || typeof v === 'number' || typeof v === 'object' } ] }); + + this._register('vscode.removeFromRecentlyOpened', (path: string) => { + return this._commands.executeCommand('_workbench.removeFromRecentlyOpened', path); + }, { + description: 'Removes an entry with the given path from the recently opened list.', + args: [ + { name: 'path', description: 'Path to remove from recently opened.', constraint: value => typeof value === 'string' } + ] + }); } // --- command impl diff --git a/src/vs/workbench/api/node/extHostDocumentContentProviders.ts b/src/vs/workbench/api/node/extHostDocumentContentProviders.ts index fe2b2937aad..719db9d89b8 100644 --- a/src/vs/workbench/api/node/extHostDocumentContentProviders.ts +++ b/src/vs/workbench/api/node/extHostDocumentContentProviders.ts @@ -32,6 +32,8 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro } registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider): vscode.Disposable { + // todo@remote + // check with scheme from fs-providers! if (scheme === 'file' || scheme === 'untitled') { throw new Error(`scheme '${scheme}' already registered`); } diff --git a/src/vs/workbench/api/node/extHostDocumentData.ts b/src/vs/workbench/api/node/extHostDocumentData.ts index 20c9fe31052..2be3ac6908d 100644 --- a/src/vs/workbench/api/node/extHostDocumentData.ts +++ b/src/vs/workbench/api/node/extHostDocumentData.ts @@ -68,6 +68,8 @@ export class ExtHostDocumentData extends MirrorTextModel { this._document = { get uri() { return data._uri; }, get fileName() { return data._uri.fsPath; }, + // todo@remote + // documents from other fs-provider must not be untitled get isUntitled() { return data._uri.scheme !== 'file'; }, get languageId() { return data._languageId; }, get version() { return data._versionId; }, diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 0767c62d320..d39a58a432e 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -6,7 +6,7 @@ import { dispose } from 'vs/base/common/lifecycle'; import { join } from 'path'; -import { mkdirp, dirExists, realpath } from 'vs/base/node/pfs'; +import { mkdirp, dirExists, realpath, writeFile } from 'vs/base/node/pfs'; import Severity from 'vs/base/common/severity'; import { TPromise } from 'vs/base/common/winjs.base'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/node/extensionDescriptionRegistry'; @@ -88,24 +88,35 @@ class ExtensionStoragePath { return undefined; } - private _getOrCreateWorkspaceStoragePath(): TPromise { + private async _getOrCreateWorkspaceStoragePath(): TPromise { if (!this._workspace) { return TPromise.as(undefined); } + const storageName = this._workspace.id; const storagePath = join(this._environment.appSettingsHome, 'workspaceStorage', storageName); - return dirExists(storagePath).then(exists => { - if (exists) { - return storagePath; - } + const exists = await dirExists(storagePath); - return mkdirp(storagePath).then(success => { - return storagePath; - }, err => { - return undefined; - }); - }); + if (exists) { + return storagePath; + } + + try { + await mkdirp(storagePath); + await writeFile( + join(storagePath, 'meta.json'), + JSON.stringify({ + id: this._workspace.id, + name: this._workspace.name + }, undefined, 2) + ); + return storagePath; + + } catch (e) { + console.error(e); + return undefined; + } } } diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index c2ad87af990..7a8b780fcc4 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -11,22 +11,72 @@ import * as vscode from 'vscode'; import { IStat } from 'vs/platform/files/common/files'; import { IDisposable } from 'vs/base/common/lifecycle'; import { asWinJsPromise } from 'vs/base/common/async'; +import { IPatternInfo } from 'vs/platform/search/common/search'; +import { values } from 'vs/base/common/map'; +import { Range } from 'vs/workbench/api/node/extHostTypes'; +import { ExtHostLanguageFeatures } from 'vs/workbench/api/node/extHostLanguageFeatures'; + +class FsLinkProvider implements vscode.DocumentLinkProvider { + + private _schemes = new Set(); + private _regex: RegExp; + + add(scheme: string): void { + this._regex = undefined; + this._schemes.add(scheme); + } + + delete(scheme: string): void { + if (this._schemes.delete(scheme)) { + this._regex = undefined; + } + } + + provideDocumentLinks(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.ProviderResult { + if (this._schemes.size === 0) { + return undefined; + } + if (!this._regex) { + this._regex = new RegExp(`(${(values(this._schemes).join('|'))}):[^\\s]+`, 'gi'); + } + let result: vscode.DocumentLink[] = []; + let max = Math.min(document.lineCount, 2500); + for (let line = 0; line < max; line++) { + this._regex.lastIndex = 0; + let textLine = document.lineAt(line); + let m: RegExpMatchArray; + while (m = this._regex.exec(textLine.text)) { + const target = URI.parse(m[0]); + const range = new Range(line, this._regex.lastIndex - m[0].length, line, this._regex.lastIndex); + result.push({ target, range }); + } + } + return result; + } +} export class ExtHostFileSystem implements ExtHostFileSystemShape { private readonly _proxy: MainThreadFileSystemShape; private readonly _provider = new Map(); + private readonly _linkProvider = new FsLinkProvider(); + private _handlePool: number = 0; - constructor(mainContext: IMainContext) { + constructor(mainContext: IMainContext, extHostLanguageFeatures: ExtHostLanguageFeatures) { this._proxy = mainContext.getProxy(MainContext.MainThreadFileSystem); + extHostLanguageFeatures.registerDocumentLinkProvider('*', this._linkProvider); } registerFileSystemProvider(scheme: string, provider: vscode.FileSystemProvider) { const handle = this._handlePool++; + this._linkProvider.add(scheme); this._provider.set(handle, provider); this._proxy.$registerFileSystemProvider(handle, scheme); - this._proxy.$onDidAddFileSystemRoot(provider.root); + if (provider.root) { + // todo@remote + this._proxy.$onDidAddFileSystemRoot(provider.root); + } let reg: IDisposable; if (provider.onDidChange) { reg = provider.onDidChange(event => this._proxy.$onFileSystemChange(handle, event)); @@ -36,6 +86,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { if (reg) { reg.dispose(); } + this._linkProvider.delete(scheme); this._provider.delete(handle); this._proxy.$unregisterFileSystemProvider(handle); } @@ -79,7 +130,27 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { if (!provider.findFiles) { return TPromise.as(undefined); } - const progress = { report: (uri) => this._proxy.$handleSearchProgress(handle, session, uri) }; + const progress = { + report: (uri) => { + this._proxy.$handleFindMatch(handle, session, uri); + } + }; return asWinJsPromise(token => provider.findFiles(query, progress, token)); } + $provideTextSearchResults(handle: number, session: number, pattern: IPatternInfo, options: { includes: string[], excludes: string[] }): TPromise { + const provider = this._provider.get(handle); + if (!provider.provideTextSearchResults) { + return TPromise.as(undefined); + } + const progress = { + report: (data: vscode.TextSearchResult) => { + this._proxy.$handleFindMatch(handle, session, [data.uri, { + lineNumber: 1 + data.range.start.line, + preview: data.preview.leading + data.preview.matching + data.preview.trailing, + offsetAndLengths: [[data.preview.leading.length, data.preview.matching.length]] + }]); + } + }; + return asWinJsPromise(token => provider.provideTextSearchResults(pattern, options, progress, token)); + } } diff --git a/src/vs/workbench/api/node/extHostTreeViews.ts b/src/vs/workbench/api/node/extHostTreeViews.ts index 5ebf180db38..a1807377c88 100644 --- a/src/vs/workbench/api/node/extHostTreeViews.ts +++ b/src/vs/workbench/api/node/extHostTreeViews.ts @@ -6,6 +6,7 @@ import { localize } from 'vs/nls'; import * as vscode from 'vscode'; +import { basename } from 'vs/base/common/paths'; import URI from 'vs/base/common/uri'; import { debounceEvent } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -77,7 +78,10 @@ interface TreeNode { class ExtHostTreeView extends Disposable { - private static ROOT_HANDLE = '0'; + private static LABEL_HANDLE_PREFIX = '0'; + private static ID_HANDLE_PREFIX = '1'; + + private rootHandles: TreeItemHandle[] = []; private elements: Map = new Map(); private nodes: Map = new Map(); @@ -85,49 +89,39 @@ class ExtHostTreeView extends Disposable { super(); this.proxy.$registerView(viewId); if (dataProvider.onDidChangeTreeData) { - this._register(debounceEvent(dataProvider.onDidChangeTreeData, (last, current) => last ? [...last, current] : [current], 200)(elements => this._refresh(elements))); + this._register(debounceEvent(dataProvider.onDidChangeTreeData, (last, current) => last ? [...last, current] : [current], 200)(elements => this.refresh(elements))); } } getChildren(parentHandle?: TreeItemHandle): TPromise { - let parentElement; - if (parentHandle) { - parentElement = this.getExtensionElement(parentHandle); - if (!parentElement) { - return TPromise.wrapError(new Error(localize('treeItem.notFound', 'No tree item with id \'{0}\' found.', parentHandle))); - } + const parentElement = parentHandle ? this.getExtensionElement(parentHandle) : void 0; + if (parentHandle && !parentElement) { + console.error(`No tree item with id \'${parentHandle}\' found.`); + return TPromise.as([]); } + this.clearChildren(parentElement); return asWinJsPromise(() => this.dataProvider.getChildren(parentElement)) - .then(elements => { - elements = coalesce(elements || []); - return TPromise.join(elements.map((element, index) => { - const node = this.nodes.get(element); - const currentHandle = node && node.parentHandle === parentHandle ? node.handle : void 0; - return this.resolveElement(element, currentHandle ? currentHandle : index, parentHandle) - .then(treeItem => { - if (treeItem) { - if (!currentHandle) { - // update the caches if current handle is not used - this.nodes.set(element, { - handle: treeItem.handle, - parentHandle, - childrenHandles: void 0 - }); - this.elements.set(treeItem.handle, element); + .then(elements => TPromise.join( + coalesce(elements || []).map(element => + asWinJsPromise(() => this.dataProvider.getTreeItem(element)) + .then(extTreeItem => { + if (extTreeItem) { + if (extTreeItem.id && this.elements.has(this.createHandle(element, extTreeItem))) { + throw new Error(localize('treeView.duplicateElement', 'Element with id {0} is already registered', extTreeItem.id)); } + return { element, extTreeItem }; } - return treeItem; - }); - })).then(treeItems => this.updateChildren(coalesce(treeItems), parentElement)); - }); + return null; + }) + ))).then(extTreeItems => extTreeItems.map((({ element, extTreeItem }) => this.createTreeItem(element, extTreeItem, parentHandle)))); } getExtensionElement(treeItemHandle: TreeItemHandle): T { return this.elements.get(treeItemHandle); } - private _refresh(elements: T[]): void { + private refresh(elements: T[]): void { const hasRoot = elements.some(element => !element); if (hasRoot) { this.proxy.$refresh(this.viewId); @@ -139,64 +133,6 @@ class ExtHostTreeView extends Disposable { } } - private resolveElement(element: T, handleOrIndex: TreeItemHandle | number, parentHandle: TreeItemHandle): TPromise { - return asWinJsPromise(() => this.dataProvider.getTreeItem(element)) - .then(extTreeItem => this.massageTreeItem(element, extTreeItem, handleOrIndex, parentHandle)); - } - - private massageTreeItem(element: T, extensionTreeItem: vscode.TreeItem, handleOrIndex: TreeItemHandle | number, parentHandle: TreeItemHandle): ITreeItem { - if (!extensionTreeItem) { - return null; - } - - const icon = this.getLightIconPath(extensionTreeItem); - const label = extensionTreeItem.label; - const handle = typeof handleOrIndex === 'number' ? - this.generateHandle(label, handleOrIndex, parentHandle) // create the handle - : handleOrIndex; // reuse the passed handle - - return { - handle, - parentHandle, - label, - command: extensionTreeItem.command ? this.commands.toInternal(extensionTreeItem.command) : void 0, - contextValue: extensionTreeItem.contextValue, - icon, - iconDark: this.getDarkIconPath(extensionTreeItem) || icon, - collapsibleState: extensionTreeItem.collapsibleState - }; - } - - private generateHandle(label: string, index: number, parentHandle: TreeItemHandle): TreeItemHandle { - parentHandle = parentHandle ? parentHandle : ExtHostTreeView.ROOT_HANDLE; - label = label.indexOf('/') !== -1 ? label.replace('/', '//') : label; - return `${parentHandle}/${index}:${label}`; - } - - private getLightIconPath(extensionTreeItem: vscode.TreeItem): string { - if (extensionTreeItem.iconPath) { - if (typeof extensionTreeItem.iconPath === 'string' || extensionTreeItem.iconPath instanceof URI) { - return this.getIconPath(extensionTreeItem.iconPath); - } - return this.getIconPath(extensionTreeItem.iconPath['light']); - } - return void 0; - } - - private getDarkIconPath(extensionTreeItem: vscode.TreeItem): string { - if (extensionTreeItem.iconPath && extensionTreeItem.iconPath['dark']) { - return this.getIconPath(extensionTreeItem.iconPath['dark']); - } - return void 0; - } - - private getIconPath(iconPath: string | URI): string { - if (iconPath instanceof URI) { - return iconPath.toString(); - } - return URI.file(iconPath).toString(); - } - private getHandlesToRefresh(elements: T[]): TreeItemHandle[] { const elementsToUpdate = new Set(); for (const element of elements) { @@ -233,39 +169,125 @@ class ExtHostTreeView extends Disposable { itemHandles.forEach(treeItemHandle => { const extElement = this.getExtensionElement(treeItemHandle); const node = this.nodes.get(extElement); - promises.push(this.resolveElement(extElement, treeItemHandle, node.parentHandle) - .then(treeItem => { - itemsToRefresh[treeItemHandle] = treeItem; + promises.push(asWinJsPromise(() => this.dataProvider.getTreeItem(extElement)) + .then(extTreeItem => { + if (extTreeItem) { + itemsToRefresh[treeItemHandle] = this.createTreeItem(extElement, extTreeItem, node.parentHandle); + } })); }); return TPromise.join(promises) - .then(treeItems => { - this.proxy.$refresh(this.viewId, itemsToRefresh); - }); + .then(treeItems => this.proxy.$refresh(this.viewId, itemsToRefresh)); } - private updateChildren(newChildren: ITreeItem[], parentElement?: T): ITreeItem[] { - let existingChildrenHandles: TreeItemHandle[] = []; - if (parentElement) { - const parentNode = this.nodes.get(parentElement); - existingChildrenHandles = parentNode.childrenHandles || []; - parentNode.childrenHandles = newChildren.map(c => c.handle); - } else { - this.nodes.forEach(node => { - if (!node.parentHandle) { - existingChildrenHandles.push(node.handle); - } - }); + private createTreeItem(element: T, extensionTreeItem: vscode.TreeItem, parentHandle: TreeItemHandle): ITreeItem { + + const handle = this.createHandle(element, extensionTreeItem, parentHandle); + const icon = this.getLightIconPath(extensionTreeItem); + this.update(element, handle, parentHandle); + + return { + handle, + parentHandle, + label: extensionTreeItem.label, + resourceUri: extensionTreeItem.resourceUri, + command: extensionTreeItem.command ? this.commands.toInternal(extensionTreeItem.command) : void 0, + contextValue: extensionTreeItem.contextValue, + icon, + iconDark: this.getDarkIconPath(extensionTreeItem) || icon, + collapsibleState: extensionTreeItem.collapsibleState + }; + } + + private createHandle(element: T, { id, label, resourceUri }: vscode.TreeItem, parentHandle?: TreeItemHandle): TreeItemHandle { + if (id) { + return `${ExtHostTreeView.ID_HANDLE_PREFIX}/${id}`; } - for (const existingChildHandle of existingChildrenHandles) { - const existingChildElement = this.elements.get(existingChildHandle); - if (existingChildElement && newChildren.every(c => c.handle !== existingChildHandle)) { - this.clear(existingChildElement); + const prefix = parentHandle ? parentHandle : ExtHostTreeView.LABEL_HANDLE_PREFIX; + let elementId = label ? label : basename(resourceUri.path); + elementId = elementId.indexOf('/') !== -1 ? elementId.replace('/', '//') : elementId; + const existingHandle = this.nodes.has(element) ? this.nodes.get(element).handle : void 0; + + for (let counter = 0; counter <= this.getChildrenHandles(parentHandle).length; counter++) { + const handle = `${prefix}/${counter}:${elementId}`; + if (!this.elements.has(handle) || existingHandle === handle) { + return handle; } } - return newChildren; + throw new Error('This should not be reached'); + } + + private getLightIconPath(extensionTreeItem: vscode.TreeItem): string { + if (extensionTreeItem.iconPath) { + if (typeof extensionTreeItem.iconPath === 'string' || extensionTreeItem.iconPath instanceof URI) { + return this.getIconPath(extensionTreeItem.iconPath); + } + return this.getIconPath(extensionTreeItem.iconPath['light']); + } + return void 0; + } + + private getDarkIconPath(extensionTreeItem: vscode.TreeItem): string { + if (extensionTreeItem.iconPath && extensionTreeItem.iconPath['dark']) { + return this.getIconPath(extensionTreeItem.iconPath['dark']); + } + return void 0; + } + + private getIconPath(iconPath: string | URI): string { + if (iconPath instanceof URI) { + return iconPath.toString(); + } + return URI.file(iconPath).toString(); + } + + private getChildrenHandles(parentHandle?: TreeItemHandle): TreeItemHandle[] { + return parentHandle ? this.nodes.get(this.getExtensionElement(parentHandle)).childrenHandles : this.rootHandles; + } + + private update(element: T, handle: TreeItemHandle, parentHandle: TreeItemHandle): void { + const node = this.nodes.get(element); + const childrenHandles = this.getChildrenHandles(parentHandle); + + // Update parent node + if (node) { + if (node.handle !== handle) { + // Remove the old handle from the system + this.elements.delete(node.handle); + childrenHandles[childrenHandles.indexOf(node.handle)] = handle; + + this.clearChildren(element); + } + } else { + childrenHandles.push(handle); + } + + // Update element maps + this.elements.set(handle, element); + this.nodes.set(element, { + handle, + parentHandle, + childrenHandles: node ? node.childrenHandles : [] + }); + } + + private clearChildren(parentElement?: T): void { + if (parentElement) { + let node = this.nodes.get(parentElement); + if (node.childrenHandles) { + for (const childHandle of node.childrenHandles) { + const childEleement = this.elements.get(childHandle); + if (childEleement) { + this.clear(childEleement); + } + } + } + node.childrenHandles = []; + } else { + this.clearAll(); + } } private clear(element: T): void { @@ -282,8 +304,13 @@ class ExtHostTreeView extends Disposable { this.elements.delete(node.handle); } - dispose() { + private clearAll(): void { + this.rootHandles = []; this.elements.clear(); this.nodes.clear(); } + + dispose() { + this.clearAll(); + } } \ No newline at end of file diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index af3ba6607cd..38ce5b91889 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -360,7 +360,8 @@ export namespace CompletionTriggerKind { switch (kind) { case modes.SuggestTriggerKind.TriggerCharacter: return types.CompletionTriggerKind.TriggerCharacter; - + case modes.SuggestTriggerKind.TriggerForIncompleteCompletions: + return types.CompletionTriggerKind.TriggerForIncompleteCompletions; case modes.SuggestTriggerKind.Invoke: default: return types.CompletionTriggerKind.Invoke; diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index b7351530c0c..59416044954 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -946,7 +946,8 @@ export class SignatureHelp { export enum CompletionTriggerKind { Invoke = 0, - TriggerCharacter = 1 + TriggerCharacter = 1, + TriggerForIncompleteCompletions = 2 } export interface CompletionContext { @@ -1479,11 +1480,20 @@ export enum ProgressLocation { export class TreeItem { + label?: string; + resourceUri?: URI; iconPath?: string | URI | { light: string | URI; dark: string | URI }; command?: vscode.Command; contextValue?: string; - constructor(public label: string, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) { + constructor(label: string, collapsibleState?: vscode.TreeItemCollapsibleState) + constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState) + constructor(arg1: string | URI, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) { + if (arg1 instanceof URI) { + this.resourceUri = arg1; + } else { + this.label = arg1; + } } } @@ -1575,3 +1585,19 @@ export enum LogLevel { Critical = 6, Off = 7 } + +//#region file api +// todo@remote +export enum FileChangeType { + Updated = 0, + Added = 1, + Deleted = 2 +} + +export enum FileType { + File = 0, + Dir = 1, + Symlink = 2 +} + +//#endregion diff --git a/src/vs/workbench/browser/actions/toggleSidebarPosition.ts b/src/vs/workbench/browser/actions/toggleSidebarPosition.ts index 2dc5bab450f..d338760c2c3 100644 --- a/src/vs/workbench/browser/actions/toggleSidebarPosition.ts +++ b/src/vs/workbench/browser/actions/toggleSidebarPosition.ts @@ -16,7 +16,7 @@ import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configur export class ToggleSidebarPositionAction extends Action { public static readonly ID = 'workbench.action.toggleSidebarPosition'; - public static readonly LABEL = nls.localize('toggleLocation', "Toggle Side Bar Location"); + public static readonly LABEL = nls.localize('toggleSidebarPosition', "Toggle Side Bar Position"); private static readonly sidebarPositionConfigurationKey = 'workbench.sideBar.location'; @@ -40,4 +40,4 @@ export class ToggleSidebarPositionAction extends Action { } const registry = Registry.as(Extensions.WorkbenchActions); -registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleSidebarPositionAction, ToggleSidebarPositionAction.ID, ToggleSidebarPositionAction.LABEL), 'View: Toggle Side Bar Location', nls.localize('view', "View")); \ No newline at end of file +registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleSidebarPositionAction, ToggleSidebarPositionAction.ID, ToggleSidebarPositionAction.LABEL), 'View: Toggle Side Bar Position', nls.localize('view', "View")); diff --git a/src/vs/workbench/browser/actions/workspaceCommands.ts b/src/vs/workbench/browser/actions/workspaceCommands.ts index 2ef4aa69ab4..6849aabe033 100644 --- a/src/vs/workbench/browser/actions/workspaceCommands.ts +++ b/src/vs/workbench/browser/actions/workspaceCommands.ts @@ -24,12 +24,9 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { isLinux } from 'vs/base/common/platform'; -export const ADD_ROOT_FOLDER_COMMAND_ID = 'workbench.command.addRootFolder'; +export const ADD_ROOT_FOLDER_COMMAND_ID = 'addRootFolder'; export const ADD_ROOT_FOLDER_LABEL = nls.localize('addFolderToWorkspace', "Add Folder to Workspace..."); -export const REMOVE_ROOT_FOLDER_COMMAND_ID = 'workbench.command.removeRootFolder'; -export const REMOVE_ROOT_FOLDER_LABEL = nls.localize('removeFolderFromWorkspace', "Remove Folder from Workspace"); - export const PICK_WORKSPACE_FOLDER_COMMAND_ID = '_workbench.pickWorkspaceFolder'; function pickFolders(buttonLabel: string, title: string, windowService: IWindowService, contextService: IWorkspaceContextService, historyService: IHistoryService): TPromise { @@ -158,14 +155,6 @@ CommandsRegistry.registerCommand({ } }); -CommandsRegistry.registerCommand({ - id: REMOVE_ROOT_FOLDER_COMMAND_ID, - handler: (accessor, resource: URI) => { - const workspaceEditingService = accessor.get(IWorkspaceEditingService); - return workspaceEditingService.removeFolders([resource]); - } -}); - CommandsRegistry.registerCommand(PICK_WORKSPACE_FOLDER_COMMAND_ID, function (accessor, args?: [IPickOptions, CancellationToken]) { const contextService = accessor.get(IWorkspaceContextService); const quickOpenService = accessor.get(IQuickOpenService); diff --git a/src/vs/workbench/browser/editor.ts b/src/vs/workbench/browser/editor.ts index 16a6140a6e4..35486960348 100644 --- a/src/vs/workbench/browser/editor.ts +++ b/src/vs/workbench/browser/editor.ts @@ -241,13 +241,19 @@ export function extractResources(e: DragEvent, externalOnly?: boolean): (IDragge // Data Transfer: URL else { - const rawURLData = e.dataTransfer.getData(DataTransfers.URL); - if (rawURLData) { - try { - resources.push({ resource: URI.parse(rawURLData), isExternal: false }); - } catch (error) { - // Invalid URI + try { + const rawURLsData = e.dataTransfer.getData(DataTransfers.URLS); + if (rawURLsData) { + const uriStrArray: string[] = JSON.parse(rawURLsData); + resources.push(...uriStrArray.map(uriStr => ({ resource: URI.parse(uriStr), isExternal: false }))); + } else { + const rawURLData = e.dataTransfer.getData(DataTransfers.URL); + if (rawURLData) { + resources.push({ resource: URI.parse(rawURLData), isExternal: false }); + } } + } catch (error) { + // Invalid URI } } } @@ -268,4 +274,4 @@ export function extractResources(e: DragEvent, externalOnly?: boolean): (IDragge } return resources; -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 81b49fbed8d..371db68f7da 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -451,7 +451,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.statusbarHeight = isStatusbarHidden ? 0 : this.partLayoutInfo.statusbar.height; this.titlebarHeight = isTitlebarHidden ? 0 : this.partLayoutInfo.titlebar.height / getZoomFactor(); // adjust for zoom prevention - const previousMaxPanelHeight = this.sidebarHeight - this.partLayoutInfo.editor.minHeight; this.sidebarHeight = this.workbenchSize.height - this.statusbarHeight - this.titlebarHeight; let sidebarSize = new Dimension(this.sidebarWidth, this.sidebarHeight); @@ -468,9 +467,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal panelHeight = 0; panelWidth = 0; } else if (panelPosition === Position.BOTTOM) { - if (this.panelHeight === previousMaxPanelHeight) { - panelHeight = maxPanelHeight; - } else if (this.panelHeight > 0) { + if (this.panelHeight > 0) { panelHeight = Math.min(maxPanelHeight, Math.max(this.partLayoutInfo.panel.minHeight, this.panelHeight)); } else { panelHeight = sidebarSize.height * DEFAULT_PANEL_SIZE_COEFFICIENT; diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 9d52f097832..627be4bee34 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -217,12 +217,4 @@ export class ActivitybarPart extends Part { super.dispose(); } - - public shutdown(): void { - // Persist Hidden State - this.compositeBar.store(); - - // Pass to super - super.shutdown(); - } } diff --git a/src/vs/workbench/browser/parts/compositebar/compositeBar.ts b/src/vs/workbench/browser/parts/compositebar/compositeBar.ts index 3cd5c0e3e77..b08ad7ef369 100644 --- a/src/vs/workbench/browser/parts/compositebar/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositebar/compositeBar.ts @@ -371,6 +371,7 @@ export class CompositeBar implements ICompositeBar { const visibleComposites = this.getVisibleComposites(); let unpinPromise: TPromise; + // remove from pinned const index = this.pinnedComposites.indexOf(compositeId); this.pinnedComposites.splice(index, 1); @@ -402,6 +403,9 @@ export class CompositeBar implements ICompositeBar { unpinPromise.then(() => { this.updateCompositeSwitcher(); }); + + // Persist + this.savePinnedComposites(); } public isPinned(compositeId: string): boolean { @@ -420,6 +424,9 @@ export class CompositeBar implements ICompositeBar { if (update) { this.updateCompositeSwitcher(); } + + // Persist + this.savePinnedComposites(); }); } @@ -449,6 +456,9 @@ export class CompositeBar implements ICompositeBar { setTimeout(() => { this.updateCompositeSwitcher(); }, 0); + + // Persist + this.savePinnedComposites(); } public layout(dimension: Dimension): void { @@ -472,7 +482,7 @@ export class CompositeBar implements ICompositeBar { this.updateCompositeSwitcher(); } - public store(): void { + private savePinnedComposites(): void { this.storageService.store(this.options.storageId, JSON.stringify(this.pinnedComposites), StorageScope.GLOBAL); } diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 6dad076f492..81e001915bb 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -9,20 +9,20 @@ import nls = require('vs/nls'); import { Action } from 'vs/base/common/actions'; import { mixin } from 'vs/base/common/objects'; import { getCodeEditor } from 'vs/editor/browser/services/codeEditorService'; -import { EditorInput, TextEditorOptions, EditorOptions, IEditorIdentifier, IEditorContext, ActiveEditorMoveArguments, ActiveEditorMovePositioning, EditorCommands, ConfirmResult } from 'vs/workbench/common/editor'; +import { EditorInput, TextEditorOptions, EditorOptions, IEditorIdentifier, ActiveEditorMoveArguments, ActiveEditorMovePositioning, EditorCommands, ConfirmResult } from 'vs/workbench/common/editor'; import { QuickOpenEntryGroup } from 'vs/base/parts/quickopen/browser/quickOpenModel'; import { EditorQuickOpenEntry, EditorQuickOpenEntryGroup, IEditorQuickOpenEntry, QuickOpenAction } from 'vs/workbench/browser/quickopen'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IPartService } from 'vs/workbench/services/part/common/partService'; -import { Position, IEditor, Direction, IResourceInput, IEditorInput } from 'vs/platform/editor/common/editor'; +import { Position, IEditor, Direction, IResourceInput, IEditorInput, POSITIONS } from 'vs/platform/editor/common/editor'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IEditorGroupService, GroupArrangement } from 'vs/workbench/services/group/common/groupService'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IWindowsService } from 'vs/platform/windows/common/windows'; -import { CLOSE_UNMODIFIED_EDITORS_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, NAVIGATE_IN_GROUP_ONE_PREFIX, NAVIGATE_ALL_EDITORS_GROUP_PREFIX, NAVIGATE_IN_GROUP_THREE_PREFIX, NAVIGATE_IN_GROUP_TWO_PREFIX } from 'vs/workbench/browser/parts/editor/editorCommands'; +import { CLOSE_EDITOR_COMMAND_ID, NAVIGATE_IN_GROUP_ONE_PREFIX, NAVIGATE_ALL_EDITORS_GROUP_PREFIX, NAVIGATE_IN_GROUP_THREE_PREFIX, NAVIGATE_IN_GROUP_TWO_PREFIX } from 'vs/workbench/browser/parts/editor/editorCommands'; export class SplitEditorAction extends Action { @@ -38,7 +38,7 @@ export class SplitEditorAction extends Action { super(id, label, 'split-editor-action'); } - public run(context?: IEditorContext): TPromise { + public run(context?: IEditorIdentifier): TPromise { let editorToSplit: IEditor; if (context) { editorToSplit = this.editorService.getVisibleEditors()[this.editorGroupService.getStacksModel().positionOfGroup(context.group)]; @@ -119,7 +119,7 @@ export class JoinTwoGroupsAction extends Action { super(id, label); } - public run(context?: IEditorContext): TPromise { + public run(context?: IEditorIdentifier): TPromise { const editorStacksModel = this.editorGroupService.getStacksModel(); @@ -537,7 +537,7 @@ export class CloseEditorAction extends Action { super(id, label, 'close-editor-action'); } - public run(context?: IEditorContext): TPromise { + public run(context?: IEditorIdentifier): TPromise { return this.commandService.executeCommand(CLOSE_EDITOR_COMMAND_ID, void 0, context); } } @@ -589,7 +589,7 @@ export class CloseLeftEditorsInGroupAction extends Action { super(id, label); } - public run(context?: IEditorContext): TPromise { + public run(context?: IEditorIdentifier): TPromise { const editor = getTarget(this.editorService, this.groupService, context); if (editor) { return this.editorService.closeEditors(editor.position, { except: editor.input, direction: Direction.LEFT }); @@ -617,7 +617,7 @@ export class CloseAllEditorsAction extends Action { // Just close all if there are no or one dirty editor if (this.textFileService.getDirty().length < 2) { - return this.editorService.closeAllEditors(); + return this.editorService.closeEditors(); } // Otherwise ask for combined confirmation @@ -635,7 +635,7 @@ export class CloseAllEditorsAction extends Action { return saveOrRevertPromise.then(success => { if (success) { - return this.editorService.closeAllEditors(); + return this.editorService.closeEditors(); } return void 0; @@ -644,24 +644,6 @@ export class CloseAllEditorsAction extends Action { } } -export class CloseUnmodifiedEditorsInGroupAction extends Action { - - public static readonly ID = 'workbench.action.closeUnmodifiedEditors'; - public static readonly LABEL = nls.localize('closeUnmodifiedEditors', "Close Unmodified Editors in Group"); - - constructor( - id: string, - label: string, - @ICommandService private commandService: ICommandService - ) { - super(id, label); - } - - public run(context?: IEditorContext): TPromise { - return this.commandService.executeCommand(CLOSE_UNMODIFIED_EDITORS_COMMAND_ID, void 0, context); - } -} - export class CloseEditorsInOtherGroupsAction extends Action { public static readonly ID = 'workbench.action.closeEditorsInOtherGroups'; @@ -676,7 +658,7 @@ export class CloseEditorsInOtherGroupsAction extends Action { super(id, label); } - public run(context?: IEditorContext): TPromise { + public run(context?: IEditorIdentifier): TPromise { let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null; if (typeof position !== 'number') { const activeEditor = this.editorService.getActiveEditor(); @@ -686,31 +668,13 @@ export class CloseEditorsInOtherGroupsAction extends Action { } if (typeof position === 'number') { - return this.editorService.closeAllEditors(position); + return this.editorService.closeEditors(POSITIONS.filter(p => p !== position)); } return TPromise.as(false); } } -export class CloseEditorsInGroupAction extends Action { - - public static readonly ID = 'workbench.action.closeEditorsInGroup'; - public static readonly LABEL = nls.localize('closeEditorsInGroup', "Close All Editors in Group"); - - constructor( - id: string, - label: string, - @ICommandService private commandService: ICommandService - ) { - super(id, label); - } - - public run(context?: IEditorContext): TPromise { - return this.commandService.executeCommand(CLOSE_EDITORS_IN_GROUP_COMMAND_ID, void 0, context); - } -} - export class MoveGroupLeftAction extends Action { public static readonly ID = 'workbench.action.moveActiveEditorGroupLeft'; @@ -725,7 +689,7 @@ export class MoveGroupLeftAction extends Action { super(id, label); } - public run(context?: IEditorContext): TPromise { + public run(context?: IEditorIdentifier): TPromise { let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null; if (typeof position !== 'number') { const activeEditor = this.editorService.getActiveEditor(); @@ -759,7 +723,7 @@ export class MoveGroupRightAction extends Action { super(id, label); } - public run(context?: IEditorContext): TPromise { + public run(context?: IEditorIdentifier): TPromise { let position = context ? this.editorGroupService.getStacksModel().positionOfGroup(context.group) : null; if (typeof position !== 'number') { const activeEditor = this.editorService.getActiveEditor(); @@ -838,7 +802,7 @@ export class MaximizeGroupAction extends Action { } } -function getTarget(editorService: IWorkbenchEditorService, editorGroupService: IEditorGroupService, context?: IEditorContext): { input: IEditorInput, position: Position } { +function getTarget(editorService: IWorkbenchEditorService, editorGroupService: IEditorGroupService, context?: IEditorIdentifier): { input: IEditorInput, position: Position } { if (context) { return { input: context.editor, position: editorGroupService.getStacksModel().positionOfGroup(context.group) }; } @@ -1446,4 +1410,4 @@ export class MoveEditorToThirdGroupAction extends MoveEditorToSpecificGroup { ) { super(id, label, Position.THREE, editorGroupService, editorService); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index cbc3db4dcda..42d2ed951c4 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -8,17 +8,20 @@ import * as types from 'vs/base/common/types'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService'; -import { ActiveEditorMoveArguments, ActiveEditorMovePositioning, ActiveEditorMovePositioningBy, EditorCommands, TextCompareEditorVisible, IEditorContext, EditorInput } from 'vs/workbench/common/editor'; +import { ActiveEditorMoveArguments, ActiveEditorMovePositioning, ActiveEditorMovePositioningBy, EditorCommands, TextCompareEditorVisible, EditorInput, IEditorIdentifier } from 'vs/workbench/common/editor'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditor, Position, POSITIONS, Direction, IEditorInput } from 'vs/platform/editor/common/editor'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { TextDiffEditor } from 'vs/workbench/browser/parts/editor/textDiffEditor'; -import { EditorStacksModel } from 'vs/workbench/common/editor/editorStacksModel'; +import { EditorStacksModel, EditorGroup } from 'vs/workbench/common/editor/editorStacksModel'; import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes'; import { TPromise } from 'vs/base/common/winjs.base'; import URI from 'vs/base/common/uri'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IDiffEditorOptions } from 'vs/editor/common/config/editorOptions'; +import { IListService } from 'vs/platform/list/browser/listService'; +import { List } from 'vs/base/browser/ui/list/listWidget'; +import { distinct } from 'vs/base/common/arrays'; export const CLOSE_UNMODIFIED_EDITORS_COMMAND_ID = 'workbench.action.closeUnmodifiedEditors'; export const CLOSE_EDITORS_IN_GROUP_COMMAND_ID = 'workbench.action.closeEditorsInGroup'; @@ -259,17 +262,24 @@ function registerEditorCommands() { weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), when: void 0, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_U), - handler: (accessor, resource: URI, editorContext: IEditorContext) => { + handler: (accessor, resource: URI, editorContext: IEditorIdentifier) => { const editorGroupService = accessor.get(IEditorGroupService); + const model = editorGroupService.getStacksModel(); const editorService = accessor.get(IWorkbenchEditorService); + const contexts = getMultiSelectedEditorContexts(editorContext, accessor.get(IListService)); - const { position } = positionAndInput(editorGroupService, editorService, editorContext); + let positionOne: { unmodifiedOnly: boolean } = undefined; + let positionTwo: { unmodifiedOnly: boolean } = undefined; + let positionThree: { unmodifiedOnly: boolean } = undefined; + contexts.forEach(c => { + switch (model.positionOfGroup(c.group)) { + case Position.ONE: positionOne = { unmodifiedOnly: true }; break; + case Position.TWO: positionTwo = { unmodifiedOnly: true }; break; + case Position.THREE: positionThree = { unmodifiedOnly: true }; break; + } + }); - if (typeof position === 'number') { - return editorService.closeEditors(position, { unmodifiedOnly: true }); - } - - return TPromise.as(false); + return editorService.closeEditors({ positionOne, positionTwo, positionThree }); } }); @@ -278,14 +288,18 @@ function registerEditorCommands() { weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), when: void 0, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_W), - handler: (accessor, resource: URI, editorContext: IEditorContext) => { + handler: (accessor, resource: URI, editorContext: IEditorIdentifier) => { const editorGroupService = accessor.get(IEditorGroupService); const editorService = accessor.get(IWorkbenchEditorService); + const contexts = getMultiSelectedEditorContexts(editorContext, accessor.get(IListService)); + const distinctGroups = distinct(contexts.map(c => c.group)); - const { position } = positionAndInput(editorGroupService, editorService, editorContext); - - if (typeof position === 'number') { - return editorService.closeEditors(position); + if (distinctGroups.length) { + return editorService.closeEditors(distinctGroups.map(g => editorGroupService.getStacksModel().positionOfGroup(g))); + } + const activeEditor = editorService.getActiveEditor(); + if (activeEditor) { + return editorService.closeEditors(activeEditor.position); } return TPromise.as(false); @@ -298,35 +312,50 @@ function registerEditorCommands() { when: void 0, primary: KeyMod.CtrlCmd | KeyCode.KEY_W, win: { primary: KeyMod.CtrlCmd | KeyCode.F4, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_W] }, - handler: (accessor, resource: URI, editorContext: IEditorContext) => { + handler: (accessor, resource: URI, editorContext: IEditorIdentifier) => { const editorGroupService = accessor.get(IEditorGroupService); const editorService = accessor.get(IWorkbenchEditorService); - const position = editorContext ? editorGroupService.getStacksModel().positionOfGroup(editorContext.group) : null; + const contexts = getMultiSelectedEditorContexts(editorContext, accessor.get(IListService)); + const groups = distinct(contexts.map(context => context.group)); - // Close Active Editor - if (typeof position !== 'number') { + const editorsToClose = new Map(); + + groups.forEach(group => { + const position = editorGroupService.getStacksModel().positionOfGroup(group); + if (position >= 0) { + editorsToClose.set(position, contexts.map(c => { + if (group === c.group) { + let input = c ? c.editor : undefined; + if (!input) { + + // Get Top Editor at Position + const visibleEditors = editorService.getVisibleEditors(); + if (visibleEditors[position]) { + input = visibleEditors[position].input; + } + } + + return input; + } + + return undefined; + }).filter(input => !!input)); + } + }); + + if (editorsToClose.size === 0) { const activeEditor = editorService.getActiveEditor(); if (activeEditor) { return editorService.closeEditor(activeEditor.position, activeEditor.input); } } - let input = editorContext ? editorContext.editor : null; - if (!input) { - - // Get Top Editor at Position - const visibleEditors = editorService.getVisibleEditors(); - if (visibleEditors[position]) { - input = visibleEditors[position].input; - } - } - - if (input) { - return editorService.closeEditor(position, input); - } - - return TPromise.as(false); + return editorService.closeEditors({ + positionOne: editorsToClose.get(Position.ONE), + positionTwo: editorsToClose.get(Position.TWO), + positionThree: editorsToClose.get(Position.THREE) + }); } }); @@ -336,17 +365,31 @@ function registerEditorCommands() { when: void 0, primary: void 0, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_T }, - handler: (accessor, resource: URI, editorContext: IEditorContext) => { + handler: (accessor, resource: URI, editorContext: IEditorIdentifier) => { const editorGroupService = accessor.get(IEditorGroupService); const editorService = accessor.get(IWorkbenchEditorService); + const contexts = getMultiSelectedEditorContexts(editorContext, accessor.get(IListService)); + const groups = distinct(contexts.map(context => context.group)); + const editorsToClose = new Map(); - const { position, input } = positionAndInput(editorGroupService, editorService, editorContext); + groups.forEach(group => { + const inputsToSkip = contexts.map(c => { + if (!!c.editor && c.group === group) { + return c.editor; + } - if (typeof position === 'number' && input) { - return editorService.closeEditors(position, { except: input }); - } + return undefined; + }).filter(input => !!input); - return TPromise.as(false); + const toClose = group.getEditors().filter(input => inputsToSkip.indexOf(input) === -1); + editorsToClose.set(editorGroupService.getStacksModel().positionOfGroup(group), toClose); + }); + + return editorService.closeEditors({ + positionOne: editorsToClose.get(Position.ONE), + positionTwo: editorsToClose.get(Position.TWO), + positionThree: editorsToClose.get(Position.THREE) + }); } }); @@ -355,7 +398,7 @@ function registerEditorCommands() { weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), when: void 0, primary: void 0, - handler: (accessor, resource: URI, editorContext: IEditorContext) => { + handler: (accessor, resource: URI, editorContext: IEditorIdentifier) => { const editorGroupService = accessor.get(IEditorGroupService); const editorService = accessor.get(IWorkbenchEditorService); @@ -374,7 +417,7 @@ function registerEditorCommands() { weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), when: void 0, primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.Enter), - handler: (accessor, resource: URI, editorContext: IEditorContext) => { + handler: (accessor, resource: URI, editorContext: IEditorIdentifier) => { const editorGroupService = accessor.get(IEditorGroupService); const editorService = accessor.get(IWorkbenchEditorService); @@ -393,7 +436,7 @@ function registerEditorCommands() { weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), when: void 0, primary: void 0, - handler: (accessor, resource: URI, editorContext: IEditorContext) => { + handler: (accessor, resource: URI, editorContext: IEditorIdentifier) => { const editorGroupService = accessor.get(IEditorGroupService); const editorService = accessor.get(IWorkbenchEditorService); const quickOpenService = accessor.get(IQuickOpenService); @@ -438,7 +481,7 @@ function registerEditorCommands() { }); } -function positionAndInput(editorGroupService: IEditorGroupService, editorService: IWorkbenchEditorService, editorContext?: IEditorContext): { position: Position, input: IEditorInput } { +function positionAndInput(editorGroupService: IEditorGroupService, editorService: IWorkbenchEditorService, editorContext?: IEditorIdentifier): { position: Position, input: IEditorInput } { let position = editorContext ? editorGroupService.getStacksModel().positionOfGroup(editorContext.group) : null; let input = editorContext ? editorContext.editor : null; @@ -451,3 +494,25 @@ function positionAndInput(editorGroupService: IEditorGroupService, editorService return { position, input }; } + +export function getMultiSelectedEditorContexts(editorContext: IEditorIdentifier, listService: IListService): IEditorIdentifier[] { + const list = listService.lastFocusedList; + // Mapping for open editors view + const isEditorIdentifier = (element: any) => 'group' in element && 'editor' in element; + const elementToContext = (element: IEditorIdentifier | EditorGroup) => element instanceof EditorGroup ? { group: element, editor: undefined } : element; + + if (list instanceof List && list.isDOMFocused()) { + const selection = list.getSelectedElements(); + const focus = list.getFocusedElements(); + // Only respect selection if it contains focused element + if (focus.length && selection && selection.indexOf(focus[0]) >= 0) { + return list.getSelectedElements().filter(e => e instanceof EditorGroup || isEditorIdentifier(e)).map(elementToContext); + } + + if (focus.length) { + return focus.filter(e => e instanceof EditorGroup || isEditorIdentifier(e)).map(elementToContext); + } + } + + return !!editorContext ? [editorContext] : []; +} diff --git a/src/vs/workbench/browser/parts/editor/editorGroupsControl.ts b/src/vs/workbench/browser/parts/editor/editorGroupsControl.ts index a6e2d0b65b7..bb490659d9f 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupsControl.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupsControl.ts @@ -36,6 +36,7 @@ import { Themable, EDITOR_GROUP_HEADER_TABS_BACKGROUND, EDITOR_GROUP_HEADER_NO_T import { attachProgressBarStyler } from 'vs/platform/theme/common/styler'; import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; import { EditorAreaDropHandler } from 'vs/workbench/browser/parts/editor/editorAreaDropHandler'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; export enum Rochade { NONE, @@ -144,7 +145,8 @@ export class EditorGroupsControl extends Themable implements IEditorGroupsContro @IContextKeyService private contextKeyService: IContextKeyService, @IExtensionService private extensionService: IExtensionService, @IInstantiationService private instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService + @IThemeService themeService: IThemeService, + @ITelemetryService private telemetryService: ITelemetryService ) { super(themeService); @@ -1518,6 +1520,14 @@ export class EditorGroupsControl extends Themable implements IEditorGroupsContro // Move to valid position if any if (moveTo !== null) { + // TODO@Ben remove me after a while + /* __GDPR__ + "editorGroupMoved" : { + "source" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "to": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('editorGroupMoved', { source: position, to: moveTo }); this.editorGroupService.moveGroup(position, moveTo); } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 7f3b63746ec..b477666f086 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -47,6 +47,7 @@ import { join } from 'vs/base/common/paths'; import { IEditorDescriptor, IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; import { ThrottledEmitter } from 'vs/base/common/async'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { isUndefinedOrNull } from 'vs/base/common/types'; class ProgressMonitor { @@ -73,6 +74,10 @@ interface IEditorReplacement extends EditorIdentifier { options?: EditorOptions; } +export type ICloseEditorsFilter = { except?: EditorInput, direction?: Direction, unmodifiedOnly?: boolean }; +export type ICloseEditorsByFilterArgs = { positionOne?: ICloseEditorsFilter, positionTwo?: ICloseEditorsFilter, positionThree?: ICloseEditorsFilter }; +export type ICloseEditorsArgs = { positionOne?: EditorInput[], positionTwo?: EditorInput[], positionThree?: EditorInput[] }; + /** * The editor part is the container for editors in the workbench. Based on the editor input being opened, it asks the registered * editor for the given input to show the contents. The editor part supports up to 3 side-by-side editors. @@ -683,58 +688,192 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService this.textCompareEditorVisible.set(this.visibleEditors.some(e => e && e.isVisible() && e.getId() === TEXT_DIFF_EDITOR_ID)); } - public closeAllEditors(except?: Position): TPromise { + public closeEditors(positions?: Position[]): TPromise; + public closeEditors(position: Position, filter?: ICloseEditorsFilter): TPromise; + public closeEditors(position: Position, editors: EditorInput[]): TPromise; + public closeEditors(editors: ICloseEditorsByFilterArgs): TPromise; + public closeEditors(editors: ICloseEditorsArgs): TPromise; + public closeEditors(positionsOrEditors?: Position[] | Position | ICloseEditorsByFilterArgs | ICloseEditorsArgs, filterOrEditors?: ICloseEditorsFilter | EditorInput[]): TPromise { + + // First check for specific position to close + if (typeof positionsOrEditors === 'number') { + return this.doCloseEditorsAtPosition(positionsOrEditors, filterOrEditors); + } + + // Then check for array of positions to close + if (Array.isArray(positionsOrEditors) || isUndefinedOrNull(positionsOrEditors)) { + return this.doCloseAllEditorsAtPositions(positionsOrEditors as Position[]); + } + + // Finally, close specific editors at multiple positions + return this.doCloseEditorsAtPositions(positionsOrEditors); + } + + private doCloseEditorsAtPositions(editors: ICloseEditorsByFilterArgs | ICloseEditorsArgs): TPromise { + + // Extract editors to close for veto + const editorsToClose: EditorIdentifier[] = []; + let groupsWithEditorsToClose = 0; + POSITIONS.forEach(position => { + const details = (position === Position.ONE) ? editors.positionOne : (position === Position.TWO) ? editors.positionTwo : editors.positionThree; + if (details && this.stacks.groupAt(position)) { + groupsWithEditorsToClose++; + editorsToClose.push(...this.extractCloseEditorDetails(position, details).editorsToClose); + } + }); + + // Check for dirty and veto + const ignoreDirtyIfOpenedInOtherGroup = (groupsWithEditorsToClose === 1); + return this.handleDirty(editorsToClose, ignoreDirtyIfOpenedInOtherGroup).then(veto => { + if (veto) { + return void 0; + } + + // Close by positions starting from last to first to prevent issues when + // editor groups close and thus move other editors around that are still open. + [Position.THREE, Position.TWO, Position.ONE].forEach(position => { + const details = (position === Position.ONE) ? editors.positionOne : (position === Position.TWO) ? editors.positionTwo : editors.positionThree; + if (details && this.stacks.groupAt(position)) { + const { group, editorsToClose, filter } = this.extractCloseEditorDetails(position, details); + + // Close with filter + if (filter) { + this.doCloseEditorsWithFilter(group, filter); + } + + // Close without filter + else { + this.doCloseEditors(group, editorsToClose.map(e => e.editor)); + } + + return void 0; + } + }); + }); + } + + private doCloseAllEditorsAtPositions(positions?: Position[]): TPromise { let groups = this.stacks.groups.reverse(); // start from the end to prevent layout to happen through rochade - // Remove position to exclude if we have any - if (typeof except === 'number') { - groups = groups.filter(group => this.stacks.positionOfGroup(group) !== except); + // Remove positions that are not being asked for if provided + if (Array.isArray(positions)) { + groups = groups.filter(group => positions.indexOf(this.stacks.positionOfGroup(group)) >= 0); } // Check for dirty and veto - return this.handleDirty(arrays.flatten(groups.map(group => group.getEditors(true /* in MRU order */).map(editor => { return { group, editor }; })))).then(veto => { + const ignoreDirtyIfOpenedInOtherGroup = (groups.length === 1); + return this.handleDirty(arrays.flatten(groups.map(group => group.getEditors(true /* in MRU order */).map(editor => ({ group, editor })))), ignoreDirtyIfOpenedInOtherGroup).then(veto => { if (veto) { return; } - groups.forEach(group => this.doCloseEditors(group)); + groups.forEach(group => this.doCloseAllEditorsInGroup(group)); }); } - public closeEditors(position: Position, filter: { except?: EditorInput, direction?: Direction, unmodifiedOnly?: boolean } = Object.create(null)): TPromise { + private doCloseAllEditorsInGroup(group: EditorGroup): void { + + // Update stacks model: remove all non active editors first to prevent opening the next editor in group + group.closeEditors(group.activeEditor); + + // Now close active editor in group which will close the group + this.doCloseActiveEditor(group); + } + + private doCloseEditorsAtPosition(position: Position, filterOrEditors?: ICloseEditorsFilter | EditorInput[]): TPromise { + const closeEditorsDetails = this.extractCloseEditorDetails(position, filterOrEditors); + if (!closeEditorsDetails) { + return TPromise.wrap(void 0); + } + + const { group, editorsToClose, filter } = closeEditorsDetails; + + // Check for dirty and veto + return this.handleDirty(editorsToClose, true /* ignore if opened in other group */).then(veto => { + if (veto) { + return void 0; + } + + // Close with filter + if (filter) { + this.doCloseEditorsWithFilter(group, filter); + } + + // Close without filter + else { + this.doCloseEditors(group, editorsToClose.map(e => e.editor)); + } + + return void 0; + }); + } + + private extractCloseEditorDetails(position: Position, filterOrEditors?: ICloseEditorsFilter | EditorInput[]): { group: EditorGroup, editorsToClose: EditorIdentifier[], filter?: ICloseEditorsFilter } { const group = this.stacks.groupAt(position); if (!group) { - return TPromise.wrap(null); + return void 0; } - let editorsToClose = group.getEditors(true /* in MRU order */); + let editorsToClose: EditorInput[]; + let filter: ICloseEditorsFilter; - // Filter: unmodified only - if (filter.unmodifiedOnly) { - editorsToClose = editorsToClose.filter(e => !e.isDirty()); + // Close: Specific Editors + if (Array.isArray(filterOrEditors)) { + editorsToClose = filterOrEditors; } - // Filter: direction (left / right) - if (!types.isUndefinedOrNull(filter.direction)) { - editorsToClose = (filter.direction === Direction.LEFT) ? editorsToClose.slice(0, group.indexOf(filter.except)) : editorsToClose.slice(group.indexOf(filter.except) + 1); - } - - // Filter: except + // Close: By Filter or all else { - editorsToClose = editorsToClose.filter(e => !filter.except || !e.matches(filter.except)); - } + editorsToClose = group.getEditors(true /* in MRU order */); + filter = filterOrEditors || Object.create(null); - // Check for dirty and veto - return this.handleDirty(editorsToClose.map(editor => { return { group, editor }; }), true /* ignore if opened in other group */).then(veto => { - if (veto) { - return; + // Filter: unmodified only + if (filter.unmodifiedOnly) { + editorsToClose = editorsToClose.filter(e => !e.isDirty()); } - this.doCloseEditors(group, filter); - }); + // Filter: direction (left / right) + else if (!types.isUndefinedOrNull(filter.direction)) { + editorsToClose = (filter.direction === Direction.LEFT) ? editorsToClose.slice(0, group.indexOf(filter.except)) : editorsToClose.slice(group.indexOf(filter.except) + 1); + } + + // Filter: except + else if (filter.except) { + editorsToClose = editorsToClose.filter(e => !e.matches(filter.except)); + } + } + + return { group, editorsToClose: editorsToClose.map(editor => ({ editor, group })), filter }; } - private doCloseEditors(group: EditorGroup, filter: { except?: EditorInput, direction?: Direction, unmodifiedOnly?: boolean } = Object.create(null)): void { + private doCloseEditors(group: EditorGroup, editors: EditorInput[]): void { + + // Close all editors in group + if (editors.length === group.count) { + this.doCloseAllEditorsInGroup(group); + } + + // Close specific editors in group + else { + + // Editors to close are not active, so we can just close them + if (!editors.some(editor => group.activeEditor.matches(editor))) { + editors.forEach(editor => this.doCloseInactiveEditor(group, editor)); + } + + // Active editor is also a candidate to close, thus we make the first + // non-candidate editor active and then close the other ones + else { + const firstEditorToKeep = group.getEditors(true).filter(editorInGroup => !editors.some(editor => editor.matches(editorInGroup)))[0]; + + this.openEditor(firstEditorToKeep, null, this.stacks.positionOfGroup(group)).done(() => { + editors.forEach(editor => this.doCloseInactiveEditor(group, editor)); + }, errors.onUnexpectedError); + } + } + } + + private doCloseEditorsWithFilter(group: EditorGroup, filter: { except?: EditorInput, direction?: Direction, unmodifiedOnly?: boolean }): void { // Close all editors if there is no editor to except and // we either are not only closing unmodified editors or @@ -750,12 +889,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Close all editors in group if (closeAllEditors) { - - // Update stacks model: remove all non active editors first to prevent opening the next editor in group - group.closeEditors(group.activeEditor); - - // Now close active editor in group which will close the group - this.doCloseActiveEditor(group); + this.doCloseAllEditorsInGroup(group); } // Close unmodified editors in group @@ -769,10 +903,10 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Active editor is also a candidate to close, thus we make the first dirty editor // active and then close the other ones else { - const firstDirtyEditor = group.getEditors().filter(editor => editor.isDirty())[0]; + const firstDirtyEditor = group.getEditors(true).filter(editor => editor.isDirty())[0]; this.openEditor(firstDirtyEditor, null, this.stacks.positionOfGroup(group)).done(() => { - this.doCloseEditors(group, filter); + this.doCloseEditorsWithFilter(group, filter); }, errors.onUnexpectedError); } } @@ -793,7 +927,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // being the expected one, otherwise we end up in an endless loop trying to open the // editor if (filter.except.matches(group.activeEditor)) { - this.doCloseEditors(group, filter); + this.doCloseEditorsWithFilter(group, filter); } }, errors.onUnexpectedError); } @@ -1100,7 +1234,9 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService return res; } - public openEditors(editors: { input: EditorInput, position: Position, options?: EditorOptions }[]): TPromise { + public openEditors(editors: { input: EditorInput, position?: Position, options?: EditorOptions }[]): TPromise; + public openEditors(editors: { input: EditorInput, options?: EditorOptions }[], sideBySide?: boolean): TPromise; + public openEditors(editors: { input: EditorInput, position?: Position, options?: EditorOptions }[], sideBySide?: boolean): TPromise { if (!editors.length) { return TPromise.as([]); } @@ -1112,7 +1248,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService const ratio = this.editorGroupsControl.getRatio(); - return this.doOpenEditors(editors, activePosition, ratio); + return this.doOpenEditors(editors, activePosition, ratio, sideBySide); } public hasEditorsToRestore(): boolean { @@ -1143,7 +1279,15 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService return this._onEditorsChanged.throttle(this.doOpenEditors(editors, activePosition, editorState && editorState.ratio)); } - private doOpenEditors(editors: { input: EditorInput, position: Position, options?: EditorOptions }[], activePosition?: number, ratio?: number[]): TPromise { + private doOpenEditors(editors: { input: EditorInput, position?: Position, options?: EditorOptions }[], activePosition?: number, ratio?: number[], sideBySide?: boolean): TPromise { + + // Find position if not provided already from calling side + editors.forEach(editor => { + if (typeof editor.position !== 'number') { + editor.position = this.findPosition(editor.input, editor.options, sideBySide); + } + }); + const positionOneEditors = editors.filter(e => e.position === Position.ONE); const positionTwoEditors = editors.filter(e => e.position === Position.TWO); const positionThreeEditors = editors.filter(e => e.position === Position.THREE); @@ -1394,8 +1538,14 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService return Position.ONE; // can only be ONE } + // Ignore revealIfVisible/revealIfOpened option if we got instructed explicitly to + // * open at a specific index + // * open to the side + // * open in a specific group + const skipReveal = (options && options.index) || arg1 === true /* open to side */ || typeof arg1 === 'number' /* open specific group */; + // Respect option to reveal an editor if it is already visible - if (options && options.revealIfVisible) { + if (!skipReveal && options && options.revealIfVisible) { const group = this.stacks.findGroup(input, true); if (group) { return this.stacks.positionOfGroup(group); @@ -1403,8 +1553,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } // Respect option to reveal an editor if it is open (not necessarily visible) - const skipRevealIfOpen = (options && options.index) || arg1 === true /* open to side */ || typeof arg1 === 'number' /* open specific group */; - if (!skipRevealIfOpen && (this.revealIfOpen || (options && options.revealIfOpened))) { + if (!skipReveal && (this.revealIfOpen || (options && options.revealIfOpened))) { const group = this.stacks.findGroup(input); if (group) { return this.stacks.positionOfGroup(group); diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index d60983725ca..4c2fbffde2a 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -310,7 +310,7 @@ export abstract class TitleControl extends Themable implements ITitleAreaControl const titleBarMenu = this.menuService.createMenu(MenuId.EditorTitle, scopedContextKeyService); this.disposeOnEditorActions.push(titleBarMenu, titleBarMenu.onDidChange(_ => this.update())); - fillInActions(titleBarMenu, { arg: this.resourceContext.get() }, { primary, secondary }, this.contextMenuService); + fillInActions(titleBarMenu, { arg: this.resourceContext.get(), shouldForwardArgs: true }, { primary, secondary }, this.contextMenuService); } return { primary, secondary }; @@ -328,16 +328,20 @@ export abstract class TitleControl extends Themable implements ITitleAreaControl // Update Editor Actions Toolbar let primaryEditorActions: IAction[] = []; let secondaryEditorActions: IAction[] = []; + + const editorActions = this.getEditorActions({ group, editor }); + + // Primary actions only for the active group if (isActive) { - const editorActions = this.getEditorActions({ group, editor }); primaryEditorActions = prepareActions(editorActions.primary); - if (isActive && editor instanceof EditorInput && editor.supportsSplitEditor()) { + if (editor instanceof EditorInput && editor.supportsSplitEditor()) { this.updateSplitActionEnablement(); primaryEditorActions.push(this.splitEditorAction); } - secondaryEditorActions = prepareActions(editorActions.secondary); } + secondaryEditorActions = prepareActions(editorActions.secondary); + const tabOptions = this.editorGroupService.getTabOptions(); const primaryEditorActionIds = primaryEditorActions.map(a => a.id); diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 17228613cdd..1162557713b 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -250,14 +250,6 @@ export class PanelPart extends CompositePart implements IPanelService { return this.toolbarWidth.get(activePanel.getId()); } - - public shutdown(): void { - // Persist Hidden State - this.compositeBar.store(); - - // Pass to super - super.shutdown(); - } } registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index c5e59196388..935b7d8bed5 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -54,7 +54,7 @@ import { BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { FileKind, IFileService } from 'vs/platform/files/common/files'; import { scoreItem, ScorerCache, compareItemsByScore, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer'; import { getBaseLabel } from 'vs/base/common/labels'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; const HELP_PREFIX = '?'; @@ -107,7 +107,6 @@ export class QuickOpenController extends Component implements IQuickOpenService @IConfigurationService private configurationService: IConfigurationService, @IInstantiationService private instantiationService: IInstantiationService, @IPartService private partService: IPartService, - @IListService private listService: IListService, @IEnvironmentService private environmentService: IEnvironmentService, @IThemeService themeService: IThemeService ) { @@ -311,7 +310,7 @@ export class QuickOpenController extends Component implements IQuickOpenService }, { inputPlaceHolder: options.placeHolder || '', keyboardSupport: false, - treeCreator: (container, config, opts) => new WorkbenchTree(container, config, opts, this.contextKeyService, this.listService, this.themeService) + treeCreator: (container, config, opts) => this.instantiationService.createInstance(WorkbenchTree, container, config, opts) } ); this.toUnbind.push(attachQuickOpenStyler(this.pickOpenWidget, this.themeService, { background: SIDE_BAR_BACKGROUND, foreground: SIDE_BAR_FOREGROUND })); @@ -569,7 +568,7 @@ export class QuickOpenController extends Component implements IQuickOpenService }, { inputPlaceHolder: this.hasHandler(HELP_PREFIX) ? nls.localize('quickOpenInput', "Type '?' to get help on the actions you can take from here") : '', keyboardSupport: false, - treeCreator: (container, config, opts) => new WorkbenchTree(container, config, opts, this.contextKeyService, this.listService, this.themeService) + treeCreator: (container, config, opts) => this.instantiationService.createInstance(WorkbenchTree, container, config, opts) } ); this.toUnbind.push(attachQuickOpenStyler(this.quickOpenWidget, this.themeService, { background: SIDE_BAR_BACKGROUND, foreground: SIDE_BAR_FOREGROUND })); @@ -1301,7 +1300,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { public run(mode: Mode, context: IEntryRunContext): boolean { if (mode === Mode.OPEN) { - const sideBySide = !context.quickNavigateConfiguration && context.keymods.ctrlCmd; + const sideBySide = !context.quickNavigateConfiguration && (context.keymods.alt || context.keymods.ctrlCmd); const pinned = !this.configurationService.getValue().workbench.editor.enablePreviewFromQuickOpen || context.keymods.alt; if (this.input instanceof EditorInput) { diff --git a/src/vs/workbench/parts/files/electron-browser/media/collapsed-dark.svg b/src/vs/workbench/browser/parts/views/media/collapsed-dark.svg similarity index 100% rename from src/vs/workbench/parts/files/electron-browser/media/collapsed-dark.svg rename to src/vs/workbench/browser/parts/views/media/collapsed-dark.svg diff --git a/src/vs/workbench/parts/files/electron-browser/media/collapsed-hc.svg b/src/vs/workbench/browser/parts/views/media/collapsed-hc.svg similarity index 100% rename from src/vs/workbench/parts/files/electron-browser/media/collapsed-hc.svg rename to src/vs/workbench/browser/parts/views/media/collapsed-hc.svg diff --git a/src/vs/workbench/parts/files/electron-browser/media/collapsed.svg b/src/vs/workbench/browser/parts/views/media/collapsed.svg similarity index 100% rename from src/vs/workbench/parts/files/electron-browser/media/collapsed.svg rename to src/vs/workbench/browser/parts/views/media/collapsed.svg diff --git a/src/vs/workbench/parts/files/electron-browser/media/expanded-dark.svg b/src/vs/workbench/browser/parts/views/media/expanded-dark.svg similarity index 100% rename from src/vs/workbench/parts/files/electron-browser/media/expanded-dark.svg rename to src/vs/workbench/browser/parts/views/media/expanded-dark.svg diff --git a/src/vs/workbench/parts/files/electron-browser/media/expanded-hc.svg b/src/vs/workbench/browser/parts/views/media/expanded-hc.svg similarity index 100% rename from src/vs/workbench/parts/files/electron-browser/media/expanded-hc.svg rename to src/vs/workbench/browser/parts/views/media/expanded-hc.svg diff --git a/src/vs/workbench/parts/files/electron-browser/media/expanded.svg b/src/vs/workbench/browser/parts/views/media/expanded.svg similarity index 100% rename from src/vs/workbench/parts/files/electron-browser/media/expanded.svg rename to src/vs/workbench/browser/parts/views/media/expanded.svg diff --git a/src/vs/workbench/browser/parts/views/media/views.css b/src/vs/workbench/browser/parts/views/media/views.css index 5eceb636e91..f3b98771b75 100644 --- a/src/vs/workbench/browser/parts/views/media/views.css +++ b/src/vs/workbench/browser/parts/views/media/views.css @@ -3,13 +3,74 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.custom-view-tree-node-item { +/* File icon themeable tree style */ +.file-icon-themable-tree .monaco-tree-row .content { + display: flex; +} + +.file-icon-themable-tree .monaco-tree-row .content::before { + background-size: 16px; + background-position: 50% 50%; + background-repeat: no-repeat; + padding-right: 6px; + width: 16px; + height: 22px; + display: inline-block; + vertical-align: top; + content: ' '; +} + +.file-icon-themable-tree.align-icons-and-twisties .monaco-tree-row:not(.has-children) .content::before { + display: none; +} + +.file-icon-themable-tree .monaco-tree-row.has-children.expanded .content::before { + background-image: url("expanded.svg"); +} + +.file-icon-themable-tree .monaco-tree-row.has-children .content::before { + display: inline-block; + background-image: url("collapsed.svg"); +} + +.vs-dark .file-icon-themable-tree .monaco-tree-row.has-children.expanded .content::before { + background-image: url("expanded-dark.svg"); +} + +.vs-dark .file-icon-themable-tree .monaco-tree-row.has-children .content::before { + background-image: url("collapsed-dark.svg"); +} + +.hc-black .file-icon-themable-tree .monaco-tree-row.has-children.expanded .content::before { + background-image: url("expanded-hc.svg"); +} + +.hc-black .file-icon-themable-tree .monaco-tree-row.has-children .content::before { + background-image: url("collapsed-hc.svg"); +} + +.file-icon-themable-tree.hide-arrows .monaco-tree-row .content::before { + display: none; +} + +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item { display: flex; height: 22px; line-height: 22px; + flex: 1; + text-overflow: ellipsis; + overflow: hidden; + flex-wrap: nowrap } -.custom-view-tree-node-item > .custom-view-tree-node-item-icon { +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item .custom-view-tree-node-item-resourceLabel, +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-label { + flex: 1; + text-overflow: ellipsis; + overflow: hidden; +} + +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon { background-size: 16px; background-position: left center; background-repeat: no-repeat; @@ -19,8 +80,19 @@ -webkit-font-smoothing: antialiased; } -.custom-view-tree-node-item > .custom-view-tree-node-item-label { - flex: 1; - text-overflow: ellipsis; - overflow: hidden; +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .actions { + display: none; +} + +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row:hover .custom-view-tree-node-item > .actions, +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row.selected .custom-view-tree-node-item > .actions, +.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row.focused .custom-view-tree-node-item > .actions { + display: block; +} + +.tree-explorer-viewlet-tree-view .monaco-tree .custom-view-tree-node-item > .actions .action-label { + width: 16px; + height: 100%; + background-position: 50% 50%; + background-repeat: no-repeat; } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/views/panelViewlet.ts b/src/vs/workbench/browser/parts/views/panelViewlet.ts index 03fb2022e2c..c9afb8b9ced 100644 --- a/src/vs/workbench/browser/parts/views/panelViewlet.ts +++ b/src/vs/workbench/browser/parts/views/panelViewlet.ts @@ -134,7 +134,7 @@ interface IViewletPanelItem { export class PanelViewlet extends Viewlet { - protected lastFocusedPanel: ViewletPanel | undefined; + private lastFocusedPanel: ViewletPanel | undefined; private panelItems: IViewletPanelItem[] = []; private panelview: PanelView; @@ -195,7 +195,12 @@ export class PanelViewlet extends Viewlet { if (this.lastFocusedPanel) { this.lastFocusedPanel.focus(); } else if (this.panelItems.length > 0) { - this.panelItems[0].panel.focus(); + for (const { panel } of this.panelItems) { + if (panel.isExpanded()) { + panel.focus(); + return; + } + } } } @@ -213,8 +218,13 @@ export class PanelViewlet extends Viewlet { addPanel(panel: ViewletPanel, size: number, index = this.panelItems.length - 1): void { const disposables: IDisposable[] = []; const onDidFocus = panel.onDidFocus(() => this.lastFocusedPanel = panel, null, disposables); + const onDidChange = panel.onDidChange(() => { + if (panel === this.lastFocusedPanel && !panel.isExpanded()) { + this.lastFocusedPanel = undefined; + } + }, null, disposables); const styler = attachPanelStyler(panel, this.themeService); - const disposable = combinedDisposable([onDidFocus, styler]); + const disposable = combinedDisposable([onDidFocus, styler, onDidChange]); const panelItem: IViewletPanelItem = { panel, disposable }; this.panelItems.splice(index, 0, panelItem); diff --git a/src/vs/workbench/browser/parts/views/treeView.ts b/src/vs/workbench/browser/parts/views/treeView.ts index d295d2728a1..a72b589137a 100644 --- a/src/vs/workbench/browser/parts/views/treeView.ts +++ b/src/vs/workbench/browser/parts/views/treeView.ts @@ -21,13 +21,17 @@ import { createActionItem, fillInActions } from 'vs/platform/actions/browser/men import { IProgressService } from 'vs/platform/progress/common/progress'; import { ITree, IDataSource, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { ActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; -import { ViewsRegistry } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ActionItem, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; +import { ViewsRegistry, TreeItemCollapsibleState, ITreeItem, ITreeViewDataProvider, TreeViewItemHandleArg } from 'vs/workbench/common/views'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; -import { TreeViewsViewletPanel, IViewletViewOptions, IViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; +import { IViewletViewOptions, IViewOptions, TreeViewsViewletPanel, FileIconThemableWorkbenchTree } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { TreeItemCollapsibleState, ITreeItem, ITreeViewDataProvider, TreeViewItemHandleArg } from 'vs/workbench/common/views'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; +import { ResourceLabel } from 'vs/workbench/browser/labels'; +import URI from 'vs/base/common/uri'; +import { basename } from 'vs/base/common/paths'; +import { FileKind } from 'vs/platform/files/common/files'; +import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; export class TreeView extends TreeViewsViewletPanel { @@ -44,16 +48,14 @@ export class TreeView extends TreeViewsViewletPanel { @IKeybindingService keybindingService: IKeybindingService, @IContextMenuService contextMenuService: IContextMenuService, @IInstantiationService private instantiationService: IInstantiationService, - @IListService private listService: IListService, - @IThemeService private themeService: IThemeService, - @IContextKeyService private contextKeyService: IContextKeyService, + @IThemeService themeService: IWorkbenchThemeService, @IExtensionService private extensionService: IExtensionService, @ICommandService private commandService: ICommandService ) { super({ ...(options as IViewOptions), ariaHeaderLabel: options.name }, keybindingService, contextMenuService); this.menus = this.instantiationService.createInstance(Menus, this.id); this.menus.onDidChangeTitle(() => this.updateActions(), this, this.disposables); - this.themeService.onThemeChange(() => this.tree.refresh() /* soft refresh */, this, this.disposables); + themeService.onThemeChange(() => this.tree.refresh() /* soft refresh */, this, this.disposables); if (options.expanded) { this.activate(); } @@ -85,15 +87,12 @@ export class TreeView extends TreeViewsViewletPanel { public createViewer(container: Builder): WorkbenchTree { const dataSource = this.instantiationService.createInstance(TreeDataSource, this.id); - const renderer = this.instantiationService.createInstance(TreeRenderer); + const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, this.menus); const controller = this.instantiationService.createInstance(TreeController, this.id, this.menus); - const tree = new WorkbenchTree( + const tree = this.instantiationService.createInstance(FileIconThemableWorkbenchTree, container.getHTMLElement(), { dataSource, renderer, controller }, - { keyboardSupport: false }, - this.contextKeyService, - this.listService, - this.themeService + { keyboardSupport: false } ); tree.contextKeyService.createKey(this.id, true); @@ -263,8 +262,10 @@ class TreeDataSource implements IDataSource { } interface ITreeExplorerTemplateData { - icon: Builder; - label: Builder; + label: HTMLElement; + resourceLabel: ResourceLabel; + icon: HTMLElement; + actionBar: ActionBar; } class TreeRenderer implements IRenderer { @@ -272,7 +273,12 @@ class TreeRenderer implements IRenderer { private static readonly ITEM_HEIGHT = 22; private static readonly TREE_TEMPLATE_ID = 'treeExplorer'; - constructor( @IThemeService private themeService: IThemeService) { + constructor( + private treeViewId: string, + private menus: Menus, + @IInstantiationService private instantiationService: IInstantiationService, + @IThemeService private themeService: IThemeService + ) { } public getHeight(tree: ITree, element: any): number { @@ -284,33 +290,51 @@ class TreeRenderer implements IRenderer { } public renderTemplate(tree: ITree, templateId: string, container: HTMLElement): ITreeExplorerTemplateData { - const el = $(container); - const item = $('.custom-view-tree-node-item'); - item.appendTo(el); + const el = DOM.append(container, DOM.$('.custom-view-tree-node-item')); - const icon = $('.custom-view-tree-node-item-icon').appendTo(item); - const label = $('.custom-view-tree-node-item-label').appendTo(item); - const link = $('a.label').appendTo(label); + const icon = DOM.append(el, DOM.$('.custom-view-tree-node-item-icon')); + const label = DOM.append(el, DOM.$('.custom-view-tree-node-item-label')); + const resourceLabel = this.instantiationService.createInstance(ResourceLabel, el, {}); + const actionsContainer = DOM.append(el, DOM.$('.actions')); + const actionBar = new ActionBar(actionsContainer, { + actionRunner: new MultipleSelectionActionRunner(() => tree.getSelection()) + }); - return { label: link, icon }; + return { label, resourceLabel, icon, actionBar }; } public renderElement(tree: ITree, node: ITreeItem, templateId: string, templateData: ITreeExplorerTemplateData): void { - templateData.label.text(node.label).title(node.label); - + const resource = node.resourceUri ? URI.revive(node.resourceUri) : null; + const name = node.label || basename(resource.path); const theme = this.themeService.getTheme(); const icon = theme.type === LIGHT ? node.icon : node.iconDark; - if (icon) { - templateData.icon.getHTMLElement().style.backgroundImage = `url('${icon}')`; - DOM.addClass(templateData.icon.getHTMLElement(), 'custom-view-tree-node-item-icon'); + // reset + templateData.resourceLabel.clear(); + templateData.actionBar.clear(); + templateData.label.textContent = ''; + DOM.removeClass(templateData.label, 'custom-view-tree-node-item-label'); + DOM.removeClass(templateData.resourceLabel.element, 'custom-view-tree-node-item-resourceLabel'); + DOM.removeClass(templateData.icon, 'custom-view-tree-node-item-icon'); + + if (resource && !icon) { + templateData.resourceLabel.setLabel({ name, resource }, { fileKind: node.collapsibleState === TreeItemCollapsibleState.Collapsed || node.collapsibleState === TreeItemCollapsibleState.Expanded ? FileKind.FOLDER : FileKind.FILE }); + DOM.addClass(templateData.resourceLabel.element, 'custom-view-tree-node-item-resourceLabel'); } else { - templateData.icon.getHTMLElement().style.backgroundImage = ''; - DOM.removeClass(templateData.icon.getHTMLElement(), 'custom-view-tree-node-item-icon'); + templateData.label.textContent = name; + DOM.addClass(templateData.label, 'custom-view-tree-node-item-label'); + templateData.icon.style.backgroundImage = `url('${icon}')`; + if (icon) { + DOM.addClass(templateData.icon, 'custom-view-tree-node-item-icon'); + } } + + templateData.actionBar.context = ({ $treeViewId: this.treeViewId, $treeItemHandle: node.handle }); + templateData.actionBar.push(this.menus.getResourceActions(node), { icon: true, label: false }); } public disposeTemplate(tree: ITree, templateId: string, templateData: ITreeExplorerTemplateData): void { + templateData.resourceLabel.dispose(); } } @@ -439,6 +463,10 @@ class Menus implements IDisposable { return this.titleSecondaryActions; } + getResourceActions(element: ITreeItem): IAction[] { + return this.getActions(MenuId.ViewItemContext, { key: 'viewItem', value: element.contextValue }).primary; + } + getResourceContextActions(element: ITreeItem): IAction[] { return this.getActions(MenuId.ViewItemContext, { key: 'viewItem', value: element.contextValue }).secondary; } @@ -452,7 +480,7 @@ class Menus implements IDisposable { const primary: IAction[] = []; const secondary: IAction[] = []; const result = { primary, secondary }; - fillInActions(menu, { shouldForwardArgs: true }, result, this.contextMenuService); + fillInActions(menu, { shouldForwardArgs: true }, result, this.contextMenuService, g => /^inline/.test(g)); menu.dispose(); contextKeyService.dispose(); diff --git a/src/vs/workbench/browser/parts/views/viewsRegistry.ts b/src/vs/workbench/browser/parts/views/viewsRegistry.ts deleted file mode 100644 index aa8ccb4bdca..00000000000 --- a/src/vs/workbench/browser/parts/views/viewsRegistry.ts +++ /dev/null @@ -1,149 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import Event, { Emitter } from 'vs/base/common/event'; -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { ITreeViewDataProvider } from 'vs/workbench/common/views'; -import { localize } from 'vs/nls'; - -export class ViewLocation { - - static readonly Explorer = new ViewLocation('explorer'); - static readonly Debug = new ViewLocation('debug'); - static readonly Extensions = new ViewLocation('extensions'); - - constructor(private _id: string) { - } - - get id(): string { - return this._id; - } - - static getContributedViewLocation(value: string): ViewLocation { - switch (value) { - case ViewLocation.Explorer.id: return ViewLocation.Explorer; - case ViewLocation.Debug.id: return ViewLocation.Debug; - } - return void 0; - } -} - -export interface IViewDescriptor { - - readonly id: string; - - readonly name: string; - - readonly location: ViewLocation; - - // TODO do we really need this?! - readonly ctor: any; - - readonly when?: ContextKeyExpr; - - readonly order?: number; - - readonly weight?: number; - - readonly collapsed?: boolean; - - readonly canToggleVisibility?: boolean; -} - -export interface IViewsRegistry { - - readonly onViewsRegistered: Event; - - readonly onViewsDeregistered: Event; - - readonly onTreeViewDataProviderRegistered: Event; - - registerViews(views: IViewDescriptor[]): void; - - deregisterViews(ids: string[], location: ViewLocation): void; - - registerTreeViewDataProvider(id: string, factory: ITreeViewDataProvider): void; - - deregisterTreeViewDataProviders(): void; - - getViews(loc: ViewLocation): IViewDescriptor[]; - - getTreeViewDataProvider(id: string): ITreeViewDataProvider; - -} - -export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry { - - private _onViewsRegistered: Emitter = new Emitter(); - readonly onViewsRegistered: Event = this._onViewsRegistered.event; - - private _onViewsDeregistered: Emitter = new Emitter(); - readonly onViewsDeregistered: Event = this._onViewsDeregistered.event; - - private _onTreeViewDataProviderRegistered: Emitter = new Emitter(); - readonly onTreeViewDataProviderRegistered: Event = this._onTreeViewDataProviderRegistered.event; - - private _views: Map = new Map(); - private _treeViewDataPoviders: Map = new Map(); - - registerViews(viewDescriptors: IViewDescriptor[]): void { - if (viewDescriptors.length) { - for (const viewDescriptor of viewDescriptors) { - let views = this._views.get(viewDescriptor.location); - if (!views) { - views = []; - this._views.set(viewDescriptor.location, views); - } - if (views.some(v => v.id === viewDescriptor.id)) { - throw new Error(localize('duplicateId', "A view with id `{0}` is already registered in the location `{1}`", viewDescriptor.id, viewDescriptor.location.id)); - } - views.push(viewDescriptor); - } - this._onViewsRegistered.fire(viewDescriptors); - } - } - - deregisterViews(ids: string[], location: ViewLocation): void { - const views = this._views.get(location); - - if (!views) { - return; - } - - const viewsToDeregister = views.filter(view => ids.indexOf(view.id) !== -1); - - if (viewsToDeregister.length) { - this._views.set(location, views.filter(view => ids.indexOf(view.id) === -1)); - } - - this._onViewsDeregistered.fire(viewsToDeregister); - } - - registerTreeViewDataProvider(id: string, factory: ITreeViewDataProvider) { - if (!this.isDataProviderRegistered(id)) { - // TODO: throw error - } - this._treeViewDataPoviders.set(id, factory); - this._onTreeViewDataProviderRegistered.fire(id); - } - - deregisterTreeViewDataProviders(): void { - this._treeViewDataPoviders.clear(); - } - - getViews(loc: ViewLocation): IViewDescriptor[] { - return this._views.get(loc) || []; - } - - getTreeViewDataProvider(id: string): ITreeViewDataProvider { - return this._treeViewDataPoviders.get(id); - } - - private isDataProviderRegistered(id: string): boolean { - let registered = false; - this._views.forEach(views => registered = registered || views.some(view => view.id === id)); - return registered; - } -}; diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 7bc93ba609f..1ab63b6f749 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -17,7 +17,7 @@ import { DelayedDragHandler } from 'vs/base/browser/dnd'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewsRegistry, ViewLocation, IViewDescriptor, IViewsViewlet } from 'vs/workbench/common/views'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -27,7 +27,10 @@ import { IContextKeyService, IContextKeyChangeEvent } from 'vs/platform/contextk import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { PanelViewlet, ViewletPanel } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IPanelOptions } from 'vs/base/browser/ui/splitview/panelview'; -import { WorkbenchTree } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { IWorkbenchThemeService, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; +import Event, { Emitter } from 'vs/base/common/event'; export interface IViewOptions extends IPanelOptions { id: string; @@ -96,14 +99,12 @@ export abstract class ViewsViewletPanel extends ViewletPanel { } -// TODO@isidor @sandeep remove this class export abstract class TreeViewsViewletPanel extends ViewsViewletPanel { readonly id: string; readonly name: string; protected treeContainer: HTMLElement; - // TODO@sandeep why is tree here? isn't this coming only from TreeView protected tree: WorkbenchTree; protected isDisposed: boolean; private dragHandler: DelayedDragHandler; @@ -121,8 +122,10 @@ export abstract class TreeViewsViewletPanel extends ViewsViewletPanel { } setExpanded(expanded: boolean): void { - this.updateTreeVisibility(this.tree, expanded); - super.setExpanded(expanded); + if (this.isExpanded() !== expanded) { + this.updateTreeVisibility(this.tree, expanded); + super.setExpanded(expanded); + } } protected renderHeader(container: HTMLElement): void { @@ -259,7 +262,7 @@ export interface IViewState { order: number; } -export class ViewsViewlet extends PanelViewlet { +export class ViewsViewlet extends PanelViewlet implements IViewsViewlet { private viewHeaderContextMenuListeners: IDisposable[] = []; private viewletSettings: object; @@ -270,6 +273,9 @@ export class ViewsViewlet extends PanelViewlet { protected viewsStates: Map = new Map(); private areExtensionsReady: boolean = false; + private _onDidChangeViewVisibilityState: Emitter = new Emitter(); + readonly onDidChangeViewVisibilityState: Event = this._onDidChangeViewVisibilityState.event; + constructor( id: string, private location: ViewLocation, @@ -324,6 +330,17 @@ export class ViewsViewlet extends PanelViewlet { .then(() => void 0); } + openView(id: string): void { + this.focus(); + const view = this.getView(id); + if (view) { + view.setExpanded(true); + view.focus(); + } else { + this.toggleViewVisibility(id); + } + } + layout(dimension: Dimension): void { super.layout(dimension); this.dimension = dimension; @@ -347,16 +364,22 @@ export class ViewsViewlet extends PanelViewlet { super.shutdown(); } - toggleViewVisibility(id: string, visible?: boolean): void { - const view = this.getView(id); + toggleViewVisibility(id: string): void { let viewState = this.viewsStates.get(id); - - if (!viewState || (visible === true && view) || (visible === false && !view)) { + if (!viewState) { return; } - viewState.isHidden = !!view; - this.updateViews(); + viewState.isHidden = !!this.getView(id); + this.updateViews() + .then(() => { + this._onDidChangeViewVisibilityState.fire(id); + if (!viewState.isHidden) { + this.openView(id); + } else { + this.focus(); + } + }); } private onViewsRegistered(views: IViewDescriptor[]): void { @@ -563,7 +586,7 @@ export class ViewsViewlet extends PanelViewlet { getAnchor: () => anchor, getActions: () => TPromise.as([{ id: `${view.id}.removeView`, - label: nls.localize('hideView', "Hide from Side Bar"), + label: nls.localize('hideView', "Hide"), enabled: true, run: () => this.toggleViewVisibility(view.id) }]), @@ -659,10 +682,12 @@ export class ViewsViewlet extends PanelViewlet { export class PersistentViewsViewlet extends ViewsViewlet { + private readonly hiddenViewsStorageId: string; + constructor( id: string, location: ViewLocation, - private viewletStateStorageId: string, + private readonly viewletStateStorageId: string, showHeaderInTitleWhenSingleView: boolean, @ITelemetryService telemetryService: ITelemetryService, @IStorageService storageService: IStorageService, @@ -674,6 +699,8 @@ export class PersistentViewsViewlet extends ViewsViewlet { @IExtensionService extensionService: IExtensionService ) { super(id, location, showHeaderInTitleWhenSingleView, telemetryService, storageService, instantiationService, themeService, contextKeyService, contextMenuService, extensionService); + this.hiddenViewsStorageId = `${this.viewletStateStorageId}.hidden`; + this._register(this.onDidChangeViewVisibilityState(id => this.onViewVisibilityChanged(id))); } create(parent: Builder): TPromise { @@ -712,6 +739,51 @@ export class PersistentViewsViewlet extends ViewsViewlet { protected loadViewsStates(): void { const viewsStates = JSON.parse(this.storageService.get(this.viewletStateStorageId, this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? StorageScope.WORKSPACE : StorageScope.GLOBAL, '{}')); - Object.keys(viewsStates).forEach(id => this.viewsStates.set(id, viewsStates[id])); + const hiddenViews = this.loadHiddenViews(); + Object.keys(viewsStates).forEach(id => this.viewsStates.set(id, { ...viewsStates[id], ...{ isHidden: hiddenViews.indexOf(id) !== -1 } })); + } + + private onViewVisibilityChanged(id: string) { + const hiddenViews = this.loadHiddenViews(); + const index = hiddenViews.indexOf(id); + if (this.getView(id) && index !== -1) { + hiddenViews.splice(index, 1); + } else if (index === -1) { + hiddenViews.push(id); + } + this.storeHiddenViews(hiddenViews); + } + + private storeHiddenViews(hiddenViews: string[]): void { + this.storageService.store(this.hiddenViewsStorageId, JSON.stringify(hiddenViews), StorageScope.GLOBAL); + } + + private loadHiddenViews(): string[] { + return JSON.parse(this.storageService.get(this.hiddenViewsStorageId, StorageScope.GLOBAL, '[]')); + } +} + +export class FileIconThemableWorkbenchTree extends WorkbenchTree { + + constructor( + container: HTMLElement, + configuration: ITreeConfiguration, + options: ITreeOptions, + @IContextKeyService contextKeyService: IContextKeyService, + @IListService listService: IListService, + @IThemeService themeService: IWorkbenchThemeService + ) { + super(container, configuration, { ...options, ...{ showTwistie: false, twistiePixels: 12 } }, contextKeyService, listService, themeService); + + DOM.addClass(container, 'file-icon-themable-tree'); + DOM.addClass(container, 'show-file-icons'); + + const onFileIconThemeChange = (fileIconTheme: IFileIconTheme) => { + DOM.toggleClass(container, 'align-icons-and-twisties', fileIconTheme.hasFileIcons && !fileIconTheme.hasFolderIcons); + DOM.toggleClass(container, 'hide-arrows', fileIconTheme.hidesExplorerArrows === true); + }; + + this.disposables.push(themeService.onDidFileIconThemeChange(onFileIconThemeChange)); + onFileIconThemeChange(themeService.getFileIconTheme()); } } diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 9f4352f8d05..03436fe0657 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -788,10 +788,6 @@ export interface IEditorIdentifier { editor: IEditorInput; } -export interface IEditorContext extends IEditorIdentifier { - event?: any; -} - export interface IEditorCloseEvent extends IEditorIdentifier { replaced: boolean; index: number; diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 00b5ddbc939..f7a59c538b0 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -4,8 +4,161 @@ *--------------------------------------------------------------------------------------------*/ import { TPromise } from 'vs/base/common/winjs.base'; -import Event from 'vs/base/common/event'; import { Command } from 'vs/editor/common/modes'; +import { UriComponents } from 'vs/base/common/uri'; +import Event, { Emitter } from 'vs/base/common/event'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { ITreeViewDataProvider } from 'vs/workbench/common/views'; +import { localize } from 'vs/nls'; +import { IViewlet } from 'vs/workbench/common/viewlet'; + +export class ViewLocation { + + static readonly Explorer = new ViewLocation('explorer'); + static readonly Debug = new ViewLocation('debug'); + static readonly Extensions = new ViewLocation('extensions'); + + constructor(private _id: string) { + } + + get id(): string { + return this._id; + } + + static getContributedViewLocation(value: string): ViewLocation { + switch (value) { + case ViewLocation.Explorer.id: return ViewLocation.Explorer; + case ViewLocation.Debug.id: return ViewLocation.Debug; + } + return void 0; + } +} + +export interface IViewDescriptor { + + readonly id: string; + + readonly name: string; + + readonly location: ViewLocation; + + // TODO do we really need this?! + readonly ctor: any; + + readonly when?: ContextKeyExpr; + + readonly order?: number; + + readonly weight?: number; + + readonly collapsed?: boolean; + + readonly canToggleVisibility?: boolean; +} + +export interface IViewsRegistry { + + readonly onViewsRegistered: Event; + + readonly onViewsDeregistered: Event; + + readonly onTreeViewDataProviderRegistered: Event; + + registerViews(views: IViewDescriptor[]): void; + + deregisterViews(ids: string[], location: ViewLocation): void; + + registerTreeViewDataProvider(id: string, factory: ITreeViewDataProvider): void; + + deregisterTreeViewDataProviders(): void; + + getViews(loc: ViewLocation): IViewDescriptor[]; + + getTreeViewDataProvider(id: string): ITreeViewDataProvider; + +} + +export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry { + + private _onViewsRegistered: Emitter = new Emitter(); + readonly onViewsRegistered: Event = this._onViewsRegistered.event; + + private _onViewsDeregistered: Emitter = new Emitter(); + readonly onViewsDeregistered: Event = this._onViewsDeregistered.event; + + private _onTreeViewDataProviderRegistered: Emitter = new Emitter(); + readonly onTreeViewDataProviderRegistered: Event = this._onTreeViewDataProviderRegistered.event; + + private _views: Map = new Map(); + private _treeViewDataPoviders: Map = new Map(); + + registerViews(viewDescriptors: IViewDescriptor[]): void { + if (viewDescriptors.length) { + for (const viewDescriptor of viewDescriptors) { + let views = this._views.get(viewDescriptor.location); + if (!views) { + views = []; + this._views.set(viewDescriptor.location, views); + } + if (views.some(v => v.id === viewDescriptor.id)) { + throw new Error(localize('duplicateId', "A view with id `{0}` is already registered in the location `{1}`", viewDescriptor.id, viewDescriptor.location.id)); + } + views.push(viewDescriptor); + } + this._onViewsRegistered.fire(viewDescriptors); + } + } + + deregisterViews(ids: string[], location: ViewLocation): void { + const views = this._views.get(location); + + if (!views) { + return; + } + + const viewsToDeregister = views.filter(view => ids.indexOf(view.id) !== -1); + + if (viewsToDeregister.length) { + this._views.set(location, views.filter(view => ids.indexOf(view.id) === -1)); + } + + this._onViewsDeregistered.fire(viewsToDeregister); + } + + registerTreeViewDataProvider(id: string, factory: ITreeViewDataProvider) { + if (!this.isDataProviderRegistered(id)) { + // TODO: throw error + } + this._treeViewDataPoviders.set(id, factory); + this._onTreeViewDataProviderRegistered.fire(id); + } + + deregisterTreeViewDataProviders(): void { + this._treeViewDataPoviders.clear(); + } + + getViews(loc: ViewLocation): IViewDescriptor[] { + return this._views.get(loc) || []; + } + + getTreeViewDataProvider(id: string): ITreeViewDataProvider { + return this._treeViewDataPoviders.get(id); + } + + private isDataProviderRegistered(id: string): boolean { + let registered = false; + this._views.forEach(views => registered = registered || views.some(view => view.id === id)); + return registered; + } +}; + +export interface IViewsViewlet extends IViewlet { + + openView(id: string): void; + +} + +// Custom view export type TreeViewItemHandleArg = { $treeViewId: string, @@ -24,12 +177,14 @@ export interface ITreeItem { parentHandle: string; - label: string; + label?: string; icon?: string; iconDark?: string; + resourceUri?: UriComponents; + contextValue?: string; command?: Command; diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts index f0a5ba05fad..8d7c147db61 100644 --- a/src/vs/workbench/electron-browser/actions.ts +++ b/src/vs/workbench/electron-browser/actions.ts @@ -46,6 +46,10 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IExtensionService, ActivationTimes } from 'vs/platform/extensions/common/extensions'; import { getEntries } from 'vs/base/common/performance'; import { IEditor } from 'vs/platform/editor/common/editor'; +import { IIssueService } from 'vs/platform/issue/common/issue'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { textLinkForeground, inputBackground, inputBorder, inputForeground, buttonBackground, buttonHoverBackground, buttonForeground, inputValidationErrorBorder, foreground, inputActiveOptionBorder } from 'vs/platform/theme/common/colorRegistry'; +import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; // --- actions @@ -324,14 +328,6 @@ export class ShowStartupPerformance extends Action { (console).table(this.getStartupMetricsTable(nodeModuleLoadTime)); - if (this.environmentService.performance) { - const data = this.analyzeLoaderStats(); - for (let type in data) { - (console).groupCollapsed(`Loader: ${type}`); - (console).table(data[type]); - (console).groupEnd(); - } - } (console).groupEnd(); @@ -422,114 +418,6 @@ export class ShowStartupPerformance extends Action { return { table: result, duration: Math.round(total) }; } - - private analyzeLoaderStats(): { [type: string]: any[] } { - const stats = (require).getStats().slice(0).sort((a: ILoaderEvent, b: ILoaderEvent) => { - if (a.detail < b.detail) { - return -1; - } else if (a.detail > b.detail) { - return 1; - } else if (a.type < b.type) { - return -1; - } else if (a.type > b.type) { - return 1; - } else { - return 0; - } - }); - - class Tick { - - public readonly duration: number; - public readonly detail: string; - - constructor(public readonly start: ILoaderEvent, public readonly end: ILoaderEvent) { - console.assert(start.detail === end.detail); - - this.duration = this.end.timestamp - this.start.timestamp; - this.detail = start.detail; - } - - toTableObject() { - return { - ['Path']: this.start.detail, - ['Took (ms)']: this.duration.toFixed(2), - // ['Start (ms)']: this.start.timestamp, - // ['End (ms)']: this.end.timestamp - }; - } - - static compareUsingStartTimestamp(a: Tick, b: Tick): number { - if (a.start.timestamp < b.start.timestamp) { - return -1; - } else if (a.start.timestamp > b.start.timestamp) { - return 1; - } else { - return 0; - } - } - } - - const ticks: { [type: number]: Tick[] } = { - [LoaderEventType.BeginLoadingScript]: [], - [LoaderEventType.BeginInvokeFactory]: [], - [LoaderEventType.NodeBeginEvaluatingScript]: [], - [LoaderEventType.NodeBeginNativeRequire]: [], - }; - - for (let i = 1; i < stats.length - 1; i++) { - const stat = stats[i]; - const nextStat = stats[i + 1]; - - if (nextStat.type - stat.type > 2) { - //bad?! - break; - } - - i += 1; - ticks[stat.type].push(new Tick(stat, nextStat)); - } - - ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.BeginInvokeFactory].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.NodeBeginEvaluatingScript].sort(Tick.compareUsingStartTimestamp); - ticks[LoaderEventType.NodeBeginNativeRequire].sort(Tick.compareUsingStartTimestamp); - - const ret = { - 'Load Script': ticks[LoaderEventType.BeginLoadingScript].map(t => t.toTableObject()), - '(Node) Load Script': ticks[LoaderEventType.NodeBeginNativeRequire].map(t => t.toTableObject()), - 'Eval Script': ticks[LoaderEventType.BeginInvokeFactory].map(t => t.toTableObject()), - '(Node) Eval Script': ticks[LoaderEventType.NodeBeginEvaluatingScript].map(t => t.toTableObject()), - }; - - function total(ticks: Tick[]): number { - let sum = 0; - for (const tick of ticks) { - sum += tick.duration; - } - return sum; - } - - // totals - ret['Load Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.BeginLoadingScript]).toFixed(2) - }); - ret['Eval Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.BeginInvokeFactory]).toFixed(2) - }); - ret['(Node) Load Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.NodeBeginNativeRequire]).toFixed(2) - }); - ret['(Node) Eval Script'].push({ - ['Path']: 'TOTAL TIME', - ['Took (ms)']: total(ticks[LoaderEventType.NodeBeginEvaluatingScript]).toFixed(2) - }); - - return ret; - } } export class ReloadWindowAction extends Action { @@ -859,6 +747,41 @@ export class CloseMessagesAction extends Action { } } +export class OpenIssueReporterAction extends Action { + public static readonly ID = 'workbench.action.openIssueReporter'; + public static readonly LABEL = nls.localize('openIssueReporter', "Open Issue Reporter"); + + constructor( + id: string, + label: string, + @IIssueService private issueService: IIssueService, + @IThemeService private themeService: IThemeService + ) { + super(id, label); + } + + public run(): TPromise { + const theme = this.themeService.getTheme(); + const style = { + backgroundColor: theme.getColor(SIDE_BAR_BACKGROUND) && theme.getColor(SIDE_BAR_BACKGROUND).toString(), + color: theme.getColor(foreground).toString(), + textLinkColor: theme.getColor(textLinkForeground) && theme.getColor(textLinkForeground).toString(), + inputBackground: theme.getColor(inputBackground) && theme.getColor(inputBackground).toString(), + inputForeground: theme.getColor(inputForeground) && theme.getColor(inputForeground).toString(), + inputBorder: theme.getColor(inputBorder) && theme.getColor(inputBorder).toString(), + inputActiveBorder: theme.getColor(inputActiveOptionBorder) && theme.getColor(inputActiveOptionBorder).toString(), + inputErrorBorder: theme.getColor(inputValidationErrorBorder) && theme.getColor(inputValidationErrorBorder).toString(), + buttonBackground: theme.getColor(buttonBackground) && theme.getColor(buttonBackground).toString(), + buttonForeground: theme.getColor(buttonForeground) && theme.getColor(buttonForeground).toString(), + buttonHoverBackground: theme.getColor(buttonHoverBackground) && theme.getColor(buttonHoverBackground).toString(), + zoomLevel: webFrame.getZoomLevel() + }; + return this.issueService.openReporter(style).then(() => { + return TPromise.as(true); + }); + } +} + export class ReportIssueAction extends Action { public static readonly ID = 'workbench.action.reportIssues'; diff --git a/src/vs/workbench/electron-browser/commands.ts b/src/vs/workbench/electron-browser/commands.ts index e26ffd3117d..f222e047687 100644 --- a/src/vs/workbench/electron-browser/commands.ts +++ b/src/vs/workbench/electron-browser/commands.ts @@ -22,11 +22,33 @@ import { WorkbenchListFocusContextKey, IListService, WorkbenchListSupportsMultiS import { PagedList } from 'vs/base/browser/ui/list/listPaging'; import { range } from 'vs/base/common/arrays'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { ITree } from 'vs/base/parts/tree/browser/tree'; // --- List Commands export function registerCommands(): void { + function focusDown(accessor: ServicesAccessor, arg2?: number): void { + const focused = accessor.get(IListService).lastFocusedList; + const count = typeof arg2 === 'number' ? arg2 : 1; + + // List + if (focused instanceof List || focused instanceof PagedList) { + const list = focused; + + list.focusNext(count); + list.reveal(list.getFocus()[0]); + } + + // Tree + else if (focused) { + const tree = focused; + + tree.focusNext(count, { origin: 'keyboard' }); + tree.reveal(tree.getFocus()).done(null, errors.onUnexpectedError); + } + } + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'list.focusDown', weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), @@ -36,28 +58,93 @@ export function registerCommands(): void { primary: KeyCode.DownArrow, secondary: [KeyMod.WinCtrl | KeyCode.KEY_N] }, + handler: (accessor, arg2) => focusDown(accessor, arg2) + }); + + function expandMultiSelection(focused: List | PagedList | ITree, previousFocus: any): void { + + // List + if (focused instanceof List || focused instanceof PagedList) { + const list = focused; + + const focus = list.getFocus() ? list.getFocus()[0] : void 0; + const selection = list.getSelection(); + if (selection && selection.indexOf(focus) >= 0) { + list.setSelection(selection.filter(s => s !== previousFocus)); + } else { + list.setSelection(selection.concat(focus)); + } + } + + // Tree + else if (focused) { + const tree = focused; + + const focus = tree.getFocus(); + const selection = tree.getSelection(); + if (selection && selection.indexOf(focus) >= 0) { + tree.setSelection(selection.filter(s => s !== previousFocus)); + } else { + tree.setSelection(selection.concat(focus)); + } + } + } + + KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'list.expandSelectionDown', + weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), + when: WorkbenchListFocusContextKey, + primary: KeyMod.Shift | KeyCode.DownArrow, handler: (accessor, arg2) => { const focused = accessor.get(IListService).lastFocusedList; - const count = typeof arg2 === 'number' ? arg2 : 1; // List if (focused instanceof List || focused instanceof PagedList) { const list = focused; - list.focusNext(count); - list.reveal(list.getFocus()[0]); + // Focus down first + const previousFocus = list.getFocus() ? list.getFocus()[0] : void 0; + focusDown(accessor, arg2); + + // Then adjust selection + expandMultiSelection(focused, previousFocus); } // Tree else if (focused) { const tree = focused; - tree.focusNext(count, { origin: 'keyboard' }); - tree.reveal(tree.getFocus()).done(null, errors.onUnexpectedError); + // Focus down first + const previousFocus = tree.getFocus(); + focusDown(accessor, arg2); + + // Then adjust selection + expandMultiSelection(focused, previousFocus); } } }); + function focusUp(accessor: ServicesAccessor, arg2?: number): void { + const focused = accessor.get(IListService).lastFocusedList; + const count = typeof arg2 === 'number' ? arg2 : 1; + + // List + if (focused instanceof List || focused instanceof PagedList) { + const list = focused; + + list.focusPrevious(count); + list.reveal(list.getFocus()[0]); + } + + // Tree + else if (focused) { + const tree = focused; + + tree.focusPrevious(count, { origin: 'keyboard' }); + tree.reveal(tree.getFocus()).done(null, errors.onUnexpectedError); + } + } + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'list.focusUp', weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), @@ -67,24 +154,39 @@ export function registerCommands(): void { primary: KeyCode.UpArrow, secondary: [KeyMod.WinCtrl | KeyCode.KEY_P] }, + handler: (accessor, arg2) => focusUp(accessor, arg2) + }); + + KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'list.expandSelectionUp', + weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), + when: WorkbenchListFocusContextKey, + primary: KeyMod.Shift | KeyCode.UpArrow, handler: (accessor, arg2) => { const focused = accessor.get(IListService).lastFocusedList; - const count = typeof arg2 === 'number' ? arg2 : 1; // List if (focused instanceof List || focused instanceof PagedList) { const list = focused; - list.focusPrevious(count); - list.reveal(list.getFocus()[0]); + // Focus up first + const previousFocus = list.getFocus() ? list.getFocus()[0] : void 0; + focusUp(accessor, arg2); + + // Then adjust selection + expandMultiSelection(focused, previousFocus); } // Tree else if (focused) { const tree = focused; - tree.focusPrevious(count, { origin: 'keyboard' }); - tree.reveal(tree.getFocus()).done(null, errors.onUnexpectedError); + // Focus up first + const previousFocus = tree.getFocus(); + focusUp(accessor, arg2); + + // Then adjust selection + expandMultiSelection(focused, previousFocus); } } }); @@ -426,4 +528,12 @@ export function registerCommands(): void { return void 0; }); }); + + CommandsRegistry.registerCommand('_workbench.removeFromRecentlyOpened', function (accessor: ServicesAccessor, path: string) { + const windowsService = accessor.get(IWindowsService); + + return windowsService.removeFromRecentlyOpened([path]).then(() => { + return void 0; + }); + }); } diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index c4c44281642..6bcbf87b95d 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -14,7 +14,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'v import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; -import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, ReportIssueAction, ReportPerformanceIssueAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseWorkspaceAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, CloseMessagesAction, NavigateUpAction, NavigateDownAction, NavigateLeftAction, NavigateRightAction, IncreaseViewSizeAction, DecreaseViewSizeAction, ShowStartupPerformance, ToggleSharedProcessAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, ConfigureLocaleAction } from 'vs/workbench/electron-browser/actions'; +import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenIssueReporterAction, ReportIssueAction, ReportPerformanceIssueAction, ZoomResetAction, ZoomOutAction, ZoomInAction, ToggleFullScreenAction, ToggleMenuBarAction, CloseWorkspaceAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, CloseMessagesAction, NavigateUpAction, NavigateDownAction, NavigateLeftAction, NavigateRightAction, IncreaseViewSizeAction, DecreaseViewSizeAction, ShowStartupPerformance, ToggleSharedProcessAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, ConfigureLocaleAction } from 'vs/workbench/electron-browser/actions'; import { MessagesVisibleContext } from 'vs/workbench/electron-browser/workbench'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { registerCommands } from 'vs/workbench/electron-browser/commands'; @@ -46,6 +46,7 @@ if (isMacintosh) { } workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'File: Close Workspace', fileCategory); +workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenIssueReporterAction, OpenIssueReporterAction.ID, OpenIssueReporterAction.LABEL), 'Help: Open Issue Reporter', helpCategory); if (!!product.reportIssueUrl) { workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ReportIssueAction, ReportIssueAction.ID, ReportIssueAction.LABEL), 'Help: Report Issues', helpCategory); workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ReportPerformanceIssueAction, ReportPerformanceIssueAction.ID, ReportPerformanceIssueAction.LABEL), 'Help: Report Performance Issue', helpCategory); diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 9e75b4e4cfa..9f6e912a251 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -31,7 +31,7 @@ import { IWindowConfiguration, IWindowsService } from 'vs/platform/windows/commo import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { StorageService, inMemoryLocalStorageInstance } from 'vs/platform/storage/common/storageService'; +import { StorageService, inMemoryLocalStorageInstance, IStorage } from 'vs/platform/storage/common/storageService'; import { Client as ElectronIPCClient } from 'vs/base/parts/ipc/electron-browser/ipc.electron-browser'; import { webFrame } from 'electron'; import { UpdateChannelClient } from 'vs/platform/update/common/updateIpc'; @@ -44,6 +44,8 @@ import { createSpdLogService } from 'vs/platform/log/node/spdlogService'; import fs = require('fs'); import { ConsoleLogService, MultiplexLogService } from 'vs/platform/log/common/log'; +import { IssueChannelClient } from 'vs/platform/issue/common/issueIpc'; +import { IIssueService } from 'vs/platform/issue/common/issue'; gracefulFs.gracefulify(fs); // enable gracefulFs export function startup(configuration: IWindowConfiguration): TPromise { @@ -82,7 +84,6 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise { // Since the configuration service is one of the core services that is used in so many places, we initialize it // right before startup of the workbench shell to have its data ready for consumers return createAndInitializeWorkspaceService(configuration, environmentService).then(workspaceService => { - const timerService = new TimerService((window).MonacoEnvironment.timers as IInitData, workspaceService.getWorkbenchState() === WorkbenchState.EMPTY); const storageService = createStorageService(workspaceService, environmentService); @@ -185,7 +186,16 @@ function createStorageService(workspaceService: IWorkspaceContextService, enviro } const disableStorage = !!environmentService.extensionTestsPath; // never keep any state when running extension tests! - const storage = disableStorage ? inMemoryLocalStorageInstance : window.localStorage; + + let storage: IStorage; + if (disableStorage) { + storage = inMemoryLocalStorageInstance; + } else { + // TODO@Ben remove me after a while + perf.mark('willAccessLocalStorage'); + storage = window.localStorage; + perf.mark('didAccessLocalStorage'); + } return new StorageService(storage, storage, workspaceId, secondaryWorkspaceId); } @@ -202,6 +212,9 @@ function createMainProcessServices(mainProcessClient: ElectronIPCClient, configu const urlChannel = mainProcessClient.getChannel('url'); serviceCollection.set(IURLService, new SyncDescriptor(URLChannelClient, urlChannel, configuration.windowId)); + const issueChannel = mainProcessClient.getChannel('issue'); + serviceCollection.set(IIssueService, new SyncDescriptor(IssueChannelClient, issueChannel)); + const workspacesChannel = mainProcessClient.getChannel('workspaces'); serviceCollection.set(IWorkspacesService, new WorkspacesChannelClient(workspacesChannel)); diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index ace1369afb0..cc86097415f 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -87,6 +87,8 @@ import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/elect import { HashService } from 'vs/workbench/services/hash/node/hashService'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { ILogService } from 'vs/platform/log/common/log'; +import { stat } from 'fs'; +import { join } from 'path'; /** * Services that we require for the Shell @@ -161,17 +163,7 @@ export class WorkbenchShell { const [instantiationService, serviceCollection] = this.initServiceCollection(parent.getHTMLElement()); // Workbench - this.workbench = instantiationService.createInstance(Workbench, parent.getHTMLElement(), workbenchContainer.getHTMLElement(), this.configuration, serviceCollection, this.lifecycleService); - try { - this.workbench.startup().done(startupInfos => this.onWorkbenchStarted(startupInfos, instantiationService)); - } catch (error) { - - // Log it - this.logService.error(toErrorMessage(error, true)); - - // Rethrow - throw error; - } + this.workbench = this.createWorkbench(instantiationService, serviceCollection, parent.getHTMLElement(), workbenchContainer.getHTMLElement()); // Window this.workbench.getInstantiationService().createInstance(ElectronWindow, this.container); @@ -188,26 +180,50 @@ export class WorkbenchShell { return workbenchContainer; } - private onWorkbenchStarted(info: IWorkbenchStartedInfo, instantiationService: IInstantiationService): void { + private createWorkbench(instantiationService: IInstantiationService, serviceCollection: ServiceCollection, parent: HTMLElement, workbenchContainer: HTMLElement): Workbench { + try { + const workbench = instantiationService.createInstance(Workbench, parent, workbenchContainer, this.configuration, serviceCollection, this.lifecycleService); - // Startup Telemetry - this.logStartupTelemetry(info); + // Set lifecycle phase to `Restoring` + this.lifecycleService.phase = LifecyclePhase.Restoring; - // Set lifecycle phase to `Runnning` so that other contributions can now do something - this.lifecycleService.phase = LifecyclePhase.Running; + // Startup Workbench + workbench.startup().done(startupInfos => { - // Set lifecycle phase to `Runnning For A Bit` after a short delay - let timeoutHandle = setTimeout(() => { - timeoutHandle = void 0; - this.lifecycleService.phase = LifecyclePhase.Eventually; - }, 3000); - this.toUnbind.push({ - dispose: () => { - if (timeoutHandle) { - clearTimeout(timeoutHandle); + // Set lifecycle phase to `Runnning` so that other contributions can now do something + this.lifecycleService.phase = LifecyclePhase.Running; + + // Startup Telemetry + this.logStartupTelemetry(startupInfos); + + // Set lifecycle phase to `Runnning For A Bit` after a short delay + let eventuallPhaseTimeoutHandle = setTimeout(() => { + eventuallPhaseTimeoutHandle = void 0; + this.lifecycleService.phase = LifecyclePhase.Eventually; + }, 3000); + this.toUnbind.push({ + dispose: () => { + if (eventuallPhaseTimeoutHandle) { + clearTimeout(eventuallPhaseTimeoutHandle); + } + } + }); + + // localStorage metrics (TODO@Ben remove me later) + if (!this.environmentService.extensionTestsPath && this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { + this.logLocalStorageMetrics(); } - } - }); + }); + + return workbench; + } catch (error) { + + // Log it + this.logService.error(toErrorMessage(error, true)); + + // Rethrow + throw error; + } } private logStartupTelemetry(info: IWorkbenchStartedInfo): void { @@ -265,6 +281,37 @@ export class WorkbenchShell { }); } + private logLocalStorageMetrics(): void { + perf.mark('willReadLocalStorage'); + if (!this.storageService.getBoolean('localStorageMetricsSent')) { + perf.mark('didReadLocalStorage'); + + perf.mark('willWriteLocalStorage'); + this.storageService.store('localStorageMetricsSent', true); + + stat(join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage'), (error, stat) => { + /* __GDPR__ + "localStorageMetrics" : { + "accessTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "firstReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "subsequentReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "writeTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "keys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "size": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('localStorageMetrics', { + 'accessTime': perf.getDuration('willAccessLocalStorage', 'didAccessLocalStorage'), + 'firstReadTime': perf.getDuration('willReadWorkspaceIdentifier', 'didReadWorkspaceIdentifier'), + 'subsequentReadTime': perf.getDuration('willReadLocalStorage', 'didReadLocalStorage'), + 'writeTime': perf.getDuration('willWriteLocalStorage', 'willComputeLocalStorageSize'), + 'keys': window.localStorage.length, + 'size': stat ? stat.size : -1 + }); + }); + } + } + private initServiceCollection(container: HTMLElement): [IInstantiationService, ServiceCollection] { const serviceCollection = new ServiceCollection(); serviceCollection.set(IWorkspaceContextService, this.contextService); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 758bdb709ea..e13edb24a93 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -76,7 +76,7 @@ import { ProgressService2 } from 'vs/workbench/services/progress/browser/progres import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { ShutdownReason, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle'; import { LifecycleService } from 'vs/workbench/services/lifecycle/electron-browser/lifecycleService'; import { IWindowService, IWindowConfiguration as IWindowSettings, IWindowConfiguration, IPath } from 'vs/platform/windows/common/windows'; import { IMessageService } from 'vs/platform/message/common/message'; @@ -97,7 +97,6 @@ import URI from 'vs/base/common/uri'; import { IListService, ListService } from 'vs/platform/list/browser/listService'; import { domEvent } from 'vs/base/browser/event'; import { InputFocusedContext } from 'vs/platform/workbench/common/contextkeys'; -import { onUnexpectedError } from 'vs/base/common/errors'; export const MessagesVisibleContext = new RawContextKey('globalMessageVisible', false); export const EditorsVisibleContext = new RawContextKey('editorIsOpen', false); @@ -321,7 +320,6 @@ export class Workbench implements IPartService { perf.mark('willRestoreEditors'); const restoredEditors: string[] = []; restorePromises.push(this.resolveEditorsToOpen().then(inputs => { - let editorOpenPromise: TPromise; if (inputs.length) { editorOpenPromise = this.editorService.openEditors(inputs.map(input => { return { input, position: EditorPosition.ONE }; })); @@ -329,10 +327,7 @@ export class Workbench implements IPartService { editorOpenPromise = this.editorPart.restoreEditors(); } - // update lifecycle *after* triggering the editor restore - this.lifecycleService.phase = LifecyclePhase.Restoring; - - editorOpenPromise.then(editors => { + return editorOpenPromise.then(editors => { this.handleEditorBackground(); // make sure we show the proper background in the editor area perf.mark('didRestoreEditors'); @@ -346,7 +341,7 @@ export class Workbench implements IPartService { } } } - }).done(undefined, onUnexpectedError); + }); })); // Restore Sidebar diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.ts b/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.ts index 023bb504812..48b4ecdae9c 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/wordWrapMigration.ts @@ -109,7 +109,7 @@ class WordWrapMigrationController extends Disposable implements IEditorContribut ); const dontShowAgainAction = new Action( 'wordWrapMigration.dontShowAgain', - nls.localize('wordWrapMigration.dontShowAgain', "Don't show again"), + nls.localize('wordWrapMigration.dontShowAgain', "Don't Show Again"), null, true, () => { diff --git a/src/vs/workbench/parts/debug/browser/debugViewlet.ts b/src/vs/workbench/parts/debug/browser/debugViewlet.ts index 803cb32cb64..67381c841c1 100644 --- a/src/vs/workbench/parts/debug/browser/debugViewlet.ts +++ b/src/vs/workbench/parts/debug/browser/debugViewlet.ts @@ -22,7 +22,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { ViewLocation } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewLocation } from 'vs/workbench/common/views'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; diff --git a/src/vs/workbench/parts/debug/electron-browser/breakpointsView.ts b/src/vs/workbench/parts/debug/electron-browser/breakpointsView.ts index de6a551619b..6e4c6862c91 100644 --- a/src/vs/workbench/parts/debug/electron-browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/breakpointsView.ts @@ -28,9 +28,8 @@ import { IEditorService, IEditor } from 'vs/platform/editor/common/editor'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { WorkbenchList, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { ViewsViewletPanel, IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -50,11 +49,9 @@ export class BreakpointsView extends ViewsViewletPanel { @IDebugService private debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService, @IInstantiationService private instantiationService: IInstantiationService, - @IListService private listService: IListService, @IThemeService private themeService: IThemeService, @IEditorService private editorService: IEditorService, - @IContextViewService private contextViewService: IContextViewService, - @IContextKeyService private contextKeyService: IContextKeyService + @IContextViewService private contextViewService: IContextViewService ) { super(options, keybindingService, contextMenuService); @@ -67,7 +64,7 @@ export class BreakpointsView extends ViewsViewletPanel { dom.addClass(container, 'debug-breakpoints'); const delegate = new BreakpointsDelegate(this.debugService); - this.list = new WorkbenchList(container, delegate, [ + this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [ this.instantiationService.createInstance(BreakpointsRenderer), new ExceptionBreakpointsRenderer(this.debugService), new FunctionBreakpointsRenderer(this.debugService), @@ -75,7 +72,7 @@ export class BreakpointsView extends ViewsViewletPanel { ], { identityProvider: element => element.getId(), multipleSelectionSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); CONTEXT_BREAKPOINTS_FOCUSED.bindTo(this.list.contextKeyService); @@ -95,14 +92,14 @@ export class BreakpointsView extends ViewsViewletPanel { this.disposables.push(this.list.onKeyUp(e => { const event = new StandardKeyboardEvent(e); if (event.equals(KeyCode.Enter)) { - handleBreakpointFocus(false, event && (event.ctrlKey || event.metaKey), false); + handleBreakpointFocus(false, event && (event.ctrlKey || event.metaKey || event.altKey), false); } })); this.disposables.push(this.list.onMouseDblClick(e => { - handleBreakpointFocus(false, false, true); + handleBreakpointFocus(false, e.browserEvent.altKey, true); })); this.disposables.push(this.list.onMouseClick(e => { - handleBreakpointFocus(true, false, false); + handleBreakpointFocus(true, e.browserEvent.altKey, false); })); this.list.splice(0, this.list.length, this.elements); diff --git a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts index 5948091a39d..fd458ff3c8b 100644 --- a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts @@ -15,7 +15,6 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { MenuId } from 'vs/platform/actions/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseDebugController, twistiePixels, renderViewTree } from 'vs/workbench/parts/debug/electron-browser/baseDebugView'; import { ITree, IActionProvider, IDataSource, IRenderer, IAccessibilityProvider } from 'vs/base/parts/tree/browser/tree'; import { IAction, IActionItem } from 'vs/base/common/actions'; @@ -25,8 +24,7 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/ import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Source } from 'vs/workbench/parts/debug/common/debugSource'; import { basenameOrAuthority } from 'vs/base/common/resources'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import FileResultsNavigation from 'vs/workbench/parts/files/browser/fileResultsNavigation'; @@ -44,12 +42,9 @@ export class CallStackView extends TreeViewsViewletPanel { constructor( private options: IViewletViewOptions, @IContextMenuService contextMenuService: IContextMenuService, - @IContextKeyService private contextKeyService: IContextKeyService, @IDebugService private debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService, @IInstantiationService private instantiationService: IInstantiationService, - @IThemeService private themeService: IThemeService, - @IListService private listService: IListService, @IWorkbenchEditorService private editorService: IWorkbenchEditorService, ) { super({ ...(options as IViewOptions), ariaHeaderLabel: nls.localize('callstackSection', "Call Stack Section") }, keybindingService, contextMenuService); @@ -99,7 +94,7 @@ export class CallStackView extends TreeViewsViewletPanel { const actionProvider = new CallStackActionProvider(this.debugService, this.keybindingService); const controller = this.instantiationService.createInstance(CallStackController, actionProvider, MenuId.DebugCallStackContext); - this.tree = new WorkbenchTree(this.treeContainer, { + this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { dataSource: new CallStackDataSource(), renderer: this.instantiationService.createInstance(CallStackRenderer), accessibilityProvider: this.instantiationService.createInstance(CallstackAccessibilityProvider), @@ -108,7 +103,7 @@ export class CallStackView extends TreeViewsViewletPanel { ariaLabel: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'callStackAriaLabel' }, "Debug Call Stack"), twistiePixels, keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); const fileResultsNavigation = new FileResultsNavigation(this.tree); this.disposables.push(fileResultsNavigation); diff --git a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts index 043476e62ce..f8768ff718e 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debug.contribution.ts @@ -41,7 +41,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi import * as debugCommands from 'vs/workbench/parts/debug/electron-browser/debugCommands'; import { IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; import { StatusBarColorProvider } from 'vs/workbench/parts/debug/electron-browser/statusbarColorProvider'; -import { ViewLocation, ViewsRegistry } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewLocation, ViewsRegistry } from 'vs/workbench/common/views'; import { isMacintosh } from 'vs/base/common/platform'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import URI from 'vs/base/common/uri'; diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index 3a779ea68b0..f31e9cb9b68 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -102,11 +102,11 @@ export const debuggersExtPoint = extensionsRegistry.ExtensionsRegistry.registerE } }, osx: { - description: nls.localize('vscode.extension.contributes.debuggers.osx', "OS X specific settings."), + description: nls.localize('vscode.extension.contributes.debuggers.osx', "macOS specific settings."), type: 'object', properties: { runtime: { - description: nls.localize('vscode.extension.contributes.debuggers.osx.runtime', "Runtime used for OSX."), + description: nls.localize('vscode.extension.contributes.debuggers.osx.runtime', "Runtime used for macOS."), type: 'string' } } @@ -403,6 +403,7 @@ export class ConfigurationManager implements IConfigurationManager { } const editor = this.editorService.getActiveEditor(); + let candidates: Adapter[]; if (editor) { const codeEditor = editor.getControl(); if (isCodeEditor(codeEditor)) { @@ -412,10 +413,16 @@ export class ConfigurationManager implements IConfigurationManager { if (adapters.length === 1) { return TPromise.as(adapters[0]); } + if (adapters.length > 1) { + candidates = adapters; + } } } - return this.quickOpenService.pick([...this.adapters.filter(a => a.hasInitialConfiguration() || a.hasConfigurationProvider), { label: 'More...', separator: { border: true } }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) + if (!candidates) { + candidates = this.adapters.filter(a => a.hasInitialConfiguration() || a.hasConfigurationProvider); + } + return this.quickOpenService.pick([...candidates, { label: 'More...', separator: { border: true } }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) .then(picked => { if (picked instanceof Adapter) { return picked; diff --git a/src/vs/workbench/parts/debug/electron-browser/debugEditorContribution.ts b/src/vs/workbench/parts/debug/electron-browser/debugEditorContribution.ts index 9205cb17df3..5db4e4a3828 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugEditorContribution.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugEditorContribution.ts @@ -41,7 +41,6 @@ import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands'; import { first } from 'vs/base/common/arrays'; import { IMarginData } from 'vs/editor/browser/controller/mouseTarget'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IListService } from 'vs/platform/list/browser/listService'; const HOVER_DELAY = 300; const LAUNCH_JSON_REGEX = /launch\.json$/; @@ -78,13 +77,12 @@ export class DebugEditorContribution implements IDebugEditorContribution { @ICommandService private commandService: ICommandService, @ICodeEditorService private codeEditorService: ICodeEditorService, @ITelemetryService private telemetryService: ITelemetryService, - @IListService listService: IListService, @IConfigurationService private configurationService: IConfigurationService, @IThemeService themeService: IThemeService, @IKeybindingService private keybindingService: IKeybindingService ) { this.breakpointHintDecoration = []; - this.hoverWidget = new DebugHoverWidget(this.editor, this.debugService, this.instantiationService, themeService, contextKeyService, listService); + this.hoverWidget = new DebugHoverWidget(this.editor, this.debugService, this.instantiationService, themeService); this.toDispose = []; this.showHoverScheduler = new RunOnceScheduler(() => this.showHover(this.hoverRange, false), HOVER_DELAY); this.hideHoverScheduler = new RunOnceScheduler(() => this.hoverWidget.hide(), HOVER_DELAY); diff --git a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts index 072347dc3b7..30c4fca4496 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts @@ -25,8 +25,7 @@ import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableEle import { attachStylerCallback } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { editorHoverBackground, editorHoverBorder } from 'vs/platform/theme/common/colorRegistry'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; const $ = dom.$; const MAX_ELEMENTS_SHOWN = 18; @@ -54,9 +53,7 @@ export class DebugHoverWidget implements IContentWidget { private editor: ICodeEditor, private debugService: IDebugService, private instantiationService: IInstantiationService, - private themeService: IThemeService, - private contextKeyService: IContextKeyService, - private listService: IListService + private themeService: IThemeService ) { this.toDispose = []; @@ -71,7 +68,7 @@ export class DebugHoverWidget implements IContentWidget { this.complexValueTitle = dom.append(this.complexValueContainer, $('.title')); this.treeContainer = dom.append(this.complexValueContainer, $('.debug-hover-tree')); this.treeContainer.setAttribute('role', 'tree'); - this.tree = new WorkbenchTree(this.treeContainer, { + this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { dataSource: new VariablesDataSource(), renderer: this.instantiationService.createInstance(VariablesHoverRenderer), controller: new DebugHoverController(this.editor) @@ -80,7 +77,7 @@ export class DebugHoverWidget implements IContentWidget { twistiePixels: 15, ariaLabel: nls.localize('treeAriaLabel', "Debug Hover"), keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); this.valueContainer = $('.value'); this.valueContainer.tabIndex = 0; diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 26eadcb5141..b2434227ac5 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -728,9 +728,6 @@ export class DebugService implements debug.IDebugService { if (config && config.type) { return this.createProcess(root, config, sessionId); } - if (launch) { - return launch.openConfigFile(false, type).then(() => undefined); - } return undefined; }) diff --git a/src/vs/workbench/parts/debug/electron-browser/repl.ts b/src/vs/workbench/parts/debug/electron-browser/repl.ts index db4c7dd26a1..6ea2b74afef 100644 --- a/src/vs/workbench/parts/debug/electron-browser/repl.ts +++ b/src/vs/workbench/parts/debug/electron-browser/repl.ts @@ -41,7 +41,7 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { clipboard } from 'electron'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { memoize } from 'vs/base/common/decorators'; import { dispose } from 'vs/base/common/lifecycle'; @@ -93,8 +93,7 @@ export class Repl extends Panel implements IPrivateReplService { @IPanelService private panelService: IPanelService, @IThemeService protected themeService: IThemeService, @IModelService private modelService: IModelService, - @IContextKeyService private contextKeyService: IContextKeyService, - @IListService private listService: IListService + @IContextKeyService private contextKeyService: IContextKeyService ) { super(debug.REPL_ID, telemetryService, themeService); @@ -139,12 +138,12 @@ export class Repl extends Panel implements IPrivateReplService { const controller = this.instantiationService.createInstance(ReplExpressionsController, new ReplExpressionsActionProvider(this.instantiationService), MenuId.DebugConsoleContext); controller.toFocusOnClick = this.replInput; - this.tree = new WorkbenchTree(this.treeContainer, { + this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { dataSource: new ReplExpressionsDataSource(), renderer: this.renderer, accessibilityProvider: new ReplExpressionsAccessibilityProvider(), controller - }, replTreeOptions, this.contextKeyService, this.listService, this.themeService); + }, replTreeOptions); if (!Repl.HISTORY) { Repl.HISTORY = new ReplHistory(JSON.parse(this.storageService.get(HISTORY_STORAGE_KEY, StorageScope.WORKSPACE, '[]'))); diff --git a/src/vs/workbench/parts/debug/electron-browser/terminalSupport.ts b/src/vs/workbench/parts/debug/electron-browser/terminalSupport.ts index 34ad85f35c5..3cf08e18ec4 100644 --- a/src/vs/workbench/parts/debug/electron-browser/terminalSupport.ts +++ b/src/vs/workbench/parts/debug/electron-browser/terminalSupport.ts @@ -5,6 +5,7 @@ import * as nls from 'vs/nls'; import * as platform from 'vs/base/common/platform'; +import cp = require('child_process'); import { IDisposable } from 'vs/base/common/lifecycle'; import { TPromise } from 'vs/base/common/winjs.base'; import { ITerminalService, ITerminalInstance, ITerminalConfiguration } from 'vs/workbench/parts/terminal/common/terminal'; @@ -24,11 +25,6 @@ export class TerminalSupport { return nativeTerminalService.runInTerminal(args.title, args.cwd, args.args, args.env || {}); } - let delay = 0; - if (!TerminalSupport.integratedTerminalInstance) { - TerminalSupport.integratedTerminalInstance = terminalService.createInstance({ name: args.title || nls.localize('debug.terminal.title', "debuggee") }); - delay = 2000; // delay the first sendText so that the newly created terminal is ready. - } if (!TerminalSupport.terminalDisposedListener) { // React on terminal disposed and check if that is the debug terminal #12956 TerminalSupport.terminalDisposedListener = terminalService.onInstanceDisposed(terminal => { @@ -37,22 +33,34 @@ export class TerminalSupport { } }); } - terminalService.setActiveInstance(TerminalSupport.integratedTerminalInstance); + + let t = TerminalSupport.integratedTerminalInstance; + if ((t && this.isBusy(t)) || !t) { + t = terminalService.createInstance({ name: args.title || nls.localize('debug.terminal.title', "debuggee") }); + TerminalSupport.integratedTerminalInstance = t; + } + terminalService.setActiveInstance(t); terminalService.showPanel(true); - return new TPromise((c, e) => { + const command = this.prepareCommand(args, configurationService); + t.sendText(command, true); - setTimeout(() => { - if (TerminalSupport.integratedTerminalInstance) { - const command = this.prepareCommand(args, configurationService); - TerminalSupport.integratedTerminalInstance.sendText(command, true); - c(void 0); - } else { - e(new Error(nls.localize('debug.terminal.not.available.error', "Integrated terminal not available"))); - } - }, delay); + return TPromise.as(void 0); + } - }); + private static isBusy(t: ITerminalInstance): boolean { + if (t.processId) { + // if shell has at least one child process, assume that shell is busy + if (platform.isWindows) { + const result = cp.spawnSync('wmic', ['process', 'get', 'ParentProcessId']); + const pids = result.stdout.toString().split('\r\n'); + return pids.some(p => parseInt(p) === t.processId); + } else { + const result = cp.spawnSync('/usr/bin/pgrep', ['-P', String(t.processId)]); + return result.stdout.toString().trim().length > 0; + } + } + return true; } private static prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments, configurationService: IConfigurationService): string { diff --git a/src/vs/workbench/parts/debug/electron-browser/variablesView.ts b/src/vs/workbench/parts/debug/electron-browser/variablesView.ts index 36384afa9f8..e157a61a862 100644 --- a/src/vs/workbench/parts/debug/electron-browser/variablesView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/variablesView.ts @@ -16,7 +16,6 @@ import { IContextMenuService, IContextViewService } from 'vs/platform/contextvie import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { MenuId } from 'vs/platform/actions/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { once } from 'vs/base/common/event'; import { twistiePixels, renderViewTree, IVariableTemplateData, BaseDebugController, renderRenameBox, renderVariable } from 'vs/workbench/parts/debug/electron-browser/baseDebugView'; @@ -28,7 +27,7 @@ import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { ViewModel } from 'vs/workbench/parts/debug/common/debugViewModel'; import { equalsIgnoreCase } from 'vs/base/common/strings'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; const $ = dom.$; @@ -45,10 +44,7 @@ export class VariablesView extends TreeViewsViewletPanel { @IContextMenuService contextMenuService: IContextMenuService, @IDebugService private debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService, - @IInstantiationService private instantiationService: IInstantiationService, - @IListService private listService: IListService, - @IContextKeyService private contextKeyService: IContextKeyService, - @IThemeService private themeService: IThemeService + @IInstantiationService private instantiationService: IInstantiationService ) { super({ ...(options as IViewOptions), ariaHeaderLabel: nls.localize('variablesSection', "Variables Section") }, keybindingService, contextMenuService); @@ -87,7 +83,7 @@ export class VariablesView extends TreeViewsViewletPanel { dom.addClass(container, 'debug-variables'); this.treeContainer = renderViewTree(container); - this.tree = new WorkbenchTree(this.treeContainer, { + this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { dataSource: new VariablesDataSource(), renderer: this.instantiationService.createInstance(VariablesRenderer), accessibilityProvider: new VariablesAccessibilityProvider(), @@ -96,7 +92,7 @@ export class VariablesView extends TreeViewsViewletPanel { ariaLabel: nls.localize('variablesAriaTreeLabel', "Debug Variables"), twistiePixels, keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); CONTEXT_VARIABLES_FOCUSED.bindTo(this.tree.contextKeyService); diff --git a/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts b/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts index 23ddbee6eff..dbbd7bfeb29 100644 --- a/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts @@ -19,7 +19,6 @@ import { IContextMenuService, IContextViewService } from 'vs/platform/contextvie import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { MenuId } from 'vs/platform/actions/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { once } from 'vs/base/common/event'; import { IAction, IActionItem } from 'vs/base/common/actions'; @@ -29,7 +28,7 @@ import { equalsIgnoreCase } from 'vs/base/common/strings'; import { IMouseEvent, DragMouseEvent } from 'vs/base/browser/mouseEvent'; import { DefaultDragAndDrop } from 'vs/base/parts/tree/browser/treeDefaults'; import { IVariableTemplateData, renderVariable, renderRenameBox, renderExpressionValue, BaseDebugController, twistiePixels, renderViewTree } from 'vs/workbench/parts/debug/electron-browser/baseDebugView'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; const $ = dom.$; const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024; @@ -46,10 +45,7 @@ export class WatchExpressionsView extends TreeViewsViewletPanel { @IContextMenuService contextMenuService: IContextMenuService, @IDebugService private debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService, - @IContextKeyService private contextKeyService: IContextKeyService, - @IListService private listService: IListService, - @IInstantiationService private instantiationService: IInstantiationService, - @IThemeService private themeService: IThemeService + @IInstantiationService private instantiationService: IInstantiationService ) { super({ ...(options as IViewOptions), ariaHeaderLabel: nls.localize('expressionsSection', "Expressions Section") }, keybindingService, contextMenuService); this.settings = options.viewletSettings; @@ -65,7 +61,7 @@ export class WatchExpressionsView extends TreeViewsViewletPanel { this.treeContainer = renderViewTree(container); const actionProvider = new WatchExpressionsActionProvider(this.debugService, this.keybindingService); - this.tree = new WorkbenchTree(this.treeContainer, { + this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { dataSource: new WatchExpressionsDataSource(this.debugService), renderer: this.instantiationService.createInstance(WatchExpressionsRenderer), accessibilityProvider: new WatchExpressionsAccessibilityProvider(), @@ -75,7 +71,7 @@ export class WatchExpressionsView extends TreeViewsViewletPanel { ariaLabel: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'watchAriaTreeLabel' }, "Debug Watch Expressions"), twistiePixels, keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); CONTEXT_WATCH_EXPRESSIONS_FOCUSED.bindTo(this.tree.contextKeyService); diff --git a/src/vs/workbench/parts/execution/electron-browser/execution.contribution.ts b/src/vs/workbench/parts/execution/electron-browser/execution.contribution.ts index 97871707c4e..30be861e92f 100644 --- a/src/vs/workbench/parts/execution/electron-browser/execution.contribution.ts +++ b/src/vs/workbench/parts/execution/electron-browser/execution.contribution.ts @@ -6,7 +6,6 @@ import * as nls from 'vs/nls'; import * as env from 'vs/base/common/platform'; -import { TPromise } from 'vs/base/common/winjs.base'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -25,7 +24,8 @@ import { ResourceContextKey } from 'vs/workbench/common/resources'; import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IFileService } from 'vs/platform/files/common/files'; import { IListService } from 'vs/platform/list/browser/listService'; -import { getResourceForCommand } from 'vs/workbench/parts/files/electron-browser/fileCommands'; +import { getResourceForCommand } from 'vs/workbench/parts/files/browser/files'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; if (env.isWindows) { registerSingleton(ITerminalService, WinTerminalService); @@ -75,25 +75,18 @@ DEFAULT_TERMINAL_LINUX_READY.then(defaultTerminalLinux => { }); }); -const OPEN_CONSOLE_COMMAND_ID = 'workbench.command.terminal.openNativeConsole'; - -KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: OPEN_CONSOLE_COMMAND_ID, - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C, - when: KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED, - weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), +const OPEN_IN_TERMINAL_COMMAND_ID = 'openInTerminal'; +CommandsRegistry.registerCommand({ + id: OPEN_IN_TERMINAL_COMMAND_ID, handler: (accessor, resource: uri) => { const configurationService = accessor.get(IConfigurationService); - const historyService = accessor.get(IHistoryService); const editorService = accessor.get(IWorkbenchEditorService); const fileService = accessor.get(IFileService); const integratedTerminalService = accessor.get(IIntegratedTerminalService); const terminalService = accessor.get(ITerminalService); resource = getResourceForCommand(resource, accessor.get(IListService), editorService); - // Try workspace path first - const root = historyService.getLastActiveWorkspaceRoot('file'); - return !uri.isUri(resource) ? TPromise.as(root && root.fsPath) : fileService.resolveFile(resource).then(stat => { + return fileService.resolveFile(resource).then(stat => { return stat.isDirectory ? stat.resource.fsPath : paths.dirname(stat.resource.fsPath); }).then(directoryToOpen => { if (configurationService.getValue().terminal.explorerKind === 'integrated') { @@ -109,16 +102,33 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); +const OPEN_NATIVE_CONSOLE_COMMAND_ID = 'workbench.action.terminal.openNativeConsole'; +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: OPEN_NATIVE_CONSOLE_COMMAND_ID, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C, + when: KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED, + weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), + handler: (accessor) => { + const historyService = accessor.get(IHistoryService); + const terminalService = accessor.get(ITerminalService); + const root = historyService.getLastActiveWorkspaceRoot('file'); + terminalService.openTerminal(root.fsPath); + } +}); + +MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: OPEN_NATIVE_CONSOLE_COMMAND_ID, + title: env.isWindows ? nls.localize('globalConsoleActionWin', "Open New Command Prompt") : + nls.localize('globalConsoleActionMacLinux', "Open New Terminal") + } +}); + const openConsoleCommand = { - id: OPEN_CONSOLE_COMMAND_ID, + id: OPEN_IN_TERMINAL_COMMAND_ID, title: env.isWindows ? nls.localize('scopedConsoleActionWin', "Open in Command Prompt") : nls.localize('scopedConsoleActionMacLinux', "Open in Terminal") }; - -MenuRegistry.appendMenuItem(MenuId.CommandPalette, { - command: openConsoleCommand -}); - MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: 'navigation', order: 30, diff --git a/src/vs/workbench/parts/extensions/browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/browser/extensionEditor.ts index 95a51e0fadc..94917051daf 100644 --- a/src/vs/workbench/parts/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/browser/extensionEditor.ts @@ -51,7 +51,8 @@ import { Command, ICommandOptions } from 'vs/editor/browser/editorExtensions'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { Color } from 'vs/base/common/color'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; /** A context key that is set when an extension editor webview has focus. */ export const KEYBINDING_CONTEXT_EXTENSIONEDITOR_WEBVIEW_FOCUS = new RawContextKey('extensionEditorWebviewFocus', undefined); @@ -63,12 +64,13 @@ export const KEYBINDING_CONTEXT_EXTENSIONEDITOR_FIND_WIDGET_INPUT_FOCUSED = new export const KEYBINDING_CONTEXT_EXTENSIONEDITOR_FIND_WIDGET_INPUT_NOT_FOCUSED: ContextKeyExpr = KEYBINDING_CONTEXT_EXTENSIONEDITOR_FIND_WIDGET_INPUT_FOCUSED.toNegated(); function renderBody(body: string): string { + const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-core-resource://'); return ` - - + + @@ -190,11 +192,12 @@ export class ExtensionEditor extends BaseEditor { @IKeybindingService private keybindingService: IKeybindingService, @IMessageService private messageService: IMessageService, @IOpenerService private openerService: IOpenerService, - @IListService private listService: IListService, @IPartService private partService: IPartService, @IContextViewService private contextViewService: IContextViewService, @IContextKeyService private contextKeyService: IContextKeyService, - @IExtensionTipsService private extensionTipsService: IExtensionTipsService + @IExtensionTipsService private extensionTipsService: IExtensionTipsService, + @IEnvironmentService private environmentService: IEnvironmentService + ) { super(ExtensionEditor.ID, telemetryService, themeService); this.disposables = []; @@ -412,8 +415,8 @@ export class ExtensionEditor extends BaseEditor { .then(removeEmbeddedSVGs) .then(body => { const allowedBadgeProviders = this.extensionsWorkbenchService.allowedBadgeProviders; - const webViewOptions = allowedBadgeProviders.length > 0 ? { allowScripts: false, allowSvgs: false, svgWhiteList: allowedBadgeProviders } : undefined; - this.activeWebview = new WebView(this.content, this.partService.getContainer(Parts.EDITOR_PART), this.contextViewService, this.contextKey, this.findInputFocusContextKey, webViewOptions); + const webViewOptions = allowedBadgeProviders.length > 0 ? { allowScripts: false, allowSvgs: false, svgWhiteList: allowedBadgeProviders } : {}; + this.activeWebview = new WebView(this.content, this.partService.getContainer(Parts.EDITOR_PART), this.environmentService, this.contextViewService, this.contextKey, this.findInputFocusContextKey, webViewOptions, false); const removeLayoutParticipant = arrays.insert(this.layoutParticipants, this.activeWebview); this.contentDisposables.push(toDisposable(removeLayoutParticipant)); @@ -514,7 +517,7 @@ export class ExtensionEditor extends BaseEditor { private renderDependencies(container: HTMLElement, extensionDependencies: IExtensionDependencies): Tree { const renderer = this.instantiationService.createInstance(Renderer); const controller = this.instantiationService.createInstance(Controller); - const tree = new WorkbenchTree(container, { + const tree = this.instantiationService.createInstance(WorkbenchTree, container, { dataSource: new DataSource(), renderer, controller @@ -522,7 +525,7 @@ export class ExtensionEditor extends BaseEditor { indentPixels: 40, twistiePixels: 20, keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); tree.setInput(extensionDependencies); diff --git a/src/vs/workbench/parts/extensions/browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/browser/extensionsActions.ts index fa54bc803d7..905b22e3f88 100644 --- a/src/vs/workbench/parts/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/browser/extensionsActions.ts @@ -437,7 +437,7 @@ export class EnableForWorkspaceAction extends Action implements IExtensionAction private update(): void { this.enabled = false; if (this.extension) { - this.enabled = (this.extension.enablementState === EnablementState.Disabled || this.extension.enablementState === EnablementState.WorkspaceDisabled) && this.extensionEnablementService.canChangeEnablement(); + this.enabled = (this.extension.enablementState === EnablementState.Disabled || this.extension.enablementState === EnablementState.WorkspaceDisabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local); } } @@ -475,7 +475,7 @@ export class EnableGloballyAction extends Action implements IExtensionAction { private update(): void { this.enabled = false; if (this.extension) { - this.enabled = (this.extension.enablementState === EnablementState.Disabled || this.extension.enablementState === EnablementState.WorkspaceDisabled) && this.extensionEnablementService.canChangeEnablement(); + this.enabled = (this.extension.enablementState === EnablementState.Disabled || this.extension.enablementState === EnablementState.WorkspaceDisabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local); } } @@ -560,7 +560,8 @@ export class DisableForWorkspaceAction extends Action implements IExtensionActio constructor(label: string, @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, - @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService + @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, + @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService ) { super(DisableForWorkspaceAction.ID, label); @@ -572,7 +573,7 @@ export class DisableForWorkspaceAction extends Action implements IExtensionActio private update(): void { this.enabled = false; if (this.extension && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY) { - this.enabled = this.extension.type !== LocalExtensionType.System && (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled); + this.enabled = this.extension.type !== LocalExtensionType.System && (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local); } } @@ -598,7 +599,8 @@ export class DisableGloballyAction extends Action implements IExtensionAction { set extension(extension: IExtension) { this._extension = extension; this.update(); } constructor(label: string, - @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService + @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, + @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService ) { super(DisableGloballyAction.ID, label); @@ -609,7 +611,7 @@ export class DisableGloballyAction extends Action implements IExtensionAction { private update(): void { this.enabled = false; if (this.extension) { - this.enabled = this.extension.type !== LocalExtensionType.System && (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled); + this.enabled = this.extension.type !== LocalExtensionType.System && (this.extension.enablementState === EnablementState.Enabled || this.extension.enablementState === EnablementState.WorkspaceEnabled) && this.extension.local && this.extensionEnablementService.canChangeEnablement(this.extension.local); } } @@ -1633,7 +1635,7 @@ export class EnableAllAction extends Action { } private update(): void { - this.enabled = this.extensionsWorkbenchService.local.some(e => this.extensionEnablementService.canChangeEnablement() && (e.enablementState === EnablementState.Disabled || e.enablementState === EnablementState.WorkspaceDisabled)); + this.enabled = this.extensionsWorkbenchService.local.some(e => e.local && this.extensionEnablementService.canChangeEnablement(e.local) && (e.enablementState === EnablementState.Disabled || e.enablementState === EnablementState.WorkspaceDisabled)); } run(): TPromise { @@ -1666,7 +1668,7 @@ export class EnableAllWorkpsaceAction extends Action { } private update(): void { - this.enabled = this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY && this.extensionsWorkbenchService.local.some(e => this.extensionEnablementService.canChangeEnablement() && (e.enablementState === EnablementState.Disabled || e.enablementState === EnablementState.WorkspaceDisabled)); + this.enabled = this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY && this.extensionsWorkbenchService.local.some(e => e.local && this.extensionEnablementService.canChangeEnablement(e.local) && (e.enablementState === EnablementState.Disabled || e.enablementState === EnablementState.WorkspaceDisabled)); } run(): TPromise { diff --git a/src/vs/workbench/parts/extensions/common/extensions.ts b/src/vs/workbench/parts/extensions/common/extensions.ts index b836148a1b7..d90719c48f0 100644 --- a/src/vs/workbench/parts/extensions/common/extensions.ts +++ b/src/vs/workbench/parts/extensions/common/extensions.ts @@ -8,7 +8,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import Event from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; import { IPager } from 'vs/base/common/paging'; -import { IQueryOptions, IExtensionManifest, LocalExtensionType, EnablementState } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IQueryOptions, IExtensionManifest, LocalExtensionType, EnablementState, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; export const VIEWLET_ID = 'workbench.view.extensions'; @@ -51,6 +51,7 @@ export interface IExtension { getManifest(): TPromise; getReadme(): TPromise; getChangelog(): TPromise; + local?: ILocalExtension; } export interface IExtensionDependencies { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index c2fec16cc64..619aace599d 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -29,6 +29,9 @@ import * as pfs from 'vs/base/node/pfs'; import * as os from 'os'; import { flatten, distinct } from 'vs/base/common/arrays'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { guessMimeTypes, MIME_UNKNOWN } from 'vs/base/common/mime'; +import { ShowLanguageExtensionsAction } from 'vs/workbench/browser/parts/editor/editorStatus'; +import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; interface IExtensionsContent { recommendations: string[]; @@ -36,6 +39,8 @@ interface IExtensionsContent { const empty: { [key: string]: any; } = Object.create(null); const milliSecondsInADay = 1000 * 60 * 60 * 24; +const choiceNever = localize('neverShowAgain', "Don't show again"); +const choiceClose = localize('close', "Close"); export class ExtensionTipsService extends Disposable implements IExtensionTipsService { @@ -61,7 +66,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe @IConfigurationService private configurationService: IConfigurationService, @IMessageService private messageService: IMessageService, @ITelemetryService private telemetryService: ITelemetryService, - @IEnvironmentService private environmentService: IEnvironmentService + @IEnvironmentService private environmentService: IEnvironmentService, + @ILifecycleService private lifecycleService: ILifecycleService ) { super(); @@ -69,7 +75,10 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe return; } - this._suggestFileBasedRecommendations(); + this.lifecycleService.when(LifecyclePhase.Eventually).then(() => { + this._suggestFileBasedRecommendations(); + }); + this.promptWorkspaceRecommendationsPromise = this._suggestWorkspaceRecommendations(); // Executable based recommendations carry out a lot of file stats, so run them after 10 secs @@ -80,9 +89,9 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe getAllRecommendationsWithReason(): { [id: string]: string; } { let output: { [id: string]: string; } = Object.create(null); - Object.keys(this._fileBasedRecommendations).forEach(x => output[x.toLowerCase()] = localize('fileBasedRecommendation', "This extension is recommended based on the files you recently opened.")); this._allWorkspaceRecommendedExtensions.forEach(x => output[x.toLowerCase()] = localize('workspaceRecommendation', "This extension is recommended by users of the current workspace.")); - forEach(this._exeBasedRecommendations, entry => output[entry.key.toLowerCase()] = localize('exeBasedRecommendation', "This extension is recommended because you have {0} installed.", entry.value)); + Object.keys(this._fileBasedRecommendations).forEach(x => output[x.toLowerCase()] = output[x.toLowerCase()] || localize('fileBasedRecommendation', "This extension is recommended based on the files you recently opened.")); + forEach(this._exeBasedRecommendations, entry => output[entry.key.toLowerCase()] = output[entry.key.toLowerCase()] || localize('exeBasedRecommendation', "This extension is recommended because you have {0} installed.", entry.value)); return output; } @@ -256,6 +265,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private _suggest(model: ITextModel): void { const uri = model.uri; + let hasSuggestion = false; if (!uri || uri.scheme !== Schemas.file) { return; @@ -282,91 +292,168 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe ); const config = this.configurationService.getValue(ConfigurationKey); - const importantRecommendationsIgnoreList = JSON.parse(this.storageService.get('extensionsAssistant/importantRecommendationsIgnore', StorageScope.GLOBAL, '[]')); - - if (config.ignoreRecommendations || !product.extensionImportantTips) { + if (config.ignoreRecommendations) { return; } - this.extensionsService.getInstalled(LocalExtensionType.User).done(local => { - Object.keys(product.extensionImportantTips) - .filter(id => importantRecommendationsIgnoreList.indexOf(id) === -1) - .filter(id => local.every(local => `${local.manifest.publisher}.${local.manifest.name}` !== id)) - .forEach(id => { - const { pattern, name } = product.extensionImportantTips[id]; + const importantRecommendationsIgnoreList = JSON.parse(this.storageService.get('extensionsAssistant/importantRecommendationsIgnore', StorageScope.GLOBAL, '[]')); + let recommendationsToSuggest = Object.keys(product.extensionImportantTips || []) + .filter(id => importantRecommendationsIgnoreList.indexOf(id) === -1 && match(product.extensionImportantTips[id]['pattern'], uri.fsPath)); - if (!match(pattern, uri.fsPath)) { - return; - } + const importantTipsPromise = recommendationsToSuggest.length === 0 ? TPromise.as(null) : this.extensionsService.getInstalled(LocalExtensionType.User).then(local => { + recommendationsToSuggest = recommendationsToSuggest.filter(id => local.every(local => `${local.manifest.publisher}.${local.manifest.name}` !== id)); + if (!recommendationsToSuggest.length) { + return; + } + const id = recommendationsToSuggest[0]; + const name = product.extensionImportantTips[id]['name']; - let message = localize('reallyRecommended2', "The '{0}' extension is recommended for this file type.", name); - // Temporary fix for the only extension pack we recommend. See https://github.com/Microsoft/vscode/issues/35364 - if (id === 'vscjava.vscode-java-pack') { - message = localize('reallyRecommendedExtensionPack', "The '{0}' extension pack is recommended for this file type.", name); - } + // Indicates we have a suggested extension via the whitelist + hasSuggestion = true; - const recommendationsAction = this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, localize('showRecommendations', "Show Recommendations")); - const installAction = this.instantiationService.createInstance(InstallRecommendedExtensionAction, id); - const options = [ - localize('install', 'Install'), - recommendationsAction.label, - localize('neverShowAgain', "Don't show again"), - localize('close', "Close") - ]; + let message = localize('reallyRecommended2', "The '{0}' extension is recommended for this file type.", name); + // Temporary fix for the only extension pack we recommend. See https://github.com/Microsoft/vscode/issues/35364 + if (id === 'vscjava.vscode-java-pack') { + message = localize('reallyRecommendedExtensionPack', "The '{0}' extension pack is recommended for this file type.", name); + } - this.choiceService.choose(Severity.Info, message, options, 3).done(choice => { - switch (choice) { - case 0: - /* __GDPR__ - "extensionRecommendations:popup" : { - "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'install', extensionId: name }); - return installAction.run(); - case 1: - /* __GDPR__ - "extensionRecommendations:popup" : { - "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'show', extensionId: name }); - return recommendationsAction.run(); - case 2: importantRecommendationsIgnoreList.push(id); - this.storageService.store( - 'extensionsAssistant/importantRecommendationsIgnore', - JSON.stringify(importantRecommendationsIgnoreList), - StorageScope.GLOBAL - ); - /* __GDPR__ - "extensionRecommendations:popup" : { - "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'neverShowAgain', extensionId: name }); - return this.ignoreExtensionRecommendations(); - case 3: - /* __GDPR__ - "extensionRecommendations:popup" : { - "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'close', extensionId: name }); - } - }, () => { + const recommendationsAction = this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, localize('showRecommendations', "Show Recommendations")); + const installAction = this.instantiationService.createInstance(InstallRecommendedExtensionAction, id); + const options = [ + localize('install', 'Install'), + recommendationsAction.label, + choiceNever, + choiceClose + ]; + + this.choiceService.choose(Severity.Info, message, options, 3).done(choice => { + switch (choice) { + case 0: /* __GDPR__ "extensionRecommendations:popup" : { "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } } */ - this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'cancelled', extensionId: name }); - }); + this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'install', extensionId: name }); + return installAction.run(); + case 1: + /* __GDPR__ + "extensionRecommendations:popup" : { + "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'show', extensionId: name }); + return recommendationsAction.run(); + case 2: importantRecommendationsIgnoreList.push(id); + this.storageService.store( + 'extensionsAssistant/importantRecommendationsIgnore', + JSON.stringify(importantRecommendationsIgnoreList), + StorageScope.GLOBAL + ); + /* __GDPR__ + "extensionRecommendations:popup" : { + "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'neverShowAgain', extensionId: name }); + return this.ignoreExtensionRecommendations(); + case 3: + /* __GDPR__ + "extensionRecommendations:popup" : { + "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'close', extensionId: name }); + } + }, () => { + /* __GDPR__ + "extensionRecommendations:popup" : { + "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('extensionRecommendations:popup', { userReaction: 'cancelled', extensionId: name }); + }); + }); + + importantTipsPromise.then(() => { + const fileExtensionSuggestionIgnoreList = JSON.parse(this.storageService.get + ('extensionsAssistant/fileExtensionsSuggestionIgnore', StorageScope.GLOBAL, '[]')); + let mimeTypes = guessMimeTypes(uri.fsPath); + let fileExtension = paths.extname(uri.fsPath); + if (fileExtension) { + fileExtension = fileExtension.substr(1); // Strip the dot + } + + if (hasSuggestion || + !fileExtension || + mimeTypes.length !== 1 || + mimeTypes[0] !== MIME_UNKNOWN || + fileExtensionSuggestionIgnoreList.indexOf(fileExtension) > -1 + ) { + return; + } + + const keywords = this.getKeywordsForExtension(fileExtension); + this._galleryService.query({ text: `tag:"__ext_${fileExtension}" ${keywords.map(tag => `tag:"${tag}"`)}` }).then(pager => { + if (!pager || !pager.firstPage || !pager.firstPage.length) { + return; + } + + // Suggest the search only once as this is not a strong recommendation + fileExtensionSuggestionIgnoreList.push(fileExtension); + this.storageService.store( + 'extensionsAssistant/fileExtensionsSuggestionIgnore', + JSON.stringify(fileExtensionSuggestionIgnoreList), + StorageScope.GLOBAL + ); + + + const message = localize('showLanguageExtensions', "The Marketplace has extensions that can help with '.{0}' files", fileExtension); + + const searchMarketplaceAction = this.instantiationService.createInstance(ShowLanguageExtensionsAction, fileExtension); + + const options = [ + localize('searchMarketplace', "Search Marketplace"), + choiceClose + ]; + + this.choiceService.choose(Severity.Info, message, options, 1).done(choice => { + switch (choice) { + case 0: + /* __GDPR__ + "fileExtensionSuggestion:popup" : { + "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('fileExtensionSuggestion:popup', { userReaction: 'ok', fileExtension: fileExtension }); + searchMarketplaceAction.run(); + break; + case 1: + /* __GDPR__ + "fileExtensionSuggestion:popup" : { + "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('fileExtensionSuggestion:popup', { userReaction: 'close', fileExtension: fileExtension }); + break; + } + }, () => { + /* __GDPR__ + "fileExtensionSuggestion:popup" : { + "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } + } + */ + this.telemetryService.publicLog('fileExtensionSuggestion:popup', { userReaction: 'cancelled', fileExtension: fileExtension }); }); + }); }); }); } @@ -395,8 +482,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe const options = [ installAllAction.label, showAction.label, - localize('neverShowAgain', "Don't show again"), - localize('close', "Close") + choiceNever, + choiceClose ]; return this.choiceService.choose(Severity.Info, message, options, 3).done(choice => { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts index 18f4e4a6d56..c5e6add7d77 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -222,4 +222,4 @@ CommandsRegistry.registerCommand('_extensions.manage', (accessor: ServicesAccess if (extension.length === 1) { extensionService.open(extension[0]).done(null, errors.onUnexpectedError); } -}); +}); \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index f4c1b8f3578..6be04be6baa 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -38,7 +38,7 @@ export class OpenExtensionsFolderAction extends Action { return this.fileService.resolveFile(URI.file(extensionsHome)).then(file => { let itemToShow: string; - if (file.hasChildren) { + if (file.children && file.children.length > 0) { itemToShow = file.children[0].resource.fsPath; } else { itemToShow = paths.normalize(extensionsHome, true); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsUtils.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsUtils.ts index de679af9945..ac45a445b75 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsUtils.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsUtils.ts @@ -90,7 +90,7 @@ export class KeymapExtensions implements IWorkbenchContribution { this.telemetryService.publicLog('disableOtherKeymaps', telemetryData); if (confirmed) { return TPromise.join(oldKeymaps.map(keymap => { - return this.extensionEnablementService.setEnablement(keymap.local.identifier, EnablementState.Disabled); + return this.extensionEnablementService.setEnablement(keymap.local, EnablementState.Disabled); })); } return undefined; diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 5adfee8f751..ac4d9aafbc7 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -45,7 +45,7 @@ import { IActivityService, ProgressBadge, NumberBadge } from 'vs/workbench/servi import { IThemeService } from 'vs/platform/theme/common/themeService'; import { inputForeground, inputBackground, inputBorder } from 'vs/platform/theme/common/colorRegistry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/common/views'; import { PersistentViewsViewlet, ViewsViewletPanel } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index 8f6cb11fba0..3c7d35378b0 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -35,8 +35,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction } from 'vs/workbench/parts/extensions/browser/extensionsActions'; -import { WorkbenchPagedList, IListService } from 'vs/platform/list/browser/listService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { WorkbenchPagedList } from 'vs/platform/list/browser/listService'; export class ExtensionsListView extends ViewsViewletPanel { @@ -52,7 +51,6 @@ export class ExtensionsListView extends ViewsViewletPanel { @IKeybindingService keybindingService: IKeybindingService, @IContextMenuService contextMenuService: IContextMenuService, @IInstantiationService protected instantiationService: IInstantiationService, - @IListService private listService: IListService, @IThemeService private themeService: IThemeService, @IExtensionService private extensionService: IExtensionService, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, @@ -60,8 +58,7 @@ export class ExtensionsListView extends ViewsViewletPanel { @IEditorGroupService private editorInputService: IEditorGroupService, @IExtensionTipsService private tipsService: IExtensionTipsService, @IModeService private modeService: IModeService, - @ITelemetryService private telemetryService: ITelemetryService, - @IContextKeyService private contextKeyService: IContextKeyService + @ITelemetryService private telemetryService: ITelemetryService ) { super({ ...(options as IViewOptions), ariaHeaderLabel: options.name }, keybindingService, contextMenuService); } @@ -80,10 +77,10 @@ export class ExtensionsListView extends ViewsViewletPanel { this.messageBox = append(container, $('.message')); const delegate = new Delegate(); const renderer = this.instantiationService.createInstance(Renderer); - this.list = new WorkbenchPagedList(this.extensionsList, delegate, [renderer], { + this.list = this.instantiationService.createInstance(WorkbenchPagedList, this.extensionsList, delegate, [renderer], { ariaLabel: localize('extensions', "Extensions"), keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); chain(this.list.onSelectionChange) .map(e => e.elements[0]) @@ -237,7 +234,7 @@ export class ExtensionsListView extends ViewsViewletPanel { const languageTag = languageName ? ` tag:"${languageName}"` : ''; // Construct a rich query - return `tag:"__ext_${ext}"${keywords.map(tag => ` tag:${tag}`)}${languageTag}`; + return `tag:"__ext_${ext}" ${keywords.map(tag => `tag:"${tag}"`).join(' ')}${languageTag}`; }); if (names.length) { diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/runtimeExtensionsEditor.css b/src/vs/workbench/parts/extensions/electron-browser/media/runtimeExtensionsEditor.css index 54046a8f2a1..bad1b92e994 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/runtimeExtensionsEditor.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/runtimeExtensionsEditor.css @@ -3,12 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.runtime-extensions-editor .monaco-list .monaco-list-rows > .monaco-list-row.odd { - background-color: #f5f5f5; -} - -.runtime-extensions-editor .monaco-list .monaco-list-rows > .monaco-list-row:hover:not(.odd) { - background-color: transparent; +.runtime-extensions-editor .monaco-list .monaco-list-rows > .monaco-list-row:nth-child(even):not(:hover):not(.focused) { + background-color: rgba(130, 130, 130, 0.08); } .runtime-extensions-editor .extension { @@ -86,11 +82,6 @@ background: url('save-inverse.svg') center center no-repeat; } -.vs-dark .runtime-extensions-editor .monaco-list .monaco-list-rows > .monaco-list-row.odd, -.hc-black .runtime-extensions-editor .monaco-list .monaco-list-rows > .monaco-list-row.odd { - background-color: #262829; -} - .runtime-extensions-editor .monaco-action-bar { padding-top: 21px; flex-shrink: 0; diff --git a/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts index fe50f9bbe7b..23c2fa6549b 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -20,11 +20,10 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionsWorkbenchService, IExtension } from 'vs/workbench/parts/extensions/common/extensions'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService, IExtensionDescription, IExtensionsStatus, IExtensionHostProfile } from 'vs/platform/extensions/common/extensions'; import { IDelegate, IRenderer } from 'vs/base/browser/ui/list/list'; -import { WorkbenchList, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { append, $, addClass, toggleClass } from 'vs/base/browser/dom'; import { ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; @@ -103,8 +102,6 @@ export class RuntimeExtensionsEditor extends BaseEditor { @IThemeService themeService: IThemeService, @IExtensionsWorkbenchService private readonly _extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionService private readonly _extensionService: IExtensionService, - @IListService private readonly _listService: IListService, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IMessageService private readonly _messageService: IMessageService, @IContextMenuService private readonly _contextMenuService: IContextMenuService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @@ -294,8 +291,6 @@ export class RuntimeExtensionsEditor extends BaseEditor { data.elementDisposables = dispose(data.elementDisposables); - toggleClass(data.root, 'odd', index % 2 === 1); - data.name.textContent = element.marketplaceInfo ? element.marketplaceInfo.displayName : element.description.displayName; const activationTimes = element.status.activationTimes; @@ -365,9 +360,9 @@ export class RuntimeExtensionsEditor extends BaseEditor { } }; - this._list = new WorkbenchList(container, delegate, [renderer], { + this._list = this._instantiationService.createInstance(WorkbenchList, container, delegate, [renderer], { multipleSelectionSupport: false - }, this._contextKeyService, this._listService, this.themeService); + }); this._list.splice(0, this._list.length, this._elements); diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts index 10a5d3b69ed..566a87e56c3 100644 --- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts @@ -35,6 +35,7 @@ import { IURLService } from 'vs/platform/url/common/url'; import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput'; import product from 'vs/platform/node/product'; import { ILogService } from 'vs/platform/log/common/log'; +import { IProgressService2, ProgressLocation } from 'vs/platform/progress/common/progress'; interface IExtensionStateProvider { (extension: Extension): ExtensionState; @@ -345,7 +346,8 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { @IURLService urlService: IURLService, @IExtensionEnablementService private extensionEnablementService: IExtensionEnablementService, @IWindowService private windowService: IWindowService, - @ILogService private logService: ILogService + @ILogService private logService: ILogService, + @IProgressService2 private progressService: IProgressService2 ) { this.stateProvider = ext => this.getExtensionState(ext); @@ -536,7 +538,11 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { install(extension: string | IExtension): TPromise { if (typeof extension === 'string') { - return this.extensionService.install(extension); + return this.progressService.withProgress({ + location: ProgressLocation.Extensions, + title: nls.localize('installingVSIXExtension', 'Installing extension from VSIX...'), + tooltip: `${extension}` + }, () => this.extensionService.install(extension)); } if (!(extension instanceof Extension)) { @@ -550,7 +556,11 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { return TPromise.wrapError(new Error('Missing gallery')); } - return this.extensionService.installFromGallery(gallery); + return this.progressService.withProgress({ + location: ProgressLocation.Extensions, + title: nls.localize('installingMarketPlaceExtension', 'Installing extension from Market place....'), + tooltip: `${extension.id}` + }, () => this.extensionService.installFromGallery(gallery)); } setEnablement(extension: IExtension, enablementState: EnablementState): TPromise { @@ -591,8 +601,11 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } this.logService.info(`Requested uninstalling the extension ${extension.id} from window ${this.windowService.getCurrentWindowId()}`); - return this.extensionService.uninstall(local); - + return this.progressService.withProgress({ + location: ProgressLocation.Extensions, + title: nls.localize('uninstallingExtension', 'Uninstalling extension....'), + tooltip: `${local.identifier.id}` + }, () => this.extensionService.uninstall(local)); } private promptAndSetEnablement(extension: IExtension, enablementState: EnablementState, enable: boolean): TPromise { @@ -709,7 +722,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } private doSetEnablement(extension: IExtension, enablementState: EnablementState): TPromise { - return this.extensionEnablementService.setEnablement(extension, enablementState); + return this.extensionEnablementService.setEnablement(extension.local, enablementState); } get allowedBadgeProviders(): string[] { @@ -743,25 +756,25 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { private onDidInstallExtension(event: DidInstallExtensionEvent): void { const { local, zipPath, error, gallery } = event; - const installing = gallery ? this.installing.filter(e => areSameExtensions(e.extension, gallery.identifier))[0] : null; - const extension: Extension = installing ? installing.extension : zipPath ? new Extension(this.galleryService, this.stateProvider, null, null, this.telemetryService) : null; + const installingExtension = gallery ? this.installing.filter(e => areSameExtensions(e.extension, gallery.identifier))[0] : null; + const extension: Extension = installingExtension ? installingExtension.extension : zipPath ? new Extension(this.galleryService, this.stateProvider, null, null, this.telemetryService) : null; if (extension) { - this.installing = installing ? this.installing.filter(e => e !== installing) : this.installing; + this.installing = installingExtension ? this.installing.filter(e => e !== installingExtension) : this.installing; if (error) { if (extension.gallery) { // Updating extension can be only a gallery extension const installed = this.installed.filter(e => e.id === extension.id)[0]; - if (installed && installing) { - installing.operation = Operation.Updating; + if (installed && installingExtension) { + installingExtension.operation = Operation.Updating; } } } else { extension.local = local; const installed = this.installed.filter(e => e.id === extension.id)[0]; if (installed) { - if (installing) { - installing.operation = Operation.Updating; + if (installingExtension) { + installingExtension.operation = Operation.Updating; } installed.local = local; } else { @@ -770,7 +783,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } if (extension.gallery) { // Report telemetry only for gallery extensions - this.reportTelemetry(installing, error); + this.reportTelemetry(installingExtension, error); } } this._onChange.fire(); diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts index 0e697f0d9ef..ec79e302d8c 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsActions.test.ts @@ -92,78 +92,79 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test Install action when state is installed', (done) => { + test('Test Install action when state is installed', () => { const workbenchService = instantiationService.get(IExtensionsWorkbenchService); const testObject: ExtensionsActions.InstallAction = instantiationService.createInstance(ExtensionsActions.InstallAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - workbenchService.queryLocal().done(() => { - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local.identifier }))); - workbenchService.queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - assert.ok(!testObject.enabled); - assert.equal('Install', testObject.label); - assert.equal('extension-action prominent install', testObject.class); - done(); + return workbenchService.queryLocal() + .then(() => { + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local.identifier }))); + return workbenchService.queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + assert.ok(!testObject.enabled); + assert.equal('Install', testObject.label); + assert.equal('extension-action prominent install', testObject.class); + }); }); - }); }); - test('Test Install action when state is installing', (done) => { + test('Test Install action when state is installing', () => { const workbenchService = instantiationService.get(IExtensionsWorkbenchService); const testObject: ExtensionsActions.InstallAction = instantiationService.createInstance(ExtensionsActions.InstallAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - workbenchService.queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); + return workbenchService.queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + installEvent.fire({ identifier: gallery.identifier, gallery }); - assert.ok(!testObject.enabled); - assert.equal('Installing', testObject.label); - assert.equal('extension-action install installing', testObject.class); - done(); - }); + assert.ok(!testObject.enabled); + assert.equal('Installing', testObject.label); + assert.equal('extension-action install installing', testObject.class); + }); }); - test('Test Install action when state is uninstalled', (done) => { + test('Test Install action when state is uninstalled', () => { const workbenchService = instantiationService.get(IExtensionsWorkbenchService); const testObject: ExtensionsActions.InstallAction = instantiationService.createInstance(ExtensionsActions.InstallAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - workbenchService.queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - assert.ok(testObject.enabled); - assert.equal('Install', testObject.label); - done(); - }); + return workbenchService.queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + assert.ok(testObject.enabled); + assert.equal('Install', testObject.label); + }); }); - test('Test Install action when extension is system action', (done) => { + test('Test Install action when extension is system action', () => { const testObject: ExtensionsActions.InstallAction = instantiationService.createInstance(ExtensionsActions.InstallAction); const local = aLocalExtension('a', {}, { type: LocalExtensionType.System }); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - uninstallEvent.fire(local.identifier); - didUninstallEvent.fire({ identifier: local.identifier }); - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + uninstallEvent.fire(local.identifier); + didUninstallEvent.fire({ identifier: local.identifier }); + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); }); - test('Test Install action when extension doesnot has gallery', (done) => { + test('Test Install action when extension doesnot has gallery', () => { const testObject: ExtensionsActions.InstallAction = instantiationService.createInstance(ExtensionsActions.InstallAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - uninstallEvent.fire(local.identifier); - didUninstallEvent.fire({ identifier: local.identifier }); - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + uninstallEvent.fire(local.identifier); + didUninstallEvent.fire({ identifier: local.identifier }); + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); }); test('Uninstall action is disabled when there is no extension', () => { @@ -172,65 +173,65 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test Uninstall action when state is uninstalling', (done) => { + test('Test Uninstall action when state is uninstalling', () => { const testObject: ExtensionsActions.UninstallAction = instantiationService.createInstance(ExtensionsActions.UninstallAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); - assert.ok(!testObject.enabled); - assert.equal('Uninstalling', testObject.label); - assert.equal('extension-action uninstall uninstalling', testObject.class); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + uninstallEvent.fire(local.identifier); + assert.ok(!testObject.enabled); + assert.equal('Uninstalling', testObject.label); + assert.equal('extension-action uninstall uninstalling', testObject.class); + }); }); - test('Test Uninstall action when state is installed and is user extension', (done) => { + test('Test Uninstall action when state is installed and is user extension', () => { const testObject: ExtensionsActions.UninstallAction = instantiationService.createInstance(ExtensionsActions.UninstallAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - assert.equal('Uninstall', testObject.label); - assert.equal('extension-action uninstall', testObject.class); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + assert.equal('Uninstall', testObject.label); + assert.equal('extension-action uninstall', testObject.class); + }); }); - test('Test Uninstall action when state is installed and is system extension', (done) => { + test('Test Uninstall action when state is installed and is system extension', () => { const testObject: ExtensionsActions.UninstallAction = instantiationService.createInstance(ExtensionsActions.UninstallAction); const local = aLocalExtension('a', {}, { type: LocalExtensionType.System }); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - assert.equal('Uninstall', testObject.label); - assert.equal('extension-action uninstall', testObject.class); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + assert.equal('Uninstall', testObject.label); + assert.equal('extension-action uninstall', testObject.class); + }); }); - test('Test Uninstall action after extension is installed', (done) => { + test('Test Uninstall action after extension is installed', () => { const testObject: ExtensionsActions.UninstallAction = instantiationService.createInstance(ExtensionsActions.UninstallAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(paged => { - testObject.extension = paged.firstPage[0]; + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(paged => { + testObject.extension = paged.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); - didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); + installEvent.fire({ identifier: gallery.identifier, gallery }); + didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); - assert.ok(testObject.enabled); - assert.equal('Uninstall', testObject.label); - assert.equal('extension-action uninstall', testObject.class); - done(); - }); + assert.ok(testObject.enabled); + assert.equal('Uninstall', testObject.label); + assert.equal('extension-action uninstall', testObject.class); + }); }); test('Test CombinedInstallAction when there is no extension', () => { @@ -240,77 +241,77 @@ suite('ExtensionsActions Test', () => { assert.equal('extension-action prominent install no-extension', testObject.class); }); - test('Test CombinedInstallAction when extension is system extension', (done) => { + test('Test CombinedInstallAction when extension is system extension', () => { const testObject: ExtensionsActions.CombinedInstallAction = instantiationService.createInstance(ExtensionsActions.CombinedInstallAction); const local = aLocalExtension('a', {}, { type: LocalExtensionType.System }); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - assert.equal('extension-action prominent install no-extension', testObject.class); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + assert.equal('extension-action prominent install no-extension', testObject.class); + }); }); - test('Test CombinedInstallAction when installAction is enabled', (done) => { + test('Test CombinedInstallAction when installAction is enabled', () => { const workbenchService = instantiationService.get(IExtensionsWorkbenchService); const testObject: ExtensionsActions.CombinedInstallAction = instantiationService.createInstance(ExtensionsActions.CombinedInstallAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - workbenchService.queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - assert.ok(testObject.enabled); - assert.equal('Install', testObject.label); - assert.equal('extension-action prominent install', testObject.class); - done(); - }); + return workbenchService.queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + assert.ok(testObject.enabled); + assert.equal('Install', testObject.label); + assert.equal('extension-action prominent install', testObject.class); + }); }); - test('Test CombinedInstallAction when unInstallAction is enabled', (done) => { + test('Test CombinedInstallAction when unInstallAction is enabled', () => { const testObject: ExtensionsActions.CombinedInstallAction = instantiationService.createInstance(ExtensionsActions.CombinedInstallAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - assert.equal('Uninstall', testObject.label); - assert.equal('extension-action uninstall', testObject.class); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + assert.equal('Uninstall', testObject.label); + assert.equal('extension-action uninstall', testObject.class); + }); }); - test('Test CombinedInstallAction when state is installing', (done) => { + test('Test CombinedInstallAction when state is installing', () => { const testObject: ExtensionsActions.CombinedInstallAction = instantiationService.createInstance(ExtensionsActions.CombinedInstallAction); const workbenchService = instantiationService.get(IExtensionsWorkbenchService); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - workbenchService.queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); + return workbenchService.queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + installEvent.fire({ identifier: gallery.identifier, gallery }); - assert.ok(!testObject.enabled); - assert.equal('Installing', testObject.label); - assert.equal('extension-action install installing', testObject.class); - done(); - }); + assert.ok(!testObject.enabled); + assert.equal('Installing', testObject.label); + assert.equal('extension-action install installing', testObject.class); + }); }); - test('Test CombinedInstallAction when state is uninstalling', (done) => { + test('Test CombinedInstallAction when state is uninstalling', () => { const testObject: ExtensionsActions.CombinedInstallAction = instantiationService.createInstance(ExtensionsActions.CombinedInstallAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); - assert.ok(!testObject.enabled); - assert.equal('Uninstalling', testObject.label); - assert.equal('extension-action uninstall uninstalling', testObject.class); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + uninstallEvent.fire(local.identifier); + assert.ok(!testObject.enabled); + assert.equal('Uninstalling', testObject.label); + assert.equal('extension-action uninstall uninstalling', testObject.class); + }); }); test('Test UpdateAction when there is no extension', () => { @@ -319,77 +320,75 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test UpdateAction when extension is uninstalled', (done) => { + test('Test UpdateAction when extension is uninstalled', () => { const testObject: ExtensionsActions.UpdateAction = instantiationService.createInstance(ExtensionsActions.UpdateAction); const gallery = aGalleryExtension('a', { version: '1.0.0' }); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + assert.ok(!testObject.enabled); + }); }); - test('Test UpdateAction when extension is installed and not outdated', (done) => { + test('Test UpdateAction when extension is installed and not outdated', () => { const testObject: ExtensionsActions.UpdateAction = instantiationService.createInstance(ExtensionsActions.UpdateAction); const local = aLocalExtension('a', { version: '1.0.0' }); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local.identifier, version: local.manifest.version }))); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(extensions => { - assert.ok(!testObject.enabled); - done(); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local.identifier, version: local.manifest.version }))); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(extensions => assert.ok(!testObject.enabled)); }); - }); }); - test('Test UpdateAction when extension is installed outdated and system extension', (done) => { + test('Test UpdateAction when extension is installed outdated and system extension', () => { const testObject: ExtensionsActions.UpdateAction = instantiationService.createInstance(ExtensionsActions.UpdateAction); const local = aLocalExtension('a', { version: '1.0.0' }, { type: LocalExtensionType.System }); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local.identifier, version: '1.0.1' }))); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(extensions => { - assert.ok(!testObject.enabled); - done(); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local.identifier, version: '1.0.1' }))); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(extensions => assert.ok(!testObject.enabled)); }); - }); }); - test('Test UpdateAction when extension is installed outdated and user extension', (done) => { + test('Test UpdateAction when extension is installed outdated and user extension', () => { const testObject: ExtensionsActions.UpdateAction = instantiationService.createInstance(ExtensionsActions.UpdateAction); const local = aLocalExtension('a', { version: '1.0.0' }); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local.identifier, version: '1.0.1' }))); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(extensions => { - assert.ok(testObject.enabled); - done(); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local.identifier, version: '1.0.1' }))); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(extensions => assert.ok(testObject.enabled)); }); - }); }); - test('Test UpdateAction when extension is installing and outdated and user extension', (done) => { + test('Test UpdateAction when extension is installing and outdated and user extension', () => { const testObject: ExtensionsActions.UpdateAction = instantiationService.createInstance(ExtensionsActions.UpdateAction); const local = aLocalExtension('a', { version: '1.0.0' }); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.1' }); - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(extensions => { - installEvent.fire({ identifier: local.identifier, gallery }); - assert.ok(!testObject.enabled); - done(); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.1' }); + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(extensions => { + installEvent.fire({ identifier: local.identifier, gallery }); + assert.ok(!testObject.enabled); + }); }); - }); }); test('Test ManageExtensionAction when there is no extension', () => { @@ -398,101 +397,95 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test ManageExtensionAction when extension is installed', (done) => { + test('Test ManageExtensionAction when extension is installed', () => { const testObject: ExtensionsActions.ManageExtensionAction = instantiationService.createInstance(ExtensionsActions.ManageExtensionAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - assert.equal('extension-action manage', testObject.class); - assert.equal('', testObject.tooltip); - - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + assert.equal('extension-action manage', testObject.class); + assert.equal('', testObject.tooltip); + }); }); - test('Test ManageExtensionAction when extension is uninstalled', (done) => { + test('Test ManageExtensionAction when extension is uninstalled', () => { const testObject: ExtensionsActions.ManageExtensionAction = instantiationService.createInstance(ExtensionsActions.ManageExtensionAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(page => { - testObject.extension = page.firstPage[0]; - assert.ok(!testObject.enabled); - assert.equal('extension-action manage hide', testObject.class); - assert.equal('', testObject.tooltip); - - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(page => { + testObject.extension = page.firstPage[0]; + assert.ok(!testObject.enabled); + assert.equal('extension-action manage hide', testObject.class); + assert.equal('', testObject.tooltip); + }); }); - test('Test ManageExtensionAction when extension is installing', (done) => { + test('Test ManageExtensionAction when extension is installing', () => { const testObject: ExtensionsActions.ManageExtensionAction = instantiationService.createInstance(ExtensionsActions.ManageExtensionAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(page => { - testObject.extension = page.firstPage[0]; + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(page => { + testObject.extension = page.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); - assert.ok(!testObject.enabled); - assert.equal('extension-action manage hide', testObject.class); - assert.equal('', testObject.tooltip); - - done(); - }); + installEvent.fire({ identifier: gallery.identifier, gallery }); + assert.ok(!testObject.enabled); + assert.equal('extension-action manage hide', testObject.class); + assert.equal('', testObject.tooltip); + }); }); - test('Test ManageExtensionAction when extension is queried from gallery and installed', (done) => { + test('Test ManageExtensionAction when extension is queried from gallery and installed', () => { const testObject: ExtensionsActions.ManageExtensionAction = instantiationService.createInstance(ExtensionsActions.ManageExtensionAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(page => { - testObject.extension = page.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); - didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(page => { + testObject.extension = page.firstPage[0]; + installEvent.fire({ identifier: gallery.identifier, gallery }); + didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); - assert.ok(testObject.enabled); - assert.equal('extension-action manage', testObject.class); - assert.equal('', testObject.tooltip); - - done(); - }); + assert.ok(testObject.enabled); + assert.equal('extension-action manage', testObject.class); + assert.equal('', testObject.tooltip); + }); }); - test('Test ManageExtensionAction when extension is system extension', (done) => { + test('Test ManageExtensionAction when extension is system extension', () => { const testObject: ExtensionsActions.ManageExtensionAction = instantiationService.createInstance(ExtensionsActions.ManageExtensionAction); const local = aLocalExtension('a', {}, { type: LocalExtensionType.System }); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - assert.equal('extension-action manage hide', testObject.class); - assert.equal('', testObject.tooltip); - - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + assert.equal('extension-action manage hide', testObject.class); + assert.equal('', testObject.tooltip); + }); }); - test('Test ManageExtensionAction when extension is uninstalling', (done) => { + test('Test ManageExtensionAction when extension is uninstalling', () => { const testObject: ExtensionsActions.ManageExtensionAction = instantiationService.createInstance(ExtensionsActions.ManageExtensionAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + uninstallEvent.fire(local.identifier); - assert.ok(!testObject.enabled); - assert.equal('extension-action manage', testObject.class); - assert.equal('Uninstalling', testObject.tooltip); - - done(); - }); + assert.ok(!testObject.enabled); + assert.equal('extension-action manage', testObject.class); + assert.equal('Uninstalling', testObject.tooltip); + }); }); test('Test EnableForWorkspaceAction when there is no extension', () => { @@ -501,20 +494,7 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test EnableForWorkspaceAction when there extension is not disabled', (done) => { - const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, 'id'); - const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); - }); - - test('Test EnableForWorkspaceAction when the extension is disabled globally', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); + test('Test EnableForWorkspaceAction when there extension is not disabled', () => { const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, 'id'); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); @@ -522,34 +502,53 @@ suite('ExtensionsActions Test', () => { return instantiationService.get(IExtensionsWorkbenchService).queryLocal() .then(extensions => { testObject.extension = extensions[0]; - assert.ok(testObject.enabled); + assert.ok(!testObject.enabled); + }); + }); + + test('Test EnableForWorkspaceAction when the extension is disabled globally', () => { + const local = aLocalExtension('a'); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); }); }); test('Test EnableForWorkspaceAction when extension is disabled for workspace', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, 'id'); const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) + .then(() => { + const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - return instantiationService.get(IExtensionsWorkbenchService).queryLocal() - .then(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); }); }); test('Test EnableForWorkspaceAction when the extension is disabled globally and workspace', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, 'id'); const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled)) + .then(() => { + const testObject: ExtensionsActions.EnableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.EnableForWorkspaceAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - return instantiationService.get(IExtensionsWorkbenchService).queryLocal() - .then(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); }); }); @@ -559,56 +558,62 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test EnableGloballyAction when the extension is not disabled', (done) => { - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); + test('Test EnableGloballyAction when the extension is not disabled', () => { const local = aLocalExtension('a'); + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); }); - test('Test EnableGloballyAction when the extension is disabled for workspace', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); + test('Test EnableGloballyAction when the extension is disabled for workspace', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) + .then(() => { + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); + }); }); - test('Test EnableGloballyAction when the extension is disabled globally', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); + test('Test EnableGloballyAction when the extension is disabled globally', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); + }); }); - test('Test EnableGloballyAction when the extension is disabled in both', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); + test('Test EnableGloballyAction when the extension is disabled in both', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled)) + .then(() => { + const testObject: ExtensionsActions.EnableGloballyAction = instantiationService.createInstance(ExtensionsActions.EnableGloballyAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); + }); }); test('Test EnableAction when there is no extension', () => { @@ -617,82 +622,85 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test EnableAction when extension is installed and enabled', (done) => { + test('Test EnableAction when extension is installed and enabled', () => { const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); }); - test('Test EnableAction when extension is installed and disabled globally', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + test('Test EnableAction when extension is installed and disabled globally', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); + }); }); - test('Test EnableAction when extension is installed and disabled for workspace', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + test('Test EnableAction when extension is installed and disabled for workspace', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) + .then(() => { + const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); + }); }); - test('Test EnableAction when extension is uninstalled', (done) => { + test('Test EnableAction when extension is uninstalled', () => { const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(page => { - testObject.extension = page.firstPage[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(page => { + testObject.extension = page.firstPage[0]; + assert.ok(!testObject.enabled); + }); }); - test('Test EnableAction when extension is installing', (done) => { + test('Test EnableAction when extension is installing', () => { const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(page => { - testObject.extension = page.firstPage[0]; + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(page => { + testObject.extension = page.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); - assert.ok(!testObject.enabled); - - done(); - }); + installEvent.fire({ identifier: gallery.identifier, gallery }); + assert.ok(!testObject.enabled); + }); }); - test('Test EnableAction when extension is uninstalling', (done) => { + test('Test EnableAction when extension is uninstalling', () => { const testObject: ExtensionsActions.EnableAction = instantiationService.createInstance(ExtensionsActions.EnableAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + uninstallEvent.fire(local.identifier); + assert.ok(!testObject.enabled); + }); }); test('Test DisableForWorkspaceAction when there is no extension', () => { @@ -701,42 +709,46 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test DisableForWorkspaceAction when the extension is disabled globally', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); + test('Test DisableForWorkspaceAction when the extension is disabled globally', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); + }); }); - test('Test DisableForWorkspaceAction when the extension is disabled workspace', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); + test('Test DisableForWorkspaceAction when the extension is disabled workspace', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); + }); }); - test('Test DisableForWorkspaceAction when extension is enabled', (done) => { + test('Test DisableForWorkspaceAction when extension is enabled', () => { const testObject: ExtensionsActions.DisableForWorkspaceAction = instantiationService.createInstance(ExtensionsActions.DisableForWorkspaceAction, 'id'); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); }); test('Test DisableGloballyAction when there is no extension', () => { @@ -745,42 +757,46 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test DisableGloballyAction when the extension is disabled globally', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); + test('Test DisableGloballyAction when the extension is disabled globally', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); + }); }); - test('Test DisableGloballyAction when the extension is disabled for workspace', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); + test('Test DisableGloballyAction when the extension is disabled for workspace', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) + .then(() => { + const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); + }); }); - test('Test DisableGloballyAction when the extension is enabled', (done) => { + test('Test DisableGloballyAction when the extension is enabled', () => { const testObject: ExtensionsActions.DisableGloballyAction = instantiationService.createInstance(ExtensionsActions.DisableGloballyAction, 'id'); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); }); test('Test DisableAction when there is no extension', () => { @@ -789,82 +805,85 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test DisableAction when extension is installed and enabled', (done) => { + test('Test DisableAction when extension is installed and enabled', () => { const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(testObject.enabled); + }); }); - test('Test DisableAction when extension is installed and disabled globally', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + test('Test DisableAction when extension is installed and disabled globally', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); + }); }); - test('Test DisableAction when extension is installed and disabled for workspace', (done) => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + test('Test DisableAction when extension is installed and disabled for workspace', () => { const local = aLocalExtension('a'); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.WorkspaceDisabled) + .then(() => { + const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + assert.ok(!testObject.enabled); + }); + }); }); - test('Test DisableAction when extension is uninstalled', (done) => { + test('Test DisableAction when extension is uninstalled', () => { const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(page => { - testObject.extension = page.firstPage[0]; - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(page => { + testObject.extension = page.firstPage[0]; + assert.ok(!testObject.enabled); + }); }); - test('Test DisableAction when extension is installing', (done) => { + test('Test DisableAction when extension is installing', () => { const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done(page => { - testObject.extension = page.firstPage[0]; + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then(page => { + testObject.extension = page.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); - assert.ok(!testObject.enabled); - - done(); - }); + installEvent.fire({ identifier: gallery.identifier, gallery }); + assert.ok(!testObject.enabled); + }); }); - test('Test DisableAction when extension is uninstalling', (done) => { + test('Test DisableAction when extension is uninstalling', () => { const testObject: ExtensionsActions.DisableAction = instantiationService.createInstance(ExtensionsActions.DisableAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + uninstallEvent.fire(local.identifier); + assert.ok(!testObject.enabled); + }); }); test('Test UpdateAllAction when no installed extensions', () => { @@ -873,60 +892,59 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test UpdateAllAction when installed extensions are not outdated', (done) => { + test('Test UpdateAllAction when installed extensions are not outdated', () => { const testObject: ExtensionsActions.UpdateAllAction = instantiationService.createInstance(ExtensionsActions.UpdateAllAction, 'id', 'label'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a'), aLocalExtension('b')]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => assert.ok(!testObject.enabled)); }); - test('Test UpdateAllAction when some installed extensions are outdated', (done) => { + test('Test UpdateAllAction when some installed extensions are outdated', () => { const testObject: ExtensionsActions.UpdateAllAction = instantiationService.createInstance(ExtensionsActions.UpdateAllAction, 'id', 'label'); const local = [aLocalExtension('a', { version: '1.0.1' }), aLocalExtension('b', { version: '1.0.1' }), aLocalExtension('c', { version: '1.0.1' })]; const workbenchService = instantiationService.get(IExtensionsWorkbenchService); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', local); - workbenchService.queryLocal().done(() => { - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local[0].identifier, version: '1.0.2' }), aGalleryExtension('b', { identifier: local[1].identifier, version: '1.0.2' }), aGalleryExtension('c', local[2].manifest))); - workbenchService.queryGallery().done(() => { - assert.ok(testObject.enabled); - done(); + return workbenchService.queryLocal() + .then(() => { + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a', { identifier: local[0].identifier, version: '1.0.2' }), aGalleryExtension('b', { identifier: local[1].identifier, version: '1.0.2' }), aGalleryExtension('c', local[2].manifest))); + return workbenchService.queryGallery() + .then(() => assert.ok(testObject.enabled)); }); - }); }); - test('Test UpdateAllAction when some installed extensions are outdated and some outdated are being installed', (done) => { + test('Test UpdateAllAction when some installed extensions are outdated and some outdated are being installed', () => { const testObject: ExtensionsActions.UpdateAllAction = instantiationService.createInstance(ExtensionsActions.UpdateAllAction, 'id', 'label'); const local = [aLocalExtension('a', { version: '1.0.1' }), aLocalExtension('b', { version: '1.0.1' }), aLocalExtension('c', { version: '1.0.1' })]; const gallery = [aGalleryExtension('a', { identifier: local[0].identifier, version: '1.0.2' }), aGalleryExtension('b', { identifier: local[1].identifier, version: '1.0.2' }), aGalleryExtension('c', local[2].manifest)]; const workbenchService = instantiationService.get(IExtensionsWorkbenchService); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', local); - workbenchService.queryLocal().done(() => { - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...gallery)); - workbenchService.queryGallery().done(() => { - installEvent.fire({ identifier: local[0].identifier, gallery: gallery[0] }); - assert.ok(testObject.enabled); - done(); + return workbenchService.queryLocal() + .then(() => { + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...gallery)); + return workbenchService.queryGallery() + .then(() => { + installEvent.fire({ identifier: local[0].identifier, gallery: gallery[0] }); + assert.ok(testObject.enabled); + }); }); - }); }); - test('Test UpdateAllAction when some installed extensions are outdated and all outdated are being installed', (done) => { + test('Test UpdateAllAction when some installed extensions are outdated and all outdated are being installed', () => { const testObject: ExtensionsActions.UpdateAllAction = instantiationService.createInstance(ExtensionsActions.UpdateAllAction, 'id', 'label'); const local = [aLocalExtension('a', { version: '1.0.1' }), aLocalExtension('b', { version: '1.0.1' }), aLocalExtension('c', { version: '1.0.1' })]; const gallery = [aGalleryExtension('a', { identifier: local[0].identifier, version: '1.0.2' }), aGalleryExtension('b', { identifier: local[1].identifier, version: '1.0.2' }), aGalleryExtension('c', local[2].manifest)]; const workbenchService = instantiationService.get(IExtensionsWorkbenchService); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', local); - workbenchService.queryLocal().done(() => { - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...gallery)); - workbenchService.queryGallery().done(() => { - installEvent.fire({ identifier: local[0].identifier, gallery: gallery[0] }); - installEvent.fire({ identifier: local[1].identifier, gallery: gallery[1] }); - assert.ok(!testObject.enabled); - done(); + return workbenchService.queryLocal() + .then(() => { + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(...gallery)); + return workbenchService.queryGallery() + .then(() => { + installEvent.fire({ identifier: local[0].identifier, gallery: gallery[0] }); + installEvent.fire({ identifier: local[1].identifier, gallery: gallery[1] }); + assert.ok(!testObject.enabled); + }); }); - }); }); test('Test ReloadAction when there is no extension', () => { @@ -935,233 +953,241 @@ suite('ExtensionsActions Test', () => { assert.ok(!testObject.enabled); }); - test('Test ReloadAction when extension state is installing', (done) => { + test('Test ReloadAction when extension state is installing', () => { const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const workbenchService = instantiationService.get(IExtensionsWorkbenchService); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - workbenchService.queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); + return workbenchService.queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + installEvent.fire({ identifier: gallery.identifier, gallery }); - assert.ok(!testObject.enabled); - done(); - }); + assert.ok(!testObject.enabled); + }); }); - test('Test ReloadAction when extension state is uninstalling', (done) => { + test('Test ReloadAction when extension state is uninstalling', () => { const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + uninstallEvent.fire(local.identifier); + assert.ok(!testObject.enabled); + }); }); - test('Test ReloadAction when extension is newly installed', (done) => { + test('Test ReloadAction when extension is newly installed', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.b' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - installEvent.fire({ identifier: gallery.identifier, gallery }); - didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + installEvent.fire({ identifier: gallery.identifier, gallery }); + didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); - assert.ok(testObject.enabled); - assert.equal('Reload to activate', testObject.tooltip); - assert.equal(`Reload this window to activate the extension 'a'?`, testObject.reloadMessage); - done(); - }); + assert.ok(testObject.enabled); + assert.equal('Reload to activate', testObject.tooltip); + assert.equal(`Reload this window to activate the extension 'a'?`, testObject.reloadMessage); + }); }); - test('Test ReloadAction when extension is installed and uninstalled', (done) => { + test('Test ReloadAction when extension is installed and uninstalled', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.b' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const gallery = aGalleryExtension('a'); instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery)); - instantiationService.get(IExtensionsWorkbenchService).queryGallery().done((paged) => { - testObject.extension = paged.firstPage[0]; - const identifier = { id: getLocalExtensionIdFromGallery(gallery, gallery.version) }; - installEvent.fire({ identifier: identifier, gallery }); - didInstallEvent.fire({ identifier: identifier, gallery, local: aLocalExtension('a', gallery, { identifier }) }); - uninstallEvent.fire(identifier); - didUninstallEvent.fire({ identifier: identifier }); + return instantiationService.get(IExtensionsWorkbenchService).queryGallery() + .then((paged) => { + testObject.extension = paged.firstPage[0]; + const identifier = { id: getLocalExtensionIdFromGallery(gallery, gallery.version) }; + installEvent.fire({ identifier: identifier, gallery }); + didInstallEvent.fire({ identifier: identifier, gallery, local: aLocalExtension('a', gallery, { identifier }) }); + uninstallEvent.fire(identifier); + didUninstallEvent.fire({ identifier: identifier }); - assert.ok(!testObject.enabled); - done(); - }); + assert.ok(!testObject.enabled); + }); }); - test('Test ReloadAction when extension is uninstalled', (done) => { + test('Test ReloadAction when extension is uninstalled', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); - didUninstallEvent.fire({ identifier: local.identifier }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + uninstallEvent.fire(local.identifier); + didUninstallEvent.fire({ identifier: local.identifier }); - assert.ok(testObject.enabled); - assert.equal('Reload to deactivate', testObject.tooltip); - assert.equal(`Reload this window to deactivate the uninstalled extension 'a'?`, testObject.reloadMessage); - done(); - }); + assert.ok(testObject.enabled); + assert.equal('Reload to deactivate', testObject.tooltip); + assert.equal(`Reload this window to deactivate the uninstalled extension 'a'?`, testObject.reloadMessage); + }); }); - test('Test ReloadAction when extension is uninstalled and installed', (done) => { + test('Test ReloadAction when extension is uninstalled and installed', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a', version: '1.0.0' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - instantiationService.get(IExtensionsWorkbenchService).queryLocal().done(extensions => { - testObject.extension = extensions[0]; - uninstallEvent.fire(local.identifier); - didUninstallEvent.fire({ identifier: local.identifier }); + return instantiationService.get(IExtensionsWorkbenchService).queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + uninstallEvent.fire(local.identifier); + didUninstallEvent.fire({ identifier: local.identifier }); - const gallery = aGalleryExtension('a'); - const id = getLocalExtensionIdFromGallery(gallery, gallery.version); - installEvent.fire({ identifier: { id }, gallery }); - didInstallEvent.fire({ identifier: { id }, gallery, local }); + const gallery = aGalleryExtension('a'); + const id = getLocalExtensionIdFromGallery(gallery, gallery.version); + installEvent.fire({ identifier: { id }, gallery }); + didInstallEvent.fire({ identifier: { id }, gallery, local }); - assert.ok(!testObject.enabled); - done(); - }); + assert.ok(!testObject.enabled); + }); }); - test('Test ReloadAction when extension is updated while running', (done) => { + test('Test ReloadAction when extension is updated while running', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a', version: '1.0.1' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a', { version: '1.0.1' }); const workbenchService = instantiationService.get(IExtensionsWorkbenchService); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - workbenchService.queryLocal().done(extensions => { - testObject.extension = extensions[0]; + return workbenchService.queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; - const gallery = aGalleryExtension('a', { uuid: local.identifier.id, version: '1.0.2' }); - installEvent.fire({ identifier: gallery.identifier, gallery }); - didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); + const gallery = aGalleryExtension('a', { uuid: local.identifier.id, version: '1.0.2' }); + installEvent.fire({ identifier: gallery.identifier, gallery }); + didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); - assert.ok(testObject.enabled); - assert.equal('Reload to update', testObject.tooltip); - assert.equal(`Reload this window to activate the updated extension 'a'?`, testObject.reloadMessage); - done(); - - }); + assert.ok(testObject.enabled); + assert.equal('Reload to update', testObject.tooltip); + assert.equal(`Reload this window to activate the updated extension 'a'?`, testObject.reloadMessage); + }); }); - test('Test ReloadAction when extension is updated when not running', (done) => { + test('Test ReloadAction when extension is updated when not running', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.b' }]); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a', { version: '1.0.1' }); - const workbenchService = instantiationService.get(IExtensionsWorkbenchService); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - workbenchService.queryLocal().done(extensions => { - testObject.extension = extensions[0]; + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); + const workbenchService = instantiationService.get(IExtensionsWorkbenchService); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return workbenchService.queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; - const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.2' }); - installEvent.fire({ identifier: gallery.identifier, gallery }); - didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); + const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.2' }); + installEvent.fire({ identifier: gallery.identifier, gallery }); + didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); - assert.ok(!testObject.enabled); - done(); - }); + assert.ok(!testObject.enabled); + }); + }); }); - test('Test ReloadAction when extension is disabled when running', (done) => { + test('Test ReloadAction when extension is disabled when running', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); const workbenchService = instantiationService.get(IExtensionsWorkbenchService); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - workbenchService.queryLocal().done(extensions => { + return workbenchService.queryLocal().then(extensions => { testObject.extension = extensions[0]; - workbenchService.setEnablement(extensions[0], EnablementState.Disabled); - - assert.ok(testObject.enabled); - assert.equal('Reload to deactivate', testObject.tooltip); - assert.equal(`Reload this window to deactivate the extension 'a'?`, testObject.reloadMessage); - done(); + return workbenchService.setEnablement(extensions[0], EnablementState.Disabled) + .then(() => { + assert.ok(testObject.enabled); + assert.equal('Reload to deactivate', testObject.tooltip); + assert.equal(`Reload this window to deactivate the extension 'a'?`, testObject.reloadMessage); + }); }); }); - test('Test ReloadAction when extension enablement is toggled when running', (done) => { + test('Test ReloadAction when extension enablement is toggled when running', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.a', version: '1.0.0' }]); const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); const workbenchService = instantiationService.get(IExtensionsWorkbenchService); instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - workbenchService.queryLocal().done(extensions => { - testObject.extension = extensions[0]; - workbenchService.setEnablement(extensions[0], EnablementState.Disabled); - workbenchService.setEnablement(extensions[0], EnablementState.Enabled); - - assert.ok(!testObject.enabled); - done(); - }); + return workbenchService.queryLocal(). + then(extensions => { + testObject.extension = extensions[0]; + return workbenchService.setEnablement(extensions[0], EnablementState.Disabled) + .then(() => workbenchService.setEnablement(extensions[0], EnablementState.Enabled)) + .then(() => assert.ok(!testObject.enabled)); + }); }); - test('Test ReloadAction when extension is enabled when not running', (done) => { + test('Test ReloadAction when extension is enabled when not running', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.b' }]); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); - const workbenchService = instantiationService.get(IExtensionsWorkbenchService); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - workbenchService.queryLocal().done(extensions => { - testObject.extension = extensions[0]; - workbenchService.setEnablement(extensions[0], EnablementState.Enabled); - - assert.ok(testObject.enabled); - assert.equal('Reload to activate', testObject.tooltip); - assert.equal(`Reload this window to activate the extension 'a'?`, testObject.reloadMessage); - done(); - }); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); + const workbenchService = instantiationService.get(IExtensionsWorkbenchService); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return workbenchService.queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + return workbenchService.setEnablement(extensions[0], EnablementState.Enabled) + .then(() => { + assert.ok(testObject.enabled); + assert.equal('Reload to activate', testObject.tooltip); + assert.equal(`Reload this window to activate the extension 'a'?`, testObject.reloadMessage); + }); + }); + }); }); - test('Test ReloadAction when extension enablement is toggled when not running', (done) => { + test('Test ReloadAction when extension enablement is toggled when not running', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.b' }]); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a'); - const workbenchService = instantiationService.get(IExtensionsWorkbenchService); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - workbenchService.queryLocal().done(extensions => { - testObject.extension = extensions[0]; - workbenchService.setEnablement(extensions[0], EnablementState.Enabled); - workbenchService.setEnablement(extensions[0], EnablementState.Disabled); - - assert.ok(!testObject.enabled); - done(); - }); + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); + const workbenchService = instantiationService.get(IExtensionsWorkbenchService); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return workbenchService.queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; + return workbenchService.setEnablement(extensions[0], EnablementState.Enabled) + .then(() => workbenchService.setEnablement(extensions[0], EnablementState.Disabled)) + .then(() => assert.ok(!testObject.enabled)); + }); + }); }); - test('Test ReloadAction when extension is updated when not running and enabled', (done) => { + test('Test ReloadAction when extension is updated when not running and enabled', () => { instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ id: 'pub.b' }]); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); const local = aLocalExtension('a', { version: '1.0.1' }); - const workbenchService = instantiationService.get(IExtensionsWorkbenchService); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); - workbenchService.queryLocal().done(extensions => { - testObject.extension = extensions[0]; + return instantiationService.get(IExtensionEnablementService).setEnablement(local, EnablementState.Disabled) + .then(() => { + const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction); + const workbenchService = instantiationService.get(IExtensionsWorkbenchService); + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]); + return workbenchService.queryLocal() + .then(extensions => { + testObject.extension = extensions[0]; - const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.2' }); - installEvent.fire({ identifier: gallery.identifier, gallery }); - didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); - workbenchService.setEnablement(extensions[0], EnablementState.Enabled); + const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.2' }); + installEvent.fire({ identifier: gallery.identifier, gallery }); + didInstallEvent.fire({ identifier: gallery.identifier, gallery, local: aLocalExtension('a', gallery, gallery) }); + return workbenchService.setEnablement(extensions[0], EnablementState.Enabled) + .then(() => { + assert.ok(testObject.enabled); + assert.equal('Reload to activate', testObject.tooltip); + assert.equal(`Reload this window to activate the extension 'a'?`, testObject.reloadMessage); + }); - assert.ok(testObject.enabled); - assert.equal('Reload to activate', testObject.tooltip); - assert.equal(`Reload this window to activate the extension 'a'?`, testObject.reloadMessage); - done(); - }); + }); + }); }); function aLocalExtension(name: string = 'someext', manifest: any = {}, properties: any = {}): ILocalExtension { diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts index a46d4cb2361..b37b3533a57 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -46,6 +46,7 @@ import { IChoiceService } from 'vs/platform/message/common/message'; import product from 'vs/platform/node/product'; import { ITextModel } from 'vs/editor/common/model'; import { IModelService } from 'vs/editor/common/services/modelService'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; const mockExtensionGallery: IGalleryExtension[] = [ aGalleryExtension('MockExtension1', { @@ -179,7 +180,7 @@ suite('ExtensionsTipsService Test', () => { uninstallEvent = new Emitter(); didUninstallEvent = new Emitter(); instantiationService.stub(IExtensionGalleryService, ExtensionGalleryService); - + instantiationService.stub(ILifecycleService, new TestLifecycleService()); testConfigurationService = new TestConfigurationService(); instantiationService.stub(IConfigurationService, testConfigurationService); instantiationService.stub(IExtensionManagementService, ExtensionManagementService); diff --git a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 0e32124f83d..0390501aceb 100644 --- a/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/parts/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -34,6 +34,8 @@ import { IChoiceService } from 'vs/platform/message/common/message'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IProgressService2 } from 'vs/platform/progress/common/progress'; +import { ProgressService2 } from 'vs/workbench/services/progress/browser/progressService2'; suite('ExtensionsWorkbenchService Test', () => { @@ -56,6 +58,7 @@ suite('ExtensionsWorkbenchService Test', () => { instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(ILogService, NullLogService); instantiationService.stub(IWindowService, TestWindowService); + instantiationService.stub(IProgressService2, ProgressService2); instantiationService.stub(IExtensionGalleryService, ExtensionGalleryService); @@ -698,283 +701,374 @@ suite('ExtensionsWorkbenchService Test', () => { }); test('test uninstalled extensions are always enabled', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.WorkspaceDisabled); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a'))); - return testObject.queryGallery().then(pagedResponse => { - const actual = pagedResponse.firstPage[0]; - assert.equal(actual.enablementState, EnablementState.Enabled); - }); + return instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('b'), EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('c'), EnablementState.WorkspaceDisabled)) + .then(() => { + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(aGalleryExtension('a'))); + return testObject.queryGallery().then(pagedResponse => { + const actual = pagedResponse.firstPage[0]; + assert.equal(actual.enablementState, EnablementState.Enabled); + }); + }); }); test('test enablement state installed enabled extension', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.WorkspaceDisabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('b'), EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('c'), EnablementState.WorkspaceDisabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - const actual = testObject.local[0]; + const actual = testObject.local[0]; - assert.equal(actual.enablementState, EnablementState.Enabled); + assert.equal(actual.enablementState, EnablementState.Enabled); + }); }); test('test workspace disabled extension', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.d' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.e' }, EnablementState.WorkspaceDisabled); + const extensionA = aLocalExtension('a'); + return instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('b'), EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('d'), EnablementState.Disabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.WorkspaceDisabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('e'), EnablementState.WorkspaceDisabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const actual = testObject.local[0]; - const actual = testObject.local[0]; - - assert.equal(actual.enablementState, EnablementState.WorkspaceDisabled); + assert.equal(actual.enablementState, EnablementState.WorkspaceDisabled); + }); }); test('test globally disabled extension', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.d' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.WorkspaceDisabled); + const localExtension = aLocalExtension('a'); + return instantiationService.get(IExtensionEnablementService).setEnablement(localExtension, EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('d'), EnablementState.Disabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('c'), EnablementState.WorkspaceDisabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [localExtension]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const actual = testObject.local[0]; - const actual = testObject.local[0]; - - assert.equal(actual.enablementState, EnablementState.Disabled); + assert.equal(actual.enablementState, EnablementState.Disabled); + }); }); test('test enablement state is updated for user extensions', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.WorkspaceDisabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - - testObject.setEnablement(testObject.local[0], EnablementState.WorkspaceDisabled); - const actual = testObject.local[0]; - - assert.equal(actual.enablementState, EnablementState.WorkspaceDisabled); + return instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('c'), EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('b'), EnablementState.WorkspaceDisabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return testObject.setEnablement(testObject.local[0], EnablementState.WorkspaceDisabled) + .then(() => { + const actual = testObject.local[0]; + assert.equal(actual.enablementState, EnablementState.WorkspaceDisabled); + }); + }); }); test('test enable extension globally when extension is disabled for workspace', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.WorkspaceDisabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - - testObject.setEnablement(testObject.local[0], EnablementState.Enabled); - const actual = testObject.local[0]; - - assert.equal(actual.enablementState, EnablementState.Enabled); + const localExtension = aLocalExtension('a'); + return instantiationService.get(IExtensionEnablementService).setEnablement(localExtension, EnablementState.WorkspaceDisabled) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [localExtension]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return testObject.setEnablement(testObject.local[0], EnablementState.Enabled) + .then(() => { + const actual = testObject.local[0]; + assert.equal(actual.enablementState, EnablementState.Enabled); + }); + }); }); test('test disable extension globally', () => { instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); - const actual = testObject.local[0]; - - assert.equal(actual.enablementState, EnablementState.Disabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => { + const actual = testObject.local[0]; + assert.equal(actual.enablementState, EnablementState.Disabled); + }); }); test('test system extensions are always enabled', () => { instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', {}, { type: LocalExtensionType.System })]); testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); - const actual = testObject.local[0]; - - assert.equal(actual.enablementState, EnablementState.Enabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => { + const actual = testObject.local[0]; + assert.equal(actual.enablementState, EnablementState.Enabled); + }); }); test('test enablement state is updated on change from outside', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.WorkspaceDisabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const localExtension = aLocalExtension('a'); + return instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('c'), EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('b'), EnablementState.WorkspaceDisabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [localExtension]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - const actual = testObject.local[0]; - - assert.equal(actual.enablementState, EnablementState.Disabled); + return instantiationService.get(IExtensionEnablementService).setEnablement(localExtension, EnablementState.Disabled) + .then(() => { + const actual = testObject.local[0]; + assert.equal(actual.enablementState, EnablementState.Disabled); + }); + }); }); test('test disable extension with dependencies disable only itself', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Enabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b'), aLocalExtension('c')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b'); + const extensionC = aLocalExtension('c'); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Enabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Enabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => { + assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Enabled); + }); + }); }); test('test disable extension with dependencies disable all', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Enabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b'), aLocalExtension('c')]); - instantiationService.stubPromise(IChoiceService, 'choose', 1); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b'); + const extensionC = aLocalExtension('c'); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Enabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + instantiationService.stubPromise(IChoiceService, 'choose', 1); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => { + assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + }); + }); }); test('test disable extension fails if extension is a dependent of other', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Enabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b'), aLocalExtension('c')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b'); + const extensionC = aLocalExtension('c'); - return testObject.setEnablement(testObject.local[1], EnablementState.Disabled).then(() => assert.fail('Should fail'), error => assert.ok(true)); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Enabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return testObject.setEnablement(testObject.local[1], EnablementState.Disabled).then(() => assert.fail('Should fail'), error => assert.ok(true)); + }); }); test('test disable extension does not fail if its dependency is a dependent of other but chosen to disable only itself', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Enabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b'), aLocalExtension('c', { extensionDependencies: ['pub.b'] })]); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b'); + const extensionC = aLocalExtension('c', { extensionDependencies: ['pub.b'] }); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Enabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); - - assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => { + assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); + }); + }); }); test('test disable extension fails if its dependency is a dependent of other', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Enabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b'), aLocalExtension('c', { extensionDependencies: ['pub.b'] })]); - instantiationService.stubPromise(IChoiceService, 'choose', 1); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b'); + const extensionC = aLocalExtension('c', { extensionDependencies: ['pub.b'] }); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - - return testObject.setEnablement(testObject.local[0], EnablementState.Disabled).then(() => assert.fail('Should fail'), error => assert.ok(true)); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Enabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + instantiationService.stubPromise(IChoiceService, 'choose', 1); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled).then(() => assert.fail('Should fail'), error => assert.ok(true)); + }); }); test('test disable extension if its dependency is a dependent of other disabled extension', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Disabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b'), aLocalExtension('c', { extensionDependencies: ['pub.b'] })]); - instantiationService.stubPromise(IChoiceService, 'choose', 1); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b'); + const extensionC = aLocalExtension('c', { extensionDependencies: ['pub.b'] }); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Enabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Disabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + instantiationService.stubPromise(IChoiceService, 'choose', 1); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => { + assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + }); + }); }); test('test disable extension if its dependencys dependency is itself', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Enabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b', { extensionDependencies: ['pub.a'] }), aLocalExtension('c')]); - instantiationService.stubPromise(IChoiceService, 'choose', 1); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b', { extensionDependencies: ['pub.a'] }); + const extensionC = aLocalExtension('c'); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Enabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + instantiationService.stubPromise(IChoiceService, 'choose', 1); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => { + assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + }); + }); }); test('test disable extension if its dependency is dependent and is disabled', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Enabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b'), aLocalExtension('c', { extensionDependencies: ['pub.b'] })]); - instantiationService.stubPromise(IChoiceService, 'choose', 1); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b'); + const extensionC = aLocalExtension('c', { extensionDependencies: ['pub.b'] }); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Disabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + instantiationService.stubPromise(IChoiceService, 'choose', 1); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => assert.equal(testObject.local[0].enablementState, EnablementState.Disabled)); + }); }); test('test disable extension with cyclic dependencies', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Enabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Enabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b', { extensionDependencies: ['pub.c'] }), aLocalExtension('c', { extensionDependencies: ['pub.a'] })]); - instantiationService.stubPromise(IChoiceService, 'choose', 1); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b', { extensionDependencies: ['pub.c'] }); + const extensionC = aLocalExtension('c', { extensionDependencies: ['pub.a'] }); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Enabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Enabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Enabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + instantiationService.stubPromise(IChoiceService, 'choose', 1); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => { + assert.equal(testObject.local[0].enablementState, EnablementState.Disabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Disabled); + }); + }); }); test('test enable extension with dependencies enable all', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Disabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b'), aLocalExtension('c')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b'); + const extensionC = aLocalExtension('c'); - testObject.setEnablement(testObject.local[0], EnablementState.Enabled); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Disabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Disabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - assert.equal(testObject.local[0].enablementState, EnablementState.Enabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Enabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Enabled) + .then(() => { + assert.equal(testObject.local[0].enablementState, EnablementState.Enabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Enabled); + }); + }); }); test('test enable extension with cyclic dependencies', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Disabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a', { extensionDependencies: ['pub.b'] }), aLocalExtension('b', { extensionDependencies: ['pub.c'] }), aLocalExtension('c', { extensionDependencies: ['pub.a'] })]); + const extensionA = aLocalExtension('a', { extensionDependencies: ['pub.b'] }); + const extensionB = aLocalExtension('b', { extensionDependencies: ['pub.c'] }); + const extensionC = aLocalExtension('c', { extensionDependencies: ['pub.a'] }); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + return instantiationService.get(IExtensionEnablementService).setEnablement(extensionA, EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionB, EnablementState.Disabled)) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(extensionC, EnablementState.Disabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [extensionA, extensionB, extensionC]); - testObject.setEnablement(testObject.local[0], EnablementState.Enabled); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - assert.equal(testObject.local[0].enablementState, EnablementState.Enabled); - assert.equal(testObject.local[1].enablementState, EnablementState.Enabled); - assert.equal(testObject.local[2].enablementState, EnablementState.Enabled); + return testObject.setEnablement(testObject.local[0], EnablementState.Enabled) + .then(() => { + assert.equal(testObject.local[0].enablementState, EnablementState.Enabled); + assert.equal(testObject.local[1].enablementState, EnablementState.Enabled); + assert.equal(testObject.local[2].enablementState, EnablementState.Enabled); + }); + }); }); test('test change event is fired when disablement flags are changed', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.WorkspaceDisabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - const target = sinon.spy(); - testObject.onChange(target); + return instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('c'), EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('b'), EnablementState.WorkspaceDisabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const target = sinon.spy(); + testObject.onChange(target); - testObject.setEnablement(testObject.local[0], EnablementState.Disabled); - - assert.ok(target.calledOnce); + return testObject.setEnablement(testObject.local[0], EnablementState.Disabled) + .then(() => assert.ok(target.calledOnce)); + }); }); test('test change event is fired when disablement flags are changed from outside', () => { - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.c' }, EnablementState.Disabled); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.b' }, EnablementState.WorkspaceDisabled); - instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [aLocalExtension('a')]); - testObject = instantiationService.createInstance(ExtensionsWorkbenchService); - const target = sinon.spy(); - testObject.onChange(target); + const localExtension = aLocalExtension('a'); + return instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('c'), EnablementState.Disabled) + .then(() => instantiationService.get(IExtensionEnablementService).setEnablement(aLocalExtension('b'), EnablementState.WorkspaceDisabled)) + .then(() => { + instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [localExtension]); + testObject = instantiationService.createInstance(ExtensionsWorkbenchService); + const target = sinon.spy(); + testObject.onChange(target); - instantiationService.get(IExtensionEnablementService).setEnablement({ id: 'pub.a' }, EnablementState.Disabled); - - assert.ok(target.calledOnce); + return instantiationService.get(IExtensionEnablementService).setEnablement(localExtension, EnablementState.Disabled) + .then(() => assert.ok(target.calledOnce)); + }); }); function aLocalExtension(name: string = 'someext', manifest: any = {}, properties: any = {}): ILocalExtension { diff --git a/src/vs/workbench/parts/files/browser/fileResultsNavigation.ts b/src/vs/workbench/parts/files/browser/fileResultsNavigation.ts index 5d7b8dd13b4..46558d347a0 100644 --- a/src/vs/workbench/parts/files/browser/fileResultsNavigation.ts +++ b/src/vs/workbench/parts/files/browser/fileResultsNavigation.ts @@ -60,13 +60,13 @@ export default class FileResultsNavigation extends Disposable { originalEvent.preventDefault(); // focus moves to editor, we need to prevent default } - const sideBySide = (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)); + const sideBySide = (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey || originalEvent.altKey)); const preserveFocus = !((keyboard && (!payload || !payload.preserveFocus)) || pinned || (payload && payload.focusEditor)); this._openFile.fire({ editorOptions: { preserveFocus, pinned, - revealIfVisible: !sideBySide + revealIfVisible: true }, sideBySide, element: this.tree.getSelection()[0], diff --git a/src/vs/workbench/parts/files/browser/files.ts b/src/vs/workbench/parts/files/browser/files.ts new file mode 100644 index 00000000000..09a9d911524 --- /dev/null +++ b/src/vs/workbench/parts/files/browser/files.ts @@ -0,0 +1,59 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import URI from 'vs/base/common/uri'; +import { IListService } from 'vs/platform/list/browser/listService'; +import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { FileStat, OpenEditor } from 'vs/workbench/parts/files/common/explorerModel'; +import { toResource } from 'vs/workbench/common/editor'; +import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; +import { List } from 'vs/base/browser/ui/list/listWidget'; + +// Commands can get exeucted from a command pallete, from a context menu or from some list using a keybinding +// To cover all these cases we need to properly compute the resource on which the command is being executed +export function getResourceForCommand(resource: URI, listService: IListService, editorService: IWorkbenchEditorService): URI { + if (URI.isUri(resource)) { + return resource; + } + + const list = listService.lastFocusedList; + if (list && list.isDOMFocused()) { + const focus = list.getFocus(); + if (focus instanceof FileStat) { + return focus.resource; + } else if (focus instanceof OpenEditor) { + return focus.getResource(); + } + } + + return toResource(editorService.getActiveEditorInput(), { supportSideBySide: true }); +} + +export function getMultiSelectedResources(resource: URI, listService: IListService, editorService: IWorkbenchEditorService): URI[] { + const list = listService.lastFocusedList; + if (list && list.isDOMFocused()) { + // Explorer + if (list instanceof Tree) { + const focus = list.getFocus(); + const selection = list.getSelection(); + if (selection && selection.indexOf(focus) >= 0) { + return selection.map(fs => fs.resource); + } + } + // Open editors view + if (list instanceof List) { + const focus = list.getFocusedElements(); + const selection = list.getSelectedElements(); + if (selection && focus.length && selection.indexOf(focus[0]) >= 0) { + return selection.filter(s => s instanceof OpenEditor).map((oe: OpenEditor) => oe.getResource()); + } + } + } + + const result = getResourceForCommand(resource, listService, editorService); + return !!result ? [result] : []; +} diff --git a/src/vs/workbench/parts/files/common/explorerModel.ts b/src/vs/workbench/parts/files/common/explorerModel.ts index 090251625fc..1b5c744e122 100644 --- a/src/vs/workbench/parts/files/common/explorerModel.ts +++ b/src/vs/workbench/parts/files/common/explorerModel.ts @@ -12,7 +12,7 @@ import { isLinux } from 'vs/base/common/platform'; import { IFileStat, isParent } from 'vs/platform/files/common/files'; import { IEditorInput } from 'vs/platform/editor/common/editor'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IEditorGroup, toResource } from 'vs/workbench/common/editor'; +import { IEditorGroup, toResource, IEditorIdentifier } from 'vs/workbench/common/editor'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { getPathLabel } from 'vs/base/common/labels'; @@ -73,17 +73,15 @@ export class FileStat implements IFileStat { public mtime: number; public etag: string; private _isDirectory: boolean; - public hasChildren: boolean; public children: FileStat[]; public parent: FileStat; public isDirectoryResolved: boolean; - constructor(resource: URI, public root: FileStat, isDirectory?: boolean, hasChildren?: boolean, name: string = getPathLabel(resource), mtime?: number, etag?: string) { + constructor(resource: URI, public root: FileStat, isDirectory?: boolean, name: string = getPathLabel(resource), mtime?: number, etag?: string) { this.resource = resource; this.name = name; this.isDirectory = !!isDirectory; - this.hasChildren = isDirectory && hasChildren; this.etag = etag; this.mtime = mtime; @@ -123,7 +121,7 @@ export class FileStat implements IFileStat { } public static create(raw: IFileStat, root: FileStat, resolveTo?: URI[]): FileStat { - const stat = new FileStat(raw.resource, root, raw.isDirectory, raw.hasChildren, raw.name, raw.mtime, raw.etag); + const stat = new FileStat(raw.resource, root, raw.isDirectory, raw.name, raw.mtime, raw.etag); // Recursively add children if present if (stat.isDirectory) { @@ -141,7 +139,6 @@ export class FileStat implements IFileStat { const child = FileStat.create(raw.children[i], root, resolveTo); child.parent = stat; stat.children.push(child); - stat.hasChildren = stat.children.length > 0; } } } @@ -169,7 +166,6 @@ export class FileStat implements IFileStat { local.resource = disk.resource; local.name = disk.name; local.isDirectory = disk.isDirectory; - local.hasChildren = disk.isDirectory && disk.hasChildren; local.mtime = disk.mtime; local.isDirectoryResolved = disk.isDirectoryResolved; @@ -217,7 +213,6 @@ export class FileStat implements IFileStat { child.updateResource(false); this.children.push(child); - this.hasChildren = this.children.length > 0; } /** @@ -230,8 +225,6 @@ export class FileStat implements IFileStat { break; } } - - this.hasChildren = this.children.length > 0; } /** @@ -256,10 +249,9 @@ export class FileStat implements IFileStat { private updateResource(recursive: boolean): void { this.resource = this.parent.resource.with({ path: paths.join(this.parent.resource.path, this.name) }); - // this.resource = URI.file(paths.join(this.parent.resource.fsPath, this.name)); if (recursive) { - if (this.isDirectory && this.hasChildren && this.children) { + if (this.isDirectory && this.children) { this.children.forEach((child: FileStat) => { child.updateResource(true); }); @@ -293,7 +285,7 @@ export class FileStat implements IFileStat { } // Return if not having any children - if (!this.hasChildren) { + if (!this.children) { return null; } @@ -322,7 +314,7 @@ export class NewStatPlaceholder extends FileStat { private directoryPlaceholder: boolean; constructor(isDirectory: boolean, root: FileStat) { - super(URI.file(''), root, false, false, ''); + super(URI.file(''), root, false, ''); this.id = NewStatPlaceholder.ID++; this.isDirectoryResolved = isDirectory; @@ -335,7 +327,6 @@ export class NewStatPlaceholder extends FileStat { this.isDirectoryResolved = void 0; this.name = void 0; this.isDirectory = void 0; - this.hasChildren = void 0; this.mtime = void 0; } @@ -374,24 +365,22 @@ export class NewStatPlaceholder extends FileStat { child.parent = parent; parent.children.push(child); - parent.hasChildren = parent.children.length > 0; - return child; } } -export class OpenEditor { +export class OpenEditor implements IEditorIdentifier { - constructor(private editor: IEditorInput, private group: IEditorGroup) { + constructor(private _editor: IEditorInput, private _group: IEditorGroup) { // noop } - public get editorInput() { - return this.editor; + public get editor() { + return this._editor; } - public get editorGroup() { - return this.group; + public get group() { + return this._group; } public getId(): string { diff --git a/src/vs/workbench/parts/files/common/files.ts b/src/vs/workbench/parts/files/common/files.ts index 9a538d836bb..3147b323330 100644 --- a/src/vs/workbench/parts/files/common/files.ts +++ b/src/vs/workbench/parts/files/common/files.ts @@ -77,7 +77,6 @@ export interface IFilesConfiguration extends IFilesConfiguration, IWorkbenchEdit explorer: { openEditors: { visible: number; - dynamicHeight: boolean; }; autoReveal: boolean; enableDragAndDrop: boolean; diff --git a/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts b/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts index b7b9b3cd8d8..7dd040a28c2 100644 --- a/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts +++ b/src/vs/workbench/parts/files/electron-browser/explorerViewlet.ts @@ -30,50 +30,31 @@ import { IWorkbenchEditorService, DelegatingWorkbenchEditorService } from 'vs/wo import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/browser/parts/views/viewsRegistry'; +import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/common/views'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorerViewlet { - private static readonly EXPLORER_VIEWS_STATE = 'workbench.explorer.views.state'; +export class ExplorerViewletViewsContribution extends Disposable implements IWorkbenchContribution { - private viewletState: FileViewletState; - private viewletVisibleContextKey: IContextKey; private openEditorsVisibleContextKey: IContextKey; constructor( - @ITelemetryService telemetryService: ITelemetryService, - @IWorkspaceContextService protected contextService: IWorkspaceContextService, - @IStorageService protected storageService: IStorageService, - @IEditorGroupService private editorGroupService: IEditorGroupService, - @IWorkbenchEditorService private editorService: IWorkbenchEditorService, + @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, @IConfigurationService private configurationService: IConfigurationService, - @IInstantiationService protected instantiationService: IInstantiationService, - @IContextKeyService contextKeyService: IContextKeyService, - @IThemeService themeService: IThemeService, - @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService + @IContextKeyService contextKeyService: IContextKeyService ) { - super(VIEWLET_ID, ViewLocation.Explorer, ExplorerViewlet.EXPLORER_VIEWS_STATE, true, telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService); - - this.viewletState = new FileViewletState(); - this.viewletVisibleContextKey = ExplorerViewletVisibleContext.bindTo(contextKeyService); - this.openEditorsVisibleContextKey = OpenEditorsVisibleContext.bindTo(contextKeyService); + super(); this.registerViews(); + + this.openEditorsVisibleContextKey = OpenEditorsVisibleContext.bindTo(contextKeyService); this.updateOpenEditorsVisibility(); + this._register(workspaceContextService.onDidChangeWorkbenchState(() => this.registerViews())); + this._register(workspaceContextService.onDidChangeWorkspaceFolders(() => this.registerViews())); this._register(this.configurationService.onDidChangeConfiguration(e => this.onConfigurationUpdated(e))); - this._register(this.contextService.onDidChangeWorkspaceName(e => this.updateTitleArea())); - this._register(this.contextService.onDidChangeWorkbenchState(() => this.registerViews())); - this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.registerViews())); - } - - async create(parent: Builder): TPromise { - await super.create(parent); - - const el = parent.getHTMLElement(); - DOM.addClass(el, 'explorer-viewlet'); } private registerViews(): void { @@ -92,7 +73,7 @@ export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorer if (!openEditorsViewDescriptorExists) { viewDescriptorsToRegister.push(openEditorsViewDescriptor); } - if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY || this.contextService.getWorkspace().folders.length === 0) { + if (this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY || this.workspaceContextService.getWorkspace().folders.length === 0) { if (explorerViewDescriptorExists) { viewDescriptorsToDeregister.push(explorerViewDescriptor.id); } @@ -157,7 +138,43 @@ export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorer } private updateOpenEditorsVisibility(): void { - this.openEditorsVisibleContextKey.set(this.isOpenEditorsVisible()); + this.openEditorsVisibleContextKey.set(this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY || this.configurationService.getValue('explorer.openEditors.visible') !== 0); + } +} + +export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorerViewlet { + + private static readonly EXPLORER_VIEWS_STATE = 'workbench.explorer.views.state'; + + private viewletState: FileViewletState; + private viewletVisibleContextKey: IContextKey; + + constructor( + @ITelemetryService telemetryService: ITelemetryService, + @IWorkspaceContextService protected contextService: IWorkspaceContextService, + @IStorageService protected storageService: IStorageService, + @IEditorGroupService private editorGroupService: IEditorGroupService, + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, + @IConfigurationService private configurationService: IConfigurationService, + @IInstantiationService protected instantiationService: IInstantiationService, + @IContextKeyService contextKeyService: IContextKeyService, + @IThemeService themeService: IThemeService, + @IContextMenuService contextMenuService: IContextMenuService, + @IExtensionService extensionService: IExtensionService + ) { + super(VIEWLET_ID, ViewLocation.Explorer, ExplorerViewlet.EXPLORER_VIEWS_STATE, true, telemetryService, storageService, instantiationService, themeService, contextService, contextKeyService, contextMenuService, extensionService); + + this.viewletState = new FileViewletState(); + this.viewletVisibleContextKey = ExplorerViewletVisibleContext.bindTo(contextKeyService); + + this._register(this.contextService.onDidChangeWorkspaceName(e => this.updateTitleArea())); + } + + async create(parent: Builder): TPromise { + await super.create(parent); + + const el = parent.getHTMLElement(); + DOM.addClass(el, 'explorer-viewlet'); } private isOpenEditorsVisible(): boolean { @@ -226,67 +243,6 @@ export class ExplorerViewlet extends PersistentViewsViewlet implements IExplorer return super.setVisible(visible); } - public focus(): void { - const hasOpenedEditors = !!this.editorGroupService.getStacksModel().activeGroup; - - let openEditorsView = this.getOpenEditorsView(); - if (this.lastFocusedPanel && this.lastFocusedPanel.isExpanded() && this.hasSelectionOrFocus(this.lastFocusedPanel as ViewsViewletPanel)) { - if (this.lastFocusedPanel !== openEditorsView || hasOpenedEditors) { - this.lastFocusedPanel.focus(); - return; - } - } - - if (this.hasSelectionOrFocus(openEditorsView) && hasOpenedEditors) { - return openEditorsView.focus(); - } - - let explorerView = this.getExplorerView(); - if (this.hasSelectionOrFocus(explorerView)) { - return explorerView.focus(); - } - - if (openEditorsView && openEditorsView.isExpanded() && hasOpenedEditors) { - return openEditorsView.focus(); // we have entries in the opened editors view to focus on - } - - if (explorerView && explorerView.isExpanded()) { - return explorerView.focus(); - } - - let emptyView = this.getEmptyView(); - if (emptyView && emptyView.isExpanded()) { - return emptyView.focusBody(); - } - - super.focus(); - } - - private hasSelectionOrFocus(view: ViewsViewletPanel): boolean { - if (!view) { - return false; - } - - if (!view.isExpanded()) { - return false; - } - - if (view instanceof ExplorerView) { - const viewer = view.getViewer(); - if (!viewer) { - return false; - } - - return !!viewer.getFocus() || (viewer.getSelection() && viewer.getSelection().length > 0); - - } - if (view instanceof OpenEditorsView && !!view.getList()) { - return view.getList().isDOMFocused(); - } - - return false; - } - public getActionRunner(): IActionRunner { if (!this.actionRunner) { this.actionRunner = new ActionRunner(this.viewletState); diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts index 81a173321f7..0ef23baac4c 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.contribution.ts @@ -6,22 +6,23 @@ import nls = require('vs/nls'); import { Registry } from 'vs/platform/registry/common/platform'; -import { GlobalNewUntitledFileAction, ShowOpenedFileInNewWindow, CopyPathAction, FocusOpenEditorsView, FocusFilesExplorer, GlobalCompareResourcesAction, GlobalNewFileAction, GlobalNewFolderAction, SaveAllAction, ShowActiveFileInExplorer, CollapseExplorerView, RefreshExplorerView, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler } from 'vs/workbench/parts/files/electron-browser/fileActions'; +import { GlobalNewUntitledFileAction, ShowOpenedFileInNewWindow, CopyPathAction, FocusOpenEditorsView, FocusFilesExplorer, GlobalCompareResourcesAction, SaveAllAction, ShowActiveFileInExplorer, CollapseExplorerView, RefreshExplorerView, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler } from 'vs/workbench/parts/files/electron-browser/fileActions'; import { revertLocalChangesCommand, acceptLocalChangesCommand, CONFLICT_RESOLUTION_CONTEXT } from 'vs/workbench/parts/files/electron-browser/saveErrorHandler'; import { SyncActionDescriptor, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; -import { openWindowCommand, REVEAL_IN_OS_COMMAND_ID, COPY_PATH_COMMAND_ID, REVEAL_IN_EXPLORER_COMMAND_ID, OPEN_TO_SIDE_COMMAND_ID, REVERT_FILE_COMMAND_ID, SAVE_FILE_COMMAND_ID, SAVE_FILE_LABEL, SAVE_FILE_AS_COMMAND_ID, SAVE_FILE_AS_LABEL, SAVE_ALL_IN_GROUP_COMMAND_ID, OpenEditorsGroupContext, COMPARE_WITH_SAVED_COMMAND_ID, COMPARE_RESOURCE_COMMAND_ID, SELECT_FOR_COMPARE_COMMAND_ID, ResourceSelectedForCompareContext, REVEAL_IN_OS_LABEL, DirtyEditorContext } from 'vs/workbench/parts/files/electron-browser/fileCommands'; +import { openWindowCommand, REVEAL_IN_OS_COMMAND_ID, COPY_PATH_COMMAND_ID, REVEAL_IN_EXPLORER_COMMAND_ID, OPEN_TO_SIDE_COMMAND_ID, REVERT_FILE_COMMAND_ID, SAVE_FILE_COMMAND_ID, SAVE_FILE_LABEL, SAVE_FILE_AS_COMMAND_ID, SAVE_FILE_AS_LABEL, SAVE_ALL_IN_GROUP_COMMAND_ID, OpenEditorsGroupContext, COMPARE_WITH_SAVED_COMMAND_ID, COMPARE_RESOURCE_COMMAND_ID, SELECT_FOR_COMPARE_COMMAND_ID, ResourceSelectedForCompareContext, REVEAL_IN_OS_LABEL, DirtyEditorContext, COMPARE_SELECTED_COMMAND_ID, REMOVE_ROOT_FOLDER_COMMAND_ID, REMOVE_ROOT_FOLDER_LABEL, SAVE_FILES_COMMAND_ID } from 'vs/workbench/parts/files/electron-browser/fileCommands'; import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { isWindows, isMacintosh } from 'vs/base/common/platform'; -import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext } from 'vs/workbench/parts/files/common/files'; -import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL, REMOVE_ROOT_FOLDER_COMMAND_ID, REMOVE_ROOT_FOLDER_LABEL } from 'vs/workbench/browser/actions/workspaceCommands'; +import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerFocusedContext } from 'vs/workbench/parts/files/common/files'; +import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL } from 'vs/workbench/browser/actions/workspaceCommands'; import { CLOSE_UNMODIFIED_EDITORS_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; import { OPEN_FOLDER_SETTINGS_COMMAND, OPEN_FOLDER_SETTINGS_LABEL } from 'vs/workbench/parts/preferences/browser/preferencesActions'; import { AutoSaveContext } from 'vs/workbench/services/textfile/common/textfiles'; import { ResourceContextKey } from 'vs/workbench/common/resources'; +import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService'; // Contribute Global Actions @@ -29,8 +30,6 @@ const category = nls.localize('filesCategory', "File"); const registry = Registry.as(ActionExtensions.WorkbenchActions); registry.registerWorkbenchAction(new SyncActionDescriptor(SaveAllAction, SaveAllAction.ID, SaveAllAction.LABEL, { primary: void 0, mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_S }, win: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_S) } }), 'File: Save All', category); -registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalNewFileAction, GlobalNewFileAction.ID, GlobalNewFileAction.LABEL), 'File: New File', category); -registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalNewFolderAction, GlobalNewFolderAction.ID, GlobalNewFolderAction.LABEL), 'File: New Folder', category); registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalCompareResourcesAction, GlobalCompareResourcesAction.ID, GlobalCompareResourcesAction.LABEL), 'File: Compare Active File With...', category); registry.registerWorkbenchAction(new SyncActionDescriptor(FocusOpenEditorsView, FocusOpenEditorsView.ID, FocusOpenEditorsView.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_E) }), 'File: Focus on Open Editors View', category); registry.registerWorkbenchAction(new SyncActionDescriptor(FocusFilesExplorer, FocusFilesExplorer.ID, FocusFilesExplorer.LABEL), 'File: Focus on Files Explorer', category); @@ -102,16 +101,16 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ }); // Editor Title Context Menu -appendEditorTitleContextMenuItem(REVEAL_IN_OS_COMMAND_ID, REVEAL_IN_OS_LABEL); -appendEditorTitleContextMenuItem(COPY_PATH_COMMAND_ID, CopyPathAction.LABEL); -appendEditorTitleContextMenuItem(REVEAL_IN_EXPLORER_COMMAND_ID, nls.localize('revealInSideBar', "Reveal in Side Bar")); +appendEditorTitleContextMenuItem(REVEAL_IN_OS_COMMAND_ID, REVEAL_IN_OS_LABEL, ResourceContextKey.Scheme.isEqualTo('file')); +appendEditorTitleContextMenuItem(COPY_PATH_COMMAND_ID, CopyPathAction.LABEL, ResourceContextKey.IsFile); +appendEditorTitleContextMenuItem(REVEAL_IN_EXPLORER_COMMAND_ID, nls.localize('revealInSideBar', "Reveal in Side Bar"), ResourceContextKey.IsFile); -function appendEditorTitleContextMenuItem(id: string, title: string): void { +function appendEditorTitleContextMenuItem(id: string, title: string, when: ContextKeyExpr): void { // Menu MenuRegistry.appendMenuItem(MenuId.EditorTitleContext, { command: { id, title }, - when: ContextKeyExpr.equals('resourceScheme', 'file'), + when, group: '2_files' }); } @@ -136,23 +135,28 @@ function appendSaveConflictEditorTitleAction(id: string, title: string, iconClas // Menu registration - command palette -function appendToCommandPalette(id: string, title: string, category: string): void { +function appendToCommandPalette(id: string, title: string, category: string, when?: ContextKeyExpr): void { MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id, title, category - } + }, + when }); } appendToCommandPalette(COPY_PATH_COMMAND_ID, nls.localize('copyPathOfActive', "Copy Path of Active File"), category); appendToCommandPalette(SAVE_FILE_COMMAND_ID, SAVE_FILE_LABEL, category); appendToCommandPalette(SAVE_ALL_IN_GROUP_COMMAND_ID, nls.localize('saveAllInGroup', "Save All in Group"), category); +appendToCommandPalette(SAVE_FILES_COMMAND_ID, nls.localize('saveFiles', "Save All Files"), category); appendToCommandPalette(REVERT_FILE_COMMAND_ID, nls.localize('revert', "Revert File"), category); appendToCommandPalette(COMPARE_WITH_SAVED_COMMAND_ID, nls.localize('compareActiveWithSaved', "Compare Active File with Saved"), category); appendToCommandPalette(REVEAL_IN_OS_COMMAND_ID, REVEAL_IN_OS_LABEL, category); appendToCommandPalette(SAVE_FILE_AS_COMMAND_ID, SAVE_FILE_AS_LABEL, category); appendToCommandPalette(CLOSE_EDITOR_COMMAND_ID, nls.localize('closeEditor', "Close Editor"), nls.localize('view', "View")); +appendToCommandPalette(NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, category, ExplorerFocusedContext); +appendToCommandPalette(NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, category, ExplorerFocusedContext); + // Menu registration - open editors @@ -187,7 +191,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: 'navigation', order: 40, command: copyPathCommand, - when: ResourceContextKey.HasResource + when: ResourceContextKey.IsFile }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -238,7 +242,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { title: nls.localize('compareWithSaved', "Compare with Saved"), precondition: DirtyEditorContext }, - when: ContextKeyExpr.and(ResourceContextKey.IsFile, AutoSaveContext.notEqualsTo('afterDelay')) + when: ContextKeyExpr.and(ResourceContextKey.IsFile, AutoSaveContext.notEqualsTo('afterDelay'), WorkbenchListDoubleSelection.toNegated()) }); const compareResourceCommand = { @@ -249,7 +253,7 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: '3_compare', order: 20, command: compareResourceCommand, - when: ContextKeyExpr.and(ResourceContextKey.HasResource, ResourceSelectedForCompareContext) + when: ContextKeyExpr.and(ResourceContextKey.IsFile, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated()) }); const selectForCompareCommand = { @@ -260,7 +264,18 @@ MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { group: '3_compare', order: 30, command: selectForCompareCommand, - when: ResourceContextKey.HasResource + when: ContextKeyExpr.and(ResourceContextKey.IsFile, WorkbenchListDoubleSelection.toNegated()) +}); + +const compareSelectedCommand = { + id: COMPARE_SELECTED_COMMAND_ID, + title: nls.localize('compareSelected', "Compare Selected") +}; +MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { + group: '3_compare', + order: 30, + command: compareSelectedCommand, + when: ContextKeyExpr.and(ResourceContextKey.IsFile, WorkbenchListDoubleSelection) }); MenuRegistry.appendMenuItem(MenuId.OpenEditorsContext, { @@ -327,28 +342,35 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { group: 'navigation', order: 10, command: openToSideCommand, - when: ContextKeyExpr.and(ResourceContextKey.Scheme.isEqualTo('file'), ExplorerFolderContext.toNegated()) + when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.HasResource) }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { group: 'navigation', order: 20, command: revealInOsCommand, - when: ResourceContextKey.HasResource + when: ResourceContextKey.Scheme.isEqualTo('file') }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { group: '3_compare', order: 20, command: compareResourceCommand, - when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.IsFile, ResourceSelectedForCompareContext) + when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.IsFile, ResourceSelectedForCompareContext, WorkbenchListDoubleSelection.toNegated()) }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { group: '3_compare', order: 30, command: selectForCompareCommand, - when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.IsFile) + when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.IsFile, WorkbenchListDoubleSelection.toNegated()) +}); + +MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { + group: '3_compare', + order: 30, + command: compareSelectedCommand, + when: ContextKeyExpr.and(ExplorerFolderContext.toNegated(), ResourceContextKey.IsFile, WorkbenchListDoubleSelection) }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { @@ -376,7 +398,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { group: '5_cutcopypaste', order: 30, command: copyPathCommand, - when: ResourceContextKey.Scheme.isEqualTo('file') + when: ResourceContextKey.IsFile }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { diff --git a/src/vs/workbench/parts/files/electron-browser/fileActions.ts b/src/vs/workbench/parts/files/electron-browser/fileActions.ts index d39e684d6c7..e80a6804eb1 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileActions.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileActions.ts @@ -37,11 +37,11 @@ import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IUntitledResourceInput } from 'vs/platform/editor/common/editor'; import { IInstantiationService, IConstructorSignature2, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IMessageService, IMessageWithAction, IConfirmation, Severity, CancelAction, IConfirmationResult } from 'vs/platform/message/common/message'; +import { IMessageService, IMessageWithAction, IConfirmation, Severity, CancelAction, IConfirmationResult, getConfirmMessage } from 'vs/platform/message/common/message'; import { ITextModel } from 'vs/editor/common/model'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { IWindowsService } from 'vs/platform/windows/common/windows'; -import { COPY_PATH_COMMAND_ID, REVEAL_IN_EXPLORER_COMMAND_ID, SAVE_ALL_COMMAND_ID, SAVE_ALL_LABEL, SAVE_FILES_COMMAND_ID, SAVE_FILES_LABEL, SAVE_ALL_IN_GROUP_COMMAND_ID } from 'vs/workbench/parts/files/electron-browser/fileCommands'; +import { COPY_PATH_COMMAND_ID, REVEAL_IN_EXPLORER_COMMAND_ID, SAVE_ALL_COMMAND_ID, SAVE_ALL_LABEL, SAVE_ALL_IN_GROUP_COMMAND_ID } from 'vs/workbench/parts/files/electron-browser/fileCommands'; import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { once } from 'vs/base/common/event'; @@ -51,6 +51,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IListService, ListWidget } from 'vs/platform/list/browser/listService'; import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { distinctParents } from 'vs/base/common/resources'; export interface IEditableData { action: IAction; @@ -63,10 +64,10 @@ export interface IFileViewletState { clearEditable(stat: IFileStat): void; } -export const NEW_FILE_COMMAND_ID = 'workbench.command.files.newFile'; +export const NEW_FILE_COMMAND_ID = 'explorer.newFile'; export const NEW_FILE_LABEL = nls.localize('newFile', "New File"); -export const NEW_FOLDER_COMMAND_ID = 'workbench.command.files.newFolder'; +export const NEW_FOLDER_COMMAND_ID = 'explorer.newFolder'; export const NEW_FOLDER_LABEL = nls.localize('newFolder', "New Folder"); export const TRIGGER_RENAME_LABEL = nls.localize('rename', "Rename"); @@ -537,26 +538,6 @@ export class GlobalNewUntitledFileAction extends Action { } } -/* Create new file from anywhere */ -export class GlobalNewFileAction extends BaseGlobalNewAction { - public static readonly ID = 'explorer.newFile'; - public static readonly LABEL = nls.localize('newFile', "New File"); - - protected getAction(): IConstructorSignature2 { - return NewFileAction; - } -} - -/* Create new folder from anywhere */ -export class GlobalNewFolderAction extends BaseGlobalNewAction { - public static readonly ID = 'explorer.newFolder'; - public static readonly LABEL = nls.localize('newFolder', "New Folder"); - - protected getAction(): IConstructorSignature2 { - return NewFolderAction; - } -} - /* Create New File/Folder (only used internally by explorerViewer) */ export abstract class BaseCreateAction extends BaseRenameAction { @@ -626,14 +607,12 @@ class BaseDeleteFileAction extends BaseFileAction { private static readonly CONFIRM_DELETE_SETTING_KEY = 'explorer.confirmDelete'; - private tree: ITree; - private useTrash: boolean; private skipConfirm: boolean; constructor( - tree: ITree, - element: FileStat, - useTrash: boolean, + private tree: ITree, + private elements: FileStat[], + private useTrash: boolean, @IFileService fileService: IFileService, @IMessageService messageService: IMessageService, @ITextFileService textFileService: ITextFileService, @@ -642,13 +621,12 @@ class BaseDeleteFileAction extends BaseFileAction { super('moveFileToTrash', MOVE_FILE_TO_TRASH_LABEL, fileService, messageService, textFileService); this.tree = tree; - this.element = element; - this.useTrash = useTrash && !paths.isUNC(element.resource.fsPath); // on UNC shares there is no trash + this.useTrash = useTrash && elements.every(e => !paths.isUNC(e.resource.fsPath)); // on UNC shares there is no trash this._updateEnablement(); } - public run(context?: any): TPromise { + public run(): TPromise { // Remove highlight if (this.tree) { @@ -662,12 +640,16 @@ class BaseDeleteFileAction extends BaseFileAction { primaryButton = nls.localize({ key: 'deleteButtonLabel', comment: ['&& denotes a mnemonic'] }, "&&Delete"); } + const distinctElements = distinctParents(this.elements, e => e.resource); + // Handle dirty let confirmDirtyPromise: TPromise = TPromise.as(true); - const dirty = this.textFileService.getDirty().filter(d => resources.isEqualOrParent(d, this.element.resource, !isLinux /* ignorecase */)); + const dirty = this.textFileService.getDirty().filter(d => distinctElements.some(e => resources.isEqualOrParent(d, e.resource, !isLinux /* ignorecase */))); if (dirty.length) { let message: string; - if (this.element.isDirectory) { + if (distinctElements.length > 1) { + message = nls.localize('dirtyMessageFilesDelete', "You are deleting files with unsaved changes. Do you want to continue?"); + } else if (distinctElements[0].isDirectory) { if (dirty.length === 1) { message = nls.localize('dirtyMessageFolderOneDelete', "You are deleting a folder with unsaved changes in 1 file. Do you want to continue?"); } else { @@ -707,8 +689,11 @@ class BaseDeleteFileAction extends BaseFileAction { // Confirm for moving to trash else if (this.useTrash) { + const message = distinctElements.length > 1 ? getConfirmMessage(nls.localize('confirmMoveTrashMessageMultiple', "Are you sure you want to delete the following {0} files?", distinctElements.length), distinctElements.map(e => e.resource)) + : distinctElements[0].isDirectory ? nls.localize('confirmMoveTrashMessageFolder', "Are you sure you want to delete '{0}' and its contents?", distinctElements[0].name) + : nls.localize('confirmMoveTrashMessageFile', "Are you sure you want to delete '{0}'?", distinctElements[0].name); confirmDeletePromise = this.messageService.confirmWithCheckbox({ - message: this.element.isDirectory ? nls.localize('confirmMoveTrashMessageFolder', "Are you sure you want to delete '{0}' and its contents?", this.element.name) : nls.localize('confirmMoveTrashMessageFile', "Are you sure you want to delete '{0}'?", this.element.name), + message, detail: isWindows ? nls.localize('undoBin', "You can restore from the recycle bin.") : nls.localize('undoTrash', "You can restore from the trash."), primaryButton, checkbox: { @@ -720,8 +705,11 @@ class BaseDeleteFileAction extends BaseFileAction { // Confirm for deleting permanently else { + const message = distinctElements.length > 1 ? getConfirmMessage(nls.localize('confirmDeleteMessageMultiple', "Are you sure you want to permanently delete the following {0} files?", distinctElements.length), distinctElements.map(e => e.resource)) + : distinctElements[0].isDirectory ? nls.localize('confirmDeleteMessageFolder', "Are you sure you want to permanently delete '{0}' and its contents?", distinctElements[0].name) + : nls.localize('confirmDeleteMessageFile', "Are you sure you want to permanently delete '{0}'?", distinctElements[0].name); confirmDeletePromise = this.messageService.confirmWithCheckbox({ - message: this.element.isDirectory ? nls.localize('confirmDeleteMessageFolder', "Are you sure you want to permanently delete '{0}' and its contents?", this.element.name) : nls.localize('confirmDeleteMessageFile', "Are you sure you want to permanently delete '{0}'?", this.element.name), + message, detail: nls.localize('irreversible', "This action is irreversible!"), primaryButton, type: 'warning' @@ -744,9 +732,9 @@ class BaseDeleteFileAction extends BaseFileAction { } // Call function - const servicePromise = this.fileService.del(this.element.resource, this.useTrash).then(() => { - if (this.element.parent) { - this.tree.setFocus(this.element.parent); // move focus to parent + const servicePromise = TPromise.join(distinctElements.map(e => this.fileService.del(e.resource, this.useTrash))).then(() => { + if (distinctElements[0].parent) { + this.tree.setFocus(distinctElements[0].parent); // move focus to parent } }, (error: any) => { @@ -885,7 +873,7 @@ export class ImportFileAction extends BaseFileAction { } // Copy File/Folder -let fileToCopy: FileStat; +let filesToCopy: FileStat[]; let fileCopiedContextKey: IContextKey; class CopyFileAction extends BaseFileAction { @@ -893,7 +881,7 @@ class CopyFileAction extends BaseFileAction { private tree: ITree; constructor( tree: ITree, - element: FileStat, + private elements: FileStat[], @IFileService fileService: IFileService, @IMessageService messageService: IMessageService, @ITextFileService textFileService: ITextFileService, @@ -902,7 +890,6 @@ class CopyFileAction extends BaseFileAction { super('filesExplorer.copy', COPY_FILE_LABEL, fileService, messageService, textFileService); this.tree = tree; - this.element = element; if (!fileCopiedContextKey) { fileCopiedContextKey = FileCopiedContext.bindTo(contextKeyService); } @@ -912,8 +899,8 @@ class CopyFileAction extends BaseFileAction { public run(): TPromise { // Remember as file/folder to copy - fileToCopy = this.element; - fileCopiedContextKey.set(!!this.element); + filesToCopy = this.elements; + fileCopiedContextKey.set(!!filesToCopy.length); // Remove highlight if (this.tree) { @@ -952,7 +939,7 @@ class PasteFileAction extends BaseFileAction { this._updateEnablement(); } - public run(): TPromise { + public run(fileToCopy: FileStat): TPromise { const exists = fileToCopy.root.find(fileToCopy.resource); if (!exists) { @@ -1212,20 +1199,6 @@ export class SaveAllInGroupAction extends BaseSaveAllAction { } } -export class SaveFilesAction extends BaseSaveAllAction { - - public static readonly ID = 'workbench.action.files.saveFiles'; - public static readonly LABEL = SAVE_FILES_LABEL; - - protected doRun(context: any): TPromise { - return this.commandService.executeCommand(SAVE_FILES_COMMAND_ID, false); - } - - protected includeUntitled(): boolean { - return false; - } -} - export class FocusOpenEditorsView extends Action { public static readonly ID = 'workbench.files.action.focusOpenEditorsView'; @@ -1533,11 +1506,17 @@ if (!diag) { interface IExplorerContext { viewletState: IFileViewletState; stat: FileStat; + selection: FileStat[]; } -function getContext(tree: ListWidget, viewletService: IViewletService): IExplorerContext { +function getContext(listWidget: ListWidget, viewletService: IViewletService): IExplorerContext { // These commands can only be triggered when explorer viewlet is visible so get it using the active viewlet - return { stat: tree.getFocus(), viewletState: (viewletService.getActiveViewlet()).getViewletState() }; + const tree = listWidget; + const stat = tree.getFocus(); + const selection = tree.getSelection(); + + // Only respect the selection if user clicked inside it (focus belongs to it) + return { stat, selection: selection && selection.indexOf(stat) >= 0 ? selection : [], viewletState: (viewletService.getActiveViewlet()).getViewletState() }; } // TODO@isidor these commands are calling into actions due to the complex inheritance action structure. @@ -1575,38 +1554,43 @@ export const renameHandler = (accessor: ServicesAccessor) => { return renameAction.run(explorerContext); }; -export const moveFileToTrashHandler = (accessor) => { +export const moveFileToTrashHandler = (accessor: ServicesAccessor) => { const instantationService = accessor.get(IInstantiationService); const listService = accessor.get(IListService); const explorerContext = getContext(listService.lastFocusedList, accessor.get(IViewletService)); + const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; - const moveFileToTrashAction = instantationService.createInstance(BaseDeleteFileAction, listService.lastFocusedList, explorerContext.stat, true); - return moveFileToTrashAction.run(explorerContext); + const moveFileToTrashAction = instantationService.createInstance(BaseDeleteFileAction, listService.lastFocusedList, stats, true); + return moveFileToTrashAction.run(); }; -export const deleteFileHandler = (accessor) => { +export const deleteFileHandler = (accessor: ServicesAccessor) => { const instantationService = accessor.get(IInstantiationService); const listService = accessor.get(IListService); const explorerContext = getContext(listService.lastFocusedList, accessor.get(IViewletService)); + const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; - const deleteFileAction = instantationService.createInstance(BaseDeleteFileAction, listService.lastFocusedList, explorerContext.stat, false); - return deleteFileAction.run(explorerContext); + const deleteFileAction = instantationService.createInstance(BaseDeleteFileAction, listService.lastFocusedList, stats, false); + return deleteFileAction.run(); }; -export const copyFileHandler = (accessor) => { +export const copyFileHandler = (accessor: ServicesAccessor) => { const instantationService = accessor.get(IInstantiationService); const listService = accessor.get(IListService); const explorerContext = getContext(listService.lastFocusedList, accessor.get(IViewletService)); + const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; - const copyFileAction = instantationService.createInstance(CopyFileAction, listService.lastFocusedList, explorerContext.stat); + const copyFileAction = instantationService.createInstance(CopyFileAction, listService.lastFocusedList, stats); return copyFileAction.run(); }; -export const pasteFileHandler = (accessor) => { +export const pasteFileHandler = (accessor: ServicesAccessor) => { const instantationService = accessor.get(IInstantiationService); const listService = accessor.get(IListService); const explorerContext = getContext(listService.lastFocusedList, accessor.get(IViewletService)); - const pasteFileAction = instantationService.createInstance(PasteFileAction, listService.lastFocusedList, explorerContext.stat); - return pasteFileAction.run(); + return TPromise.join(distinctParents(filesToCopy, s => s.resource).map(toCopy => { + const pasteFileAction = instantationService.createInstance(PasteFileAction, listService.lastFocusedList, explorerContext.stat); + return pasteFileAction.run(toCopy); + })); }; diff --git a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts index 6f4b3a5486e..b562912f181 100644 --- a/src/vs/workbench/parts/files/electron-browser/fileCommands.ts +++ b/src/vs/workbench/parts/files/electron-browser/fileCommands.ts @@ -12,13 +12,13 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as labels from 'vs/base/common/labels'; import URI from 'vs/base/common/uri'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { toResource, IEditorContext } from 'vs/workbench/common/editor'; +import { toResource, IEditorIdentifier } from 'vs/workbench/common/editor'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { ExplorerFocusCondition, FileOnDiskContentProvider, VIEWLET_ID } from 'vs/workbench/parts/files/common/files'; import { ExplorerViewlet } from 'vs/workbench/parts/files/electron-browser/explorerViewlet'; -import { VIEWLET_ID, ExplorerFocusCondition, FileOnDiskContentProvider } from 'vs/workbench/parts/files/common/files'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService'; import { IMessageService, Severity } from 'vs/platform/message/common/message'; @@ -38,17 +38,22 @@ import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRe import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes'; import { isWindows, isMacintosh } from 'vs/base/common/platform'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; -import { FileStat, OpenEditor } from 'vs/workbench/parts/files/common/explorerModel'; +import { sequence } from 'vs/base/common/async'; +import { getResourceForCommand, getMultiSelectedResources } from 'vs/workbench/parts/files/browser/files'; +import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; +import { getMultiSelectedEditorContexts } from 'vs/workbench/browser/parts/editor/editorCommands'; // Commands export const REVEAL_IN_OS_COMMAND_ID = 'revealFileInOS'; export const REVEAL_IN_OS_LABEL = isWindows ? nls.localize('revealInWindows', "Reveal in Explorer") : isMacintosh ? nls.localize('revealInMac', "Reveal in Finder") : nls.localize('openContainer', "Open Containing Folder"); -export const REVEAL_IN_EXPLORER_COMMAND_ID = 'workbench.command.files.revealInExplorer'; +export const REVEAL_IN_EXPLORER_COMMAND_ID = 'revealInExplorer'; export const REVERT_FILE_COMMAND_ID = 'workbench.action.files.revert'; export const OPEN_TO_SIDE_COMMAND_ID = 'explorer.openToSide'; -export const SELECT_FOR_COMPARE_COMMAND_ID = 'workbench.files.command.selectForCompare'; -export const COMPARE_RESOURCE_COMMAND_ID = 'workbench.files.command.compareFiles'; +export const SELECT_FOR_COMPARE_COMMAND_ID = 'selectForCompare'; + +export const COMPARE_SELECTED_COMMAND_ID = 'compareSelected'; +export const COMPARE_RESOURCE_COMMAND_ID = 'compareFiles'; export const COMPARE_WITH_SAVED_COMMAND_ID = 'workbench.files.action.compareWithSaved'; export const COPY_PATH_COMMAND_ID = 'copyFilePath'; @@ -57,43 +62,25 @@ export const SAVE_FILE_AS_LABEL = nls.localize('saveAs', "Save As..."); export const SAVE_FILE_COMMAND_ID = 'workbench.action.files.save'; export const SAVE_FILE_LABEL = nls.localize('save', "Save"); -export const SAVE_ALL_COMMAND_ID = 'workbench.command.files.saveAll'; +export const SAVE_ALL_COMMAND_ID = 'saveAll'; export const SAVE_ALL_LABEL = nls.localize('saveAll', "Save All"); export const SAVE_ALL_IN_GROUP_COMMAND_ID = 'workbench.files.action.saveAllInGroup'; -export const SAVE_FILES_COMMAND_ID = 'workbench.command.files.saveFiles'; -export const SAVE_FILES_LABEL = nls.localize('saveFiles', "Save All Files"); +export const SAVE_FILES_COMMAND_ID = 'workbench.action.files.saveFiles'; export const OpenEditorsGroupContext = new RawContextKey('groupFocusedInOpenEditors', false); export const DirtyEditorContext = new RawContextKey('dirtyEditor', false); export const ResourceSelectedForCompareContext = new RawContextKey('resourceSelectedForCompare', false); +export const REMOVE_ROOT_FOLDER_COMMAND_ID = 'removeRootFolder'; +export const REMOVE_ROOT_FOLDER_LABEL = nls.localize('removeFolderFromWorkspace', "Remove Folder from Workspace"); + export const openWindowCommand = (accessor: ServicesAccessor, paths: string[], forceNewWindow: boolean) => { const windowsService = accessor.get(IWindowsService); windowsService.openWindow(paths, { forceNewWindow }); }; -// Commands can get exeucted from a command pallete, from a context menu or from some list using a keybinding -// To cover all these cases we need to properly compute the resource on which the command is being executed -export function getResourceForCommand(resource: URI, listService: IListService, editorService: IWorkbenchEditorService): URI { - if (URI.isUri(resource)) { - return resource; - } - - const list = listService.lastFocusedList; - if (list && list.isDOMFocused()) { - const focus = list.getFocus(); - if (focus instanceof FileStat) { - return focus.resource; - } else if (focus instanceof OpenEditor) { - return focus.editorInput.getResource(); - } - } - - return toResource(editorService.getActiveEditorInput(), { supportSideBySide: true }); -} - function save(resource: URI, isSaveAs: boolean, editorService: IWorkbenchEditorService, fileService: IFileService, untitledEditorService: IUntitledEditorService, textFileService: ITextFileService, editorGroupService: IEditorGroupService): TPromise { @@ -257,10 +244,10 @@ CommandsRegistry.registerCommand({ const editorService = accessor.get(IWorkbenchEditorService); const textFileService = accessor.get(ITextFileService); const messageService = accessor.get(IMessageService); - resource = getResourceForCommand(resource, accessor.get(IListService), editorService); + const resources = getMultiSelectedResources(resource, accessor.get(IListService), editorService); if (resource && resource.scheme !== 'untitled') { - return textFileService.revert(resource, { force: true }).then(null, error => { + return textFileService.revertAll(resources, { force: true }).then(null, error => { messageService.show(Severity.Error, nls.localize('genericRevertError', "Failed to revert '{0}': {1}", basename(resource.fsPath), toErrorMessage(error, false))); }); } @@ -280,7 +267,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const editorService = accessor.get(IWorkbenchEditorService); const listService = accessor.get(IListService); const tree = listService.lastFocusedList; - resource = getResourceForCommand(resource, listService, editorService); + const resources = getMultiSelectedResources(resource, listService, editorService); // Remove highlight if (tree instanceof Tree) { @@ -288,8 +275,15 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } // Set side input - if (URI.isUri(resource)) { - return editorService.openEditor({ resource, options: { preserveFocus: false } }, true); + if (resources.length) { + return editorService.openEditors(resources.map(resource => { + return { + input: { + resource, + options: { preserveFocus: false } + } + }; + }), true); } return TPromise.as(true); @@ -346,6 +340,19 @@ CommandsRegistry.registerCommand({ } }); +CommandsRegistry.registerCommand({ + id: COMPARE_SELECTED_COMMAND_ID, + handler: (accessor, resource: URI) => { + const editorService = accessor.get(IWorkbenchEditorService); + const resources = getMultiSelectedResources(resource, accessor.get(IListService), editorService); + + return editorService.openEditor({ + leftResource: resources[0], + rightResource: resources[1] + }); + } +}); + CommandsRegistry.registerCommand({ id: COMPARE_RESOURCE_COMMAND_ID, handler: (accessor, resource: URI) => { @@ -366,11 +373,11 @@ CommandsRegistry.registerCommand({ const revealInOSHandler = (accessor: ServicesAccessor, resource: URI) => { // Without resource, try to look at the active editor - resource = getResourceForCommand(resource, accessor.get(IListService), accessor.get(IWorkbenchEditorService)); + const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IWorkbenchEditorService)); - if (resource) { + if (resources.length) { const windowsService = accessor.get(IWindowsService); - windowsService.showItemInFolder(paths.normalize(resource.fsPath, true)); + sequence(resources.map(r => () => windowsService.showItemInFolder(paths.normalize(r.fsPath, true)))); } else { const messageService = accessor.get(IMessageService); messageService.show(severity.Info, nls.localize('openFileToReveal', "Open a file first to reveal")); @@ -393,6 +400,18 @@ CommandsRegistry.registerCommand({ handler: revealInOSHandler }); +const copyPathHandler = (accessor, resource: URI) => { + const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IWorkbenchEditorService)); + if (resources.length) { + const clipboardService = accessor.get(IClipboardService); + const text = resources.map(r => r.scheme === 'file' ? labels.getPathLabel(r) : r.toString()).join('\n'); + clipboardService.writeText(text); + } else { + const messageService = accessor.get(IMessageService); + messageService.show(severity.Info, nls.localize('openFileToCopy', "Open a file first to copy its path")); + } +}; + KeybindingsRegistry.registerCommandAndKeybindingRule({ weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), when: ExplorerFocusCondition, @@ -401,16 +420,13 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_C }, id: COPY_PATH_COMMAND_ID, - handler: (accessor, resource: URI) => { - resource = getResourceForCommand(resource, accessor.get(IListService), accessor.get(IWorkbenchEditorService)); - if (resource) { - const clipboardService = accessor.get(IClipboardService); - clipboardService.writeText(resource.scheme === 'file' ? labels.getPathLabel(resource) : resource.toString()); - } else { - const messageService = accessor.get(IMessageService); - messageService.show(severity.Info, nls.localize('openFileToCopy', "Open a file first to copy its path")); - } - } + handler: copyPathHandler +}); + +// TODO@isidor deprecated remove in february +CommandsRegistry.registerCommand({ + id: 'workbench.action.files.copyPathOfActiveFile', + handler: copyPathHandler }); CommandsRegistry.registerCommand({ @@ -457,8 +473,13 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ id: SAVE_FILE_COMMAND_ID, handler: (accessor, resource: URI) => { const editorService = accessor.get(IWorkbenchEditorService); - resource = getResourceForCommand(resource, accessor.get(IListService), editorService); - return save(resource, false, editorService, accessor.get(IFileService), accessor.get(IUntitledEditorService), accessor.get(ITextFileService), accessor.get(IEditorGroupService)); + const resources = getMultiSelectedResources(resource, accessor.get(IListService), editorService); + + if (resources.length === 1) { + // If only one resource is selected explictly call save since the behavior is a bit different than save all #41841 + return save(resources[0], false, editorService, accessor.get(IFileService), accessor.get(IUntitledEditorService), accessor.get(ITextFileService), accessor.get(IEditorGroupService)); + } + return saveAll(resources, editorService, accessor.get(IUntitledEditorService), accessor.get(ITextFileService), accessor.get(IEditorGroupService)); } }); @@ -471,19 +492,22 @@ CommandsRegistry.registerCommand({ CommandsRegistry.registerCommand({ id: SAVE_ALL_IN_GROUP_COMMAND_ID, - handler: (accessor, resource: URI, editorContext: IEditorContext) => { + handler: (accessor, resource: URI, editorContext: IEditorIdentifier) => { + const contexts = getMultiSelectedEditorContexts(editorContext, accessor.get(IListService)); let saveAllArg: any; - if (!editorContext) { + if (!contexts.length) { saveAllArg = true; } else { const fileService = accessor.get(IFileService); - const editorGroup = editorContext.group; saveAllArg = []; - editorGroup.getEditors().forEach(editor => { - const resource = toResource(editor, { supportSideBySide: true }); - if (resource && (resource.scheme === 'untitled' || fileService.canHandleResource(resource))) { - saveAllArg.push(resource); - } + contexts.forEach(context => { + const editorGroup = context.group; + editorGroup.getEditors().forEach(editor => { + const resource = toResource(editor, { supportSideBySide: true }); + if (resource && (resource.scheme === 'untitled' || fileService.canHandleResource(resource))) { + saveAllArg.push(resource); + } + }); }); } @@ -497,3 +521,18 @@ CommandsRegistry.registerCommand({ return saveAll(false, accessor.get(IWorkbenchEditorService), accessor.get(IUntitledEditorService), accessor.get(ITextFileService), accessor.get(IEditorGroupService)); } }); + +CommandsRegistry.registerCommand({ + id: REMOVE_ROOT_FOLDER_COMMAND_ID, + handler: (accessor, resource: URI) => { + const workspaceEditingService = accessor.get(IWorkspaceEditingService); + const contextService = accessor.get(IWorkspaceContextService); + const workspace = contextService.getWorkspace(); + const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IWorkbenchEditorService)).filter(r => + // Need to verify resources are workspaces since multi selection can trigger this command on some non workspace resources + workspace.folders.some(f => f.uri.toString() === r.toString()) + ); + + return workspaceEditingService.removeFolders(resources); + } +}); diff --git a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts index 8bedc8f8563..1f3a9ba56f3 100644 --- a/src/vs/workbench/parts/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/electron-browser/files.contribution.ts @@ -29,7 +29,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; import { DirtyFilesTracker } from 'vs/workbench/parts/files/common/dirtyFilesTracker'; -import { ExplorerViewlet } from 'vs/workbench/parts/files/electron-browser/explorerViewlet'; +import { ExplorerViewlet, ExplorerViewletViewsContribution } from 'vs/workbench/parts/files/electron-browser/explorerViewlet'; import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; import { DataUriEditorInput } from 'vs/workbench/common/editor/dataUriEditorInput'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; @@ -139,6 +139,9 @@ class FileEditorInputFactory implements IEditorInputFactory { Registry.as(EditorInputExtensions.EditorInputFactories).registerEditorInputFactory(FILE_EDITOR_INPUT_ID, FileEditorInputFactory); +// Register Explorer views +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(ExplorerViewletViewsContribution, LifecyclePhase.Starting); + // Register File Editor Tracker Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(FileEditorTracker, LifecyclePhase.Starting); @@ -303,14 +306,9 @@ configurationRegistry.registerConfiguration({ 'properties': { 'explorer.openEditors.visible': { 'type': 'number', - 'description': nls.localize({ key: 'openEditorsVisible', comment: ['Open is an adjective'] }, "Number of editors shown in the Open Editors pane. Set it to 0 to hide the pane."), + 'description': nls.localize({ key: 'openEditorsVisible', comment: ['Open is an adjective'] }, "Number of editors shown in the Open Editors pane."), 'default': 9 }, - 'explorer.openEditors.dynamicHeight': { - 'type': 'boolean', - 'description': nls.localize({ key: 'dynamicHeight', comment: ['Open is an adjective'] }, "Controls if the height of the open editors section should adapt dynamically to the number of elements or not."), - 'default': true - }, 'explorer.autoReveal': { 'type': 'boolean', 'description': nls.localize('autoReveal', "Controls if the explorer should automatically reveal and select files when opening them."), diff --git a/src/vs/workbench/parts/files/electron-browser/media/explorerviewlet.css b/src/vs/workbench/parts/files/electron-browser/media/explorerviewlet.css index ef3c88021fd..eb657380a67 100644 --- a/src/vs/workbench/parts/files/electron-browser/media/explorerviewlet.css +++ b/src/vs/workbench/parts/files/electron-browser/media/explorerviewlet.css @@ -58,55 +58,6 @@ display: none; } -.explorer-folders-view .monaco-tree-row .content { - display: flex; -} - -.explorer-folders-view .monaco-tree-row .content::before { - background-size: 16px; - background-position: 50% 50%; - background-repeat: no-repeat; - padding-right: 6px; - width: 16px; - height: 22px; - display: inline-block; - vertical-align: top; - content: ' '; -} - -.explorer-folders-view.align-icons-and-twisties .monaco-tree-row:not(.has-children) .content::before { - display: none; -} - -.explorer-folders-view .monaco-tree-row.has-children.expanded .content::before { - background-image: url("expanded.svg"); -} - -.explorer-folders-view .monaco-tree-row.has-children .content::before { - display: inline-block; - background-image: url("collapsed.svg"); -} - -.vs-dark .explorer-folders-view .monaco-tree-row.has-children.expanded .content::before { - background-image: url("expanded-dark.svg"); -} - -.vs-dark .explorer-folders-view .monaco-tree-row.has-children .content::before { - background-image: url("collapsed-dark.svg"); -} - -.hc-black .explorer-folders-view .monaco-tree-row.has-children.expanded .content::before { - background-image: url("expanded-hc.svg"); -} - -.hc-black .explorer-folders-view .monaco-tree-row.has-children .content::before { - background-image: url("collapsed-hc.svg"); -} - -.explorer-folders-view.hide-arrows .monaco-tree-row .content::before { - display: none; -} - .explorer-viewlet .explorer-open-editors .monaco-list .monaco-list-row:hover > .monaco-action-bar, .explorer-viewlet .explorer-open-editors .monaco-list.focused .monaco-list-row.focused > .monaco-action-bar, .explorer-viewlet .explorer-open-editors .monaco-list .monaco-list-row.dirty > .monaco-action-bar { diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts index 024b758d31c..ad23c7e52e9 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts @@ -24,7 +24,7 @@ import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService'; import * as DOM from 'vs/base/browser/dom'; import { CollapseAction } from 'vs/workbench/browser/viewlet'; -import { TreeViewsViewletPanel, IViewletViewOptions, IViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; +import { IViewletViewOptions, IViewOptions, TreeViewsViewletPanel, FileIconThemableWorkbenchTree } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { FileStat, Model } from 'vs/workbench/parts/files/common/explorerModel'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IPartService } from 'vs/workbench/services/part/common/partService'; @@ -39,10 +39,9 @@ import { IMessageService, Severity } from 'vs/platform/message/common/message'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ResourceContextKey } from 'vs/workbench/common/resources'; import { ResourceGlobMatcher } from 'vs/workbench/electron-browser/resources'; -import { IWorkbenchThemeService, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { isLinux } from 'vs/base/common/platform'; import { IDecorationsService } from 'vs/workbench/services/decorations/browser/decorations'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; export interface IExplorerViewOptions extends IViewletViewOptions { viewletState: FileViewletState; @@ -84,14 +83,12 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView @IEditorGroupService private editorGroupService: IEditorGroupService, @IWorkspaceContextService private contextService: IWorkspaceContextService, @IProgressService private progressService: IProgressService, - @IListService private listService: IListService, @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IFileService private fileService: IFileService, @IPartService private partService: IPartService, @IKeybindingService keybindingService: IKeybindingService, - @IContextKeyService private contextKeyService: IContextKeyService, + @IContextKeyService contextKeyService: IContextKeyService, @IConfigurationService private configurationService: IConfigurationService, - @IWorkbenchThemeService private themeService: IWorkbenchThemeService, @IDecorationsService decorationService: IDecorationsService ) { super({ ...(options as IViewOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService); @@ -156,7 +153,6 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView public renderBody(container: HTMLElement): void { this.treeContainer = super.renderViewTree(container); DOM.addClass(this.treeContainer, 'explorer-folders-view'); - DOM.addClass(this.treeContainer, 'show-file-icons'); this.tree = this.createViewer($(this.treeContainer)); @@ -164,15 +160,8 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView this.toolbar.setActions(this.getActions(), this.getSecondaryActions())(); } - const onFileIconThemeChange = (fileIconTheme: IFileIconTheme) => { - DOM.toggleClass(this.treeContainer, 'align-icons-and-twisties', fileIconTheme.hasFileIcons && !fileIconTheme.hasFolderIcons); - DOM.toggleClass(this.treeContainer, 'hide-arrows', fileIconTheme.hidesExplorerArrows === true); - }; - - this.disposables.push(this.themeService.onDidFileIconThemeChange(onFileIconThemeChange)); this.disposables.push(this.contextService.onDidChangeWorkspaceFolders(e => this.refreshFromEvent(e.added))); this.disposables.push(this.contextService.onDidChangeWorkbenchState(e => this.refreshFromEvent())); - onFileIconThemeChange(this.themeService.getFileIconTheme()); } public getActions(): IAction[] { @@ -404,7 +393,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView const dnd = this.instantiationService.createInstance(FileDragAndDrop); const accessibilityProvider = this.instantiationService.createInstance(FileAccessibilityProvider); - this.explorerViewer = new WorkbenchTree(container.getHTMLElement(), { + this.explorerViewer = this.instantiationService.createInstance(FileIconThemableWorkbenchTree, container.getHTMLElement(), { dataSource, renderer, controller, @@ -415,10 +404,8 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView }, { autoExpandSingleChildren: true, ariaLabel: nls.localize('treeAriaLabel', "Files Explorer"), - twistiePixels: 12, - showTwistie: false, keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); // Bind context keys FilesExplorerFocusedContext.bindTo(this.explorerViewer.contextKeyService); @@ -613,7 +600,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView const added = e.getAdded(); // Check added: Refresh if added file/folder is not part of resolved root and parent is part of it - const ignoredPaths: { [fsPath: string]: boolean } = <{ [fsPath: string]: boolean }>{}; + const ignoredPaths: { [resource: string]: boolean } = <{ [resource: string]: boolean }>{}; for (let i = 0; i < added.length; i++) { const change = added[i]; if (!this.contextService.isInsideWorkspace(change.resource)) { @@ -621,22 +608,22 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView } // Find parent - const parent = paths.dirname(change.resource.fsPath); + const parent = resources.dirname(change.resource); // Continue if parent was already determined as to be ignored - if (ignoredPaths[parent]) { + if (ignoredPaths[parent.toString()]) { continue; } // Compute if parent is visible and added file not yet part of it - const parentStat = this.model.findClosest(URI.file(parent)); + const parentStat = this.model.findClosest(parent); if (parentStat && parentStat.isDirectoryResolved && !this.model.findClosest(change.resource)) { return true; } // Keep track of path that can be ignored for faster lookup if (!parentStat || !parentStat.isDirectoryResolved) { - ignoredPaths[parent] = true; + ignoredPaths[parent.toString()] = true; } } } @@ -787,8 +774,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView name: paths.basename(resource.fsPath), mtime: 0, etag: undefined, - isDirectory: true, - hasChildren: false + isDirectory: true }, root); if (targetsToResolve.every(t => t.root.resource.scheme === 'file')) { diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts index 4f2133dfd9a..a812d54aaff 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts @@ -39,7 +39,7 @@ import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configur import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IMessageService, IConfirmation, Severity, IConfirmationResult } from 'vs/platform/message/common/message'; +import { IMessageService, IConfirmation, Severity, IConfirmationResult, getConfirmMessage } from 'vs/platform/message/common/message'; import { IProgressService } from 'vs/platform/progress/common/progress'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -55,6 +55,8 @@ import { getPathLabel } from 'vs/base/common/labels'; import { extractResources } from 'vs/workbench/browser/editor'; import { relative } from 'path'; import { DataTransfers } from 'vs/base/browser/dnd'; +import { distinctParents } from 'vs/base/common/resources'; +import { WorkbenchTree, multiSelectModifierSettingKey } from 'vs/platform/list/browser/listService'; export class FileDataSource implements IDataSource { constructor( @@ -104,7 +106,6 @@ export class FileDataSource implements IDataSource { return stat.children; }, (e: any) => { - stat.hasChildren = false; this.messageService.show(Severity.Error, e); return []; // we could not resolve any children because of an error @@ -279,16 +280,15 @@ export class FileRenderer implements IRenderer { inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length }); inputBox.focus(); - const done = once((commit: boolean) => { + const done = once((commit: boolean, blur: boolean) => { tree.clearHighlight(); if (commit && inputBox.value) { editableData.action.run({ value: inputBox.value }); } - const restoreFocus = document.activeElement === inputBox.inputElement; // https://github.com/Microsoft/vscode/issues/20269 setTimeout(() => { - if (restoreFocus) { + if (!blur) { // https://github.com/Microsoft/vscode/issues/20269 tree.DOMFocus(); } lifecycle.dispose(toDispose); @@ -301,14 +301,14 @@ export class FileRenderer implements IRenderer { DOM.addStandardDisposableListener(inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: IKeyboardEvent) => { if (e.equals(KeyCode.Enter)) { if (inputBox.validate()) { - done(true); + done(true, false); } } else if (e.equals(KeyCode.Escape)) { - done(false); + done(false, false); } }), DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => { - done(inputBox.isInputValid()); + done(inputBox.isInputValid(), true); }), label, styler @@ -329,19 +329,31 @@ export class FileController extends DefaultController implements IDisposable { private contributedContextMenu: IMenu; private toDispose: IDisposable[]; + private previousSelectionRangeStop: FileStat; + private useAltAsMultiSelectModifier: boolean; - constructor( @IWorkbenchEditorService private editorService: IWorkbenchEditorService, + constructor( + @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IContextMenuService private contextMenuService: IContextMenuService, @ITelemetryService private telemetryService: ITelemetryService, - @IMenuService menuService: IMenuService, - @IContextKeyService contextKeyService: IContextKeyService + @IMenuService private menuService: IMenuService, + @IContextKeyService contextKeyService: IContextKeyService, + @IConfigurationService private configurationService: IConfigurationService ) { super({ clickBehavior: ClickBehavior.ON_MOUSE_UP /* do not change to not break DND */, keyboardSupport: false /* handled via IListService */ }); + this.useAltAsMultiSelectModifier = configurationService.getValue(multiSelectModifierSettingKey) === 'alt'; this.toDispose = []; - this.contributedContextMenu = menuService.createMenu(MenuId.ExplorerContext, contextKeyService); - this.toDispose.push(this.contributedContextMenu); + this.registerListeners(); + } + + private registerListeners(): void { + this.toDispose.push(this.configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(multiSelectModifierSettingKey)) { + this.useAltAsMultiSelectModifier = this.configurationService.getValue(multiSelectModifierSettingKey) === 'alt'; + } + })); } public onLeftClick(tree: ITree, stat: FileStat | Model, event: IMouseEvent, origin: string = 'mouse'): boolean { @@ -377,20 +389,40 @@ export class FileController extends DefaultController implements IDisposable { // Set DOM focus tree.DOMFocus(); + if (stat instanceof NewStatPlaceholder) { + return true; + } - // Expand / Collapse - tree.toggleExpansion(stat, event.altKey); + // Allow to multiselect + if ((this.useAltAsMultiSelectModifier && event.altKey) || !this.useAltAsMultiSelectModifier && (event.ctrlKey || event.metaKey)) { + const selection = tree.getSelection(); + this.previousSelectionRangeStop = undefined; + if (selection.indexOf(stat) >= 0) { + tree.setSelection(selection.filter(s => s !== stat)); + } else { + tree.setSelection(selection.concat(stat)); + } + tree.setFocus(stat, payload); + } // Allow to unselect - if (event.shiftKey && !(stat instanceof NewStatPlaceholder)) { - const selection = tree.getSelection(); - if (selection && selection.length > 0 && selection[0] === stat) { - tree.clearSelection(payload); + else if (event.shiftKey) { + const focus = tree.getFocus(); + if (focus) { + if (this.previousSelectionRangeStop) { + tree.deselectRange(stat, this.previousSelectionRangeStop); + } + tree.selectRange(focus, stat, payload); + this.previousSelectionRangeStop = stat; } } // Select, Focus and open files - else if (!(stat instanceof NewStatPlaceholder)) { + else { + // Expand / Collapse + tree.toggleExpansion(stat, event.altKey); + this.previousSelectionRangeStop = undefined; + const preserveFocus = !isDoubleClick; tree.setFocus(stat, payload); @@ -401,14 +433,19 @@ export class FileController extends DefaultController implements IDisposable { tree.setSelection([stat], payload); if (!stat.isDirectory) { - this.openEditor(stat, { preserveFocus, sideBySide: event && (event.ctrlKey || event.metaKey), pinned: isDoubleClick }); + let sideBySide = false; + if (event) { + sideBySide = this.useAltAsMultiSelectModifier ? (event.ctrlKey || event.metaKey) : event.altKey; + } + + this.openEditor(stat, { preserveFocus, sideBySide, pinned: isDoubleClick }); } } return true; } - public onContextMenu(tree: ITree, stat: FileStat | Model, event: ContextMenuEvent): boolean { + public onContextMenu(tree: WorkbenchTree, stat: FileStat | Model, event: ContextMenuEvent): boolean { if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') { return false; } @@ -418,7 +455,13 @@ export class FileController extends DefaultController implements IDisposable { tree.setFocus(stat); + if (!this.contributedContextMenu) { + this.contributedContextMenu = this.menuService.createMenu(MenuId.ExplorerContext, tree.contextKeyService); + this.toDispose.push(this.contributedContextMenu); + } + const anchor = { x: event.posx, y: event.posy }; + const selection = tree.getSelection(); this.contextMenuService.showContextMenu({ getAnchor: () => anchor, getActions: () => { @@ -430,7 +473,8 @@ export class FileController extends DefaultController implements IDisposable { if (wasCancelled) { tree.DOMFocus(); } - } + }, + getActionsContext: () => selection && selection.indexOf(stat) >= 0 ? selection.map((fs: FileStat) => fs.resource) : [stat] }); return true; @@ -677,23 +721,24 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { public onDragStart(tree: ITree, data: IDragAndDropData, originalEvent: DragMouseEvent): void { const sources: FileStat[] = data.getData(); - let source: FileStat = null; - if (sources.length > 0) { - source = sources[0]; - } + if (sources && sources.length) { + // When dragging folders, make sure to collapse them to free up some space + sources.forEach(s => { + if (s.isDirectory && tree.isExpanded(s)) { + tree.collapse(s, false); + } + }); - // When dragging folders, make sure to collapse them to free up some space - if (source && source.isDirectory && tree.isExpanded(source)) { - tree.collapse(source, false); - } + // Apply some datatransfer types to allow for dragging the element outside of the application + originalEvent.dataTransfer.setData(DataTransfers.TEXT, sources.map(fs => fs.resource.scheme === 'file' ? getPathLabel(fs.resource) : fs.resource.toString()).join('\n')); + if (sources.length === 1) { + if (!sources[0].isDirectory) { + originalEvent.dataTransfer.setData(DataTransfers.DOWNLOAD_URL, [MIME_BINARY, sources[0].name, sources[0].resource.toString()].join(':')); + } - // Apply some datatransfer types to allow for dragging the element outside of the application - if (source) { - if (!source.isDirectory) { - originalEvent.dataTransfer.setData(DataTransfers.DOWNLOAD_URL, [MIME_BINARY, source.name, source.resource.toString()].join(':')); + } else { + originalEvent.dataTransfer.setData(DataTransfers.URLS, JSON.stringify(sources.filter(s => !s.isDirectory).map(s => s.resource.toString()))); } - - originalEvent.dataTransfer.setData(DataTransfers.TEXT, getPathLabel(source.resource)); } } @@ -844,7 +889,7 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { } private handleExplorerDrop(tree: ITree, data: IDragAndDropData, target: FileStat, originalEvent: DragMouseEvent): TPromise { - const source: FileStat = data.getData()[0]; + const sources: FileStat[] = distinctParents(data.getData(), s => s.resource); const isCopy = (originalEvent.ctrlKey && !isMacintosh) || (originalEvent.altKey && isMacintosh); let confirmPromise: TPromise; @@ -853,7 +898,8 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { const confirmDragAndDrop = !isCopy && this.configurationService.getValue(FileDragAndDrop.CONFIRM_DND_SETTING_KEY); if (confirmDragAndDrop) { confirmPromise = this.messageService.confirmWithCheckbox({ - message: nls.localize('confirmMove', "Are you sure you want to move '{0}'?", source.name), + message: sources.length > 1 ? getConfirmMessage(nls.localize('confirmMultiMove', "Are you sure you want to move the following {0} files?", sources.length), sources.map(s => s.resource)) + : nls.localize('confirmMove', "Are you sure you want to move '{0}'?", sources[0].name), checkbox: { label: nls.localize('doNotAskAgain', "Do not ask me again") }, @@ -874,7 +920,7 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop { return updateConfirmSettingsPromise.then(() => { if (confirmation.confirmed) { - return this.doHandleExplorerDrop(tree, data, source, target, isCopy); + return TPromise.join(sources.map(source => this.doHandleExplorerDrop(tree, data, source, target, isCopy))).then(() => void 0); } return TPromise.as(void 0); diff --git a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts index d1971cbbbb4..2c882a9221b 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts @@ -21,14 +21,14 @@ import { OpenEditorsFocusedContext, ExplorerFocusedContext, IFilesConfiguration import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; import { OpenEditor } from 'vs/workbench/parts/files/common/explorerModel'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; -import { CloseAllEditorsAction, CloseUnmodifiedEditorsInGroupAction, CloseEditorsInGroupAction, CloseEditorAction } from 'vs/workbench/browser/parts/editor/editorActions'; +import { CloseAllEditorsAction, CloseEditorAction } from 'vs/workbench/browser/parts/editor/editorActions'; import { ToggleEditorLayoutAction } from 'vs/workbench/browser/actions/toggleEditorLayout'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { EditorGroup } from 'vs/workbench/common/editor/editorStacksModel'; import { attachStylerCallback } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { badgeBackground, badgeForeground, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; -import { IListService, WorkbenchList } from 'vs/platform/list/browser/listService'; +import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { IDelegate, IRenderer, IListContextMenuEvent, IListMouseEvent } from 'vs/base/browser/ui/list/list'; import { EditorLabel } from 'vs/workbench/browser/labels'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; @@ -51,7 +51,6 @@ const $ = dom.$; export class OpenEditorsView extends ViewsViewletPanel { private static readonly DEFAULT_VISIBLE_OPEN_EDITORS = 9; - private static readonly DEFAULT_DYNAMIC_HEIGHT = true; static readonly ID = 'workbench.explorer.openEditorsView'; static NAME = nls.localize({ key: 'openEditors', comment: ['Open is an adjective'] }, "Open Editors"); @@ -75,12 +74,11 @@ export class OpenEditorsView extends ViewsViewletPanel { @IEditorGroupService private editorGroupService: IEditorGroupService, @IConfigurationService private configurationService: IConfigurationService, @IKeybindingService keybindingService: IKeybindingService, - @IListService private listService: IListService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IContextKeyService private contextKeyService: IContextKeyService, @IThemeService private themeService: IThemeService, @ITelemetryService private telemetryService: ITelemetryService, - @IMenuService menuService: IMenuService + @IMenuService private menuService: IMenuService ) { super({ ...(options as IViewOptions), @@ -99,8 +97,6 @@ export class OpenEditorsView extends ViewsViewletPanel { } this.needsRefresh = false; }, this.structuralRefreshDelay); - this.contributedContextMenu = menuService.createMenu(MenuId.OpenEditorsContext, contextKeyService); - this.disposables.push(this.contributedContextMenu); // update on model changes this.disposables.push(this.model.onModelChanged(e => this.onEditorStacksModelChanged(e))); @@ -144,13 +140,25 @@ export class OpenEditorsView extends ViewsViewletPanel { dom.addClass(container, 'show-file-icons'); const delegate = new OpenEditorsDelegate(); - this.list = new WorkbenchList(container, delegate, [ + const getSelectedElements = () => { + const selected = this.list.getSelectedElements(); + const focused = this.list.getFocusedElements(); + if (focused.length && selected.indexOf(focused[0]) >= 0) { + return selected; + } + + return focused; + }; + this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [ new EditorGroupRenderer(this.keybindingService, this.instantiationService, this.editorGroupService), - new OpenEditorRenderer(this.instantiationService, this.keybindingService, this.configurationService, this.editorGroupService) + new OpenEditorRenderer(getSelectedElements, this.instantiationService, this.keybindingService, this.configurationService, this.editorGroupService) ], { - identityProvider: element => element instanceof OpenEditor ? element.getId() : element.id.toString(), - multipleSelectionSupport: false - }, this.contextKeyService, this.listService, this.themeService); + keyboardSupport: false, + identityProvider: element => element instanceof OpenEditor ? element.getId() : element.id.toString() + }); + + this.contributedContextMenu = this.menuService.createMenu(MenuId.OpenEditorsContext, this.list.contextKeyService); + this.disposables.push(this.contributedContextMenu); this.updateSize(); @@ -185,7 +193,7 @@ export class OpenEditorsView extends ViewsViewletPanel { const focused = this.list.getFocusedElements(); const element = focused.length ? focused[0] : undefined; if (element instanceof OpenEditor) { - this.openEditor(element, { pinned: false, sideBySide: !!event.ctrlKey, preserveFocus: false }); + this.openEditor(element, { pinned: false, sideBySide: !!(event.altKey || event.ctrlKey || event.metaKey), preserveFocus: false }); } } })); @@ -216,6 +224,11 @@ export class OpenEditorsView extends ViewsViewletPanel { }); } + public focus(): void { + this.list.domFocus(); + super.focus(); + } + public getList(): WorkbenchList { return this.list; } @@ -262,10 +275,10 @@ export class OpenEditorsView extends ViewsViewletPanel { } if (event.browserEvent && event.browserEvent.button === 1 /* Middle Button */) { - const position = this.model.positionOfGroup(element.editorGroup); - this.editorService.closeEditor(position, element.editorInput).done(null, errors.onUnexpectedError); + const position = this.model.positionOfGroup(element.group); + this.editorService.closeEditor(position, element.editor).done(null, errors.onUnexpectedError); } else { - this.openEditor(element, { preserveFocus: !isDoubleClick, pinned: isDoubleClick, sideBySide: event.browserEvent.ctrlKey || event.browserEvent.metaKey }); + this.openEditor(element, { preserveFocus: !isDoubleClick, pinned: isDoubleClick, sideBySide: this.list.useAltAsMultiSelectModifier ? (event.browserEvent.ctrlKey || event.browserEvent.metaKey) : event.browserEvent.altKey }); } } @@ -278,12 +291,12 @@ export class OpenEditorsView extends ViewsViewletPanel { } */ this.telemetryService.publicLog('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'openEditors' }); - let position = this.model.positionOfGroup(element.editorGroup); + let position = this.model.positionOfGroup(element.group); if (options.sideBySide && position !== Position.THREE) { position++; } this.editorGroupService.activateGroup(this.model.groupAt(position)); - this.editorService.openEditor(element.editorInput, options, position) + this.editorService.openEditor(element.editor, options, position) .done(() => this.editorGroupService.activateGroup(this.model.groupAt(position)), errors.onUnexpectedError); } } @@ -294,10 +307,10 @@ export class OpenEditorsView extends ViewsViewletPanel { getAnchor: () => e.anchor, getActions: () => { const actions = []; - fillInActions(this.contributedContextMenu, { shouldForwardArgs: true, arg: element instanceof OpenEditor ? element.editorInput.getResource() : undefined }, actions, this.contextMenuService); + fillInActions(this.contributedContextMenu, { shouldForwardArgs: true, arg: element instanceof OpenEditor ? element.editor.getResource() : {} }, actions, this.contextMenuService); return TPromise.as(actions); }, - getActionsContext: () => element instanceof OpenEditor ? { group: element.editorGroup, editor: element.editorInput } : { group: element } + getActionsContext: () => element instanceof OpenEditor ? { group: element.group, editor: element.editor } : { group: element } }); } @@ -328,7 +341,6 @@ export class OpenEditorsView extends ViewsViewletPanel { if (this.model.activeGroup && this.model.activeGroup.activeEditor /* could be empty */) { const index = this.getIndex(this.model.activeGroup, this.model.activeGroup.activeEditor); this.list.setFocus([index]); - this.list.setSelection([index]); this.list.reveal(index); } } @@ -376,22 +388,11 @@ export class OpenEditorsView extends ViewsViewletPanel { visibleOpenEditors = OpenEditorsView.DEFAULT_VISIBLE_OPEN_EDITORS; } - let dynamicHeight = this.configurationService.getValue('explorer.openEditors.dynamicHeight'); - if (typeof dynamicHeight !== 'boolean') { - dynamicHeight = OpenEditorsView.DEFAULT_DYNAMIC_HEIGHT; - } - - return this.computeMinExpandedBodySize(visibleOpenEditors, dynamicHeight); + return this.computeMinExpandedBodySize(visibleOpenEditors); } - private computeMinExpandedBodySize(visibleOpenEditors = OpenEditorsView.DEFAULT_VISIBLE_OPEN_EDITORS, dynamicHeight = OpenEditorsView.DEFAULT_DYNAMIC_HEIGHT): number { - let itemsToShow: number; - if (dynamicHeight) { - itemsToShow = Math.min(Math.max(visibleOpenEditors, 1), this.elementCount); - } else { - itemsToShow = Math.max(visibleOpenEditors, 1); - } - + private computeMinExpandedBodySize(visibleOpenEditors = OpenEditorsView.DEFAULT_VISIBLE_OPEN_EDITORS): number { + const itemsToShow = Math.min(Math.max(visibleOpenEditors, 1), this.elementCount); return itemsToShow * OpenEditorsDelegate.ITEM_HEIGHT; } @@ -461,19 +462,13 @@ class EditorGroupRenderer implements IRenderer { - const key = this.keybindingService.lookupKeybinding(a.id); - editorGroupTemplate.actionBar.push(a, { icon: true, label: false, keybinding: key ? key.getLabel() : void 0 }); - }); + const saveAllInGroupAction = this.instantiationService.createInstance(SaveAllInGroupAction, SaveAllInGroupAction.ID, SaveAllInGroupAction.LABEL); + const key = this.keybindingService.lookupKeybinding(saveAllInGroupAction.id); + editorGroupTemplate.actionBar.push(saveAllInGroupAction, { icon: true, label: false, keybinding: key ? key.getLabel() : void 0 }); editorGroupTemplate.toDispose = []; editorGroupTemplate.toDispose.push(dom.addDisposableListener(container, dom.EventType.DRAG_OVER, (e: DragEvent) => { - if (OpenEditorRenderer.DRAGGED_OPEN_EDITOR) { + if (OpenEditorRenderer.DRAGGED_OPEN_EDITORS) { dom.addClass(container, 'focused'); } })); @@ -482,10 +477,11 @@ class EditorGroupRenderer implements IRenderer { dom.removeClass(container, 'focused'); - if (OpenEditorRenderer.DRAGGED_OPEN_EDITOR) { + if (OpenEditorRenderer.DRAGGED_OPEN_EDITORS) { const model = this.editorGroupService.getStacksModel(); const positionOfTargetGroup = model.positionOfGroup(editorGroupTemplate.editorGroup); - this.editorGroupService.moveEditor(OpenEditorRenderer.DRAGGED_OPEN_EDITOR.editorInput, model.positionOfGroup(OpenEditorRenderer.DRAGGED_OPEN_EDITOR.editorGroup), positionOfTargetGroup, { preserveFocus: true }); + OpenEditorRenderer.DRAGGED_OPEN_EDITORS.forEach(oe => + this.editorGroupService.moveEditor(oe.editor, model.positionOfGroup(oe.group), positionOfTargetGroup, { preserveFocus: true })); this.editorGroupService.activateGroup(positionOfTargetGroup); } })); @@ -507,9 +503,10 @@ class EditorGroupRenderer implements IRenderer { static readonly ID = 'openeditor'; - public static DRAGGED_OPEN_EDITOR: OpenEditor; + public static DRAGGED_OPEN_EDITORS: OpenEditor[]; constructor( + private getSelectedElements: () => (OpenEditor | IEditorGroup)[], private instantiationService: IInstantiationService, private keybindingService: IKeybindingService, private configurationService: IConfigurationService, @@ -541,29 +538,31 @@ class OpenEditorRenderer implements IRenderer document.body.removeChild(dragImage), 0); - OpenEditorRenderer.DRAGGED_OPEN_EDITOR = editorTemplate.openEditor; + const dragged = this.getSelectedElements().filter(e => e instanceof OpenEditor); + OpenEditorRenderer.DRAGGED_OPEN_EDITORS = dragged; - if (editorTemplate.openEditor && editorTemplate.openEditor.editorInput) { - const resource = editorTemplate.openEditor.editorInput.getResource(); - if (resource) { - const resourceStr = resource.toString(); + if (editorTemplate.openEditor && editorTemplate.openEditor.editor) { + // enables dropping editor resource path into text controls + e.dataTransfer.setData(DataTransfers.TEXT, dragged.map(d => d.getResource()).map(resource => resource.scheme === 'file' ? getPathLabel(resource) : resource.toString()).join('\n')); + if (dragged.length === 1) { + const resource = dragged[0].getResource(); e.dataTransfer.setData(DataTransfers.URL, resource.toString()); // enables dropping editor into editor area - e.dataTransfer.setData(DataTransfers.TEXT, getPathLabel(resource)); // enables dropping editor resource path into text controls - if (resource.scheme === 'file') { - e.dataTransfer.setData(DataTransfers.DOWNLOAD_URL, [MIME_BINARY, getBaseLabel(resource), resourceStr].join(':')); // enables support to drag an editor as file to desktop + e.dataTransfer.setData(DataTransfers.DOWNLOAD_URL, [MIME_BINARY, getBaseLabel(resource), resource.toString()].join(':')); // enables support to drag an editor as file to desktop } + } else { + e.dataTransfer.setData(DataTransfers.URLS, JSON.stringify(dragged.map(s => s.getResource().toString()))); } } })); editorTemplate.toDispose.push(dom.addDisposableListener(container, dom.EventType.DRAG_OVER, () => { - if (OpenEditorRenderer.DRAGGED_OPEN_EDITOR) { + if (OpenEditorRenderer.DRAGGED_OPEN_EDITORS) { dom.addClass(container, 'focused'); } })); @@ -572,18 +571,18 @@ class OpenEditorRenderer implements IRenderer { dom.removeClass(container, 'focused'); - if (OpenEditorRenderer.DRAGGED_OPEN_EDITOR) { + if (OpenEditorRenderer.DRAGGED_OPEN_EDITORS) { const model = this.editorGroupService.getStacksModel(); - const positionOfTargetGroup = model.positionOfGroup(editorTemplate.openEditor.editorGroup); - const index = editorTemplate.openEditor.editorGroup.indexOf(editorTemplate.openEditor.editorInput); + const positionOfTargetGroup = model.positionOfGroup(editorTemplate.openEditor.group); + const index = editorTemplate.openEditor.group.indexOf(editorTemplate.openEditor.editor); - this.editorGroupService.moveEditor(OpenEditorRenderer.DRAGGED_OPEN_EDITOR.editorInput, - model.positionOfGroup(OpenEditorRenderer.DRAGGED_OPEN_EDITOR.editorGroup), positionOfTargetGroup, { index, preserveFocus: true }); + OpenEditorRenderer.DRAGGED_OPEN_EDITORS.forEach(oe => + this.editorGroupService.moveEditor(oe.editor, model.positionOfGroup(oe.group), positionOfTargetGroup, { index, preserveFocus: true })); this.editorGroupService.activateGroup(positionOfTargetGroup); } })); editorTemplate.toDispose.push(dom.addDisposableListener(container, dom.EventType.DRAG_END, () => { - OpenEditorRenderer.DRAGGED_OPEN_EDITOR = undefined; + OpenEditorRenderer.DRAGGED_OPEN_EDITORS = undefined; })); return editorTemplate; @@ -592,12 +591,12 @@ class OpenEditorRenderer implements IRenderer().explorer.decorations }); - templateData.actionBar.context = { group: editor.editorGroup, editor: editor.editorInput }; + templateData.actionBar.context = { group: editor.group, editor: editor.editor }; } disposeTemplate(templateData: IOpenEditorTemplateData): void { diff --git a/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts b/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts index fd651f9af7c..9bf052609fd 100644 --- a/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts +++ b/src/vs/workbench/parts/files/test/electron-browser/explorerModel.test.ts @@ -14,7 +14,7 @@ import { validateFileName } from 'vs/workbench/parts/files/electron-browser/file import { FileStat } from 'vs/workbench/parts/files/common/explorerModel'; function createStat(path: string, name: string, isFolder: boolean, hasChildren: boolean, size: number, mtime: number): FileStat { - return new FileStat(toResource(path), undefined, isFolder, hasChildren, name, mtime); + return new FileStat(toResource(path), undefined, isFolder, name, mtime); } function toResource(path) { @@ -31,7 +31,6 @@ suite('Files - View Model', () => { assert.strictEqual(s.resource.fsPath, toResource('/path/to/stat').fsPath); assert.strictEqual(s.name, 'sName'); assert.strictEqual(s.isDirectory, true); - assert.strictEqual(s.hasChildren, true); assert.strictEqual(s.mtime, new Date(d).getTime()); assert(isArray(s.children) && s.children.length === 0); @@ -49,14 +48,12 @@ suite('Files - View Model', () => { s.addChild(child1); assert(s.children.length === 1); - assert(s.hasChildren); s.removeChild(child1); s.addChild(child1); assert(s.children.length === 1); s.removeChild(child1); - assert(!s.hasChildren); assert(s.children.length === 0); // Assert that adding a child updates its path properly @@ -79,7 +76,6 @@ suite('Files - View Model', () => { s4.move(s1); assert.strictEqual(s3.children.length, 0); - assert.strictEqual(s3.hasChildren, false); assert.strictEqual(s1.children.length, 2); @@ -239,20 +235,20 @@ suite('Files - View Model', () => { test('Merge Local with Disk', function () { const d = new Date().toUTCString(); - const merge1 = new FileStat(URI.file(join('C:\\', '/path/to')), undefined, true, false, 'to', Date.now(), d); - const merge2 = new FileStat(URI.file(join('C:\\', '/path/to')), undefined, true, false, 'to', Date.now(), new Date(0).toUTCString()); + const merge1 = new FileStat(URI.file(join('C:\\', '/path/to')), undefined, true, 'to', Date.now(), d); + const merge2 = new FileStat(URI.file(join('C:\\', '/path/to')), undefined, true, 'to', Date.now(), new Date(0).toUTCString()); // Merge Properties FileStat.mergeLocalWithDisk(merge2, merge1); assert.strictEqual(merge1.mtime, merge2.mtime); // Merge Child when isDirectoryResolved=false is a no-op - merge2.addChild(new FileStat(URI.file(join('C:\\', '/path/to/foo.html')), undefined, true, false, 'foo.html', Date.now(), d)); + merge2.addChild(new FileStat(URI.file(join('C:\\', '/path/to/foo.html')), undefined, true, 'foo.html', Date.now(), d)); FileStat.mergeLocalWithDisk(merge2, merge1); assert.strictEqual(merge1.children.length, 0); // Merge Child with isDirectoryResolved=true - const child = new FileStat(URI.file(join('C:\\', '/path/to/foo.html')), undefined, true, false, 'foo.html', Date.now(), d); + const child = new FileStat(URI.file(join('C:\\', '/path/to/foo.html')), undefined, true, 'foo.html', Date.now(), d); merge2.removeChild(child); merge2.addChild(child); merge2.isDirectoryResolved = true; diff --git a/src/vs/workbench/parts/html/browser/htmlPreviewPart.ts b/src/vs/workbench/parts/html/browser/htmlPreviewPart.ts index 9674b857ced..edee199e773 100644 --- a/src/vs/workbench/parts/html/browser/htmlPreviewPart.ts +++ b/src/vs/workbench/parts/html/browser/htmlPreviewPart.ts @@ -25,6 +25,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import Webview, { WebviewOptions } from './webview'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { WebviewEditor } from './webviewEditor'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; /** @@ -46,13 +47,14 @@ export class HtmlPreviewPart extends WebviewEditor { constructor( @ITelemetryService telemetryService: ITelemetryService, - @ITextModelService private textModelResolverService: ITextModelService, @IThemeService themeService: IThemeService, - @IOpenerService private readonly openerService: IOpenerService, - @IPartService private partService: IPartService, @IStorageService storageService: IStorageService, - @IContextViewService private _contextViewService: IContextViewService, - @IContextKeyService contextKeyService: IContextKeyService + @IContextKeyService contextKeyService: IContextKeyService, + @ITextModelService private readonly textModelResolverService: ITextModelService, + @IOpenerService private readonly openerService: IOpenerService, + @IPartService private readonly partService: IPartService, + @IContextViewService private readonly _contextViewService: IContextViewService, + @IEnvironmentService private readonly _environmentService: IEnvironmentService ) { super(HtmlPreviewPart.ID, telemetryService, themeService, storageService, contextKeyService); } @@ -84,7 +86,7 @@ export class HtmlPreviewPart extends WebviewEditor { webviewOptions = this.input.options; } - this._webview = new Webview(this.content, this.partService.getContainer(Parts.EDITOR_PART), this._contextViewService, this.contextKey, this.findInputFocusContextKey, webviewOptions); + this._webview = new Webview(this.content, this.partService.getContainer(Parts.EDITOR_PART), this._environmentService, this._contextViewService, this.contextKey, this.findInputFocusContextKey, webviewOptions, true); if (this.input && this.input instanceof HtmlInput) { const state = this.loadViewState(this.input.getResource()); this.scrollYPercentage = state ? state.scrollYPercentage : 0; diff --git a/src/vs/workbench/parts/html/browser/webview-pre.js b/src/vs/workbench/parts/html/browser/webview-pre.js index ebb69c9bd46..17c09cdc32f 100644 --- a/src/vs/workbench/parts/html/browser/webview-pre.js +++ b/src/vs/workbench/parts/html/browser/webview-pre.js @@ -264,7 +264,7 @@ contentWindow.addEventListener('scroll', handleInnerScroll); pendingMessages.forEach(function (data) { - contentWindow.postMessage(data, document.location.origin); + contentWindow.postMessage(data, '*'); }); pendingMessages = []; } @@ -303,7 +303,7 @@ } else { const target = getActiveFrame(); if (target) { - target.contentWindow.postMessage(data, document.location.origin); + target.contentWindow.postMessage(data, '*'); } } }); diff --git a/src/vs/workbench/parts/html/browser/webview.ts b/src/vs/workbench/parts/html/browser/webview.ts index c4954e1f376..90f7cd006cd 100644 --- a/src/vs/workbench/parts/html/browser/webview.ts +++ b/src/vs/workbench/parts/html/browser/webview.ts @@ -14,6 +14,9 @@ import { ITheme, LIGHT, DARK } from 'vs/platform/theme/common/themeService'; import { WebviewFindWidget } from './webviewFindWidget'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { normalize, nativeSep } from 'vs/base/common/paths'; +import { startsWith } from 'vs/base/common/strings'; export interface WebviewElementFindInPageOptions { forward?: boolean; @@ -39,8 +42,6 @@ export interface WebviewOptions { } export default class Webview { - private static index: number = 0; - private readonly _webview: Electron.WebviewTag; private _ready: Promise; private _disposables: IDisposable[] = []; @@ -55,13 +56,15 @@ export default class Webview { constructor( private readonly parent: HTMLElement, private readonly _styleElement: Element, - @IContextViewService private readonly _contextViewService: IContextViewService, + private readonly _environmentService: IEnvironmentService, + private readonly _contextViewService: IContextViewService, private readonly _contextKey: IContextKey, private readonly _findInputContextKey: IContextKey, - private _options: WebviewOptions = {}, + private _options: WebviewOptions, + useSameOriginForRoot: boolean ) { this._webview = document.createElement('webview'); - this._webview.setAttribute('partition', this._options.allowSvgs ? 'webview' : `webview${Webview.index++}`); + this._webview.setAttribute('partition', this._options.allowSvgs ? 'webview' : `webview${Date.now()}`); // disable auxclick events (see https://developers.google.com/web/updates/2016/10/auxclick) this._webview.setAttribute('disableblinkfeatures', 'Auxclick'); @@ -75,7 +78,7 @@ export default class Webview { this._webview.style.outline = '0'; this._webview.preload = require.toUrl('./webview-pre.js'); - this._webview.src = require.toUrl('./webview.html'); + this._webview.src = useSameOriginForRoot ? require.toUrl('./webview.html') : 'data:text/html;charset=utf-8,%3C%21DOCTYPE%20html%3E%0D%0A%3Chtml%20lang%3D%22en%22%20style%3D%22width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3Chead%3E%0D%0A%09%3Ctitle%3EVirtual%20Document%3C%2Ftitle%3E%0D%0A%3C%2Fhead%3E%0D%0A%3Cbody%20style%3D%22margin%3A%200%3B%20overflow%3A%20hidden%3B%20width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3C%2Fbody%3E%0D%0A%3C%2Fhtml%3E'; this._ready = new Promise(resolve => { const subscription = addDisposableListener(this._webview, 'ipc-message', (event) => { @@ -89,9 +92,24 @@ export default class Webview { }); }); + if (!useSameOriginForRoot) { + let loaded = false; + this._disposables.push(addDisposableListener(this._webview, 'did-start-loading', () => { + if (loaded) { + return; + } + loaded = true; + + const contents = this._webview.getWebContents(); + if (contents && !contents.isDestroyed()) { + registerFileProtocol(contents, 'vscode-core-resource', [this._environmentService.appRoot]); + } + })); + } + if (!this._options.allowSvgs) { let loaded = false; - const subscription = addDisposableListener(this._webview, 'did-start-loading', () => { + this._disposables.push(addDisposableListener(this._webview, 'did-start-loading', () => { if (loaded) { return; } @@ -124,9 +142,7 @@ export default class Webview { } return callback({ cancel: false, responseHeaders: details.responseHeaders }); }); - }); - - this._disposables.push(subscription); + })); } this._disposables.push( @@ -397,3 +413,25 @@ export default class Webview { this._webviewFindWidget.showPreviousFindTerm(); } } + +function registerFileProtocol( + contents: Electron.WebContents, + protocol: string, + roots: string[] +) { + contents.session.protocol.registerFileProtocol(protocol, (request, callback: any) => { + const requestPath = URI.parse(request.url).path; + for (const root of roots) { + const normalizedPath = normalize(requestPath, true); + if (startsWith(normalizedPath, root + nativeSep)) { + callback({ path: normalizedPath }); + return; + } + } + callback({ error: 'Cannot load resource outside of protocol root' }); + }, (error) => { + if (error) { + console.error('Failed to register protocol ' + protocol); + } + }); +} \ No newline at end of file diff --git a/src/vs/workbench/parts/logs/electron-browser/logs.contribution.ts b/src/vs/workbench/parts/logs/electron-browser/logs.contribution.ts index 3ed42b36111..c17d0c7e669 100644 --- a/src/vs/workbench/parts/logs/electron-browser/logs.contribution.ts +++ b/src/vs/workbench/parts/logs/electron-browser/logs.contribution.ts @@ -35,7 +35,7 @@ class LogOutputChannels extends Disposable implements IWorkbenchContribution { } } -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LogOutputChannels, LifecyclePhase.Restoring); +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LogOutputChannels, LifecyclePhase.Running); const workbenchActionsRegistry = Registry.as(WorkbenchActionExtensions.WorkbenchActions); const devCategory = nls.localize('developer', "Developer"); diff --git a/src/vs/workbench/parts/markers/browser/markersFileDecorations.ts b/src/vs/workbench/parts/markers/browser/markersFileDecorations.ts index 7f09b13a275..447a5f43abf 100644 --- a/src/vs/workbench/parts/markers/browser/markersFileDecorations.ts +++ b/src/vs/workbench/parts/markers/browser/markersFileDecorations.ts @@ -102,7 +102,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis 'problems.decorations.enabled': { 'description': localize('markers.showOnFile', "Show Errors & Warnings on files and folder."), 'type': 'boolean', - 'default': false + 'default': true } } }); diff --git a/src/vs/workbench/parts/markers/browser/markersPanel.ts b/src/vs/workbench/parts/markers/browser/markersPanel.ts index 280626d940f..6767bce8c4f 100644 --- a/src/vs/workbench/parts/markers/browser/markersPanel.ts +++ b/src/vs/workbench/parts/markers/browser/markersPanel.ts @@ -27,13 +27,12 @@ import { CollapseAllAction, FilterAction, FilterInputBoxActionItem } from 'vs/wo import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import Messages from 'vs/workbench/parts/markers/common/messages'; import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/rangeDecorations'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import FileResultsNavigation from 'vs/workbench/parts/files/browser/fileResultsNavigation'; import { debounceEvent } from 'vs/base/common/event'; import { SimpleFileResourceDragAndDrop } from 'vs/base/parts/tree/browser/treeDnd'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { localize } from 'vs/nls'; @@ -66,9 +65,7 @@ export class MarkersPanel extends Panel { @IEditorGroupService private editorGroupService: IEditorGroupService, @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IConfigurationService private configurationService: IConfigurationService, - @IContextKeyService private contextKeyService: IContextKeyService, @ITelemetryService telemetryService: ITelemetryService, - @IListService private listService: IListService, @IThemeService themeService: IThemeService, @IActivityService private activityService: IActivityService ) { @@ -158,7 +155,7 @@ export class MarkersPanel extends Panel { selection: marker.range, preserveFocus, pinned, - revealIfVisible: !sideByside + revealIfVisible: true }, }, sideByside).done(editor => { if (editor && preserveFocus) { @@ -215,7 +212,7 @@ export class MarkersPanel extends Panel { const renderer = this.instantiationService.createInstance(Viewer.Renderer); const dnd = new SimpleFileResourceDragAndDrop(obj => obj instanceof Resource ? obj.uri : void 0); let controller = this.instantiationService.createInstance(Controller); - this.tree = new WorkbenchTree(this.treeContainer, { + this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { dataSource: new Viewer.DataSource(), renderer, controller, @@ -227,13 +224,13 @@ export class MarkersPanel extends Panel { twistiePixels: 20, ariaLabel: Messages.MARKERS_PANEL_ARIA_LABEL_PROBLEMS_TREE, keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); Constants.MarkerFocusContextKey.bindTo(this.tree.contextKeyService); const fileResultsNavigation = this._register(new FileResultsNavigation(this.tree, { openOnFocus: true })); this._register(debounceEvent(fileResultsNavigation.openFile, (last, event) => event, 75, true)(options => { - this.openFileAtElement(options.element, options.editorOptions.preserveFocus, options.editorOptions.pinned, options.sideBySide); + this.openFileAtElement(options.element, options.editorOptions.preserveFocus, options.sideBySide, options.editorOptions.pinned); })); } diff --git a/src/vs/workbench/parts/markers/browser/markersPanelActions.ts b/src/vs/workbench/parts/markers/browser/markersPanelActions.ts index 9f1412c4218..03c6c2a3c17 100644 --- a/src/vs/workbench/parts/markers/browser/markersPanelActions.ts +++ b/src/vs/workbench/parts/markers/browser/markersPanelActions.ts @@ -54,19 +54,6 @@ export class ShowProblemsPanelAction extends Action { } } -export class ToggleErrorsAndWarningsAction extends TogglePanelAction { - - public static ID: string = 'workbench.action.showErrorsWarnings'; - public static readonly LABEL = Messages.SHOW_ERRORS_WARNINGS_ACTION_LABEL; - - constructor(id: string, label: string, - @IPartService partService: IPartService, - @IPanelService panelService: IPanelService, - ) { - super(id, label, Constants.MARKERS_PANEL_ID, panelService, partService); - } -} - export class CollapseAllAction extends TreeCollapseAction { constructor(viewer: Tree.ITree, enabled: boolean) { diff --git a/src/vs/workbench/parts/markers/browser/markersTreeController.ts b/src/vs/workbench/parts/markers/browser/markersTreeController.ts index 51f591e42cd..07e688331c8 100644 --- a/src/vs/workbench/parts/markers/browser/markersTreeController.ts +++ b/src/vs/workbench/parts/markers/browser/markersTreeController.ts @@ -10,24 +10,20 @@ import tree = require('vs/base/parts/tree/browser/tree'); import treedefaults = require('vs/base/parts/tree/browser/treeDefaults'); import { MarkersModel } from 'vs/workbench/parts/markers/common/markersModel'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IMenuService, IMenu, MenuId } from 'vs/platform/actions/common/actions'; +import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; import { IAction } from 'vs/base/common/actions'; import { ActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; export class Controller extends treedefaults.DefaultController { - private contextMenu: IMenu; - constructor( @IContextMenuService private contextMenuService: IContextMenuService, - @IMenuService menuService: IMenuService, - @IContextKeyService contextKeyService: IContextKeyService, + @IMenuService private menuService: IMenuService, @IKeybindingService private _keybindingService: IKeybindingService ) { super({ clickBehavior: treedefaults.ClickBehavior.ON_MOUSE_DOWN, keyboardSupport: false }); - this.contextMenu = menuService.createMenu(MenuId.ProblemsPanelContext, contextKeyService); } protected onLeftClick(tree: tree.ITree, element: any, event: mouse.IMouseEvent): boolean { @@ -45,9 +41,9 @@ export class Controller extends treedefaults.DefaultController { return false; } - public onContextMenu(tree: tree.ITree, element: any, event: tree.ContextMenuEvent): boolean { + public onContextMenu(tree: WorkbenchTree, element: any, event: tree.ContextMenuEvent): boolean { tree.setFocus(element); - const actions = this._getMenuActions(); + const actions = this._getMenuActions(tree); if (!actions.length) { return true; } @@ -77,9 +73,11 @@ export class Controller extends treedefaults.DefaultController { return true; } - private _getMenuActions(): IAction[] { + private _getMenuActions(tree: WorkbenchTree): IAction[] { const result: IAction[] = []; - const groups = this.contextMenu.getActions(); + const menu = this.menuService.createMenu(MenuId.ProblemsPanelContext, tree.contextKeyService); + const groups = menu.getActions(); + menu.dispose(); for (let group of groups) { const [, actions] = group; diff --git a/src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts b/src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts index 1ab41b88d24..5d31a4a46c6 100644 --- a/src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts +++ b/src/vs/workbench/parts/markers/browser/markersWorkbenchContributions.ts @@ -12,7 +12,7 @@ import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRe import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel'; import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; -import { ToggleMarkersPanelAction, ToggleErrorsAndWarningsAction, ShowProblemsPanelAction } from 'vs/workbench/parts/markers/browser/markersPanelActions'; +import { ToggleMarkersPanelAction, ShowProblemsPanelAction } from 'vs/workbench/parts/markers/browser/markersPanelActions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { MarkersPanel } from 'vs/workbench/parts/markers/browser/markersPanel'; @@ -33,6 +33,16 @@ export function registerContributions(): void { } }); + KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: Constants.MARKER_SHOW_PANEL_ID, + weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), + when: undefined, + primary: undefined, + handler: (accessor, args: any) => { + accessor.get(IPanelService).openPanel(Constants.MARKERS_PANEL_ID); + } + }); + // configuration Registry.as(Extensions.Configuration).registerConfiguration({ 'id': 'problems', @@ -63,9 +73,6 @@ export function registerContributions(): void { const registry = Registry.as(ActionExtensions.WorkbenchActions); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMarkersPanelAction, ToggleMarkersPanelAction.ID, ToggleMarkersPanelAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_M - }), 'View: Toggle Problems', Messages.MARKERS_PANEL_VIEW_CATEGORY); - registry.registerWorkbenchAction(new SyncActionDescriptor(ShowProblemsPanelAction, ShowProblemsPanelAction.ID, ShowProblemsPanelAction.LABEL), 'View: Show Problems', Messages.MARKERS_PANEL_VIEW_CATEGORY); - - // Retaining old action to show errors and warnings, so that custom bindings to this action for existing users works. - registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleErrorsAndWarningsAction, ToggleErrorsAndWarningsAction.ID, ToggleErrorsAndWarningsAction.LABEL), 'Show Errors and Warnings'); + }), 'View: Toggle Problems (Errors, Warnings, Infos)', Messages.MARKERS_PANEL_VIEW_CATEGORY); + registry.registerWorkbenchAction(new SyncActionDescriptor(ShowProblemsPanelAction, ShowProblemsPanelAction.ID, ShowProblemsPanelAction.LABEL), 'View: Focus Problems (Errors, Warnings, Infos)', Messages.MARKERS_PANEL_VIEW_CATEGORY); } diff --git a/src/vs/workbench/parts/markers/common/constants.ts b/src/vs/workbench/parts/markers/common/constants.ts index e1edde7ad00..b69836eaca0 100644 --- a/src/vs/workbench/parts/markers/common/constants.ts +++ b/src/vs/workbench/parts/markers/common/constants.ts @@ -10,6 +10,7 @@ export default { MARKER_COPY_ACTION_ID: 'problems.action.copy', MARKER_COPY_MESSAGE_ACTION_ID: 'problems.action.copyMessage', MARKER_OPEN_SIDE_ACTION_ID: 'problems.action.openToSide', + MARKER_SHOW_PANEL_ID: 'workbench.action.showErrorsWarnings', MarkerFocusContextKey: new RawContextKey('problemFocus', true) }; diff --git a/src/vs/workbench/parts/markers/common/messages.ts b/src/vs/workbench/parts/markers/common/messages.ts index 95fb1fe5f7f..bd2ce9fc63b 100644 --- a/src/vs/workbench/parts/markers/common/messages.ts +++ b/src/vs/workbench/parts/markers/common/messages.ts @@ -11,8 +11,8 @@ import { IMarker } from 'vs/platform/markers/common/markers'; export default class Messages { public static MARKERS_PANEL_VIEW_CATEGORY: string = nls.localize('viewCategory', "View"); - public static MARKERS_PANEL_TOGGLE_LABEL: string = nls.localize('problems.view.toggle.label', "Toggle Problems"); - public static MARKERS_PANEL_SHOW_LABEL: string = nls.localize('problems.view.focus.label', "Focus Problems"); + public static MARKERS_PANEL_TOGGLE_LABEL: string = nls.localize('problems.view.toggle.label', "Toggle Problems (Errors, Warnings, Infos)"); + public static MARKERS_PANEL_SHOW_LABEL: string = nls.localize('problems.view.focus.label', "Focus Problems (Errors, Warnings, Infos)"); public static PROBLEMS_PANEL_CONFIGURATION_TITLE: string = nls.localize('problems.panel.configuration.title', "Problems View"); public static PROBLEMS_PANEL_CONFIGURATION_AUTO_REVEAL: string = nls.localize('problems.panel.configuration.autoreveal', "Controls if Problems view should automatically reveal files when opening them"); diff --git a/src/vs/workbench/parts/markers/electron-browser/markersElectronContributions.ts b/src/vs/workbench/parts/markers/electron-browser/markersElectronContributions.ts index 8664daaf52b..1c2bb459302 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersElectronContributions.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersElectronContributions.ts @@ -76,7 +76,6 @@ interface IActionDescriptor { // ICommandUI title: string; category?: string; - iconClass?: string; f1?: boolean; // @@ -96,13 +95,13 @@ interface IActionDescriptor { function registerAction(desc: IActionDescriptor) { - const { id, handler, title, category, iconClass, menu, keybinding } = desc; + const { id, handler, title, category, menu, keybinding } = desc; // 1) register as command CommandsRegistry.registerCommand(id, handler); // 2) menus - let command = { id, title, iconClass, category }; + let command = { id, title, category }; if (menu) { let { menuId, when, group } = menu; MenuRegistry.appendMenuItem(menuId, { diff --git a/src/vs/workbench/parts/output/electron-browser/output.contribution.ts b/src/vs/workbench/parts/output/electron-browser/output.contribution.ts index d73919d5137..e989b92d769 100644 --- a/src/vs/workbench/parts/output/electron-browser/output.contribution.ts +++ b/src/vs/workbench/parts/output/electron-browser/output.contribution.ts @@ -91,7 +91,6 @@ interface IActionDescriptor { // ICommandUI title: string; category?: string; - iconClass?: string; f1?: boolean; // menus @@ -111,13 +110,13 @@ interface IActionDescriptor { function registerAction(desc: IActionDescriptor) { - const { id, handler, title, category, iconClass, f1, menu, keybinding } = desc; + const { id, handler, title, category, f1, menu, keybinding } = desc; // 1) register as command CommandsRegistry.registerCommand(id, handler); // 2) command palette - let command = { id, title, iconClass, category }; + let command = { id, title, category }; if (f1) { MenuRegistry.addCommand(command); } diff --git a/src/vs/workbench/parts/output/electron-browser/outputServices.ts b/src/vs/workbench/parts/output/electron-browser/outputServices.ts index dd6381475e9..ce87ed605a3 100644 --- a/src/vs/workbench/parts/output/electron-browser/outputServices.ts +++ b/src/vs/workbench/parts/output/electron-browser/outputServices.ts @@ -128,7 +128,8 @@ abstract class AbstractFileOutputChannel extends Disposable { protected modelUpdater: RunOnceScheduler; protected model: ITextModel; readonly file: URI; - protected startOffset: number = 0; + + private startOffset: number = 0; protected endOffset: number = 0; constructor( @@ -201,7 +202,6 @@ abstract class AbstractFileOutputChannel extends Disposable { const lastLine = this.model.getLineCount(); const lastLineMaxColumn = this.model.getLineMaxColumn(lastLine); this.model.applyEdits([EditOperation.insert(new Position(lastLine, lastLineMaxColumn), content)]); - this.endOffset = this.endOffset + new Buffer(content).byteLength; this._onDidAppendedContent.fire(); } } @@ -245,6 +245,8 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannel implements Out } append(message: string): void { + // update end offset always as message is read + this.endOffset = this.endOffset + new Buffer(message).byteLength; if (this.loadingFromFileInProgress) { this.appendedMessage += message; } else { @@ -371,7 +373,10 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann if (this.model) { this.fileService.resolveContent(this.file, { position: this.endOffset }) .then(content => { - this.appendToModel(content.value); + if (content.value) { + this.endOffset = this.endOffset + new Buffer(content.value).byteLength; + this.appendToModel(content.value); + } this.updateInProgress = false; }, () => this.updateInProgress = false); } else { diff --git a/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts b/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts index 4850d22984f..dcff24f801f 100644 --- a/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts +++ b/src/vs/workbench/parts/performance/electron-browser/performance.contribution.ts @@ -6,3 +6,4 @@ 'use strict'; import './startupProfiler'; +import './stats'; diff --git a/src/vs/workbench/parts/performance/electron-browser/stats.ts b/src/vs/workbench/parts/performance/electron-browser/stats.ts new file mode 100644 index 00000000000..397935d4179 --- /dev/null +++ b/src/vs/workbench/parts/performance/electron-browser/stats.ts @@ -0,0 +1,126 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; + + +interface IRequire { + (...a: any[]): any; + getStats(): ILoaderEvent[]; +} + +declare var require: IRequire; + +/* Copied from loader.ts */ +enum LoaderEventType { + LoaderAvailable = 1, + + BeginLoadingScript = 10, + EndLoadingScriptOK = 11, + EndLoadingScriptError = 12, + + BeginInvokeFactory = 21, + EndInvokeFactory = 22, + + NodeBeginEvaluatingScript = 31, + NodeEndEvaluatingScript = 32, + + NodeBeginNativeRequire = 33, + NodeEndNativeRequire = 34 +} + +interface ILoaderEvent { + type: LoaderEventType; + timestamp: number; + detail: string; +} + +class Tick { + + public readonly duration: number; + public readonly detail: string; + + constructor(public readonly start: ILoaderEvent, public readonly end: ILoaderEvent) { + console.assert(start.detail === end.detail); + + this.duration = this.end.timestamp - this.start.timestamp; + this.detail = start.detail; + } + + static compareUsingStartTimestamp(a: Tick, b: Tick): number { + if (a.start.timestamp < b.start.timestamp) { + return -1; + } else if (a.start.timestamp > b.start.timestamp) { + return 1; + } else { + return 0; + } + } +} + +function getStats(): Map { + + const stats = require.getStats().slice(0).sort((a: ILoaderEvent, b: ILoaderEvent) => { + if (a.detail < b.detail) { + return -1; + } else if (a.detail > b.detail) { + return 1; + } else if (a.type < b.type) { + return -1; + } else if (a.type > b.type) { + return 1; + } else { + return 0; + } + }); + + const ticks = new Map(); + ticks.set(LoaderEventType.BeginLoadingScript, []); + ticks.set(LoaderEventType.BeginInvokeFactory, []); + ticks.set(LoaderEventType.NodeBeginEvaluatingScript, []); + ticks.set(LoaderEventType.NodeBeginNativeRequire, []); + + for (let i = 1; i < stats.length - 1; i++) { + const stat = stats[i]; + const nextStat = stats[i + 1]; + + if (nextStat.type - stat.type > 2) { + //bad?! + break; + } + + i += 1; + ticks.get(stat.type).push(new Tick(stat, nextStat)); + } + + ticks.get(LoaderEventType.BeginLoadingScript).sort(Tick.compareUsingStartTimestamp); + ticks.get(LoaderEventType.BeginInvokeFactory).sort(Tick.compareUsingStartTimestamp); + ticks.get(LoaderEventType.NodeBeginEvaluatingScript).sort(Tick.compareUsingStartTimestamp); + ticks.get(LoaderEventType.NodeBeginNativeRequire).sort(Tick.compareUsingStartTimestamp); + + return ticks; +} + +CommandsRegistry.registerCommand('dev.stats.loader', accessor => { + + const clipboard = accessor.get(IClipboardService); + const env = accessor.get(IEnvironmentService); + + if (!env.performance) { + console.warn('no loader stats, start with `--performance`'); + return; + } + + let value = `Name\tDuration\n`; + for (let tick of getStats().get(LoaderEventType.BeginInvokeFactory)) { + value += `${tick.detail}\t${tick.duration.toPrecision(2)}\n`; + } + console.log(value); + clipboard.writeText(value); +}); diff --git a/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts index ea68e3b1e2f..0b9c84a41c5 100644 --- a/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts @@ -26,7 +26,7 @@ import { SearchWidget } from 'vs/workbench/parts/preferences/browser/preferences import { DefineKeybindingWidget } from 'vs/workbench/parts/preferences/browser/keybindingWidgets'; import { IPreferencesService, IKeybindingsEditor, CONTEXT_KEYBINDING_FOCUS, CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS, KEYBINDINGS_EDITOR_COMMAND_REMOVE, KEYBINDINGS_EDITOR_COMMAND_COPY, - KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_DEFINE, KEYBINDINGS_EDITOR_COMMAND_SHOW_CONFLICTS + KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_DEFINE, KEYBINDINGS_EDITOR_COMMAND_SHOW_CONFLICTS } from 'vs/workbench/parts/preferences/common/preferences'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IKeybindingEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing'; @@ -40,7 +40,7 @@ import { KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes'; import { listHighlightForeground } from 'vs/platform/theme/common/colorRegistry'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions'; -import { WorkbenchList, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchList } from 'vs/platform/list/browser/listService'; let $ = DOM.$; @@ -104,7 +104,6 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor @IContextMenuService private contextMenuService: IContextMenuService, @IPreferencesService private preferencesService: IPreferencesService, @IKeybindingEditingService private keybindingEditingService: IKeybindingEditingService, - @IListService private listService: IListService, @IContextKeyService private contextKeyService: IContextKeyService, @IMessageService private messageService: IMessageService, @IClipboardService private clipboardService: IClipboardService, @@ -245,6 +244,13 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor return TPromise.as(null); } + copyKeybindingCommand(keybinding: IKeybindingItemEntry): TPromise { + this.selectEntry(keybinding); + this.reportKeybindingAction(KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, keybinding.keybindingItem.command, keybinding.keybindingItem.keybinding); + this.clipboardService.writeText(keybinding.keybindingItem.command); + return TPromise.as(null); + } + search(filter: string): void { this.searchWidget.focus(); } @@ -326,8 +332,8 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor private createList(parent: HTMLElement): void { this.keybindingsListContainer = DOM.append(parent, $('.keybindings-list-container')); - this.keybindingsList = this._register(new WorkbenchList(this.keybindingsListContainer, new Delegate(), [new KeybindingHeaderRenderer(), new KeybindingItemRenderer(this, this.keybindingsService)], - { identityProvider: e => e.id, keyboardSupport: false, mouseSupport: true, ariaLabel: localize('keybindingsLabel', "Keybindings") }, this.contextKeyService, this.listService, this.themeService)); + this.keybindingsList = this._register(this.instantiationService.createInstance(WorkbenchList, this.keybindingsListContainer, new Delegate(), [new KeybindingHeaderRenderer(), new KeybindingItemRenderer(this, this.keybindingsService)], + { identityProvider: e => e.id, keyboardSupport: false, mouseSupport: true, ariaLabel: localize('keybindingsLabel', "Keybindings") })); this._register(this.keybindingsList.onContextMenu(e => this.onContextMenu(e))); this._register(this.keybindingsList.onFocusChange(e => this.onFocusChange(e))); this._register(this.keybindingsList.onDidFocus(() => { @@ -456,6 +462,7 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor getAnchor: () => e.anchor, getActions: () => TPromise.as([ this.createCopyAction(e.element), + this.createCopyCommandAction(e.element), new Separator(), this.createDefineAction(e.element), this.createRemoveAction(e.element), @@ -526,6 +533,15 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor }; } + private createCopyCommandAction(keybinding: IKeybindingItemEntry): IAction { + return { + label: localize('copyCommandLabel', "Copy Command"), + enabled: true, + id: KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, + run: () => this.copyKeybindingCommand(keybinding) + }; + } + private reportFilteringUsed(filter: string): void { if (filter) { let data = { @@ -644,7 +660,6 @@ class KeybindingItemRenderer implements IRenderer .keybindings-body > .keybindings-list-container .monaco-list-row.even:not(.focused):not(.selected):not(:hover), -.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list:not(:focus) .monaco-list-row.focused.even:not(.selected):not(:hover), -.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list:not(.focused) .monaco-list-row.focused.even:not(.selected):not(:hover) { +.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row:nth-child(even):not(.focused):not(.selected):not(:hover), +.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list:not(:focus) .monaco-list-row.focused:nth-child(even):not(.selected):not(:hover), +.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list:not(.focused) .monaco-list-row.focused:nth-child(even):not(.selected):not(:hover) { background-color: rgba(130, 130, 130, 0.04); } diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts index 5525dd14aad..941892045d0 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts @@ -6,7 +6,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; -import { onUnexpectedError } from 'vs/base/common/errors'; +import { onUnexpectedError, isPromiseCanceledError, getErrorMessage } from 'vs/base/common/errors'; import * as DOM from 'vs/base/browser/dom'; import { Delayer, ThrottledDelayer } from 'vs/base/common/async'; import { Dimension, Builder } from 'vs/base/browser/builder'; @@ -14,7 +14,6 @@ import { ArrayNavigator, INavigator } from 'vs/base/common/iterator'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { SideBySideEditorInput, EditorOptions, EditorInput } from 'vs/workbench/common/editor'; -import { Scope } from 'vs/workbench/common/memento'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; import { IEditorControl, Position, Verbosity } from 'vs/platform/editor/common/editor'; @@ -25,7 +24,7 @@ import { CodeEditor } from 'vs/editor/browser/codeEditor'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IPreferencesService, ISettingsGroup, ISetting, IFilterResult, IPreferencesSearchService, - CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, SETTINGS_EDITOR_COMMAND_SEARCH, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, ISettingsEditorModel, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, IFilterMetadata, IPreferencesSearchModel + CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, SETTINGS_EDITOR_COMMAND_SEARCH, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, ISettingsEditorModel, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, IFilterMetadata, ISearchProvider, ISearchResult } from 'vs/workbench/parts/preferences/common/preferences'; import { SettingsEditorModel, DefaultSettingsEditorModel } from 'vs/workbench/parts/preferences/common/preferencesModels'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -58,6 +57,7 @@ import { MessageController } from 'vs/editor/contrib/message/messageController'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; +import { IStringDictionary } from 'vs/base/common/collections'; export class PreferencesEditorInput extends SideBySideEditorInput { public static ID: string = 'workbench.editorinputs.preferencesEditorInput'; @@ -108,14 +108,13 @@ export class PreferencesEditor extends BaseEditor { private headerContainer: HTMLElement; private searchWidget: SearchWidget; private sideBySidePreferencesWidget: SideBySidePreferencesWidget; - private preferencesRenderers: PreferencesRenderers; + private preferencesRenderers: PreferencesRenderersController; private delayedFilterLogging: Delayer; - private filterThrottle: ThrottledDelayer; + private remoteSearchThrottle: ThrottledDelayer; + private _lastReportedFilter: string; - private latestEmptyFilters: string[] = []; private lastFocusedWidget: SearchWidget | SideBySidePreferencesWidget = null; - private memento: any; constructor( @IPreferencesService private preferencesService: IPreferencesService, @@ -124,15 +123,13 @@ export class PreferencesEditor extends BaseEditor { @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @IContextKeyService private contextKeyService: IContextKeyService, @IInstantiationService private instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService, - @IStorageService storageService: IStorageService, + @IThemeService themeService: IThemeService ) { super(PreferencesEditor.ID, telemetryService, themeService); this.defaultSettingsEditorContextKey = CONTEXT_SETTINGS_EDITOR.bindTo(this.contextKeyService); this.focusSettingsContextKey = CONTEXT_SETTINGS_SEARCH_FOCUS.bindTo(this.contextKeyService); this.delayedFilterLogging = new Delayer(1000); - this.filterThrottle = new ThrottledDelayer(200); - this.memento = this.getMemento(storageService, Scope.WORKSPACE); + this.remoteSearchThrottle = new ThrottledDelayer(200); } public createEditor(parent: Builder): void { @@ -145,12 +142,8 @@ export class PreferencesEditor extends BaseEditor { ariaLabel: nls.localize('SearchSettingsWidget.AriaLabel', "Search settings"), placeholder: nls.localize('SearchSettingsWidget.Placeholder', "Search Settings"), focusKey: this.focusSettingsContextKey, - showFuzzyToggle: true, showResultCount: true })); - this.searchWidget.setFuzzyToggleVisible(this.preferencesSearchService.remoteSearchAllowed); - this.searchWidget.fuzzyEnabled = this.memento['fuzzyEnabled']; - this._register(this.preferencesSearchService.onRemoteSearchEnablementChanged(enabled => this.searchWidget.setFuzzyToggleVisible(enabled))); this._register(this.searchWidget.onDidChange(value => this.onInputChanged())); this._register(this.searchWidget.onFocus(() => this.lastFocusedWidget = this.searchWidget)); this.lastFocusedWidget = this.searchWidget; @@ -160,12 +153,7 @@ export class PreferencesEditor extends BaseEditor { this._register(this.sideBySidePreferencesWidget.onFocus(() => this.lastFocusedWidget = this.sideBySidePreferencesWidget)); this._register(this.sideBySidePreferencesWidget.onDidSettingsTargetChange(target => this.switchSettings(target))); - this.preferencesRenderers = this._register(new PreferencesRenderers(this.preferencesSearchService)); - - this._register(this.preferencesRenderers.onTriggeredFuzzy(() => { - this.searchWidget.fuzzyEnabled = true; - this.filterPreferences(); - })); + this.preferencesRenderers = this._register(new PreferencesRenderersController(this.preferencesSearchService, this.telemetryService)); this._register(this.preferencesRenderers.onDidFilterResultsCountChange(count => this.showSearchResultsMessage(count))); } @@ -250,15 +238,29 @@ export class PreferencesEditor extends BaseEditor { } private onInputChanged(): void { - if (this.searchWidget.fuzzyEnabled) { - this.triggerThrottledFilter(); - } else { - this.filterPreferences(); - } + const query = this.searchWidget.getValue().trim(); + this.delayedFilterLogging.cancel(); + TPromise.join([ + this.preferencesRenderers.localFilterPreferences(query), + this.triggerThrottledSearch(query) + ]).then(results => { + if (results) { + const [localResult, remoteResult] = results; + this.delayedFilterLogging.trigger(() => this.reportFilteringUsed( + query, + remoteResult ? remoteResult.defaultSettingsGroupCounts : localResult.defaultSettingsGroupCounts, + remoteResult && remoteResult.metadata)); + } + }); } - private triggerThrottledFilter(): void { - this.filterThrottle.trigger(() => this.filterPreferences()); + private triggerThrottledSearch(query: string): TPromise { + if (query) { + return this.remoteSearchThrottle.trigger(() => this.preferencesRenderers.remoteSearchPreferences(query)); + } else { + // When clearing the input, update immediately to clear it + return this.preferencesRenderers.remoteSearchPreferences(query); + } } private switchSettings(target: SettingsTarget): void { @@ -278,19 +280,6 @@ export class PreferencesEditor extends BaseEditor { }); } - private filterPreferences(): TPromise { - this.memento['fuzzyEnabled'] = this.searchWidget.fuzzyEnabled; - const filter = this.searchWidget.getValue().trim(); - return this.preferencesRenderers.filterPreferences({ filter, fuzzy: this.searchWidget.fuzzyEnabled }).then(result => { - this.showSearchResultsMessage(result.count); - if (result.count === 0) { - this.latestEmptyFilters.push(filter); - } - this.preferencesRenderers.focusFirst(); - this.delayedFilterLogging.trigger(() => this.reportFilteringUsed(filter, result.metadata)); - }, onUnexpectedError); - } - private showSearchResultsMessage(count: number): void { if (this.searchWidget.getValue()) { if (count === 0) { @@ -305,38 +294,27 @@ export class PreferencesEditor extends BaseEditor { } } - private reportFilteringUsed(filter: string, metadata?: IFilterMetadata): void { - if (filter) { + private reportFilteringUsed(filter: string, counts: IStringDictionary, metadata?: IFilterMetadata): void { + if (filter && filter !== this._lastReportedFilter) { let data = { filter, - emptyFilters: this.getLatestEmptyFiltersForTelemetry(), - fuzzy: !!metadata, duration: metadata ? metadata.duration : undefined, - context: metadata ? metadata.context : undefined + context: metadata ? metadata.context : undefined, + counts }; - this.latestEmptyFilters = []; /* __GDPR__ "defaultSettings.filter" : { "filter": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "emptyFilters" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "fuzzy" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "duration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "context" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + "context" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "counts" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ this.telemetryService.publicLog('defaultSettings.filter', data); + this._lastReportedFilter = filter; } } - - /** - * Put a rough limit on the size of the telemetry data, since otherwise it could be an unbounded large amount - * of data. 8192 is the max size of a property value. This is rough since that probably includes ""s, etc. - */ - private getLatestEmptyFiltersForTelemetry(): string[] { - let cumulativeSize = 0; - return this.latestEmptyFilters.filter(filterText => (cumulativeSize += filterText.length) <= 8192); - } } class SettingsNavigator implements INavigator { @@ -372,35 +350,32 @@ class SettingsNavigator implements INavigator { } } -interface ISearchCriteria { - filter: string; - fuzzy: boolean; +interface IFilterOrSearchResult { + defaultSettingsGroupCounts: IStringDictionary; + metadata: IFilterMetadata; } -class PreferencesRenderers extends Disposable { +class PreferencesRenderersController extends Disposable { private _defaultPreferencesRenderer: IPreferencesRenderer; private _defaultPreferencesRendererDisposables: IDisposable[] = []; - private _defaultPreferencesFilterResult: IFilterResult; - private _editablePreferencesFilterResult: IFilterResult; - private _editablePreferencesRenderer: IPreferencesRenderer; private _editablePreferencesRendererDisposables: IDisposable[] = []; private _settingsNavigator: SettingsNavigator; - private _filtersInProgress: TPromise[]; - private _searchCriteria: ISearchCriteria; - private _currentSearchModel: IPreferencesSearchModel; + private _filtersInProgress: TPromise[]; - private _onTriggeredFuzzy: Emitter = this._register(new Emitter()); - public onTriggeredFuzzy: Event = this._onTriggeredFuzzy.event; + private _currentLocalSearchProvider: ISearchProvider; + private _currentRemoteSearchProvider: ISearchProvider; + private _lastQuery: string; private _onDidFilterResultsCountChange: Emitter = this._register(new Emitter()); public onDidFilterResultsCountChange: Event = this._onDidFilterResultsCountChange.event; constructor( - private preferencesSearchService: IPreferencesSearchService + private preferencesSearchService: IPreferencesSearchService, + private telemetryService: ITelemetryService ) { super(); } @@ -420,12 +395,9 @@ class PreferencesRenderers extends Disposable { this._defaultPreferencesRendererDisposables = dispose(this._defaultPreferencesRendererDisposables); if (this._defaultPreferencesRenderer) { - this._defaultPreferencesRenderer.onUpdatePreference(({ key, value, source, index }) => this._updatePreference(key, value, source, index, this._editablePreferencesRenderer), this, this._defaultPreferencesRendererDisposables); + this._defaultPreferencesRenderer.onUpdatePreference(({ key, value, source }) => this._updatePreference(key, value, source, this._editablePreferencesRenderer), this, this._defaultPreferencesRendererDisposables); this._defaultPreferencesRenderer.onFocusPreference(preference => this._focusPreference(preference, this._editablePreferencesRenderer), this, this._defaultPreferencesRendererDisposables); this._defaultPreferencesRenderer.onClearFocusPreference(preference => this._clearFocus(preference, this._editablePreferencesRenderer), this, this._defaultPreferencesRendererDisposables); - if (this._defaultPreferencesRenderer.onTriggeredFuzzy) { - this._register(this._defaultPreferencesRenderer.onTriggeredFuzzy(() => this._onTriggeredFuzzy.fire())); - } } } } @@ -435,44 +407,58 @@ class PreferencesRenderers extends Disposable { this._editablePreferencesRenderer = editableSettingsRenderer; this._editablePreferencesRendererDisposables = dispose(this._editablePreferencesRendererDisposables); if (this._editablePreferencesRenderer) { - (this._editablePreferencesRenderer.preferencesModel).onDidChangeGroups(() => { - if (this._currentSearchModel) { - this._filterEditablePreferences() - .then(() => { - const count = this.consolidateAndUpdate(); - this._onDidFilterResultsCountChange.fire(count); - }); - } - }, this, this._editablePreferencesRendererDisposables); + (this._editablePreferencesRenderer.preferencesModel) + .onDidChangeGroups(this._onEditableContentDidChange, this, this._editablePreferencesRendererDisposables); } } } - filterPreferences(criteria: ISearchCriteria): TPromise<{ count: number, metadata: IFilterMetadata }> { - this._searchCriteria = criteria; + async _onEditableContentDidChange(): TPromise { + await this.localFilterPreferences(this._lastQuery, true); + await this.remoteSearchPreferences(this._lastQuery, true); + } + remoteSearchPreferences(query: string, updateCurrentResults?: boolean): TPromise { + this._currentRemoteSearchProvider = (updateCurrentResults && this._currentRemoteSearchProvider) || this.preferencesSearchService.getRemoteSearchProvider(query); + return this.filterOrSearchPreferences(query, this._currentRemoteSearchProvider, 'nlpResult', nls.localize('nlpResult', "Natural Language Results")); + } + + localFilterPreferences(query: string, updateCurrentResults?: boolean): TPromise { + this._currentLocalSearchProvider = (updateCurrentResults && this._currentLocalSearchProvider) || this.preferencesSearchService.getLocalSearchProvider(query); + return this.filterOrSearchPreferences(query, this._currentLocalSearchProvider, 'filterResult', nls.localize('filterResult', "Filtered Results")); + } + + filterOrSearchPreferences(query: string, searchProvider: ISearchProvider, groupId: string, groupLabel: string): TPromise { + this._lastQuery = query; if (this._filtersInProgress) { // Resolved/rejected promises have no .cancel() this._filtersInProgress.forEach(p => p.cancel && p.cancel()); } - this._currentSearchModel = this.preferencesSearchService.startSearch(this._searchCriteria.filter, criteria.fuzzy); - this._filtersInProgress = [this._filterDefaultPreferences(), this._filterEditablePreferences()]; + this._filtersInProgress = [ + this._filterOrSearchPreferences(query, this.defaultPreferencesRenderer, searchProvider, groupId, groupLabel), + this._filterOrSearchPreferences(query, this.editablePreferencesRenderer, searchProvider, groupId, groupLabel)]; - return TPromise.join(this._filtersInProgress).then(() => { - const count = this.consolidateAndUpdate(); - return { count, metadata: this._defaultPreferencesFilterResult && this._defaultPreferencesFilterResult.metadata }; + return TPromise.join(this._filtersInProgress).then(results => { + this._filtersInProgress = null; + const [defaultFilterResult, editableFilterResult] = results; + + this.consolidateAndUpdate(defaultFilterResult, editableFilterResult); + const result = { + metadata: defaultFilterResult && defaultFilterResult.metadata, + defaultSettingsGroupCounts: defaultFilterResult && this._countById(defaultFilterResult.filteredGroups) + }; + + return result; + }, err => { + if (isPromiseCanceledError(err)) { + return null; + } else { + onUnexpectedError(err); + } }); } - focusFirst(): void { - // Focus first match in both renderers - this._focusPreference(this._getFirstSettingFromTheGroups(this._defaultPreferencesFilterResult ? this._defaultPreferencesFilterResult.filteredGroups : []), this._defaultPreferencesRenderer); - this._focusPreference(this._getFirstSettingFromTheGroups(this._editablePreferencesFilterResult ? this._editablePreferencesFilterResult.filteredGroups : []), this._editablePreferencesRenderer); - - this._settingsNavigator.first(); // Move to first - } - focusNextPreference(forward: boolean = true) { if (!this._settingsNavigator) { return; @@ -483,56 +469,60 @@ class PreferencesRenderers extends Disposable { this._focusPreference(setting, this._editablePreferencesRenderer); } - private _filterDefaultPreferences(): TPromise { - if (this._searchCriteria && this._defaultPreferencesRenderer) { - return this._filterPreferences(this._searchCriteria, this._defaultPreferencesRenderer, this._currentSearchModel) - .then(filterResult => { this._defaultPreferencesFilterResult = filterResult; }); + private _filterOrSearchPreferences(filter: string, preferencesRenderer: IPreferencesRenderer, provider: ISearchProvider, groupId: string, groupLabel: string): TPromise { + if (preferencesRenderer) { + const model = preferencesRenderer.preferencesModel; + const searchP = provider ? provider.searchModel(model) : TPromise.wrap(null); + return searchP + .then(null, err => { + if (isPromiseCanceledError(err)) { + return TPromise.wrapError(err); + } else { + /* __GDPR__ + "defaultSettings.searchError" : { + "message": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + const message = getErrorMessage(err); + this.telemetryService.publicLog('defaultSettings.searchError', { message }); + return null; + } + }) + .then(searchResult => { + const filterResult = searchResult ? + model.updateResultGroup(groupId, { + id: groupId, + label: groupLabel, + result: searchResult + }) : + model.updateResultGroup(groupId, null); + + if (filterResult) { + filterResult.query = filter; + } + + preferencesRenderer.filterPreferences(filterResult); + return filterResult; + }); } + return TPromise.wrap(null); } - private _filterEditablePreferences(): TPromise { - if (this._searchCriteria && this._editablePreferencesRenderer) { - return this._filterPreferences(this._searchCriteria, this._editablePreferencesRenderer, this._currentSearchModel) - .then(filterResult => { this._editablePreferencesFilterResult = filterResult; }); - } - return TPromise.wrap(null); - } + private consolidateAndUpdate(defaultFilterResult: IFilterResult, editableFilterResult: IFilterResult): void { + const defaultPreferencesFilteredGroups = defaultFilterResult ? defaultFilterResult.filteredGroups : this._getAllPreferences(this._defaultPreferencesRenderer); + const editablePreferencesFilteredGroups = editableFilterResult ? editableFilterResult.filteredGroups : this._getAllPreferences(this._editablePreferencesRenderer); + const consolidatedSettings = this._consolidateSettings(editablePreferencesFilteredGroups, defaultPreferencesFilteredGroups); - private _getFirstSettingFromTheGroups(allGroups: ISettingsGroup[]): ISetting { - if (allGroups.length) { - if (allGroups[0].sections.length) { - return allGroups[0].sections[0].settings[0]; - } - } - return null; + this._settingsNavigator = new SettingsNavigator(this._lastQuery ? consolidatedSettings : []); + const totalCount = consolidatedSettings.length; + this._onDidFilterResultsCountChange.fire(totalCount); } private _getAllPreferences(preferencesRenderer: IPreferencesRenderer): ISettingsGroup[] { return preferencesRenderer ? (preferencesRenderer.preferencesModel).settingsGroups : []; } - private _filterPreferences(searchCriteria: ISearchCriteria, preferencesRenderer: IPreferencesRenderer, searchModel: IPreferencesSearchModel): TPromise { - if (preferencesRenderer && searchCriteria) { - const prefSearchP = searchModel.filterPreferences(preferencesRenderer.preferencesModel); - - return prefSearchP.then(filterResult => { - preferencesRenderer.filterPreferences(filterResult, this.preferencesSearchService.remoteSearchAllowed); - return filterResult; - }); - } - return TPromise.as(null); - } - - private consolidateAndUpdate(): number { - const defaultPreferencesFilteredGroups = this._defaultPreferencesFilterResult ? this._defaultPreferencesFilterResult.filteredGroups : this._getAllPreferences(this._defaultPreferencesRenderer); - const editablePreferencesFilteredGroups = this._editablePreferencesFilterResult ? this._editablePreferencesFilterResult.filteredGroups : this._getAllPreferences(this._editablePreferencesRenderer); - const consolidatedSettings = this._consolidateSettings(editablePreferencesFilteredGroups, defaultPreferencesFilteredGroups); - - this._settingsNavigator = new SettingsNavigator(this._searchCriteria.filter ? consolidatedSettings : []); - return consolidatedSettings.length; - } - private _focusPreference(preference: ISetting, preferencesRenderer: IPreferencesRenderer): void { if (preference && preferencesRenderer) { preferencesRenderer.focusPreference(preference); @@ -545,15 +535,15 @@ class PreferencesRenderers extends Disposable { } } - private _updatePreference(key: string, value: any, source: ISetting, index: number, preferencesRenderer: IPreferencesRenderer): void { + private _updatePreference(key: string, value: any, source: ISetting, preferencesRenderer: IPreferencesRenderer): void { if (preferencesRenderer) { - preferencesRenderer.updatePreference(key, value, source, index); + preferencesRenderer.updatePreference(key, value, source); } } private _consolidateSettings(editableSettingsGroups: ISettingsGroup[], defaultSettingsGroups: ISettingsGroup[]): ISetting[] { const editableSettings = this._flatten(editableSettingsGroups); - const defaultSettings = this._flatten(defaultSettingsGroups).filter(secondarySetting => !editableSettings.some(primarySetting => primarySetting.key === secondarySetting.key)); + const defaultSettings = this._flatten(defaultSettingsGroups).filter(secondarySetting => editableSettings.every(primarySetting => primarySetting.key !== secondarySetting.key)); return [...defaultSettings, ...editableSettings]; } @@ -564,9 +554,25 @@ class PreferencesRenderers extends Disposable { settings.push(...section.settings); } } + return settings; } + private _countById(settingsGroups: ISettingsGroup[]): IStringDictionary { + const result = {}; + + for (const group of settingsGroups) { + let i = 0; + for (const section of group.sections) { + i += section.settings.length; + } + + result[group.id] = i; + } + + return result; + } + public dispose(): void { dispose(this._defaultPreferencesRendererDisposables); dispose(this._editablePreferencesRendererDisposables); @@ -905,7 +911,8 @@ abstract class AbstractSettingsEditorContribution extends Disposable implements private _hasAssociatedPreferencesModelChanged(associatedPreferencesModelUri: URI): TPromise { return this.preferencesRendererCreationPromise.then(preferencesRenderer => { - return !(preferencesRenderer && preferencesRenderer.associatedPreferencesModel && preferencesRenderer.associatedPreferencesModel.uri.toString() === associatedPreferencesModelUri.toString()); + const associatedPreferencesModel = preferencesRenderer.getAssociatedPreferencesModel(); + return !(preferencesRenderer && associatedPreferencesModel && associatedPreferencesModel.uri.toString() === associatedPreferencesModelUri.toString()); }); } @@ -914,10 +921,11 @@ abstract class AbstractSettingsEditorContribution extends Disposable implements .then(associatedPreferencesEditorModel => { return this.preferencesRendererCreationPromise.then(preferencesRenderer => { if (preferencesRenderer) { - if (preferencesRenderer.associatedPreferencesModel) { - preferencesRenderer.associatedPreferencesModel.dispose(); + const associatedPreferencesModel = preferencesRenderer.getAssociatedPreferencesModel(); + if (associatedPreferencesModel) { + associatedPreferencesModel.dispose(); } - preferencesRenderer.associatedPreferencesModel = associatedPreferencesEditorModel; + preferencesRenderer.setAssociatedPreferencesModel(associatedPreferencesEditorModel); } return preferencesRenderer; }); @@ -928,8 +936,9 @@ abstract class AbstractSettingsEditorContribution extends Disposable implements if (this.preferencesRendererCreationPromise) { this.preferencesRendererCreationPromise.then(preferencesRenderer => { if (preferencesRenderer) { - if (preferencesRenderer.associatedPreferencesModel) { - preferencesRenderer.associatedPreferencesModel.dispose(); + const associatedPreferencesModel = preferencesRenderer.getAssociatedPreferencesModel(); + if (associatedPreferencesModel) { + associatedPreferencesModel.dispose(); } preferencesRenderer.preferencesModel.dispose(); preferencesRenderer.dispose(); diff --git a/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts index 9cdec8686f6..6d2195213c1 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts @@ -7,7 +7,6 @@ import { TPromise } from 'vs/base/common/winjs.base'; import * as nls from 'vs/nls'; import { Delayer } from 'vs/base/common/async'; import * as strings from 'vs/base/common/strings'; -import { tail } from 'vs/base/common/arrays'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IAction } from 'vs/base/common/actions'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; @@ -36,19 +35,20 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { ITextModel, IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/model'; export interface IPreferencesRenderer extends IDisposable { - preferencesModel: IPreferencesEditorModel; - associatedPreferencesModel: IPreferencesEditorModel; + readonly preferencesModel: IPreferencesEditorModel; + + getAssociatedPreferencesModel(): IPreferencesEditorModel; + setAssociatedPreferencesModel(associatedPreferencesModel: IPreferencesEditorModel): void; onFocusPreference: Event; onClearFocusPreference: Event; - onUpdatePreference?: Event<{ key: string, value: any, source: T, index: number }>; - onTriggeredFuzzy?: Event; + onUpdatePreference?: Event<{ key: string, value: any, source: T }>; render(): void; - updatePreference(key: string, value: any, source: T, index: number): void; - filterPreferences(filterResult: IFilterResult, fuzzySearchAvailable: boolean): void; + updatePreference(key: string, value: any, source: T): void; focusPreference(setting: T): void; clearFocus(setting: T): void; + filterPreferences(filterResult: IFilterResult): void; } export class UserSettingsRenderer extends Disposable implements IPreferencesRenderer { @@ -57,7 +57,7 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend private editSettingActionRenderer: EditSettingRenderer; private highlightMatchesRenderer: HighlightMatchesRenderer; private modelChangeDelayer: Delayer = new Delayer(200); - private _associatedPreferencesModel: IPreferencesEditorModel; + private associatedPreferencesModel: IPreferencesEditorModel; private _onFocusPreference: Emitter = new Emitter(); public readonly onFocusPreference: Event = this._onFocusPreference.event; @@ -77,18 +77,18 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend this.settingHighlighter = this._register(instantiationService.createInstance(SettingHighlighter, editor, this._onFocusPreference, this._onClearFocusPreference)); this.highlightMatchesRenderer = this._register(instantiationService.createInstance(HighlightMatchesRenderer, editor)); this.editSettingActionRenderer = this._register(this.instantiationService.createInstance(EditSettingRenderer, this.editor, this.preferencesModel, this.settingHighlighter)); - this._register(this.editSettingActionRenderer.onUpdateSetting(({ key, value, source, index }) => this.updatePreference(key, value, source, index, true))); + this._register(this.editSettingActionRenderer.onUpdateSetting(({ key, value, source }) => this.updatePreference(key, value, source, true))); this._register(this.editor.getModel().onDidChangeContent(() => this.modelChangeDelayer.trigger(() => this.onModelChanged()))); this.createHeader(); } - public get associatedPreferencesModel(): IPreferencesEditorModel { - return this._associatedPreferencesModel; + public getAssociatedPreferencesModel(): IPreferencesEditorModel { + return this.associatedPreferencesModel; } - public set associatedPreferencesModel(associatedPreferencesModel: IPreferencesEditorModel) { - this._associatedPreferencesModel = associatedPreferencesModel; + public setAssociatedPreferencesModel(associatedPreferencesModel: IPreferencesEditorModel): void { + this.associatedPreferencesModel = associatedPreferencesModel; this.editSettingActionRenderer.associatedPreferencesModel = associatedPreferencesModel; } @@ -103,16 +103,16 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend } } - public updatePreference(key: string, value: any, source: ISetting, index: number, fromEditableSettings?: boolean): void { + public updatePreference(key: string, value: any, source: IIndexedSetting, fromEditableSettings?: boolean): void { const data = { userConfigurationKeys: [key] }; if (this.filterResult) { data['query'] = this.filterResult.query; - data['fuzzy'] = !!this.filterResult.metadata; data['duration'] = this.filterResult.metadata && this.filterResult.metadata.duration; - data['index'] = index; + data['index'] = source.index; + data['groupId'] = source.groupId; data['editableSide'] = !!fromEditableSettings; } @@ -120,8 +120,8 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend "defaultSettingsActions.copySetting" : { "userConfigurationKeys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "query" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "fuzzy" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "duration" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "groupId" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "index" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "editableSide" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } @@ -162,6 +162,7 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend } return null; } + return this.preferencesModel.getPreference(key); } @@ -206,10 +207,15 @@ export class WorkspaceSettingsRenderer extends UserSettingsRenderer implements I this._register(new SettingsHeaderWidget(this.editor, '')).setMessage(nls.localize('emptyWorkspaceSettingsHeader', "Place your settings here to overwrite the User Settings.")); } + public setAssociatedPreferencesModel(associatedPreferencesModel: IPreferencesEditorModel): void { + super.setAssociatedPreferencesModel(associatedPreferencesModel); + this.workspaceConfigurationRenderer.render(this.getAssociatedPreferencesModel()); + } + public render(): void { super.render(); this.unsupportedSettingsRenderer.render(); - this.workspaceConfigurationRenderer.render(); + this.workspaceConfigurationRenderer.render(this.getAssociatedPreferencesModel()); } } @@ -247,9 +253,11 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR private hiddenAreasRenderer: HiddenAreasRenderer; private editSettingActionRenderer: EditSettingRenderer; private feedbackWidgetRenderer: FeedbackWidgetRenderer; + private bracesHidingRenderer: BracesHidingRenderer; + private filterResult: IFilterResult; - private _onUpdatePreference: Emitter<{ key: string, value: any, source: ISetting, index: number }> = new Emitter<{ key: string, value: any, source: ISetting, index: number }>(); - public readonly onUpdatePreference: Event<{ key: string, value: any, source: ISetting, index: number }> = this._onUpdatePreference.event; + private _onUpdatePreference: Emitter<{ key: string, value: any, source: IIndexedSetting }> = new Emitter<{ key: string, value: any, source: IIndexedSetting }>(); + public readonly onUpdatePreference: Event<{ key: string, value: any, source: IIndexedSetting }> = this._onUpdatePreference.event; private _onFocusPreference: Emitter = new Emitter(); public readonly onFocusPreference: Event = this._onFocusPreference.event; @@ -257,10 +265,6 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR private _onClearFocusPreference: Emitter = new Emitter(); public readonly onClearFocusPreference: Event = this._onClearFocusPreference.event; - public readonly onTriggeredFuzzy: Event; - - private filterResult: IFilterResult; - constructor(protected editor: ICodeEditor, public readonly preferencesModel: DefaultSettingsEditorModel, @IPreferencesService protected preferencesService: IPreferencesService, @IInstantiationService protected instantiationService: IInstantiationService @@ -272,21 +276,19 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR this.filteredMatchesRenderer = this._register(instantiationService.createInstance(FilteredMatchesRenderer, editor)); this.editSettingActionRenderer = this._register(instantiationService.createInstance(EditSettingRenderer, editor, preferencesModel, this.settingHighlighter)); this.feedbackWidgetRenderer = this._register(instantiationService.createInstance(FeedbackWidgetRenderer, editor)); - const parenthesisHidingRenderer = this._register(instantiationService.createInstance(StaticContentHidingRenderer, editor, preferencesModel)); - this.hiddenAreasRenderer = this._register(instantiationService.createInstance(HiddenAreasRenderer, editor, [this.settingsGroupTitleRenderer, this.filteredMatchesRenderer, parenthesisHidingRenderer])); + this.bracesHidingRenderer = this._register(instantiationService.createInstance(BracesHidingRenderer, editor, preferencesModel)); + this.hiddenAreasRenderer = this._register(instantiationService.createInstance(HiddenAreasRenderer, editor, [this.settingsGroupTitleRenderer, this.filteredMatchesRenderer, this.bracesHidingRenderer])); this._register(this.editSettingActionRenderer.onUpdateSetting(e => this._onUpdatePreference.fire(e))); this._register(this.settingsGroupTitleRenderer.onHiddenAreasChanged(() => this.hiddenAreasRenderer.render())); this._register(preferencesModel.onDidChangeGroups(() => this.render())); - - this.onTriggeredFuzzy = this.settingsHeaderRenderer.onClick; } - public get associatedPreferencesModel(): IPreferencesEditorModel { + public getAssociatedPreferencesModel(): IPreferencesEditorModel { return this._associatedPreferencesModel; } - public set associatedPreferencesModel(associatedPreferencesModel: IPreferencesEditorModel) { + public setAssociatedPreferencesModel(associatedPreferencesModel: IPreferencesEditorModel): void { this._associatedPreferencesModel = associatedPreferencesModel; this.editSettingActionRenderer.associatedPreferencesModel = associatedPreferencesModel; } @@ -296,18 +298,20 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR this.editSettingActionRenderer.render(this.preferencesModel.settingsGroups, this._associatedPreferencesModel); this.feedbackWidgetRenderer.render(null); this.settingHighlighter.clear(true); + this.bracesHidingRenderer.render(null, this.preferencesModel.settingsGroups); this.settingsGroupTitleRenderer.showGroup(0); this.hiddenAreasRenderer.render(); } - public filterPreferences(filterResult: IFilterResult, fuzzySearchAvailable: boolean): void { + public filterPreferences(filterResult: IFilterResult): void { this.filterResult = filterResult; if (filterResult) { this.filteredMatchesRenderer.render(filterResult, this.preferencesModel.settingsGroups); this.settingsGroupTitleRenderer.render(filterResult.filteredGroups); this.feedbackWidgetRenderer.render(filterResult); - this.settingsHeaderRenderer.render(filterResult, fuzzySearchAvailable); + this.settingsHeaderRenderer.render(filterResult); this.settingHighlighter.clear(true); + this.bracesHidingRenderer.render(filterResult, this.preferencesModel.settingsGroups); this.editSettingActionRenderer.render(filterResult.filteredGroups, this._associatedPreferencesModel); } else { this.settingHighlighter.clear(true); @@ -316,6 +320,7 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR this.settingsHeaderRenderer.render(null); this.settingsGroupTitleRenderer.render(this.preferencesModel.settingsGroups); this.settingsGroupTitleRenderer.showGroup(0); + this.bracesHidingRenderer.render(null, this.preferencesModel.settingsGroups); this.editSettingActionRenderer.render(this.preferencesModel.settingsGroups, this._associatedPreferencesModel); } @@ -372,45 +377,64 @@ export interface HiddenAreasProvider { hiddenAreas: IRange[]; } -export class StaticContentHidingRenderer extends Disposable implements HiddenAreasProvider { +export class BracesHidingRenderer extends Disposable implements HiddenAreasProvider { + private _result: IFilterResult; + private _settingsGroups: ISettingsGroup[]; - constructor(private editor: ICodeEditor, private settingsEditorModel: ISettingsEditorModel - ) { + constructor(private editor: ICodeEditor) { super(); } - get hiddenAreas(): IRange[] { - const model = this.editor.getModel(); + render(result: IFilterResult, settingsGroups: ISettingsGroup[]): void { + this._result = result; + this._settingsGroups = settingsGroups; + } - // Hide extra chars for "search results" and "commonly used" groups - const settingsGroups = this.settingsEditorModel.settingsGroups; - const lastGroup = tail(settingsGroups); - return [ + get hiddenAreas(): IRange[] { + // Opening square brace + const hiddenAreas = [ { startLineNumber: 1, - startColumn: model.getLineMinColumn(1), + startColumn: 1, endLineNumber: 2, - endColumn: model.getLineMaxColumn(2) - }, - { - startLineNumber: settingsGroups[0].range.endLineNumber + 1, - startColumn: model.getLineMinColumn(settingsGroups[0].range.endLineNumber + 1), - endLineNumber: settingsGroups[0].range.endLineNumber + 4, - endColumn: model.getLineMaxColumn(settingsGroups[0].range.endLineNumber + 4) - }, - { - startLineNumber: lastGroup.range.endLineNumber + 1, - startColumn: model.getLineMinColumn(lastGroup.range.endLineNumber + 1), - endLineNumber: Math.min(model.getLineCount(), lastGroup.range.endLineNumber + 4), - endColumn: model.getLineMaxColumn(Math.min(model.getLineCount(), lastGroup.range.endLineNumber + 4)) - }, - { - startLineNumber: model.getLineCount() - 1, - startColumn: model.getLineMinColumn(model.getLineCount() - 1), - endLineNumber: model.getLineCount(), - endColumn: model.getLineMaxColumn(model.getLineCount()) + endColumn: 1 } ]; + + const hideBraces = group => { + // Opening curly brace + hiddenAreas.push({ + startLineNumber: group.range.startLineNumber - 3, + startColumn: 1, + endLineNumber: group.range.startLineNumber - 3, + endColumn: 1 + }); + + // Closing curly brace + hiddenAreas.push({ + startLineNumber: group.range.endLineNumber + 1, + startColumn: 1, + endLineNumber: group.range.endLineNumber + 4, + endColumn: 1 + }); + }; + + this._settingsGroups.forEach(hideBraces); + if (this._result) { + this._result.filteredGroups.forEach(hideBraces); + } + + // Closing square brace + const lineCount = this.editor.getModel().getLineCount(); + hiddenAreas.push({ + startLineNumber: lineCount, + startColumn: 1, + endLineNumber: lineCount, + endColumn: 1 + }); + + + return hiddenAreas; } } @@ -426,10 +450,9 @@ class DefaultSettingsHeaderRenderer extends Disposable { this.onClick = this.settingsHeaderWidget.onClick; } - public render(filterResult: IFilterResult, fuzzySearchAvailable = false) { + public render(filterResult: IFilterResult) { const hasSettings = !filterResult || filterResult.filteredGroups.length > 0; - const promptFuzzy = fuzzySearchAvailable && filterResult && !filterResult.metadata; - this.settingsHeaderWidget.toggleMessage(hasSettings, promptFuzzy); + this.settingsHeaderWidget.toggleMessage(hasSettings); } } @@ -728,7 +751,7 @@ export class FilteredMatchesRenderer extends Disposable implements HiddenAreasPr this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, result.matches.map(match => this.createDecoration(match, model))); }); } else { - this.hiddenAreas = this.computeHiddenRanges(allSettingsGroups, allSettingsGroups, model); + this.hiddenAreas = this.computeHiddenRanges(null, allSettingsGroups, model); } } @@ -739,67 +762,26 @@ export class FilteredMatchesRenderer extends Disposable implements HiddenAreasPr stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, className: 'findMatch' } - }; } private computeHiddenRanges(filteredGroups: ISettingsGroup[], allSettingsGroups: ISettingsGroup[], model: ITextModel): IRange[] { + // Hide the contents of hidden groups const notMatchesRanges: IRange[] = []; - for (const group of allSettingsGroups) { - const filteredGroup = filteredGroups.filter(g => g.title === group.title)[0]; - if (!filteredGroup || filteredGroup.sections.every(sect => sect.settings.length === 0)) { + if (filteredGroups) { + allSettingsGroups.forEach((group, i) => { notMatchesRanges.push({ startLineNumber: group.range.startLineNumber - 1, - startColumn: model.getLineMinColumn(group.range.startLineNumber - 1), + startColumn: group.range.startColumn, endLineNumber: group.range.endLineNumber, - endColumn: model.getLineMaxColumn(group.range.endLineNumber), + endColumn: group.range.endColumn }); - } else { - for (const section of group.sections) { - if (section.titleRange) { - if (!this.containsLine(section.titleRange.startLineNumber, filteredGroup)) { - notMatchesRanges.push(this.createCompleteRange(section.titleRange, model)); - } - } - for (const setting of section.settings) { - if (!this.containsLine(setting.range.startLineNumber, filteredGroup)) { - notMatchesRanges.push(this.createCompleteRange(setting.range, model)); - } - } - } - } + }); } + return notMatchesRanges; } - private containsLine(lineNumber: number, settingsGroup: ISettingsGroup): boolean { - if (settingsGroup.titleRange && lineNumber >= settingsGroup.titleRange.startLineNumber && lineNumber <= settingsGroup.titleRange.endLineNumber) { - return true; - } - - for (const section of settingsGroup.sections) { - if (section.titleRange && lineNumber >= section.titleRange.startLineNumber && lineNumber <= section.titleRange.endLineNumber) { - return true; - } - - for (const setting of section.settings) { - if (lineNumber >= setting.range.startLineNumber && lineNumber <= setting.range.endLineNumber) { - return true; - } - } - } - return false; - } - - private createCompleteRange(range: IRange, model: ITextModel): IRange { - return { - startLineNumber: range.startLineNumber, - startColumn: model.getLineMinColumn(range.startLineNumber), - endLineNumber: range.endLineNumber, - endColumn: model.getLineMaxColumn(range.endLineNumber) - }; - } - public dispose() { if (this.decorationIds) { this.decorationIds = this.editor.changeDecorations(changeAccessor => { @@ -853,21 +835,22 @@ export class HighlightMatchesRenderer extends Disposable { } } -interface IIndexedSetting extends ISetting { +export interface IIndexedSetting extends ISetting { index: number; + groupId: string; } class EditSettingRenderer extends Disposable { - private editPreferenceWidgetForCusorPosition: EditPreferenceWidget; + private editPreferenceWidgetForCursorPosition: EditPreferenceWidget; private editPreferenceWidgetForMouseMove: EditPreferenceWidget; private settingsGroups: ISettingsGroup[]; public associatedPreferencesModel: IPreferencesEditorModel; private toggleEditPreferencesForMouseMoveDelayer: Delayer; - private _onUpdateSetting: Emitter<{ key: string, value: any, source: ISetting, index: number }> = new Emitter<{ key: string, value: any, source: ISetting, index: number }>(); - public readonly onUpdateSetting: Event<{ key: string, value: any, source: ISetting, index: number }> = this._onUpdateSetting.event; + private _onUpdateSetting: Emitter<{ key: string, value: any, source: IIndexedSetting }> = new Emitter<{ key: string, value: any, source: IIndexedSetting }>(); + public readonly onUpdateSetting: Event<{ key: string, value: any, source: IIndexedSetting }> = this._onUpdateSetting.event; constructor(private editor: ICodeEditor, private masterSettingsModel: ISettingsEditorModel, private settingHighlighter: SettingHighlighter, @@ -876,11 +859,11 @@ class EditSettingRenderer extends Disposable { ) { super(); - this.editPreferenceWidgetForCusorPosition = this._register(this.instantiationService.createInstance(EditPreferenceWidget, editor)); - this.editPreferenceWidgetForMouseMove = this._register(this.instantiationService.createInstance(EditPreferenceWidget, editor)); + this.editPreferenceWidgetForCursorPosition = >this._register(this.instantiationService.createInstance(EditPreferenceWidget, editor)); + this.editPreferenceWidgetForMouseMove = >this._register(this.instantiationService.createInstance(EditPreferenceWidget, editor)); this.toggleEditPreferencesForMouseMoveDelayer = new Delayer(75); - this._register(this.editPreferenceWidgetForCusorPosition.onClick(e => this.onEditSettingClicked(this.editPreferenceWidgetForCusorPosition, e))); + this._register(this.editPreferenceWidgetForCursorPosition.onClick(e => this.onEditSettingClicked(this.editPreferenceWidgetForCursorPosition, e))); this._register(this.editPreferenceWidgetForMouseMove.onClick(e => this.onEditSettingClicked(this.editPreferenceWidgetForMouseMove, e))); this._register(this.editor.onDidChangeCursorPosition(positionChangeEvent => this.onPositionChanged(positionChangeEvent))); @@ -889,14 +872,14 @@ class EditSettingRenderer extends Disposable { } public render(settingsGroups: ISettingsGroup[], associatedPreferencesModel: IPreferencesEditorModel): void { - this.editPreferenceWidgetForCusorPosition.hide(); + this.editPreferenceWidgetForCursorPosition.hide(); this.editPreferenceWidgetForMouseMove.hide(); this.settingsGroups = settingsGroups; this.associatedPreferencesModel = associatedPreferencesModel; const settings = this.getSettings(this.editor.getPosition().lineNumber); if (settings.length) { - this.showEditPreferencesWidget(this.editPreferenceWidgetForCusorPosition, settings); + this.showEditPreferencesWidget(this.editPreferenceWidgetForCursorPosition, settings); } } @@ -906,7 +889,7 @@ class EditSettingRenderer extends Disposable { private onConfigurationChanged(): void { if (!this.editor.getConfiguration().viewInfo.glyphMargin) { - this.editPreferenceWidgetForCusorPosition.hide(); + this.editPreferenceWidgetForCursorPosition.hide(); this.editPreferenceWidgetForMouseMove.hide(); } } @@ -915,9 +898,9 @@ class EditSettingRenderer extends Disposable { this.editPreferenceWidgetForMouseMove.hide(); const settings = this.getSettings(positionChangeEvent.position.lineNumber); if (settings.length) { - this.showEditPreferencesWidget(this.editPreferenceWidgetForCusorPosition, settings); + this.showEditPreferencesWidget(this.editPreferenceWidgetForCursorPosition, settings); } else { - this.editPreferenceWidgetForCusorPosition.hide(); + this.editPreferenceWidgetForCursorPosition.hide(); } } @@ -937,8 +920,8 @@ class EditSettingRenderer extends Disposable { if (this.editPreferenceWidgetForMouseMove.getLine() === line && this.editPreferenceWidgetForMouseMove.isVisible()) { return this.editPreferenceWidgetForMouseMove; } - if (this.editPreferenceWidgetForCusorPosition.getLine() === line && this.editPreferenceWidgetForCusorPosition.isVisible()) { - return this.editPreferenceWidgetForCusorPosition; + if (this.editPreferenceWidgetForCursorPosition.getLine() === line && this.editPreferenceWidgetForCursorPosition.isVisible()) { + return this.editPreferenceWidgetForCursorPosition; } } return null; @@ -957,7 +940,7 @@ class EditSettingRenderer extends Disposable { const line = settings[0].valueRange.startLineNumber; if (this.editor.getConfiguration().viewInfo.glyphMargin && this.marginFreeFromOtherDecorations(line)) { editPreferencesWidget.show(line, nls.localize('editTtile', "Edit"), settings); - const editPreferenceWidgetToHide = editPreferencesWidget === this.editPreferenceWidgetForCusorPosition ? this.editPreferenceWidgetForMouseMove : this.editPreferenceWidgetForCusorPosition; + const editPreferenceWidgetToHide = editPreferencesWidget === this.editPreferenceWidgetForCursorPosition ? this.editPreferenceWidgetForMouseMove : this.editPreferenceWidgetForCursorPosition; editPreferenceWidgetToHide.hide(); } } @@ -1003,7 +986,7 @@ class EditSettingRenderer extends Disposable { // index of setting, across all groups/sections let index = 0; - const settings = []; + const settings: IIndexedSetting[] = []; for (const group of this.settingsGroups) { if (group.range.startLineNumber > lineNumber) { break; @@ -1019,11 +1002,11 @@ class EditSettingRenderer extends Disposable { // Only one level because override settings cannot have override settings for (const overrideSetting of setting.overrides) { if (lineNumber >= overrideSetting.range.startLineNumber && lineNumber <= overrideSetting.range.endLineNumber) { - settings.push({ ...overrideSetting, index }); + settings.push({ ...overrideSetting, index, groupId: group.id }); } } } else { - settings.push({ ...setting, index }); + settings.push({ ...setting, index, groupId: group.id }); } } @@ -1094,7 +1077,7 @@ class EditSettingRenderer extends Disposable { } private updateSetting(key: string, value: any, source: IIndexedSetting): void { - this._onUpdateSetting.fire({ key, value, source, index: source.index }); + this._onUpdateSetting.fire({ key, value, source }); } } @@ -1239,17 +1222,20 @@ class UnsupportedSettingsRenderer extends Disposable { class WorkspaceConfigurationRenderer extends Disposable { private decorationIds: string[] = []; + private associatedSettingsEditorModel: IPreferencesEditorModel; private renderingDelayer: Delayer = new Delayer(200); constructor(private editor: ICodeEditor, private workspaceSettingsEditorModel: SettingsEditorModel, @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService ) { super(); - this._register(this.editor.getModel().onDidChangeContent(() => this.renderingDelayer.trigger(() => this.render()))); + this._register(this.editor.getModel().onDidChangeContent(() => this.renderingDelayer.trigger(() => this.render(this.associatedSettingsEditorModel)))); } - public render(): void { - if (this.workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE && this.workspaceSettingsEditorModel instanceof WorkspaceConfigurationEditorModel) { + public render(associatedSettingsEditorModel: IPreferencesEditorModel): void { + this.associatedSettingsEditorModel = associatedSettingsEditorModel; + // Dim other configurations in workspace configuration file only in the context of Settings Editor + if (this.associatedSettingsEditorModel && this.workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE && this.workspaceSettingsEditorModel instanceof WorkspaceConfigurationEditorModel) { this.editor.changeDecorations(changeAccessor => this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, [])); const ranges: IRange[] = []; diff --git a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts index 7b740eae6ae..78cba03e94d 100644 --- a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts @@ -10,7 +10,6 @@ import * as DOM from 'vs/base/browser/dom'; import { TPromise } from 'vs/base/common/winjs.base'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Widget } from 'vs/base/browser/ui/widget'; -import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import Event, { Emitter } from 'vs/base/common/event'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -22,7 +21,7 @@ import { ISettingsGroup } from 'vs/workbench/parts/preferences/common/preference import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IAction, Action } from 'vs/base/common/actions'; -import { attachInputBoxStyler, attachStylerCallback, attachCheckboxStyler } from 'vs/platform/theme/common/styler'; +import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { Position } from 'vs/editor/common/core/position'; import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; @@ -32,7 +31,6 @@ import { Separator, ActionBar, ActionsOrientation, BaseActionItem } from 'vs/bas import { MarkdownString } from 'vs/base/common/htmlContent'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { IMarginData } from 'vs/editor/browser/controller/mouseTarget'; -import { render as renderOcticons } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; import { PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_INACTIVE_TITLE_FOREGROUND } from 'vs/workbench/common/theme'; import { IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/model'; @@ -103,32 +101,20 @@ export class SettingsHeaderWidget extends Widget implements IViewZone { export class DefaultSettingsHeaderWidget extends SettingsHeaderWidget { - private linkElement: HTMLElement; private _onClick = this._register(new Emitter()); public onClick: Event = this._onClick.event; protected create() { super.create(); - this.linkElement = DOM.append(this.titleContainer, DOM.$('a.settings-header-natural-language-link')); - this.linkElement.textContent = localize('defaultSettingsFuzzyPrompt', "Try natural language search!"); - - this.onclick(this.linkElement, e => this._onClick.fire()); this.toggleMessage(true); } - public toggleMessage(hasSettings: boolean, promptFuzzy = false): void { + public toggleMessage(hasSettings: boolean): void { if (hasSettings) { this.setMessage(localize('defaultSettings', "Place your settings in the right hand side editor to override.")); - DOM.addClass(this.linkElement, 'hidden'); } else { this.setMessage(localize('noSettingsFound', "No Settings Found.")); - - if (promptFuzzy) { - DOM.removeClass(this.linkElement, 'hidden'); - } else { - DOM.addClass(this.linkElement, 'hidden'); - } } } } @@ -533,7 +519,6 @@ export class SettingsTargetsWidget extends Widget { export interface SearchOptions extends IInputOptions { focusKey?: IContextKey; - showFuzzyToggle?: boolean; showResultCount?: boolean; } @@ -544,7 +529,6 @@ export class SearchWidget extends Widget { private countElement: HTMLElement; private searchContainer: HTMLElement; private inputBox: InputBox; - private fuzzyToggle: Checkbox; private controlsDiv: HTMLElement; private _onDidChange: Emitter = this._register(new Emitter()); @@ -562,32 +546,10 @@ export class SearchWidget extends Widget { this.create(parent); } - public get fuzzyEnabled(): boolean { - return this.fuzzyToggle.checked && this.fuzzyToggle.enabled; - } - - public set fuzzyEnabled(value: boolean) { - this.fuzzyToggle.checked = value; - } - private create(parent: HTMLElement) { this.domNode = DOM.append(parent, DOM.$('div.settings-header-widget')); this.createSearchContainer(DOM.append(this.domNode, DOM.$('div.settings-search-container'))); this.controlsDiv = DOM.append(this.domNode, DOM.$('div.settings-search-controls')); - if (this.options.showFuzzyToggle) { - this.fuzzyToggle = this._register(new Checkbox({ - actionClassName: 'prefs-natural-language-search-toggle', - isChecked: false, - onChange: () => { - this.inputBox.focus(); - this._onDidChange.fire(); - }, - title: localize('enableFuzzySearch', 'Enable natural language search') - })); - this.fuzzyToggle.domNode.innerHTML = renderOcticons('$(light-bulb)'); - DOM.append(this.controlsDiv, this.fuzzyToggle.domNode); - this._register(attachCheckboxStyler(this.fuzzyToggle, this.themeService)); - } if (this.options.showResultCount) { this.countElement = DOM.append(this.controlsDiv, DOM.$('.settings-count-widget')); @@ -639,16 +601,6 @@ export class SearchWidget extends Widget { } } - public setFuzzyToggleVisible(visible: boolean): void { - if (visible) { - this.fuzzyToggle.domNode.classList.remove('hidden'); - this.fuzzyToggle.enable(); - } else { - this.fuzzyToggle.domNode.classList.add('hidden'); - this.fuzzyToggle.disable(); - } - } - private styleCountElementForeground() { const colorId = DOM.hasClass(this.countElement, 'no-results') ? errorForeground : badgeForeground; const color = this.themeService.getTheme().getColor(colorId); @@ -673,8 +625,7 @@ export class SearchWidget extends Widget { private getControlsWidth(): number { const countWidth = this.countElement ? DOM.getTotalWidth(this.countElement) : 0; - const fuzzyToggleWidth = this.fuzzyToggle ? DOM.getTotalWidth(this.fuzzyToggle.domNode) : 0; - return countWidth + fuzzyToggleWidth + 20; + return countWidth + 20; } public focus() { diff --git a/src/vs/workbench/parts/preferences/common/preferences.ts b/src/vs/workbench/parts/preferences/common/preferences.ts index 77002043556..9330e27ba91 100644 --- a/src/vs/workbench/parts/preferences/common/preferences.ts +++ b/src/vs/workbench/parts/preferences/common/preferences.ts @@ -56,15 +56,31 @@ export interface ISetting { overrideOf?: ISetting; } +export interface ISearchResult { + filterMatches: ISettingMatch[]; + metadata?: IFilterMetadata; +} + +export interface ISearchResultGroup { + id: string; + label: string; + result: ISearchResult; +} + export interface IFilterResult { - query: string; + query?: string; filteredGroups: ISettingsGroup[]; allGroups: ISettingsGroup[]; matches: IRange[]; - fuzzySearchAvailable?: boolean; metadata?: IFilterMetadata; } +export interface ISettingMatch { + setting: ISetting; + matches: IRange[]; + score: number; +} + export interface IScoredResults { [key: string]: number; } @@ -86,14 +102,14 @@ export interface IPreferencesEditorModel { } export type IGroupFilter = (group: ISettingsGroup) => boolean; -export type ISettingMatcher = (setting: ISetting) => IRange[]; +export type ISettingMatcher = (setting: ISetting) => { matches: IRange[], score: number }; export interface ISettingsEditorModel extends IPreferencesEditorModel { readonly onDidChangeGroups: Event; settingsGroups: ISettingsGroup[]; - groupsTerms: string[]; - filterSettings(filter: string, groupFilter: IGroupFilter, settingMatcher: ISettingMatcher, mostRelevantSettings?: string[]): IFilterResult; + filterSettings(filter: string, groupFilter: IGroupFilter, settingMatcher: ISettingMatcher): ISettingMatch[]; findValueMatches(filter: string, setting: ISetting): IRange[]; + updateResultGroup(id: string, resultGroup: ISearchResultGroup): IFilterResult; } export interface IKeybindingsEditorModel extends IPreferencesEditorModel { @@ -133,6 +149,7 @@ export interface IKeybindingsEditor extends IEditor { removeKeybinding(keybindingEntry: IKeybindingItemEntry): TPromise; resetKeybinding(keybindingEntry: IKeybindingItemEntry): TPromise; copyKeybinding(keybindingEntry: IKeybindingItemEntry): TPromise; + copyKeybindingCommand(keybindingEntry: IKeybindingItemEntry): TPromise; showConflicts(keybindingEntry: IKeybindingItemEntry): TPromise; } @@ -159,15 +176,12 @@ export const IPreferencesSearchService = createDecorator; - - startSearch(filter: string, remote: boolean): IPreferencesSearchModel; + getLocalSearchProvider(filter: string): ISearchProvider; + getRemoteSearchProvider(filter: string): ISearchProvider; } -export interface IPreferencesSearchModel { - filterPreferences(preferencesModel: ISettingsEditorModel): TPromise; +export interface ISearchProvider { + searchModel(preferencesModel: ISettingsEditorModel): TPromise; } export const CONTEXT_SETTINGS_EDITOR = new RawContextKey('inSettingsEditor', false); @@ -187,6 +201,7 @@ export const KEYBINDINGS_EDITOR_COMMAND_DEFINE = 'keybindings.editor.defineKeybi export const KEYBINDINGS_EDITOR_COMMAND_REMOVE = 'keybindings.editor.removeKeybinding'; export const KEYBINDINGS_EDITOR_COMMAND_RESET = 'keybindings.editor.resetKeybinding'; export const KEYBINDINGS_EDITOR_COMMAND_COPY = 'keybindings.editor.copyKeybindingEntry'; +export const KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND = 'keybindings.editor.copyCommandKeybindingEntry'; export const KEYBINDINGS_EDITOR_COMMAND_SHOW_CONFLICTS = 'keybindings.editor.showConflicts'; export const KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS = 'keybindings.editor.focusKeybindings'; diff --git a/src/vs/workbench/parts/preferences/common/preferencesModels.ts b/src/vs/workbench/parts/preferences/common/preferencesModels.ts index 0ddf3a581cb..18b63f4e9c0 100644 --- a/src/vs/workbench/parts/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/parts/preferences/common/preferencesModels.ts @@ -5,93 +5,72 @@ import * as nls from 'vs/nls'; import { assign } from 'vs/base/common/objects'; -import { tail } from 'vs/base/common/arrays'; +import * as map from 'vs/base/common/map'; +import { tail, flatten, first } from 'vs/base/common/arrays'; import URI from 'vs/base/common/uri'; import { IReference, Disposable } from 'vs/base/common/lifecycle'; import Event, { Emitter } from 'vs/base/common/event'; import { Registry } from 'vs/platform/registry/common/platform'; import { visit, JSONVisitor } from 'vs/base/common/json'; -import { ITextModel } from 'vs/editor/common/model'; +import { ITextModel, IIdentifiedSingleEditOperation } from 'vs/editor/common/model'; import { EditorModel } from 'vs/workbench/common/editor'; import { IConfigurationNode, IConfigurationRegistry, Extensions, OVERRIDE_PROPERTY_PATTERN, IConfigurationPropertySchema, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; -import { ISettingsEditorModel, IKeybindingsEditorModel, ISettingsGroup, ISetting, IFilterResult, ISettingsSection, IGroupFilter, ISettingMatcher } from 'vs/workbench/parts/preferences/common/preferences'; +import { ISettingsEditorModel, IKeybindingsEditorModel, ISettingsGroup, ISetting, IFilterResult, IGroupFilter, ISettingMatcher, ISettingMatch, ISearchResultGroup } from 'vs/workbench/parts/preferences/common/preferences'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { Selection } from 'vs/editor/common/core/selection'; export abstract class AbstractSettingsModel extends EditorModel { - public get groupsTerms(): string[] { - return this.settingsGroups.map(group => '@' + group.id); + protected _currentResultGroups = new Map(); + + public updateResultGroup(id: string, resultGroup: ISearchResultGroup): IFilterResult { + if (resultGroup) { + this._currentResultGroups.set(id, resultGroup); + } else { + this._currentResultGroups.delete(id); + } + + this.removeDuplicateResults(); + return this.update(); } - protected doFilterSettings(filter: string, groupFilter: IGroupFilter, settingMatcher: ISettingMatcher): IFilterResult { - const allGroups = this.settingsGroups; + /** + * Remove duplicates between result groups, preferring results in earlier groups + */ + private removeDuplicateResults(): void { + // Depends on order of map keys + const settingKeys = new Set(); + this._currentResultGroups.forEach((group, id) => { + group.result.filterMatches = group.result.filterMatches.filter(s => !settingKeys.has(s.setting.key)); + group.result.filterMatches.forEach(s => settingKeys.add(s.setting.key)); + }); + } - if (!filter) { - return { - filteredGroups: allGroups, - allGroups, - matches: [], - query: filter - }; - } + public filterSettings(filter: string, groupFilter: IGroupFilter, settingMatcher: ISettingMatcher): ISettingMatch[] { + const allGroups = this.filterGroups; - const group = this.filterByGroupTerm(filter); - if (group) { - return { - filteredGroups: [group], - allGroups, - matches: [], - query: filter - }; - } - - const matches: IRange[] = []; - const filteredGroups: ISettingsGroup[] = []; + const filterMatches: ISettingMatch[] = []; for (const group of allGroups) { const groupMatched = groupFilter(group); - const sections: ISettingsSection[] = []; for (const section of group.sections) { - const settings: ISetting[] = []; for (const setting of section.settings) { - const settingMatches = settingMatcher(setting); - if (groupMatched || settingMatches && settingMatches.length) { - settings.push(setting); - } + const settingMatchResult = settingMatcher(setting); - if (settingMatches) { - matches.push(...settingMatches); + if (groupMatched || settingMatchResult) { + filterMatches.push({ + setting, + matches: settingMatchResult && settingMatchResult.matches, + score: settingMatchResult ? settingMatchResult.score : 0 + }); } } - if (settings.length) { - sections.push({ - title: section.title, - settings, - titleRange: section.titleRange - }); - } - } - if (sections.length) { - filteredGroups.push({ - id: group.id, - title: group.title, - titleRange: group.titleRange, - sections, - range: group.range - }); } } - return { filteredGroups, matches, allGroups, query: filter }; - } - private filterByGroupTerm(filter: string): ISettingsGroup { - if (this.groupsTerms.indexOf(filter) !== -1) { - const id = filter.substring(1); - return this.settingsGroups.filter(group => group.id === id)[0]; - } - return null; + return filterMatches.sort((a, b) => b.score - a.score); } public getPreference(key: string): ISetting { @@ -107,9 +86,15 @@ export abstract class AbstractSettingsModel extends EditorModel { return null; } + protected get filterGroups(): ISettingsGroup[] { + return this.settingsGroups; + } + public abstract settingsGroups: ISettingsGroup[]; public abstract findValueMatches(filter: string, setting: ISetting): IRange[]; + + protected abstract update(): IFilterResult; } export class SettingsEditorModel extends AbstractSettingsModel implements ISettingsEditorModel { @@ -149,10 +134,6 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti return this.settingsModel.getValue(); } - public filterSettings(filter: string, groupFilter: IGroupFilter, settingMatcher: ISettingMatcher): IFilterResult { - return this.doFilterSettings(filter, groupFilter, settingMatcher); - } - public findValueMatches(filter: string, setting: ISetting): IRange[] { return this.settingsModel.findMatches(filter, setting.valueRange, false, false, null, false).map(match => match.range); } @@ -164,6 +145,45 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti protected parse(): void { this._settingsGroups = parse(this.settingsModel, (property: string, previousParents: string[]): boolean => this.isSettingsProperty(property, previousParents)); } + + protected update(): IFilterResult { + const resultGroups = map.values(this._currentResultGroups); + if (!resultGroups.length) { + return null; + } + + // Transform resultGroups into IFilterResult - ISetting ranges are already correct here + const filteredSettings: ISetting[] = []; + const matches: IRange[] = []; + resultGroups.forEach(group => { + group.result.filterMatches.forEach(filterMatch => { + filteredSettings.push(filterMatch.setting); + matches.push(...filterMatch.matches); + }); + }); + + let filteredGroup: ISettingsGroup; + const modelGroup = this.settingsGroups[0]; // Editable model has one or zero groups + if (modelGroup) { + filteredGroup = { + id: modelGroup.id, + range: modelGroup.range, + sections: [{ + settings: filteredSettings + }], + title: modelGroup.title, + titleRange: modelGroup.titleRange + }; + } + + const groupWithMetadata = first(resultGroups, group => !!group.result.metadata); + return { + allGroups: this.settingsGroups, + filteredGroups: filteredGroup ? [filteredGroup] : [], + matches, + metadata: groupWithMetadata && groupWithMetadata.result.metadata + }; + } } function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, previousParents: string[]) => boolean): ISettingsGroup[] { @@ -382,6 +402,7 @@ export class DefaultSettings extends Disposable { if (!this._allSettingsGroups) { this.parse(); } + return this._allSettingsGroups; } @@ -390,7 +411,7 @@ export class DefaultSettings extends Disposable { this.initAllSettingsMap(settingsGroups); const mostCommonlyUsed = this.getMostCommonlyUsedSettings(settingsGroups); this._allSettingsGroups = [mostCommonlyUsed, ...settingsGroups]; - this._content = this.toContent(true, [mostCommonlyUsed], settingsGroups); + this._content = this.toContent(true, this._allSettingsGroups); return this._content; } @@ -538,17 +559,14 @@ export class DefaultSettings extends Disposable { return c1.order - c2.order; } - private toContent(asArray: boolean, ...settingsGroups: ISettingsGroup[][]): string { + private toContent(asArray: boolean, settingsGroups: ISettingsGroup[]): string { const builder = new SettingsContentBuilder(); if (asArray) { builder.pushLine('['); } settingsGroups.forEach((settingsGroup, i) => { - builder.pushGroups(settingsGroup); - - if (i !== settingsGroups.length - 1) { - builder.pushLine(','); - } + builder.pushGroup(settingsGroup); + builder.pushLine(','); }); if (asArray) { builder.pushLine(']'); @@ -586,49 +604,101 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements return this.defaultSettings.settingsGroups; } - public filterSettings(filter: string, groupFilter: IGroupFilter, settingMatcher: ISettingMatcher, mostRelevantSettings?: string[]): IFilterResult { - if (mostRelevantSettings) { - const mostRelevantGroup = this.renderMostRelevantSettings(mostRelevantSettings); - - // calculate match ranges - const matches = mostRelevantGroup.sections[0].settings.reduce((prev, s) => { - return prev.concat(settingMatcher(s)); - }, []); - - return { - allGroups: [...this.settingsGroups, mostRelevantGroup], - filteredGroups: mostRelevantGroup.sections[0].settings.length ? [mostRelevantGroup] : [], - matches, - query: filter - }; - } else { - // Do local search and add empty 'most relevant' group - const mostRelevantGroup = this.renderMostRelevantSettings([]); - const result = this.doFilterSettings(filter, groupFilter, settingMatcher); - result.allGroups = [...result.allGroups, mostRelevantGroup]; - return result; - } + protected get filterGroups(): ISettingsGroup[] { + // Don't look at "commonly used" for filter + return this.settingsGroups.slice(1); } - private renderMostRelevantSettings(mostRelevantSettings: string[]): ISettingsGroup { - const mostRelevantLineOffset = tail(this.settingsGroups).range.endLineNumber + 2; - const builder = new SettingsContentBuilder(mostRelevantLineOffset - 1); + protected update(): IFilterResult { + // Grab current result groups, only render non-empty groups + const resultGroups = map.values(this._currentResultGroups); + const nonEmptyResultGroups = resultGroups.filter(group => group.result.filterMatches.length); + + const startLine = tail(this.settingsGroups).range.endLineNumber + 2; + const { settingsGroups: filteredGroups, matches } = this.writeResultGroups(nonEmptyResultGroups, startLine); + + const groupWithMetadata = first(resultGroups, group => !!group.result.metadata); + return resultGroups.length ? + { + allGroups: this.settingsGroups, + filteredGroups, + matches, + metadata: groupWithMetadata && groupWithMetadata.result.metadata + } : + null; + } + + /** + * Translate the ISearchResultGroups to text, and write it to the editor model + */ + private writeResultGroups(groups: ISearchResultGroup[], startLine: number): { matches: IRange[], settingsGroups: ISettingsGroup[] } { + const contentBuilderOffset = startLine - 1; + const builder = new SettingsContentBuilder(contentBuilderOffset); + + const settingsGroups: ISettingsGroup[] = []; + const matches: IRange[] = []; builder.pushLine(','); - const mostRelevantGroup = this.getMostRelevantSettings(mostRelevantSettings); - builder.pushGroups([mostRelevantGroup]); - builder.pushLine(''); + groups.forEach(resultGroup => { + const settingsGroup = this.getGroup(resultGroup); + settingsGroups.push(settingsGroup); + matches.push(...this.writeSettingsGroupToBuilder(builder, settingsGroup, resultGroup.result.filterMatches)); + }); // note: 1-indexed line numbers here - const mostRelevantContent = builder.getContent(); - const mostRelevantEndLine = this._model.getLineCount(); - this._model.applyEdits([ - { - text: mostRelevantContent, - range: new Range(mostRelevantLineOffset, 1, mostRelevantEndLine, 1) - } - ]); + const groupContent = builder.getContent() + '\n'; + const groupEndLine = this._model.getLineCount(); + const cursorPosition = new Selection(startLine, 1, startLine, 1); + const edit: IIdentifiedSingleEditOperation = { + text: groupContent, + forceMoveMarkers: true, + range: new Range(startLine, 1, groupEndLine, 1), + identifier: { major: 1, minor: 0 } + }; - return mostRelevantGroup; + this._model.pushEditOperations([cursorPosition], [edit], () => [cursorPosition]); + + // Force tokenization now - otherwise it may be slightly delayed, causing a flash of white text + const tokenizeTo = Math.min(startLine + 60, this._model.getLineCount()); + this._model.forceTokenization(tokenizeTo); + + return { matches, settingsGroups }; + } + + private writeSettingsGroupToBuilder(builder: SettingsContentBuilder, settingsGroup: ISettingsGroup, filterMatches: ISettingMatch[]): IRange[] { + // Fix match ranges to offset from setting start line + filterMatches = filterMatches.map(filteredMatch => { + return { + setting: filteredMatch.setting, + score: filteredMatch.score, + matches: filteredMatch.matches && filteredMatch.matches.map(match => { + return new Range( + match.startLineNumber - filteredMatch.setting.range.startLineNumber, + match.startColumn, + match.endLineNumber - filteredMatch.setting.range.startLineNumber, + match.endColumn); + }) + }; + }); + + builder.pushGroup(settingsGroup); + builder.pushLine(','); + + // builder has rewritten settings ranges, fix match ranges + const fixedMatches = flatten( + filterMatches + .map(m => m.matches || []) + .map((settingMatches, i) => { + const setting = settingsGroup.sections[0].settings[i]; + return settingMatches.map(range => { + return new Range( + range.startLineNumber + setting.range.startLineNumber, + range.startColumn, + range.endLineNumber + setting.range.startLineNumber, + range.endColumn); + }); + })); + + return fixedMatches; } public findValueMatches(filter: string, setting: ISetting): IRange[] { @@ -648,30 +718,28 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements return null; } - private getMostRelevantSettings(rankedSettingNames: string[]): ISettingsGroup { - const settings = rankedSettingNames.map(key => { - const setting = this.defaultSettings.getSettingByName(key); - if (setting) { - return { - description: setting.description, - key: setting.key, - value: setting.value, - range: null, - valueRange: null, - overrides: [] - }; - } - return null; - }).filter(setting => !!setting); + private copySettings(settings: ISetting[]): ISetting[] { + return settings.map(setting => { + return { + description: setting.description, + key: setting.key, + value: setting.value, + range: null, + valueRange: null, + overrides: [] + }; + }); + } + private getGroup(resultGroup: ISearchResultGroup): ISettingsGroup { return { - id: 'mostRelevant', + id: resultGroup.id, range: null, - title: nls.localize('mostRelevant', "Most Relevant"), + title: resultGroup.label, titleRange: null, sections: [ { - settings + settings: this.copySettings(resultGroup.result.filterMatches.map(m => m.setting)) } ] }; @@ -681,10 +749,6 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements class SettingsContentBuilder { private _contentByLines: string[]; - get lines(): string[] { - return this._contentByLines; - } - private get lineCountWithOffset(): number { return this._contentByLines.length + this._rangeOffset; } @@ -705,24 +769,23 @@ class SettingsContentBuilder { this._contentByLines.push(...lineText); } - pushGroups(settingsGroups: ISettingsGroup[]): void { - let lastSetting: ISetting = null; + pushGroup(settingsGroups: ISettingsGroup): void { this._contentByLines.push('{'); this._contentByLines.push(''); - for (const group of settingsGroups) { - this._contentByLines.push(''); - lastSetting = this.pushGroup(group); - } + this._contentByLines.push(''); + const lastSetting = this._pushGroup(settingsGroups); + if (lastSetting) { // Strip the comma from the last setting const lineIdx = this.offsetIndexToIndex(lastSetting.range.endLineNumber); const content = this._contentByLines[lineIdx - 2]; this._contentByLines[lineIdx - 2] = content.substring(0, content.length - 1); } + this._contentByLines.push('}'); } - private pushGroup(group: ISettingsGroup): ISetting { + private _pushGroup(group: ISettingsGroup): ISetting { const indent = ' '; let lastSetting: ISetting = null; let groupStart = this.lineCountWithOffset + 1; diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts index 24b637b2cea..986c46a2e34 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferences.contribution.ts @@ -19,7 +19,7 @@ import { KeybindingsEditor, KeybindingsEditorInput } from 'vs/workbench/parts/pr import { OpenRawDefaultSettingsAction, OpenGlobalSettingsAction, OpenGlobalKeybindingsAction, OpenGlobalKeybindingsFileAction, OpenWorkspaceSettingsAction, OpenFolderSettingsAction, ConfigureLanguageBasedSettingsAction, OPEN_FOLDER_SETTINGS_COMMAND } from 'vs/workbench/parts/preferences/browser/preferencesActions'; import { IPreferencesService, IKeybindingsEditor, IPreferencesSearchService, CONTEXT_KEYBINDING_FOCUS, CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS, KEYBINDINGS_EDITOR_COMMAND_DEFINE, KEYBINDINGS_EDITOR_COMMAND_REMOVE, KEYBINDINGS_EDITOR_COMMAND_SEARCH, - KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_SHOW_CONFLICTS, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS + KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_SHOW_CONFLICTS, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS } from 'vs/workbench/parts/preferences/common/preferences'; import { PreferencesService } from 'vs/workbench/parts/preferences/browser/preferencesService'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; @@ -238,6 +238,17 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, + weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), + when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDING_FOCUS), + primary: null, + handler: (accessor, args: any) => { + const editor = accessor.get(IWorkbenchEditorService).getActiveEditor() as IKeybindingsEditor; + editor.copyKeybindingCommand(editor.activeKeybindingEntry); + } +}); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, weight: KeybindingsRegistry.WEIGHT.workbenchContrib(), diff --git a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts index f99d62999fd..763be7bcc05 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/preferencesSearch.ts @@ -4,11 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { TPromise } from 'vs/base/common/winjs.base'; -import * as errors from 'vs/base/common/errors'; -import Event, { Emitter } from 'vs/base/common/event'; -import { ISettingsEditorModel, IFilterResult, ISetting, ISettingsGroup, IWorkbenchSettingsConfiguration, IFilterMetadata, IPreferencesSearchService, IPreferencesSearchModel } from 'vs/workbench/parts/preferences/common/preferences'; +import { ISettingsEditorModel, ISetting, ISettingsGroup, IWorkbenchSettingsConfiguration, IFilterMetadata, IPreferencesSearchService, ISearchResult, ISearchProvider, IGroupFilter, ISettingMatcher, IScoredResults } from 'vs/workbench/parts/preferences/common/preferences'; import { IRange } from 'vs/editor/common/core/range'; -import { distinct } from 'vs/base/common/arrays'; +import { distinct, top } from 'vs/base/common/arrays'; import * as strings from 'vs/base/common/strings'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -20,7 +18,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IRequestService } from 'vs/platform/request/node/request'; import { asJson } from 'vs/base/node/request'; import { Disposable } from 'vs/base/common/lifecycle'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IExtensionManagementService, LocalExtensionType, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; export interface IEndpointDetails { urlBase: string; @@ -30,19 +28,19 @@ export interface IEndpointDetails { export class PreferencesSearchService extends Disposable implements IPreferencesSearchService { _serviceBrand: any; - private _onRemoteSearchEnablementChanged = new Emitter(); - public onRemoteSearchEnablementChanged: Event = this._onRemoteSearchEnablementChanged.event; + private _installedExtensions: TPromise; constructor( @IWorkspaceConfigurationService private configurationService: IWorkspaceConfigurationService, @IEnvironmentService private environmentService: IEnvironmentService, - @IInstantiationService private instantiationService: IInstantiationService + @IInstantiationService private instantiationService: IInstantiationService, + @IExtensionManagementService private extensionManagementService: IExtensionManagementService ) { super(); - this._register(configurationService.onDidChangeConfiguration(() => this._onRemoteSearchEnablementChanged.fire(this.remoteSearchAllowed))); + this._installedExtensions = this.extensionManagementService.getInstalled(LocalExtensionType.User); } - get remoteSearchAllowed(): boolean { + private get remoteSearchAllowed(): boolean { if (this.environmentService.appQuality === 'stable') { return false; } @@ -52,10 +50,10 @@ export class PreferencesSearchService extends Disposable implements IPreferences return false; } - return !!this.endpoint.urlBase; + return !!this._endpoint.urlBase; } - get endpoint(): IEndpointDetails { + private get _endpoint(): IEndpointDetails { const workbenchSettings = this.configurationService.getValue().workbench.settings; if (workbenchSettings.naturalLanguageSearchEndpoint) { return { @@ -69,101 +67,81 @@ export class PreferencesSearchService extends Disposable implements IPreferences } } - startSearch(filter: string, remote: boolean): PreferencesSearchModel { - return this.instantiationService.createInstance(PreferencesSearchModel, this, filter, remote); + getRemoteSearchProvider(filter: string): RemoteSearchProvider { + return this.remoteSearchAllowed && this.instantiationService.createInstance(RemoteSearchProvider, filter, this._endpoint, this._installedExtensions); + } + + getLocalSearchProvider(filter: string): LocalSearchProvider { + return this.instantiationService.createInstance(LocalSearchProvider, filter); } } -export class PreferencesSearchModel implements IPreferencesSearchModel { - private _localProvider: LocalSearchProvider; - private _remoteProvider: RemoteSearchProvider; - - constructor( - private provider: IPreferencesSearchService, private filter: string, remote: boolean, - @IInstantiationService instantiationService: IInstantiationService, - @ITelemetryService private telemetryService: ITelemetryService - ) { - this._localProvider = new LocalSearchProvider(filter); - - if (remote && filter) { - this._remoteProvider = instantiationService.createInstance(RemoteSearchProvider, filter, this.provider.endpoint); - } - } - - filterPreferences(preferencesModel: ISettingsEditorModel): TPromise { - if (!this.filter) { - return TPromise.wrap(null); - } - - if (this._remoteProvider) { - return this._remoteProvider.filterPreferences(preferencesModel).then(null, err => { - const message = errors.getErrorMessage(err); - - if (message.toLowerCase() !== 'canceled') { - /* __GDPR__ - "defaultSettings.searchError" : { - "message": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this.telemetryService.publicLog('defaultSettings.searchError', { message }); - } - - return this._localProvider.filterPreferences(preferencesModel); - }); - } else { - return this._localProvider.filterPreferences(preferencesModel); - } - } -} - -class LocalSearchProvider { +export class LocalSearchProvider implements ISearchProvider { private _filter: string; constructor(filter: string) { this._filter = filter; } - filterPreferences(preferencesModel: ISettingsEditorModel): TPromise { - const regex = strings.createRegExp(this._filter, false, { global: true }); + searchModel(preferencesModel: ISettingsEditorModel): TPromise { + if (!this._filter) { + return TPromise.wrap(null); + } - const groupFilter = (group: ISettingsGroup) => { + let score = 1000; // Sort is not stable + const settingMatcher = (setting: ISetting) => { + const matches = new SettingMatches(this._filter, setting, true, (filter, setting) => preferencesModel.findValueMatches(filter, setting)).matches; + return matches && matches.length ? + { + matches, + score: score-- + } : + null; + }; + + const filterMatches = preferencesModel.filterSettings(this._filter, this.getGroupFilter(this._filter), settingMatcher); + return TPromise.wrap({ + filterMatches + }); + } + + private getGroupFilter(filter: string): IGroupFilter { + const regex = strings.createRegExp(this._filter, false, { global: true }); + return (group: ISettingsGroup) => { return regex.test(group.title); }; - - const settingMatcher = (setting: ISetting) => { - return new SettingMatches(this._filter, setting, true, (filter, setting) => preferencesModel.findValueMatches(filter, setting)).matches; - }; - - return TPromise.wrap(preferencesModel.filterSettings(this._filter, groupFilter, settingMatcher)); } } -class RemoteSearchProvider { +export class RemoteSearchProvider implements ISearchProvider { private _filter: string; private _remoteSearchP: TPromise; - constructor(filter: string, endpoint: IEndpointDetails, + constructor(filter: string, endpoint: IEndpointDetails, private installedExtensions: TPromise, @IEnvironmentService private environmentService: IEnvironmentService, - @IRequestService private requestService: IRequestService + @IRequestService private requestService: IRequestService, ) { this._filter = filter; - this._remoteSearchP = filter ? this.getSettingsFromBing(filter, endpoint) : TPromise.wrap(null); + + // @queries are always handled by local filter + this._remoteSearchP = filter && !strings.startsWith(filter, '@') ? + this.getSettingsFromBing(filter, endpoint) : + TPromise.wrap(null); } - filterPreferences(preferencesModel: ISettingsEditorModel): TPromise { + searchModel(preferencesModel: ISettingsEditorModel): TPromise { return this._remoteSearchP.then(remoteResult => { if (remoteResult) { - let sortedNames = Object.keys(remoteResult.scoredResults).sort((a, b) => remoteResult.scoredResults[b] - remoteResult.scoredResults[a]); - if (sortedNames.length) { - const highScore = remoteResult.scoredResults[sortedNames[0]]; - const minScore = highScore / 5; - sortedNames = sortedNames.filter(name => remoteResult.scoredResults[name] >= minScore); - } + const highScoreKey = top(Object.keys(remoteResult.scoredResults), (a, b) => remoteResult.scoredResults[b] - remoteResult.scoredResults[a], 1)[0]; + const highScore = highScoreKey ? remoteResult.scoredResults[highScoreKey] : 0; + const minScore = highScore / 5; - const settingMatcher = this.getRemoteSettingMatcher(sortedNames, preferencesModel); - const result = preferencesModel.filterSettings(this._filter, group => null, settingMatcher, sortedNames); - result.metadata = remoteResult; - return result; + const settingMatcher = this.getRemoteSettingMatcher(remoteResult.scoredResults, minScore, preferencesModel); + const filterMatches = preferencesModel.filterSettings(this._filter, group => null, settingMatcher); + return { + filterMatches, + metadata: remoteResult + }; } else { return null; } @@ -171,25 +149,23 @@ class RemoteSearchProvider { } private getSettingsFromBing(filter: string, endpoint: IEndpointDetails): TPromise { - const url = prepareUrl(filter, endpoint, this.environmentService.settingsSearchBuildId); const start = Date.now(); - const p = this.requestService.request({ - url, - headers: { - 'User-Agent': 'request', - 'Content-Type': 'application/json; charset=utf-8', - 'api-key': endpoint.key - }, - timeout: 5000 - }) - .then(context => { + return this.prepareUrl(filter, endpoint, this.environmentService.settingsSearchBuildId).then(url => { + return this.requestService.request({ + url, + headers: { + 'User-Agent': 'request', + 'Content-Type': 'application/json; charset=utf-8', + 'api-key': endpoint.key + }, + timeout: 5000 + }).then(context => { if (context.res.statusCode >= 300) { throw new Error(`${url} returned status code: ${context.res.statusCode}`); } return asJson(context); - }) - .then((result: any) => { + }).then((result: any) => { const timestamp = Date.now(); const duration = timestamp - start; const suggestions = (result.value || []) @@ -214,30 +190,65 @@ class RemoteSearchProvider { context: result['@odata.context'] }; }); - - return TPromise.as(p as any); + }); } - private getRemoteSettingMatcher(names: string[], preferencesModel: ISettingsEditorModel): any { - const resultSet = new Set(); - names.forEach(name => resultSet.add(name)); - + private getRemoteSettingMatcher(scoredResults: IScoredResults, minScore: number, preferencesModel: ISettingsEditorModel): ISettingMatcher { return (setting: ISetting) => { - if (resultSet.has(setting.key)) { + const score = scoredResults[setting.key]; + if (typeof score === 'number' && score >= minScore) { const settingMatches = new SettingMatches(this._filter, setting, false, (filter, setting) => preferencesModel.findValueMatches(filter, setting)).matches; - if (settingMatches.length) { - return settingMatches; + return { matches: settingMatches, score: scoredResults[setting.key] }; + } + + return null; + }; + } + + private prepareUrl(query: string, endpoint: IEndpointDetails, buildNumber: number): TPromise { + query = escapeSpecialChars(query); + const boost = 10; + const userQuery = `(${query})^${boost}`; + + // Appending Fuzzy after each word. + query = query.replace(/\ +/g, '~ ') + '~'; + + const encodedQuery = encodeURIComponent(userQuery + ' || ' + query); + let url = `${endpoint.urlBase}?`; + + return this.installedExtensions.then(exts => { + if (endpoint.key) { + url += `${API_VERSION}`; + url += `&search=${encodedQuery}`; + + const filters = exts.map(ext => { + const uuid = ext.identifier.uuid; + const versionString = ext.manifest.version + .split('.') + .map(versionPart => strings.pad(versionPart, 10)) + .join(''); + + return `(packageid eq '${uuid}' and startbuildno le '${versionString}' and endbuildno ge '${versionString}')`; + }); + + if (buildNumber) { + filters.push(`(packageid eq 'core' and startbuildno le '${buildNumber}' and endbuildno ge '${buildNumber}')`); + url += `&$filter=${filters.join(' or ')}`; + } + } else { + url += `query=${encodedQuery}`; + + if (buildNumber) { + url += `&build=${buildNumber}`; } } - return []; - }; + return url; + }); } } const API_VERSION = 'api-version=2016-09-01-Preview'; -const QUERY_TYPE = 'querytype=full'; -const SCORING_PROFILE = 'scoringProfile=ranking'; function escapeSpecialChars(query: string): string { return query.replace(/\./g, ' ') @@ -246,34 +257,6 @@ function escapeSpecialChars(query: string): string { .trim(); } -function prepareUrl(query: string, endpoint: IEndpointDetails, buildNumber: number): string { - query = escapeSpecialChars(query); - const boost = 10; - const userQuery = `(${query})^${boost}`; - - // Appending Fuzzy after each word. - query = query.replace(/\ +/g, '~ ') + '~'; - - const encodedQuery = encodeURIComponent(userQuery + ' || ' + query); - let url = `${endpoint.urlBase}?`; - if (endpoint.key) { - url += `search=${encodedQuery}`; - url += `&${API_VERSION}&${QUERY_TYPE}&${SCORING_PROFILE}`; - - if (buildNumber) { - url += `&$filter startbuildno le ${buildNumber} and endbuildno ge ${buildNumber}`; - } - } else { - url += `query=${encodedQuery}`; - - if (buildNumber) { - url += `&build=${buildNumber}`; - } - } - - return url; -} - class SettingMatches { private readonly descriptionMatchingWords: Map = new Map(); diff --git a/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.ts b/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.ts index 6d6da7ea870..91000b5b8f3 100644 --- a/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.ts +++ b/src/vs/workbench/parts/quickopen/browser/quickopen.contribution.ts @@ -43,8 +43,9 @@ const inViewsPickerContext = ContextKeyExpr.and(inQuickOpenContext, ContextKeyEx const viewPickerKeybinding = { primary: KeyMod.CtrlCmd | KeyCode.KEY_Q, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_Q }, linux: { primary: null } }; -registry.registerWorkbenchAction(new SyncActionDescriptor(OpenViewPickerAction, OpenViewPickerAction.ID, OpenViewPickerAction.LABEL), 'Open View'); -registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenViewPickerAction, QuickOpenViewPickerAction.ID, QuickOpenViewPickerAction.LABEL, viewPickerKeybinding), 'Quick Open View'); +const viewCategory = nls.localize('view', "View"); +registry.registerWorkbenchAction(new SyncActionDescriptor(OpenViewPickerAction, OpenViewPickerAction.ID, OpenViewPickerAction.LABEL), 'View: Open View', viewCategory); +registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenViewPickerAction, QuickOpenViewPickerAction.ID, QuickOpenViewPickerAction.LABEL, viewPickerKeybinding), 'View: Quick Open View', viewCategory); const quickOpenNavigateNextInViewPickerId = 'workbench.action.quickOpenNavigateNextInViewPicker'; KeybindingsRegistry.registerCommandAndKeybindingRule({ diff --git a/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts b/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts index bcfefc9f74f..2c1c4186639 100644 --- a/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts +++ b/src/vs/workbench/parts/quickopen/browser/viewPickerHandler.ts @@ -19,6 +19,12 @@ import { Action } from 'vs/base/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { fuzzyContains, stripWildcards } from 'vs/base/common/strings'; import { matchesFuzzy } from 'vs/base/common/filters'; +import { ViewsRegistry, ViewLocation, IViewsViewlet } from 'vs/workbench/common/views'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { VIEWLET_ID as EXPLORER_VIEWLET_ID } from 'vs/workbench/parts/files/common/files'; +import { VIEWLET_ID as DEBUG_VIEWLET_ID } from 'vs/workbench/parts/debug/common/debug'; +import { VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions'; +import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; export const VIEW_PICKER_PREFIX = 'view '; @@ -69,7 +75,8 @@ export class ViewPickerHandler extends QuickOpenHandler { @IViewletService private viewletService: IViewletService, @IOutputService private outputService: IOutputService, @ITerminalService private terminalService: ITerminalService, - @IPanelService private panelService: IPanelService + @IPanelService private panelService: IPanelService, + @IContextKeyService private contextKeyService: IContextKeyService, ) { super(); } @@ -116,12 +123,31 @@ export class ViewPickerHandler extends QuickOpenHandler { private getViewEntries(): ViewEntry[] { const viewEntries: ViewEntry[] = []; + const getViewEntriesForViewlet = (viewlet: ViewletDescriptor, viewLocation: ViewLocation): ViewEntry[] => { + const views = ViewsRegistry.getViews(viewLocation); + const result: ViewEntry[] = []; + if (views.length) { + for (const view of views) { + if (this.contextKeyService.contextMatchesRules(view.when)) { + result.push(new ViewEntry(view.name, viewlet.name, () => this.viewletService.openViewlet(viewlet.id, true).done(viewlet => (viewlet).openView(view.id), errors.onUnexpectedError))); + } + } + } + return result; + }; + // Viewlets const viewlets = this.viewletService.getViewlets(); viewlets.forEach((viewlet, index) => { - const viewsCategory = nls.localize('views', "Views"); - const entry = new ViewEntry(viewlet.name, viewsCategory, () => this.viewletService.openViewlet(viewlet.id, true).done(null, errors.onUnexpectedError)); - viewEntries.push(entry); + const viewLocation: ViewLocation = viewlet.id === EXPLORER_VIEWLET_ID ? ViewLocation.Explorer + : viewlet.id === DEBUG_VIEWLET_ID ? ViewLocation.Debug + : viewlet.id === EXTENSIONS_VIEWLET_ID ? ViewLocation.Extensions + : null; + + const viewEntriesForViewlet: ViewEntry[] = viewLocation ? getViewEntriesForViewlet(viewlet, viewLocation) + : [new ViewEntry(viewlet.name, nls.localize('views', "Views"), () => this.viewletService.openViewlet(viewlet.id, true).done(null, errors.onUnexpectedError))]; + + viewEntries.push(...viewEntriesForViewlet); }); const terminals = this.terminalService.terminalInstances; diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index 156a7bb20a6..6a467b92bea 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -55,7 +55,7 @@ import * as platform from 'vs/base/common/platform'; import { format } from 'vs/base/common/strings'; import { ISpliceable, ISequence, ISplice } from 'vs/base/common/sequence'; import { firstIndex } from 'vs/base/common/arrays'; -import { WorkbenchList, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchList } from 'vs/platform/list/browser/listService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; // TODO@Joao @@ -226,9 +226,7 @@ class MainPanel extends ViewletPanel { @IContextMenuService protected contextMenuService: IContextMenuService, @ISCMService protected scmService: ISCMService, @IInstantiationService private instantiationService: IInstantiationService, - @IThemeService private themeService: IThemeService, @IContextKeyService private contextKeyService: IContextKeyService, - @IListService private listService: IListService, @IMenuService private menuService: IMenuService ) { super(localize('scm providers', "Source Control Providers"), {}, keybindingService, contextMenuService); @@ -260,9 +258,9 @@ class MainPanel extends ViewletPanel { const delegate = new ProvidersListDelegate(); const renderer = this.instantiationService.createInstance(ProviderRenderer); - this.list = new WorkbenchList(container, delegate, [renderer], { + this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [renderer], { identityProvider: repository => repository.provider.id - }, this.contextKeyService, this.listService, this.themeService); + }); this.disposables.push(this.list); this.list.onSelectionChange(this.onListSelectionChange, this, this.disposables); @@ -690,12 +688,10 @@ export class RepositoryPanel extends ViewletPanel { @IThemeService protected themeService: IThemeService, @IContextMenuService protected contextMenuService: IContextMenuService, @IContextViewService protected contextViewService: IContextViewService, - @IListService protected listService: IListService, @ICommandService protected commandService: ICommandService, @IMessageService protected messageService: IMessageService, @IWorkbenchEditorService protected editorService: IWorkbenchEditorService, @IEditorGroupService protected editorGroupService: IEditorGroupService, - @IContextKeyService protected contextKeyService: IContextKeyService, @IInstantiationService protected instantiationService: IInstantiationService, @IConfigurationService protected configurationService: IConfigurationService ) { @@ -844,10 +840,10 @@ export class RepositoryPanel extends ViewletPanel { this.instantiationService.createInstance(ResourceRenderer, this.menus, actionItemProvider, () => this.getSelectedResources()), ]; - this.list = new WorkbenchList(this.listContainer, delegate, renderers, { + this.list = this.instantiationService.createInstance(WorkbenchList, this.listContainer, delegate, renderers, { identityProvider: scmResourceIdentityProvider, keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); chain(this.list.onOpen) .map(e => e.elements[0]) diff --git a/src/vs/workbench/parts/search/browser/searchViewlet.ts b/src/vs/workbench/parts/search/browser/searchViewlet.ts index 7c74f429c43..a7e14a96539 100644 --- a/src/vs/workbench/parts/search/browser/searchViewlet.ts +++ b/src/vs/workbench/parts/search/browser/searchViewlet.ts @@ -54,12 +54,11 @@ import * as Constants from 'vs/workbench/parts/search/common/constants'; import { IThemeService, ITheme, ICssStyleCollector, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { editorFindMatchHighlight, diffInserted, diffRemoved, diffInsertedOutline, diffRemovedOutline, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry'; import FileResultsNavigation from 'vs/workbench/parts/files/browser/fileResultsNavigation'; -import { IOutputService } from 'vs/workbench/parts/output/common/output'; import { getOutOfWorkspaceEditorResources } from 'vs/workbench/parts/search/common/search'; import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor'; import { SimpleFileResourceDragAndDrop } from 'vs/base/parts/tree/browser/treeDnd'; import { isDiffEditor, isCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; +import { WorkbenchTree } from 'vs/platform/list/browser/listService'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; export class SearchViewlet extends Viewlet { @@ -120,9 +119,7 @@ export class SearchViewlet extends Viewlet { @IReplaceService private replaceService: IReplaceService, @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IPreferencesService private preferencesService: IPreferencesService, - @IListService private listService: IListService, - @IThemeService protected themeService: IThemeService, - @IOutputService private outputService: IOutputService + @IThemeService protected themeService: IThemeService ) { super(Constants.VIEWLET_ID, telemetryService, themeService); @@ -499,7 +496,7 @@ export class SearchViewlet extends Viewlet { let dnd = new SimpleFileResourceDragAndDrop(obj => obj instanceof FileMatch ? obj.resource() : void 0); - this.tree = new WorkbenchTree(div.getHTMLElement(), { + this.tree = this.instantiationService.createInstance(WorkbenchTree, div.getHTMLElement(), { dataSource: dataSource, renderer: renderer, sorter: new SearchSorter(), @@ -509,7 +506,7 @@ export class SearchViewlet extends Viewlet { }, { ariaLabel: nls.localize('treeAriaLabel', "Search Results"), keyboardSupport: false - }, this.contextKeyService, this.listService, this.themeService); + }); this.tree.setInput(this.viewModel.searchResult); this.toUnbind.push(renderer); @@ -908,33 +905,41 @@ export class SearchViewlet extends Viewlet { } } - public searchInFolder(resource: URI, pathToRelative: (from: string, to: string) => string): void { - let folderPath = null; + public searchInFolders(resources: URI[], pathToRelative: (from: string, to: string) => string): void { + const folderPaths = []; const workspace = this.contextService.getWorkspace(); - if (resource) { - if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { - // Show relative path from the root for single-root mode - folderPath = paths.normalize(pathToRelative(workspace.folders[0].uri.fsPath, resource.fsPath)); - if (folderPath && folderPath !== '.') { - folderPath = './' + folderPath; - } - } else { - const owningFolder = this.contextService.getWorkspaceFolder(resource); - if (owningFolder) { - const owningRootBasename = paths.basename(owningFolder.uri.fsPath); - // If this root is the only one with its basename, use a relative ./ path. If there is another, use an absolute path - const isUniqueFolder = workspace.folders.filter(folder => paths.basename(folder.uri.fsPath) === owningRootBasename).length === 1; - if (isUniqueFolder) { - folderPath = `./${owningRootBasename}/${paths.normalize(pathToRelative(owningFolder.uri.fsPath, resource.fsPath))}`; - } else { - folderPath = resource.fsPath; + if (resources) { + resources.forEach(resource => { + let folderPath: string; + if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { + // Show relative path from the root for single-root mode + folderPath = paths.normalize(pathToRelative(workspace.folders[0].uri.fsPath, resource.fsPath)); + if (folderPath && folderPath !== '.') { + folderPath = './' + folderPath; + } + } else { + const owningFolder = this.contextService.getWorkspaceFolder(resource); + if (owningFolder) { + const owningRootBasename = paths.basename(owningFolder.uri.fsPath); + + // If this root is the only one with its basename, use a relative ./ path. If there is another, use an absolute path + const isUniqueFolder = workspace.folders.filter(folder => paths.basename(folder.uri.fsPath) === owningRootBasename).length === 1; + if (isUniqueFolder) { + folderPath = `./${owningRootBasename}/${paths.normalize(pathToRelative(owningFolder.uri.fsPath, resource.fsPath))}`; + } else { + folderPath = resource.fsPath; + } } } - } + + if (folderPath) { + folderPaths.push(folderPath); + } + }); } - if (!folderPath || folderPath === '.') { + if (!folderPaths.length || folderPaths.some(folderPath => folderPath === '.')) { this.inputPatternIncludes.setValue(''); this.searchWidget.focus(); return; @@ -945,7 +950,7 @@ export class SearchViewlet extends Viewlet { this.toggleQueryDetails(true, true); } - this.inputPatternIncludes.setValue(folderPath); + this.inputPatternIncludes.setValue(folderPaths.join(', ')); this.searchWidget.focus(false); } @@ -1064,12 +1069,7 @@ export class SearchViewlet extends Viewlet { this.showEmptyStage(); let isDone = false; - const outputChannel = this.outputService.getChannel(Constants.SEARCH_OUTPUT_CHANNEL_ID); let onComplete = (completed?: ISearchComplete) => { - if (query.useRipgrep) { - outputChannel.append('\n'); - } - isDone = true; // Complete up to 100% as needed @@ -1198,10 +1198,6 @@ export class SearchViewlet extends Viewlet { }; let onError = (e: any) => { - if (query.useRipgrep) { - outputChannel.append('\n'); - } - if (errors.isPromiseCanceledError(e)) { onComplete(null); } else { @@ -1223,10 +1219,6 @@ export class SearchViewlet extends Viewlet { if (p.worked) { worked = p.worked; } - - if (p.message) { - outputChannel.append(p.message); - } }; // Handle UI updates in an interval to show frequent progress and results @@ -1360,7 +1352,7 @@ export class SearchViewlet extends Viewlet { preserveFocus, pinned, selection, - revealIfVisible: !sideBySide + revealIfVisible: true } }, sideBySide).then(editor => { if (editor && element instanceof Match && preserveFocus) { diff --git a/src/vs/workbench/parts/search/common/constants.ts b/src/vs/workbench/parts/search/common/constants.ts index e15486d6ca5..d68fafac729 100644 --- a/src/vs/workbench/parts/search/common/constants.ts +++ b/src/vs/workbench/parts/search/common/constants.ts @@ -6,7 +6,6 @@ import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; export const VIEWLET_ID = 'workbench.view.search'; -export const SEARCH_OUTPUT_CHANNEL_ID = 'search'; export const FindInFilesActionId = 'workbench.action.findInFiles'; export const FocusActiveEditorCommandId = 'search.action.focusActiveEditor'; diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index 9bf399b29d5..8e6b0fe4bfe 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -35,7 +35,6 @@ import { ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleWholeWordKe import { ISearchWorkbenchService, SearchWorkbenchService } from 'vs/workbench/parts/search/common/searchModel'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { SearchViewlet } from 'vs/workbench/parts/search/browser/searchViewlet'; -import { IOutputChannelRegistry, Extensions as OutputExt } from 'vs/workbench/parts/output/common/output'; import { defaultQuickOpenContextKey } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { OpenSymbolHandler } from 'vs/workbench/parts/search/browser/openSymbolHandler'; import { OpenAnythingHandler } from 'vs/workbench/parts/search/browser/openAnythingHandler'; @@ -47,9 +46,10 @@ import URI from 'vs/base/common/uri'; import { relative } from 'path'; import { dirname } from 'vs/base/common/resources'; import { ResourceContextKey } from 'vs/workbench/common/resources'; -import { getResourceForCommand } from 'vs/workbench/parts/files/electron-browser/fileCommands'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IFileService } from 'vs/platform/files/common/files'; +import { distinct } from 'vs/base/common/arrays'; +import { getMultiSelectedResources } from 'vs/workbench/parts/files/browser/files'; registerSingleton(ISearchWorkbenchService, SearchWorkbenchService); replaceContributions(); @@ -192,16 +192,24 @@ CommandsRegistry.registerCommand({ const listService = accessor.get(IListService); const viewletService = accessor.get(IViewletService); const fileService = accessor.get(IFileService); - resource = getResourceForCommand(resource, listService, accessor.get(IWorkbenchEditorService)); + const resources = getMultiSelectedResources(resource, listService, accessor.get(IWorkbenchEditorService)); return viewletService.openViewlet(Constants.VIEWLET_ID, true).then(viewlet => { - if (resource) { - fileService.resolveFile(resource).then(stat => { - return stat.isDirectory ? stat.resource : dirname(stat.resource); - }).then(resource => - (viewlet as SearchViewlet).searchInFolder(resource, (from, to) => relative(from, to)) - ); + if (resources && resources.length) { + return fileService.resolveFiles(resources.map(resource => ({ resource }))).then(results => { + const folders: URI[] = []; + + results.forEach(result => { + if (result.success) { + folders.push(result.stat.isDirectory ? result.stat.resource : dirname(result.stat.resource)); + } + }); + + (viewlet as SearchViewlet).searchInFolders(distinct(folders, folder => folder.toString()), (from, to) => relative(from, to)); + }); } + + return void 0; }); } }); @@ -212,7 +220,7 @@ CommandsRegistry.registerCommand({ handler: (accessor) => { const viewletService = accessor.get(IViewletService); return viewletService.openViewlet(Constants.VIEWLET_ID, true).then(viewlet => { - (viewlet as SearchViewlet).searchInFolder(null, (from, to) => relative(from, to)); + (viewlet as SearchViewlet).searchInFolders(null, (from, to) => relative(from, to)); }); } }); @@ -362,10 +370,6 @@ Registry.as(QuickOpenExtensions.Quickopen).registerQuickOpen ) ); -// Search output channel -const outputChannelRegistry = Registry.as(OutputExt.OutputChannels); -outputChannelRegistry.registerChannel(Constants.SEARCH_OUTPUT_CHANNEL_ID, nls.localize('searchOutputChannelTitle', "Search")); - // Configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); configurationRegistry.registerConfiguration({ diff --git a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts index d86d0eccb2c..3d28a54b1d4 100644 --- a/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts +++ b/src/vs/workbench/parts/snippets/electron-browser/snippetsService.ts @@ -18,7 +18,7 @@ import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { join, basename, extname } from 'path'; import { mkdirp, readdir, exists } from 'vs/base/node/pfs'; -import { watch } from 'fs'; +import { watch } from 'vs/base/node/extfs'; import { SnippetFile, Snippet } from 'vs/workbench/parts/snippets/electron-browser/snippetsFile'; import { ISnippetsService } from 'vs/workbench/parts/snippets/electron-browser/snippets.contribution'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; @@ -48,7 +48,7 @@ namespace schema { } else if (isFalsyOrWhitespace(snippet.language) && !endsWith(snippet.path, '.code-snippets')) { extension.collector.error(localize( 'invalid.language.0', - "When omitting the language, the value of `contribtes.{0}.path` must be a `.code-snippets`-file. Provided value: {1}", + "When omitting the language, the value of `contributes.{0}.path` must be a `.code-snippets`-file. Provided value: {1}", extension.description.name, String(snippet.path) )); return false; @@ -217,9 +217,7 @@ class SnippetsService implements ISnippetsService { } }).then(() => { // watch - const watcher = watch(userSnippetsFolder); - this._disposables.push({ dispose: () => watcher.close() }); - watcher.on('change', (type, filename) => { + const watcher = watch(userSnippetsFolder, (type, filename) => { if (typeof filename !== 'string') { return; } @@ -238,6 +236,13 @@ class SnippetsService implements ISnippetsService { } }); }); + this._disposables.push({ + dispose: () => { + watcher.removeAllListeners(); + watcher.close(); + } + }); + }).then(undefined, err => { this._logService.error('Failed to load user snippets', err); }); diff --git a/src/vs/workbench/parts/terminal/common/terminal.ts b/src/vs/workbench/parts/terminal/common/terminal.ts index cd837dd9be5..59e4747ed75 100644 --- a/src/vs/workbench/parts/terminal/common/terminal.ts +++ b/src/vs/workbench/parts/terminal/common/terminal.ts @@ -47,6 +47,8 @@ export const TerminalCursorStyle = { UNDERLINE: 'underline' }; +export const TERMINAL_CONFIG_SECTION = 'terminal.integrated'; + export interface ITerminalConfiguration { shell: { linux: string; @@ -59,6 +61,7 @@ export interface ITerminalConfiguration { windows: string[]; }; enableBold: boolean; + macOptionIsMeta: boolean; rightClickCopyPaste: boolean; cursorBlinking: boolean; cursorStyle: string; @@ -170,7 +173,6 @@ export interface ITerminalService { showPreviousFindTermFindWidget(): void; setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; - updateConfig(): void; selectDefaultWindowsShell(): TPromise; setWorkspaceShellAllowed(isAllowed: boolean): void; } @@ -388,4 +390,9 @@ export interface ITerminalInstance { * Sets the title of the terminal instance. */ setTitle(title: string, eventFromProcess: boolean): void; + + /** + * Enter screen reader navigation mode. + */ + enterNavigationMode(): void; } diff --git a/src/vs/workbench/parts/terminal/common/terminalService.ts b/src/vs/workbench/parts/terminal/common/terminalService.ts index 4683d7a6250..806e092c0a6 100644 --- a/src/vs/workbench/parts/terminal/common/terminalService.ts +++ b/src/vs/workbench/parts/terminal/common/terminalService.ts @@ -9,10 +9,8 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService } from 'vs/workbench/services/part/common/partService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, TERMINAL_PANEL_ID } from 'vs/workbench/parts/terminal/common/terminal'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; export abstract class TerminalService implements ITerminalService { public _serviceBrand: any; @@ -44,7 +42,6 @@ export abstract class TerminalService implements ITerminalService { constructor( @IContextKeyService private _contextKeyService: IContextKeyService, - @IConfigurationService protected _configurationService: IConfigurationService, @IPanelService protected _panelService: IPanelService, @IPartService private _partService: IPartService, @ILifecycleService lifecycleService: ILifecycleService @@ -60,14 +57,6 @@ export abstract class TerminalService implements ITerminalService { this._onInstanceTitleChanged = new Emitter(); this._onInstancesChanged = new Emitter(); - this._configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration('terminal.integrated')) { - this.updateConfig(); - } - if (e.affectsConfiguration('editor.accessibilitySupport')) { - this.updateAccessibilitySupport(); - } - }); lifecycleService.onWillShutdown(event => event.veto(this._onWillShutdown())); lifecycleService.onShutdown(() => this._onShutdown()); this._terminalFocusContextKey = KEYBINDING_CONTEXT_TERMINAL_FOCUS.bindTo(this._contextKeyService); @@ -240,15 +229,6 @@ export abstract class TerminalService implements ITerminalService { return terminalIndex; } - public updateConfig(): void { - this.terminalInstances.forEach(instance => instance.updateConfig()); - } - - public updateAccessibilitySupport(): void { - const isEnabled = this._configurationService.getValue('editor').accessibilitySupport === 'on'; - this.terminalInstances.forEach(instance => instance.updateAccessibilitySupport(isEnabled)); - } - public setWorkspaceShellAllowed(isAllowed: boolean): void { this.configHelper.setWorkspaceShellAllowed(isAllowed); } diff --git a/src/vs/workbench/parts/terminal/electron-browser/media/scrollbar.css b/src/vs/workbench/parts/terminal/electron-browser/media/scrollbar.css index 70af76ab868..ebe03196593 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/media/scrollbar.css +++ b/src/vs/workbench/parts/terminal/electron-browser/media/scrollbar.css @@ -19,6 +19,7 @@ } .monaco-workbench .panel.integrated-terminal .xterm-viewport::-webkit-scrollbar-thumb { + min-height: 20px; background-color: inherit; } diff --git a/src/vs/workbench/parts/terminal/electron-browser/media/xterm.css b/src/vs/workbench/parts/terminal/electron-browser/media/xterm.css index aadbf436fc4..6068c9445bd 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/media/xterm.css +++ b/src/vs/workbench/parts/terminal/electron-browser/media/xterm.css @@ -127,7 +127,7 @@ cursor: text; } -.xterm .accessibility { +.xterm .xterm-accessibility { position: absolute; left: 0; top: 0; @@ -136,10 +136,14 @@ z-index: 100; } -.xterm .accessibility-tree { +.xterm .xterm-accessibility-tree { color: transparent; } +.xterm .xterm-accessibility-tree:focus [id^="xterm-active-item-"] { + outline: 1px solid #F80; +} + .xterm .live-region { position: absolute; left: -9999px; diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts index e4b726a6c83..6c596e10385 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts @@ -18,7 +18,7 @@ import { TERMINAL_DEFAULT_SHELL_UNIX_LIKE, TERMINAL_DEFAULT_SHELL_WINDOWS } from import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { KillTerminalAction, CopyTerminalSelectionAction, CreateNewTerminalAction, CreateNewInActiveWorkspaceTerminalAction, FocusActiveTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, SelectDefaultShellWindowsTerminalAction, RunSelectedTextInTerminalAction, RunActiveFileInTerminalAction, ScrollDownTerminalAction, ScrollDownPageTerminalAction, ScrollToBottomTerminalAction, ScrollUpTerminalAction, ScrollUpPageTerminalAction, ScrollToTopTerminalAction, TerminalPasteAction, ToggleTerminalAction, ClearTerminalAction, AllowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand, RenameTerminalAction, SelectAllTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, ShowNextFindTermTerminalFindWidgetAction, ShowPreviousFindTermTerminalFindWidgetAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, TERMINAL_PICKER_PREFIX } from 'vs/workbench/parts/terminal/electron-browser/terminalActions'; +import { KillTerminalAction, CopyTerminalSelectionAction, CreateNewTerminalAction, CreateNewInActiveWorkspaceTerminalAction, FocusActiveTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, SelectDefaultShellWindowsTerminalAction, RunSelectedTextInTerminalAction, RunActiveFileInTerminalAction, ScrollDownTerminalAction, ScrollDownPageTerminalAction, ScrollToBottomTerminalAction, ScrollUpTerminalAction, ScrollUpPageTerminalAction, ScrollToTopTerminalAction, TerminalPasteAction, ToggleTerminalAction, ClearTerminalAction, AllowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand, RenameTerminalAction, SelectAllTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, ShowNextFindTermTerminalFindWidgetAction, ShowPreviousFindTermTerminalFindWidgetAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, TERMINAL_PICKER_PREFIX, EnterNavigationModeTerminalAction } from 'vs/workbench/parts/terminal/electron-browser/terminalActions'; import { Registry } from 'vs/platform/registry/common/platform'; import { ShowAllCommandsAction } from 'vs/workbench/parts/quickopen/browser/commandsHandler'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; @@ -115,6 +115,11 @@ configurationRegistry.registerConfiguration({ }, 'default': [] }, + 'terminal.integrated.macOptionIsMeta': { + 'description': nls.localize('terminal.integrated.macOptionIsMeta', "Treat the option key as the meta key in the terminal on macOS."), + 'type': 'boolean', + 'default': false + }, 'terminal.integrated.rightClickCopyPaste': { 'description': nls.localize('terminal.integrated.rightClickCopyPaste', "When set, this will prevent the context menu from appearing when right clicking within the terminal, instead it will copy when there is a selection and paste when there is no selection."), 'type': 'boolean', @@ -204,6 +209,7 @@ configurationRegistry.registerConfiguration({ FocusActiveTerminalAction.ID, FocusPreviousTerminalAction.ID, FocusNextTerminalAction.ID, + EnterNavigationModeTerminalAction.ID, 'workbench.action.tasks.build', 'workbench.action.tasks.restartTask', 'workbench.action.tasks.runTask', @@ -386,6 +392,9 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteWordRightT primary: KeyMod.CtrlCmd | KeyCode.Delete, mac: { primary: KeyMod.Alt | KeyCode.Delete } }, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete Word Right', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(EnterNavigationModeTerminalAction, EnterNavigationModeTerminalAction.ID, EnterNavigationModeTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.KEY_N +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Enter Navigation Mode', category); terminalCommands.setup(); diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts index 8ab6467d691..4e9752cafa3 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts @@ -196,6 +196,27 @@ export class DeleteWordRightTerminalAction extends Action { } } +export class EnterNavigationModeTerminalAction extends Action { + + public static readonly ID = 'workbench.action.terminal.enterLineNavigationMode'; + public static readonly LABEL = nls.localize('workbench.action.terminal.enterLineNavigationMode', "Enter Line Navigation Mode"); + + constructor( + id: string, label: string, + @ITerminalService private terminalService: ITerminalService + ) { + super(id, label); + } + + public run(event?: any): TPromise { + let terminalInstance = this.terminalService.getActiveInstance(); + if (terminalInstance) { + terminalInstance.enterNavigationMode(); + } + return TPromise.as(void 0); + } +} + export class CreateNewTerminalAction extends Action { public static readonly ID = 'workbench.action.terminal.new'; diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts index eaae70691f3..24a10026878 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts @@ -11,21 +11,10 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IChoiceService } from 'vs/platform/message/common/message'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { ITerminalConfiguration, ITerminalConfigHelper, ITerminalFont, IShellLaunchConfig, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY } from 'vs/workbench/parts/terminal/common/terminal'; +import { ITerminalConfiguration, ITerminalConfigHelper, ITerminalFont, IShellLaunchConfig, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION } from 'vs/workbench/parts/terminal/common/terminal'; import { TPromise } from 'vs/base/common/winjs.base'; import Severity from 'vs/base/common/severity'; import { isFedora } from 'vs/workbench/parts/terminal/electron-browser/terminal'; -import { deepClone } from 'vs/base/common/objects'; - -interface IEditorConfiguration { - editor: IEditorOptions; -} - -interface IFullTerminalConfiguration { - terminal: { - integrated: ITerminalConfiguration; - }; -} const DEFAULT_LINE_HEIGHT = 1.0; @@ -41,16 +30,24 @@ export class TerminalConfigHelper implements ITerminalConfigHelper { private _charMeasureElement: HTMLElement; private _lastFontMeasurement: ITerminalFont; + public config: ITerminalConfiguration; public constructor( @IConfigurationService private _configurationService: IConfigurationService, @IWorkspaceConfigurationService private _workspaceConfigurationService: IWorkspaceConfigurationService, @IChoiceService private _choiceService: IChoiceService, - @IStorageService private _storageService: IStorageService) { + @IStorageService private _storageService: IStorageService + ) { + this._updateConfig(); + this._configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(TERMINAL_CONFIG_SECTION)) { + this._updateConfig(); + } + }); } - public get config(): ITerminalConfiguration { - return deepClone(this._configurationService.getValue().terminal.integrated); + private _updateConfig(): void { + this.config = this._configurationService.getValue(TERMINAL_CONFIG_SECTION); } private _measureFont(fontFamily: string, fontSize: number, lineHeight: number): ITerminalFont { @@ -89,21 +86,19 @@ export class TerminalConfigHelper implements ITerminalConfigHelper { * terminal.integrated.fontSize, terminal.integrated.lineHeight configuration properties */ public getFont(excludeDimensions?: boolean): ITerminalFont { - const config = this._configurationService.getValue(); - const editorConfig = (config).editor; - const terminalConfig = this.config; + const editorConfig = this._configurationService.getValue('editor'); - let fontFamily = terminalConfig.fontFamily || editorConfig.fontFamily; + let fontFamily = this.config.fontFamily || editorConfig.fontFamily; // Work around bad font on Fedora - if (!terminalConfig.fontFamily) { + if (!this.config.fontFamily) { if (isFedora) { fontFamily = '\'DejaVu Sans Mono\''; } } - let fontSize = this._toInteger(terminalConfig.fontSize, MINIMUM_FONT_SIZE, MAXIMUM_FONT_SIZE, EDITOR_FONT_DEFAULTS.fontSize); - const lineHeight = terminalConfig.lineHeight ? Math.max(terminalConfig.lineHeight, 1) : DEFAULT_LINE_HEIGHT; + let fontSize = this._toInteger(this.config.fontSize, MINIMUM_FONT_SIZE, MAXIMUM_FONT_SIZE, EDITOR_FONT_DEFAULTS.fontSize); + const lineHeight = this.config.lineHeight ? Math.max(this.config.lineHeight, 1) : DEFAULT_LINE_HEIGHT; if (excludeDimensions) { return { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index d9b982340fb..46bdcaefbca 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -171,6 +171,15 @@ export class TerminalInstance implements ITerminalInstance { this.attachToElement(_container); } }); + + this._configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('terminal.integrated')) { + this.updateConfig(); + } + if (e.affectsConfiguration('editor.accessibilitySupport')) { + this.updateAccessibilitySupport(); + } + }); } public addDisposable(disposable: lifecycle.IDisposable): void { @@ -273,7 +282,8 @@ export class TerminalInstance implements ITerminalInstance { lineHeight: font.lineHeight, enableBold: this._configHelper.config.enableBold, bellStyle: this._configHelper.config.enableBell ? 'sound' : 'none', - screenReaderMode: accessibilitySupport === 'on' + screenReaderMode: accessibilitySupport === 'on', + macOptionIsMeta: this._configHelper.config.macOptionIsMeta }); if (this._shellLaunchConfig.initialText) { this._xterm.writeln(this._shellLaunchConfig.initialText); @@ -903,7 +913,13 @@ export class TerminalInstance implements ITerminalInstance { while (lineIndex >= 0 && buffer.lines.get(lineIndex--).isWrapped) { lineData = buffer.translateBufferLineToString(lineIndex, true) + lineData; } - this._onLineDataListeners.forEach(listener => listener(lineData)); + this._onLineDataListeners.forEach(listener => { + try { + listener(lineData); + } catch (err) { + console.error(`onLineData listener threw`, err); + } + }); } public onExit(listener: (exitCode: number) => void): lifecycle.IDisposable { @@ -946,6 +962,7 @@ export class TerminalInstance implements ITerminalInstance { it: 'IT', ja: 'JP', ko: 'KR', + pl: 'PL', ru: 'RU', zh: 'CN' }; @@ -965,10 +982,12 @@ export class TerminalInstance implements ITerminalInstance { this._setCommandsToSkipShell(this._configHelper.config.commandsToSkipShell); this._setScrollback(this._configHelper.config.scrollback); this._setEnableBell(this._configHelper.config.enableBell); + this._setMacOptionIsMeta(this._configHelper.config.macOptionIsMeta); } - public updateAccessibilitySupport(isEnabled: boolean): void { - this._xterm.setOption('screenReaderMode', isEnabled); + public updateAccessibilitySupport(): void { + const value = this._configurationService.getValue('editor.accessibilitySupport'); + this._xterm.setOption('screenReaderMode', value === 'on'); } private _setCursorBlink(blink: boolean): void { @@ -996,6 +1015,12 @@ export class TerminalInstance implements ITerminalInstance { } } + private _setMacOptionIsMeta(value: boolean): void { + if (this._xterm && this._xterm.getOption('macOptionIsMeta') !== value) { + this._xterm.setOption('macOptionIsMeta', value); + } + } + private _setEnableBell(isEnabled: boolean): void { if (this._xterm) { if (this._xterm.getOption('bellStyle') === 'sound') { @@ -1123,6 +1148,15 @@ export class TerminalInstance implements ITerminalInstance { private _updateTheme(theme?: ITheme): void { this._xterm.setOption('theme', this._getXtermTheme(theme)); } + + public enterNavigationMode(): void { + // Perform this asynchronously as entering navigation mode will override + // the key event handlers which seemed to mess with the keybindings + // system + setTimeout(() => { + this._xterm.enterNavigationMode(); + }, 100); + } } registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts index d12de43f06d..797ae1d1a3a 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts @@ -27,6 +27,7 @@ import URI from 'vs/base/common/uri'; import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; import { TERMINAL_BACKGROUND_COLOR } from 'vs/workbench/parts/terminal/electron-browser/terminalColorRegistry'; import { DataTransfers } from 'vs/base/browser/dnd'; +import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; export class TerminalPanel extends Panel { @@ -45,6 +46,7 @@ export class TerminalPanel extends Panel { @IContextMenuService private _contextMenuService: IContextMenuService, @IInstantiationService private _instantiationService: IInstantiationService, @ITerminalService private _terminalService: ITerminalService, + @ILifecycleService private _lifecycleService: ILifecycleService, @IThemeService protected themeService: IThemeService, @ITelemetryService telemetryService: ITelemetryService ) { @@ -102,16 +104,20 @@ export class TerminalPanel extends Panel { this._updateTheme(); } else { return super.setVisible(visible).then(() => { - // Allow time for the panel to display if it is being shown - // for the first time. If there is not wait here the initial - // dimensions of the pty could be wrong. - setTimeout(() => { - const instance = this._terminalService.createInstance(); - if (instance) { - this._updateFont(); - this._updateTheme(); - } - }, 0); + // Ensure the "Running" lifecycle face has been reached before creating the + // first terminal. + this._lifecycleService.when(LifecyclePhase.Running).then(() => { + // Allow time for the panel to display if it is being shown + // for the first time. If there is not wait here the initial + // dimensions of the pty could be wrong. + setTimeout(() => { + const instance = this._terminalService.createInstance(); + if (instance) { + this._updateFont(); + this._updateTheme(); + } + }, 0); + }); return TPromise.as(void 0); }); } diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts index 24eeeb6e16b..eb2eb94177d 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts @@ -30,17 +30,17 @@ export class TerminalService extends AbstractTerminalService implements ITermina constructor( @IContextKeyService _contextKeyService: IContextKeyService, - @IConfigurationService _configurationService: IConfigurationService, @IPanelService _panelService: IPanelService, @IPartService _partService: IPartService, @ILifecycleService _lifecycleService: ILifecycleService, + @IConfigurationService private _configurationService: IConfigurationService, @IInstantiationService private _instantiationService: IInstantiationService, @IQuickOpenService private _quickOpenService: IQuickOpenService, @IChoiceService private _choiceService: IChoiceService, @IStorageService private _storageService: IStorageService, @IMessageService private _messageService: IMessageService ) { - super(_contextKeyService, _configurationService, _panelService, _partService, _lifecycleService); + super(_contextKeyService, _panelService, _partService, _lifecycleService); this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper); } @@ -121,7 +121,7 @@ export class TerminalService extends AbstractTerminalService implements ITermina } const message = nls.localize('terminal.integrated.chooseWindowsShellInfo', "You can change the default terminal shell by selecting the customize button."); - const options = [nls.localize('customize', "Customize"), nls.localize('cancel', "Cancel"), nls.localize('never again', "OK, Never Show Again")]; + const options = [nls.localize('customize', "Customize"), nls.localize('cancel', "Cancel"), nls.localize('never again', "OK, Don't Show Again")]; this._choiceService.choose(Severity.Info, message, options, 1).then(choice => { switch (choice) { case 0: diff --git a/src/vs/workbench/parts/terminal/test/electron-browser/terminalConfigHelper.test.ts b/src/vs/workbench/parts/terminal/test/electron-browser/terminalConfigHelper.test.ts index caef93152b9..ebd9dbfcdaa 100644 --- a/src/vs/workbench/parts/terminal/test/electron-browser/terminalConfigHelper.test.ts +++ b/src/vs/workbench/parts/terminal/test/electron-browser/terminalConfigHelper.test.ts @@ -6,24 +6,10 @@ 'use strict'; import * as assert from 'assert'; -import { IConfigurationService, getConfigurationValue, IConfigurationOverrides } from 'vs/platform/configuration/common/configuration'; -import { TPromise } from 'vs/base/common/winjs.base'; import { TerminalConfigHelper } from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper'; import { EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; import { isFedora } from 'vs/workbench/parts/terminal/electron-browser/terminal'; - -class MockConfigurationService implements IConfigurationService { - public _serviceBrand: any; - public serviceId = IConfigurationService; - public constructor(private configuration: any = {}) { } - public inspect(key: string, overrides?: IConfigurationOverrides): any { return { value: getConfigurationValue(this.getValue(), key), default: getConfigurationValue(this.getValue(), key), user: getConfigurationValue(this.getValue(), key), workspace: void 0, workspaceFolder: void 0 }; } - public keys() { return { default: [] as string[], user: [] as string[], workspace: [] as string[], workspaceFolder: [] as string[] }; } - public getValue(): any { return this.configuration; } - public updateValue(): TPromise { return null; } - public getConfigurationData(): any { return null; } - public onDidChangeConfiguration() { return { dispose() { } }; } - public reloadConfiguration(): TPromise { return null; } -} +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; suite('Workbench - TerminalConfigHelper', () => { let fixture: HTMLElement; @@ -33,33 +19,17 @@ suite('Workbench - TerminalConfigHelper', () => { }); test('TerminalConfigHelper - getFont fontFamily', function () { - let configurationService: IConfigurationService; - let configHelper: TerminalConfigHelper; + const configurationService = new TestConfigurationService(); + configurationService.setUserConfiguration('editor', { fontFamily: 'foo' }); + configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: 'bar' } }); - configurationService = new MockConfigurationService({ - editor: { - fontFamily: 'foo' - }, - terminal: { - integrated: { - fontFamily: 'bar' - } - } - }); - configHelper = new TerminalConfigHelper(configurationService, null, null, null); + let configHelper = new TerminalConfigHelper(configurationService, null, null, null); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontFamily, 'bar', 'terminal.integrated.fontFamily should be selected over editor.fontFamily'); - configurationService = new MockConfigurationService({ - editor: { - fontFamily: 'foo' - }, - terminal: { - integrated: { - fontFamily: 0 - } - } - }); + configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: null } }); + + // Recreate config helper as onDidChangeConfiguration isn't implemented in TestConfigurationService configHelper = new TerminalConfigHelper(configurationService, null, null, null); configHelper.panelContainer = fixture; if (isFedora) { @@ -70,64 +40,55 @@ suite('Workbench - TerminalConfigHelper', () => { }); test('TerminalConfigHelper - getFont fontSize', function () { - let configurationService: IConfigurationService; - let configHelper: TerminalConfigHelper; + const configurationService = new TestConfigurationService(); - configurationService = new MockConfigurationService({ - editor: { - fontFamily: 'foo', - fontSize: 9 - }, - terminal: { - integrated: { - fontFamily: 'bar', - fontSize: 10 - } + configurationService.setUserConfiguration('editor', { + fontFamily: 'foo', + fontSize: 9 + }); + configurationService.setUserConfiguration('terminal', { + integrated: { + fontFamily: 'bar', + fontSize: 10 } }); - configHelper = new TerminalConfigHelper(configurationService, null, null, null); + let configHelper = new TerminalConfigHelper(configurationService, null, null, null); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontSize, 10, 'terminal.integrated.fontSize should be selected over editor.fontSize'); - configurationService = new MockConfigurationService({ - editor: { - fontFamily: 'foo' - }, - terminal: { - integrated: { - fontFamily: 0, - fontSize: 0 - } + configurationService.setUserConfiguration('editor', { + fontFamily: 'foo' + }); + configurationService.setUserConfiguration('terminal', { + integrated: { + fontFamily: null, + fontSize: 0 } }); configHelper = new TerminalConfigHelper(configurationService, null, null, null); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontSize, 6, 'The minimum terminal font size should be used when terminal.integrated.fontSize less than it'); - configurationService = new MockConfigurationService({ - editor: { - fontFamily: 'foo' - }, - terminal: { - integrated: { - fontFamily: 0, - fontSize: 1500 - } + configurationService.setUserConfiguration('editor', { + fontFamily: 'foo' + }); + configurationService.setUserConfiguration('terminal', { + integrated: { + fontFamily: 0, + fontSize: 1500 } }); configHelper = new TerminalConfigHelper(configurationService, null, null, null); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontSize, 25, 'The maximum terminal font size should be used when terminal.integrated.fontSize more than it'); - configurationService = new MockConfigurationService({ - editor: { - fontFamily: 'foo', - }, - terminal: { - integrated: { - fontFamily: 0, - fontSize: null - } + configurationService.setUserConfiguration('editor', { + fontFamily: 'foo' + }); + configurationService.setUserConfiguration('terminal', { + integrated: { + fontFamily: 0, + fontSize: null } }); configHelper = new TerminalConfigHelper(configurationService, null, null, null); @@ -136,35 +97,30 @@ suite('Workbench - TerminalConfigHelper', () => { }); test('TerminalConfigHelper - getFont lineHeight', function () { - let configurationService: IConfigurationService; - let configHelper: TerminalConfigHelper; + const configurationService = new TestConfigurationService(); - configurationService = new MockConfigurationService({ - editor: { - fontFamily: 'foo', - lineHeight: 1 - }, - terminal: { - integrated: { - fontFamily: 0, - lineHeight: 2 - } + configurationService.setUserConfiguration('editor', { + fontFamily: 'foo', + lineHeight: 1 + }); + configurationService.setUserConfiguration('terminal', { + integrated: { + fontFamily: 0, + lineHeight: 2 } }); - configHelper = new TerminalConfigHelper(configurationService, null, null, null); + let configHelper = new TerminalConfigHelper(configurationService, null, null, null); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().lineHeight, 2, 'terminal.integrated.lineHeight should be selected over editor.lineHeight'); - configurationService = new MockConfigurationService({ - editor: { - fontFamily: 'foo', - lineHeight: 1 - }, - terminal: { - integrated: { - fontFamily: 0, - lineHeight: 0 - } + configurationService.setUserConfiguration('editor', { + fontFamily: 'foo', + lineHeight: 1 + }); + configurationService.setUserConfiguration('terminal', { + integrated: { + fontFamily: 0, + lineHeight: 0 } }); configHelper = new TerminalConfigHelper(configurationService, null, null, null); diff --git a/src/vs/workbench/parts/terminal/test/electron-browser/terminalInstance.test.ts b/src/vs/workbench/parts/terminal/test/electron-browser/terminalInstance.test.ts index a7f066b25bd..1dadac1f411 100644 --- a/src/vs/workbench/parts/terminal/test/electron-browser/terminalInstance.test.ts +++ b/src/vs/workbench/parts/terminal/test/electron-browser/terminalInstance.test.ts @@ -21,8 +21,11 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { TPromise } from 'vs/base/common/winjs.base'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; class TestTerminalInstance extends TerminalInstance { + public _getCwd(shell: IShellLaunchConfig, root: Uri): string { return super._getCwd(shell, root); } @@ -152,6 +155,7 @@ suite('Workbench - TerminalInstance', () => { let keybindingService = new MockKeybindingService(); let terminalFocusContextKey = contextKeyService.createKey('test', false); instantiationService = new TestInstantiationService(); + instantiationService.stub(IConfigurationService, new TestConfigurationService()); instantiationService.stub(IMessageService, new TestMessageService()); instantiationService.stub(IWorkspaceContextService, new TestContextService()); instantiationService.stub(IKeybindingService, keybindingService); diff --git a/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts b/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts index 27632cdde54..b78a3529a97 100644 --- a/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts +++ b/src/vs/workbench/parts/update/electron-browser/releaseNotesEditor.ts @@ -29,14 +29,18 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { addGAParameters } from 'vs/platform/telemetry/node/telemetryNodeUtils'; import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/tokenization'; -function renderBody(body: string, css: string): string { +function renderBody( + body: string, + css: string +): string { + const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-core-resource://'); return ` - - + + ${body} @@ -52,14 +56,14 @@ export class ReleaseNotesEditor extends WebviewEditor { constructor( @ITelemetryService telemetryService: ITelemetryService, - @IEnvironmentService private environmentService: IEnvironmentService, @IThemeService protected themeService: IThemeService, + @IStorageService storageService: IStorageService, + @IContextKeyService contextKeyService: IContextKeyService, + @IEnvironmentService private environmentService: IEnvironmentService, @IOpenerService private openerService: IOpenerService, @IModeService private modeService: IModeService, @IPartService private partService: IPartService, - @IStorageService storageService: IStorageService, - @IContextViewService private _contextViewService: IContextViewService, - @IContextKeyService contextKeyService: IContextKeyService + @IContextViewService private _contextViewService: IContextViewService ) { super(ReleaseNotesEditor.ID, telemetryService, themeService, storageService, contextKeyService); } @@ -100,7 +104,7 @@ export class ReleaseNotesEditor extends WebviewEditor { const colorMap = TokenizationRegistry.getColorMap(); const css = generateTokensCSSForColorMap(colorMap); const body = renderBody(marked(text, { renderer }), css); - this._webview = new WebView(this.content, this.partService.getContainer(Parts.EDITOR_PART), this._contextViewService, this.contextKey, this.findInputFocusContextKey); + this._webview = new WebView(this.content, this.partService.getContainer(Parts.EDITOR_PART), this.environmentService, this._contextViewService, this.contextKey, this.findInputFocusContextKey, {}, false); if (this.input && this.input instanceof ReleaseNotesInput) { const state = this.loadViewState(this.input.version); if (state) { diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index fca8ccd73a6..a64d44eed6c 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -241,7 +241,7 @@ class NeverShowAgain { private readonly key: string; - readonly action = new Action(`neverShowAgain:${this.key}`, nls.localize('neveragain', "Never Show Again"), undefined, true, () => { + readonly action = new Action(`neverShowAgain:${this.key}`, nls.localize('neveragain', "Don't Show Again"), undefined, true, () => { return TPromise.wrap(this.storageService.store(this.key, true, StorageScope.GLOBAL)); }); diff --git a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md index fbd56ebf869..946f83b6af0 100644 --- a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md +++ b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md @@ -17,11 +17,11 @@ The core editor in VS Code is packed with features. This page highlights a numb ### Multi-Cursor Editing Using multiple cursors allows you to edit multiple parts of the document at once, greatly improving your productivity. Try the following actions in the code block below: -1. Box Selection - press any combination of kb(cursorColumnSelectDown), kb(cursorColumnSelectRight), kb(cursorColumnSelectUp), kb(cursorColumnSelectLeft) to select a block of text, you can also press `⇧⌥``Shift+Alt` while selecting text with the mouse. -2. Add a cursor - press kb(editor.action.insertCursorAbove) or kb(editor.action.insertCursorBelow) to add a new cursor above or below, you can also use your mouse with +Click to add a cursor anywhere. +1. Box Selection - press any combination of kb(cursorColumnSelectDown), kb(cursorColumnSelectRight), kb(cursorColumnSelectUp), kb(cursorColumnSelectLeft) to select a block of text. You can also press `⇧⌥``Shift+Alt` while selecting text with the mouse. +2. Add a cursor - press kb(editor.action.insertCursorAbove) to add a new cursor above, or kb(editor.action.insertCursorBelow) to add a new cursor below. You can also use your mouse with +Click to add a cursor anywhere. 3. Create cursors on all occurrences of a string - select one instance of a string e.g. `background-color` and press kb(editor.action.selectHighlights). Now you can replace all instances by simply typing. -That is the tip of the iceberg for multi-cursor editing have a look at the `selection menu` and our handy [keyboard reference guide](command:workbench.action.keybindingsReference) for additional actions. +That is the tip of the iceberg for multi-cursor editing. Have a look at the selection menu and our handy [keyboard reference guide](command:workbench.action.keybindingsReference) for additional actions. ```css #p1 {background-color: #ff0000;} /* red */ @@ -29,11 +29,11 @@ That is the tip of the iceberg for multi-cursor editing have a look at the `sele #p3 {background-color: #0000ff;} /* blue */ ``` -> **CSS Tip:** you may have noticed in the example above for CSS we also provide color swatches inline, additionally if you hover over an element such as `#p1` we will show how this is represented in HTML. These swatches also act as color pickers that allow you to easily change a color value. A simple example of some language specific editor features. +> **CSS Tip:** you may have noticed in the example above we also provide color swatches inline for CSS, additionally if you hover over an element such as `#p1` we will show how this is represented in HTML. These swatches also act as color pickers that allow you to easily change a color value. A simple example of some language-specific editor features. ### IntelliSense -Visual Studio Code comes with powerful IntelliSense for JavaScript and TypeScript pre-installed. In the below example, position the text cursor in front of the error underline, right after the dot and press kb(editor.action.triggerSuggest) to invoke IntelliSense. Notice how the suggestion comes from the Request API. +Visual Studio Code comes with the powerful IntelliSense for JavaScript and TypeScript pre-installed. In the below example, position the text cursor in front of the error underline, right after the dot and press kb(editor.action.triggerSuggest) to invoke IntelliSense. Notice how the suggestion comes from the Request API. ```js var express = require('express'); @@ -50,7 +50,7 @@ app.listen(3000); ### Line Actions -Since it's very common to want to work with the entire text in a line we provide a set of useful shortcuts to help with this. +Since it's very common to work with the entire text in a line we provide a set of useful shortcuts to help with this. 1. Copy a line and insert it above or below the current position with kb(editor.action.copyLinesDownAction) or kb(editor.action.copyLinesUpAction) respectively. 2. Move an entire line or selection of lines up or down with kb(editor.action.moveLinesUpAction) and kb(editor.action.moveLinesDownAction) respectively. 3. Delete the entire line with kb(editor.action.deleteLines). @@ -68,7 +68,7 @@ Since it's very common to want to work with the entire text in a line we provide ### Rename Refactoring -It's easy to rename a symbol such as a function name or variable name. Hit kb(editor.action.rename) while in the symbol `Book` to rename all instances - this will occur across all files in a project. You can also see refactoring in the right click context menu. +It's easy to rename a symbol such as a function name or variable name. Hit kb(editor.action.rename) while in the symbol `Book` to rename all instances - this will occur across all files in a project. You can also see refactoring in the right-click context menu. ```js // Reference the function @@ -84,11 +84,11 @@ function Book(title, author) { } ``` -> **JSDoc Tip:** The example above also showcased another way to get IntelliSense hints by using `JSDoc` comments. You can try this out by invoking the `Book` function and seeing the enhanced context in the IntelliSense Experience for the function as well as parameters. +> **JSDoc Tip:** The example above also showcased another way to get IntelliSense hints by using `JSDoc` comments. You can try this out by invoking the `Book` function and seeing the enhanced context in the IntelliSense menu for the function as well as parameters. ### Refactoring via Extraction -Sometimes you want factor already written code into a separate function or constant to use it later again. Select the lines you want to factor out and press kb(editor.action.quickFix) or click the little light bulb and choose one of the respective `Extract to...` options. Try it by selecting the code inside the `if`-clause on line 3 or any other common code you want to factor out. +Sometimes you want to refactor already written code into a separate function or constant to reuse it later. Select the lines you want to refactor out and press kb(editor.action.quickFix) or click the little light bulb and choose one of the respective `Extract to...` options. Try it by selecting the code inside the `if`-clause on line 3 or any other common code you want to refactor out. ```js function findFirstEvenNumber(arr) { @@ -103,7 +103,7 @@ function findFirstEvenNumber(arr) { ### Formatting -Keeping your code looking great is hard without a good formatter. Luckily it's easy to format content either the entire document with kb(editor.action.formatDocument) or formatting can be applied to the current selection with kb(editor.action.formatSelection). Both of these options are also available through the right click context menu. +Keeping your code looking great is hard without a good formatter. Luckily it's easy to format content either the entire document with kb(editor.action.formatDocument). Formatting can be applied to the current selection with kb(editor.action.formatSelection). Both of these options are also available through the right-click context menu. ```js var cars = ["Saab", "Volvo", "BMW"]; @@ -118,7 +118,7 @@ console.log(`This is the manufacturer [${cars[i]}])`); ### Code Folding -In a large file it can often be useful to collapse sections of code to increase readability. To do this you can simply press kb(editor.fold) to `fold` the code - press kb(editor.unfold) to `unfold`. Folding can also be done with the +/- icons in the left gutter. To fold all sections kb(editor.foldAll) or to unfold all kb(editor.unfoldAll). +In a large file it can often be useful to collapse sections of code to increase readability. To do this you can simply press kb(editor.fold) to fold the code, press kb(editor.unfold) to unfold. Folding can also be done with the +/- icons in the left gutter. To fold all sections use kb(editor.foldAll) or to unfold all use kb(editor.unfoldAll). ```html
@@ -137,7 +137,7 @@ In a large file it can often be useful to collapse sections of code to increase >**Tip:** Folding is based on indentation and as a result can apply to all languages. Simply indent your code to create a foldable section you can fold a certain number of levels with shortcuts like kb(editor.foldLevel1) through to kb(editor.foldLevel5). ### Errors and Warnings -Errors and warnings are highlighted as you edit your code with `squiggles`. In the sample below you can see a number of syntax errors. By pressing kb(editor.action.marker.next) you can navigate across them in sequence and see the detailed error message. As you correct them the `squiggles` and `scrollbar indicators` will update. +Errors and warnings are highlighted as you edit your code with squiggles. In the sample below you can see a number of syntax errors. By pressing kb(editor.action.marker.next) you can navigate across them in sequence and see the detailed error message. As you correct them the squiggles and scrollbar indicators will update. ```js // This code has a few syntax errors @@ -157,11 +157,11 @@ You can greatly accelerate your editing through the use of snippets. Simply sta ``` ->**Tip:** the extension gallery includes snippets for almost every framework and language imaginable [extensions](command:workbench.extensions.action.showPopularExtensions). You can also create your own [user defined snippets](command:workbench.action.openSnippets). +>**Tip:** the [extension gallery](command:workbench.extensions.action.showPopularExtensions) includes snippets for almost every framework and language imaginable. You can also create your own [user-defined snippets](command:workbench.action.openSnippets). ### Emmet -Emmet takes the snippets idea to a whole new level: you can type CSS-like expressions that can be dynamically parsed, and produce output depending on what you type in the abbreviation. To use Emmet simply run the command `Emmet: Expand Abbreviation` with cursor at the end of a valid Emmet abbreviation or snippet and the expansion will occur. +Emmet takes the snippets idea to a whole new level: you can type CSS-like expressions that can be dynamically parsed, and produce output depending on what you type in the abbreviation. To use Emmet simply run the command `Emmet: Expand Abbreviation` with the cursor at the end of a valid Emmet abbreviation or snippet and the expansion will occur. ```html ul>li.item$*5 @@ -186,10 +186,10 @@ easy = 42; ## Thanks! Well if you have got this far then you will have touched on some of the editing features in Visual Studio Code. But don't stop now :) We have lots of additional [documentation](https://code.visualstudio.com/docs), [introductory videos](https://code.visualstudio.com/docs/getstarted/introvideos) and [tips and tricks](https://go.microsoft.com/fwlink/?linkid=852118) for the product that will help you learn how to use it. And while you are here, here are a few additional things you can try: -- Open the Integrated Terminal by pressing kb(workbench.action.terminal.toggleTerminal) then see what's possible by [reviewing the terminal documentation](https://code.visualstudio.com/docs/editor/integrated-terminal) -- Work with version control by pressing kb(workbench.view.scm) understand how to stage, commit, change branches, and view diffs and more by reviewing the [version control documentation](https://code.visualstudio.com/docs/editor/versioncontrol) -- Browse thousands of extensions in our integrated gallery by pressing with kb(workbench.view.extensions) the [documentation](https://code.visualstudio.com/docs/editor/extension-gallery) will show you how to see the most popular extensions, disable installed ones and more. +- Open the Integrated Terminal by pressing kb(workbench.action.terminal.toggleTerminal), then see what's possible by [reviewing the terminal documentation](https://code.visualstudio.com/docs/editor/integrated-terminal) +- Work with version control by pressing kb(workbench.view.scm). Understand how to stage, commit, change branches, and view diffs and more by reviewing the [version control documentation](https://code.visualstudio.com/docs/editor/versioncontrol) +- Browse thousands of extensions in our integrated gallery by pressing kb(workbench.view.extensions). The [documentation](https://code.visualstudio.com/docs/editor/extension-gallery) will show you how to see the most popular extensions, disable installed ones and more. -OK that's all for now, +That's all for now, Happy Coding! \ No newline at end of file diff --git a/src/vs/workbench/services/backup/common/backup.ts b/src/vs/workbench/services/backup/common/backup.ts index 7228988ab14..7a46ffa491e 100644 --- a/src/vs/workbench/services/backup/common/backup.ts +++ b/src/vs/workbench/services/backup/common/backup.ts @@ -13,8 +13,8 @@ import { ITextBufferFactory } from 'vs/editor/common/model'; export const IBackupFileService = createDecorator('backupFileService'); -export const BACKUP_FILE_RESOLVE_OPTIONS: IResolveContentOptions = { acceptTextOnly: true, encoding: 'utf-8' }; -export const BACKUP_FILE_UPDATE_OPTIONS: IUpdateContentOptions = { encoding: 'utf-8' }; +export const BACKUP_FILE_RESOLVE_OPTIONS: IResolveContentOptions = { acceptTextOnly: true, encoding: 'utf8' }; +export const BACKUP_FILE_UPDATE_OPTIONS: IUpdateContentOptions = { encoding: 'utf8' }; /** * A service that handles any I/O and state associated with the backup system. diff --git a/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts b/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts index bdd9c346c22..2be9fac95bd 100644 --- a/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts +++ b/src/vs/workbench/services/configuration/common/configurationExtensionPoint.ts @@ -94,7 +94,7 @@ const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint { const configurations: IConfigurationNode[] = []; - function handleConfiguration(node: IConfigurationNode, id: string, extension: IExtensionPointUser) { + function handleConfiguration(node: IConfigurationNode, extension: IExtensionPointUser) { let configuration = objects.deepClone(node); if (configuration.title && (typeof configuration.title !== 'string')) { @@ -103,17 +103,17 @@ configurationExtPoint.setHandler(extensions => { validateProperties(configuration, extension); - configuration.id = id; + configuration.id = extension.description.uuid || extension.description.id; + configuration.title = configuration.title || extension.description.displayName || extension.description.id; configurations.push(configuration); } for (let extension of extensions) { const value = extension.value; - const id = extension.description.id; if (!Array.isArray(value)) { - handleConfiguration(value, id, extension); + handleConfiguration(value, extension); } else { - value.forEach(v => handleConfiguration(v, id, extension)); + value.forEach(v => handleConfiguration(v, extension)); } } configurationRegistry.registerConfigurations(configurations, registeredDefaultConfigurations, false); diff --git a/src/vs/workbench/services/editor/common/editorService.ts b/src/vs/workbench/services/editor/common/editorService.ts index 1debca50ef7..b34c179fee1 100644 --- a/src/vs/workbench/services/editor/common/editorService.ts +++ b/src/vs/workbench/services/editor/common/editorService.ts @@ -29,6 +29,8 @@ export const IWorkbenchEditorService = createDecorator( export type IResourceInputType = IResourceInput | IUntitledResourceInput | IResourceDiffInput | IResourceSideBySideInput; +export type ICloseEditorsFilter = { except?: IEditorInput, direction?: Direction, unmodifiedOnly?: boolean }; + /** * The editor service allows to open editors and work on the active * editor input and models. @@ -68,8 +70,10 @@ export interface IWorkbenchEditorService extends IEditorService { * Similar to #openEditor() but allows to open multiple editors for different positions at the same time. If there are * more than one editor per position, only the first one will be active and the others stacked behind inactive. */ - openEditors(editors: { input: IResourceInputType, position: Position }[]): TPromise; - openEditors(editors: { input: IEditorInput, position: Position, options?: IEditorOptions | ITextEditorOptions }[]): TPromise; + openEditors(editors: { input: IResourceInputType, position?: Position }[]): TPromise; + openEditors(editors: { input: IEditorInput, position?: Position, options?: IEditorOptions | ITextEditorOptions }[]): TPromise; + openEditors(editors: { input: IResourceInputType }[], sideBySide?: boolean): TPromise; + openEditors(editors: { input: IEditorInput, options?: IEditorOptions | ITextEditorOptions }[], sideBySide?: boolean): TPromise; /** * Given a list of editors to replace, will look across all groups where this editor is open (active or hidden) @@ -83,17 +87,33 @@ export interface IWorkbenchEditorService extends IEditorService { */ closeEditor(position: Position, input: IEditorInput): TPromise; + /** + * Closes all editors of the provided groups, or all editors across all groups + * if no position is provided. + */ + closeEditors(positions?: Position[]): TPromise; + /** * Closes editors of a specific group at the provided position. If the optional editor is provided to exclude, it * will not be closed. The direction can be used in that case to control if all other editors should get closed, * or towards a specific direction. */ - closeEditors(position: Position, filter?: { except?: IEditorInput, direction?: Direction, unmodifiedOnly?: boolean }): TPromise; + closeEditors(position: Position, filter?: ICloseEditorsFilter): TPromise; /** - * Closes all editors across all groups. The optional position allows to keep one group alive. + * Closes the provided editors of a specific group at the provided position. */ - closeAllEditors(except?: Position): TPromise; + closeEditors(position: Position, editors: IEditorInput[]): TPromise; + + /** + * Closes specific editors across all groups at once. + */ + closeEditors(editors: { positionOne?: ICloseEditorsFilter, positionTwo?: ICloseEditorsFilter, positionThree?: ICloseEditorsFilter }): TPromise; + + /** + * Closes specific editors across all groups at once. + */ + closeEditors(editors: { positionOne?: IEditorInput[], positionTwo?: IEditorInput[], positionThree?: IEditorInput[] }): TPromise; /** * Allows to resolve an untyped input to a workbench typed instanceof editor input @@ -104,11 +124,15 @@ export interface IWorkbenchEditorService extends IEditorService { export interface IEditorPart { openEditor(input?: IEditorInput, options?: IEditorOptions | ITextEditorOptions, sideBySide?: boolean): TPromise; openEditor(input?: IEditorInput, options?: IEditorOptions | ITextEditorOptions, position?: Position): TPromise; - openEditors(editors: { input: IEditorInput, position: Position, options?: IEditorOptions | ITextEditorOptions }[]): TPromise; + openEditors(editors: { input: IEditorInput, position?: Position, options?: IEditorOptions | ITextEditorOptions }[]): TPromise; + openEditors(editors: { input: IEditorInput, options?: IEditorOptions | ITextEditorOptions }[], sideBySide?: boolean): TPromise; replaceEditors(editors: { toReplace: IEditorInput, replaceWith: IEditorInput, options?: IEditorOptions | ITextEditorOptions }[], position?: Position): TPromise; + closeEditors(positions?: Position[]): TPromise; closeEditor(position: Position, input: IEditorInput): TPromise; - closeEditors(position: Position, filter?: { except?: IEditorInput, direction?: Direction, unmodifiedOnly?: boolean }): TPromise; - closeAllEditors(except?: Position): TPromise; + closeEditors(position: Position, filter?: ICloseEditorsFilter): TPromise; + closeEditors(position: Position, editors: IEditorInput[]): TPromise; + closeEditors(editors: { positionOne?: ICloseEditorsFilter, positionTwo?: ICloseEditorsFilter, positionThree?: ICloseEditorsFilter }): TPromise; + closeEditors(editors: { positionOne?: IEditorInput[], positionTwo?: IEditorInput[], positionThree?: IEditorInput[] }): TPromise; getActiveEditor(): IEditor; getVisibleEditors(): IEditor[]; getActiveEditorInput(): IEditorInput; @@ -208,7 +232,9 @@ export class WorkbenchEditorService implements IWorkbenchEditorService { public openEditors(editors: { input: IResourceInputType, position: Position }[]): TPromise; public openEditors(editors: { input: IEditorInput, position: Position, options?: IEditorOptions }[]): TPromise; - public openEditors(editors: any[]): TPromise { + public openEditors(editors: { input: IResourceInputType }[], sideBySide?: boolean): TPromise; + public openEditors(editors: { input: IEditorInput, options?: IEditorOptions }[], sideBySide?: boolean): TPromise; + public openEditors(editors: any[], sideBySide?: boolean): TPromise { const inputs = editors.map(editor => this.createInput(editor.input)); const typedInputs: { input: IEditorInput, position: Position, options?: EditorOptions }[] = inputs.map((input, index) => { const options = editors[index].input instanceof EditorInput ? this.toOptions(editors[index].options) : TextEditorOptions.from(editors[index].input); @@ -220,7 +246,7 @@ export class WorkbenchEditorService implements IWorkbenchEditorService { }; }); - return this.editorPart.openEditors(typedInputs); + return this.editorPart.openEditors(typedInputs, sideBySide); } public replaceEditors(editors: { toReplace: IResourceInputType, replaceWith: IResourceInputType }[], position?: Position): TPromise; @@ -249,12 +275,13 @@ export class WorkbenchEditorService implements IWorkbenchEditorService { return this.editorPart.closeEditor(position, input); } - public closeEditors(position: Position, filter?: { except?: IEditorInput, direction?: Direction, unmodifiedOnly?: boolean }): TPromise { - return this.editorPart.closeEditors(position, filter); - } - - public closeAllEditors(except?: Position): TPromise { - return this.editorPart.closeAllEditors(except); + public closeEditors(positions?: Position[]): TPromise; + public closeEditors(position: Position, filter?: ICloseEditorsFilter): TPromise; + public closeEditors(position: Position, editors: IEditorInput[]): TPromise; + public closeEditors(editors: { positionOne?: ICloseEditorsFilter, positionTwo?: ICloseEditorsFilter, positionThree?: ICloseEditorsFilter }): TPromise; + public closeEditors(editors: { positionOne?: IEditorInput[], positionTwo?: IEditorInput[], positionThree?: IEditorInput[] }): TPromise; + public closeEditors(positionsOrEditors: any, filterOrEditors?: any): TPromise { + return this.editorPart.closeEditors(positionsOrEditors, filterOrEditors); } public createInput(input: IEditorInput): EditorInput; diff --git a/src/vs/workbench/services/editor/test/browser/editorService.test.ts b/src/vs/workbench/services/editor/test/browser/editorService.test.ts index 0e71a596420..196825b2f11 100644 --- a/src/vs/workbench/services/editor/test/browser/editorService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorService.test.ts @@ -8,7 +8,7 @@ import * as assert from 'assert'; import { Promise, TPromise } from 'vs/base/common/winjs.base'; import paths = require('vs/base/common/paths'); -import { Position, Direction, IEditor, IEditorInput } from 'vs/platform/editor/common/editor'; +import { Position, IEditor, IEditorInput } from 'vs/platform/editor/common/editor'; import URI from 'vs/base/common/uri'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorInput, EditorOptions, TextEditorOptions } from 'vs/workbench/common/editor'; @@ -18,6 +18,7 @@ import { DelegatingWorkbenchEditorService, WorkbenchEditorService, IEditorPart } import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; +import { ICloseEditorsFilter } from 'vs/workbench/browser/parts/editor/editorPart'; let activeEditor: BaseEditor = { getSelection: function () { @@ -51,11 +52,12 @@ class TestEditorPart implements IEditorPart { return TPromise.as([]); } - public closeEditors(position: Position, filter?: { except?: EditorInput, direction?: Direction, unmodifiedOnly?: boolean }): TPromise { - return TPromise.as(null); - } - - public closeAllEditors(except?: Position): TPromise { + public closeEditors(positions?: Position[]): TPromise; + public closeEditors(position: Position, filter?: ICloseEditorsFilter): TPromise; + public closeEditors(position: Position, editors?: EditorInput[]): TPromise; + public closeEditors(editors: { positionOne?: ICloseEditorsFilter, positionTwo?: ICloseEditorsFilter, positionThree?: ICloseEditorsFilter }): TPromise; + public closeEditors(editors: { positionOne?: EditorInput[], positionTwo?: EditorInput[], positionThree?: EditorInput[] }): TPromise; + public closeEditors(positionOrEditors: any, filterOrEditors?: any): TPromise { return TPromise.as(null); } diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index c01e5b32c77..8abc3ff6140 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -119,12 +119,36 @@ export class ExtensionService extends Disposable implements IExtensionService { this._extensionHostProcessCustomers = []; this._extensionHostProcessProxy = null; - lifecycleService.when(LifecyclePhase.Running).then(() => { - // delay extension host creation and extension scanning - // until after workbench is running - this._startExtensionHostProcess([]); - this._scanAndHandleExtensions(); + this.startDelayed(lifecycleService); + } + + private startDelayed(lifecycleService: ILifecycleService): void { + let started = false; + const startOnce = () => { + if (!started) { + started = true; + + this._startExtensionHostProcess([]); + this._scanAndHandleExtensions(); + } + }; + + // delay extension host creation and extension scanning + // until the workbench is restoring. we cannot defer the + // extension host more (LifecyclePhase.Running) because + // some editors require the extension host to restore + // and this would result in a deadlock + // see https://github.com/Microsoft/vscode/issues/41322 + lifecycleService.when(LifecyclePhase.Restoring).then(() => { + // we add an additional delay of 800ms because the extension host + // starting is a potential expensive operation and we do no want + // to fight with editors, viewlets and panels restoring. + setTimeout(() => startOnce(), 800); }); + + // if we are running before the 800ms delay, make sure to start + // the extension host right away though. + lifecycleService.when(LifecyclePhase.Running).then(() => startOnce()); } public dispose(): void { diff --git a/src/vs/workbench/services/files/electron-browser/fileService.ts b/src/vs/workbench/services/files/electron-browser/fileService.ts index 3d199425abc..5eeae64bf3a 100644 --- a/src/vs/workbench/services/files/electron-browser/fileService.ts +++ b/src/vs/workbench/services/files/electron-browser/fileService.ts @@ -100,7 +100,7 @@ export class FileService implements IFileService { // Forward to unexpected error handler errors.onUnexpectedError(msg); - // Detect if we run < .NET Framework 4.5 + // Detect if we run < .NET Framework 4.5 (TODO@ben remove with new watcher impl) if (typeof msg === 'string' && msg.indexOf(FileService.NET_VERSION_ERROR) >= 0 && !this.storageService.getBoolean(FileService.NET_VERSION_ERROR_IGNORE_KEY, StorageScope.WORKSPACE)) { this.messageService.show(Severity.Warning, { message: nls.localize('netVersionError', "The Microsoft .NET Framework 4.5 is required. Please follow the link to install it."), diff --git a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts index ab28accf00d..2bf1ba014e1 100644 --- a/src/vs/workbench/services/files/electron-browser/remoteFileService.ts +++ b/src/vs/workbench/services/files/electron-browser/remoteFileService.ts @@ -31,7 +31,6 @@ function toIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], recurse const [resource, stat] = tuple; const fileStat: IFileStat = { isDirectory: false, - hasChildren: false, resource: resource, name: basename(resource.path), mtime: stat.mtime, @@ -39,27 +38,25 @@ function toIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], recurse etag: stat.mtime.toString(29) + stat.size.toString(31), }; - if (stat.type === FileType.File) { - // done - return TPromise.as(fileStat); + if (stat.type === FileType.Dir) { + fileStat.isDirectory = true; - } else { - // dir -> resolve - return provider.readdir(resource).then(entries => { - fileStat.isDirectory = true; - fileStat.hasChildren = entries.length > 0; + if (recurse && recurse([resource, stat])) { + // dir -> resolve + return provider.readdir(resource).then(entries => { + fileStat.isDirectory = true; - if (recurse && recurse([resource, stat])) { // resolve children if requested return TPromise.join(entries.map(stat => toIFileStat(provider, stat, recurse))).then(children => { fileStat.children = children; return fileStat; }); - } else { - return fileStat; - } - }); + }); + } } + + // file or (un-resolved) dir + return TPromise.as(fileStat); } export function toDeepIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], to: URI[]): TPromise { @@ -234,7 +231,16 @@ export class RemoteFileService extends FileService { return this.resolveFile(resource).then(fileStat => { - if (options.etag === fileStat.etag) { + if (fileStat.isDirectory) { + // todo@joh cannot copy a folder + // https://github.com/Microsoft/vscode/issues/41547 + throw new FileOperationError( + localize('fileIsDirectoryError', "File is directory"), + FileOperationResult.FILE_IS_DIRECTORY, + options + ); + } + if (fileStat.etag === options.etag) { throw new FileOperationError( localize('fileNotModifiedError', "File not modified since"), FileOperationResult.FILE_NOT_MODIFIED_SINCE, @@ -474,10 +480,9 @@ export class RemoteFileService extends FileService { : TPromise.as(null); return prepare.then(() => { - // TODO@Joh This does only work for textfiles - // because the content turns things into a string - // and all binary data will be broken - return this.resolveContent(source).then(content => { + // todo@ben, can only copy text files + // https://github.com/Microsoft/vscode/issues/41543 + return this.resolveContent(source, { acceptTextOnly: true }).then(content => { return this._withProvider(target).then(provider => { return this._doUpdateContent(provider, target, content.value, { encoding: content.encoding }).then(fileStat => { this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.COPY, fileStat)); diff --git a/src/vs/workbench/services/files/node/fileService.ts b/src/vs/workbench/services/files/node/fileService.ts index 81b3bf49b55..b1475b44eb9 100644 --- a/src/vs/workbench/services/files/node/fileService.ts +++ b/src/vs/workbench/services/files/node/fileService.ts @@ -1132,7 +1132,6 @@ export class StatResolver { const fileStat: IFileStat = { resource: this.resource, isDirectory: this.isDirectory, - hasChildren: undefined, name: this.name, etag: this.etag, size: this.size, @@ -1161,7 +1160,6 @@ export class StatResolver { // Load children this.resolveChildren(this.resource.fsPath, absoluteTargetPaths, options && options.resolveSingleChildDescendants, children => { children = arrays.coalesce(children); // we don't want those null children (could be permission denied when reading a child) - fileStat.hasChildren = children && children.length > 0; fileStat.children = children || []; c(fileStat); @@ -1215,7 +1213,6 @@ export class StatResolver { const childStat: IFileStat = { resource: fileResource, isDirectory: fileStat.isDirectory(), - hasChildren: childCount > 0, name: file, mtime: fileStat.mtime.getTime(), etag: etag(fileStat), @@ -1239,7 +1236,6 @@ export class StatResolver { if (resolveFolderChildren) { $this.resolveChildren(fileResource.fsPath, absoluteTargetPaths, resolveSingleChildDescendants, children => { children = arrays.coalesce(children); // we don't want those null children - childStat.hasChildren = children && children.length > 0; childStat.children = children || []; clb(null, childStat); diff --git a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts index eb14be46361..675e464d805 100644 --- a/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/nsfw/watcherService.ts @@ -15,6 +15,7 @@ import { FileChangesEvent, IFilesConfiguration } from 'vs/platform/files/common/ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Schemas } from 'vs/base/common/network'; export class FileWatcher { private static readonly MAX_RESTARTS = 5; @@ -97,7 +98,10 @@ export class FileWatcher { return; } - this.service.setRoots(this.contextService.getWorkspace().folders.map(folder => { + this.service.setRoots(this.contextService.getWorkspace().folders.filter(folder => { + // Only workspace folders on disk + return folder.uri.scheme === Schemas.file; + }).map(folder => { // Fetch the root's watcherExclude setting and return it const configuration = this.configurationService.getValue({ resource: folder.uri @@ -128,4 +132,4 @@ export class FileWatcher { this.isDisposed = true; this.toDispose = dispose(this.toDispose); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/files/test/node/resolver.test.ts b/src/vs/workbench/services/files/test/node/resolver.test.ts index cc314d67d75..a6ed59a578b 100644 --- a/src/vs/workbench/services/files/test/node/resolver.test.ts +++ b/src/vs/workbench/services/files/test/node/resolver.test.ts @@ -54,7 +54,7 @@ suite('Stat Resolver', () => { resolver.resolve(null).then(result => { assert.ok(result); assert.ok(result.children); - assert.ok(result.hasChildren); + assert.ok(result.children.length > 0); assert.ok(result.isDirectory); assert.equal(result.children.length, testsElements.length); @@ -68,13 +68,12 @@ suite('Stat Resolver', () => { assert.ok(path.basename(value.resource.fsPath)); if (['examples', 'other'].indexOf(path.basename(value.resource.fsPath)) >= 0) { assert.ok(value.isDirectory); - assert.ok(value.hasChildren); } else if (path.basename(value.resource.fsPath) === 'index.html') { assert.ok(!value.isDirectory); - assert.ok(value.hasChildren === false); + assert.ok(!value.children); } else if (path.basename(value.resource.fsPath) === 'site.css') { assert.ok(!value.isDirectory); - assert.ok(value.hasChildren === false); + assert.ok(!value.children); } else { assert.ok(!'Unexpected value ' + path.basename(value.resource.fsPath)); } @@ -89,7 +88,7 @@ suite('Stat Resolver', () => { resolver.resolve({ resolveTo: [toResource('other/deep')] }).then(result => { assert.ok(result); assert.ok(result.children); - assert.ok(result.hasChildren); + assert.ok(result.children.length > 0); assert.ok(result.isDirectory); let children = result.children; @@ -97,11 +96,11 @@ suite('Stat Resolver', () => { let other = utils.getByName(result, 'other'); assert.ok(other); - assert.ok(other.hasChildren); + assert.ok(other.children.length > 0); let deep = utils.getByName(other, 'deep'); assert.ok(deep); - assert.ok(deep.hasChildren); + assert.ok(deep.children.length > 0); assert.equal(deep.children.length, 4); }) .done(() => done(), done); @@ -113,7 +112,7 @@ suite('Stat Resolver', () => { resolver.resolve({ resolveTo: [toResource('other/Deep')] }).then(result => { assert.ok(result); assert.ok(result.children); - assert.ok(result.hasChildren); + assert.ok(result.children.length > 0); assert.ok(result.isDirectory); let children = result.children; @@ -121,16 +120,15 @@ suite('Stat Resolver', () => { let other = utils.getByName(result, 'other'); assert.ok(other); - assert.ok(other.hasChildren); + assert.ok(other.children.length > 0); let deep = utils.getByName(other, 'deep'); if (isLinux) { // Linux has case sensitive file system assert.ok(deep); - assert.ok(deep.hasChildren); assert.ok(!deep.children); // not resolved because we got instructed to resolve other/Deep with capital D } else { assert.ok(deep); - assert.ok(deep.hasChildren); + assert.ok(deep.children.length > 0); assert.equal(deep.children.length, 4); } }) @@ -143,7 +141,7 @@ suite('Stat Resolver', () => { resolver.resolve({ resolveTo: [toResource('other/deep'), toResource('examples')] }).then(result => { assert.ok(result); assert.ok(result.children); - assert.ok(result.hasChildren); + assert.ok(result.children.length > 0); assert.ok(result.isDirectory); let children = result.children; @@ -151,16 +149,16 @@ suite('Stat Resolver', () => { let other = utils.getByName(result, 'other'); assert.ok(other); - assert.ok(other.hasChildren); + assert.ok(other.children.length > 0); let deep = utils.getByName(other, 'deep'); assert.ok(deep); - assert.ok(deep.hasChildren); + assert.ok(deep.children.length > 0); assert.equal(deep.children.length, 4); let examples = utils.getByName(result, 'examples'); assert.ok(examples); - assert.ok(examples.hasChildren); + assert.ok(examples.children.length > 0); assert.equal(examples.children.length, 4); }) .done(() => done(), done); @@ -172,7 +170,7 @@ suite('Stat Resolver', () => { resolver.resolve({ resolveSingleChildDescendants: true }).then(result => { assert.ok(result); assert.ok(result.children); - assert.ok(result.hasChildren); + assert.ok(result.children.length > 0); assert.ok(result.isDirectory); let children = result.children; @@ -180,7 +178,7 @@ suite('Stat Resolver', () => { let deep = utils.getByName(result, 'deep'); assert.ok(deep); - assert.ok(deep.hasChildren); + assert.ok(deep.children.length > 0); assert.equal(deep.children.length, 4); }) .done(() => done(), done); diff --git a/src/vs/workbench/services/progress/browser/progressService2.ts b/src/vs/workbench/services/progress/browser/progressService2.ts index 8c87a033e1c..ad8d9889ea9 100644 --- a/src/vs/workbench/services/progress/browser/progressService2.ts +++ b/src/vs/workbench/services/progress/browser/progressService2.ts @@ -75,6 +75,8 @@ export class ProgressService2 implements IProgressService2 { return this._withWindowProgress(options, task); case ProgressLocation.Scm: return this._withViewletProgress('workbench.view.scm', task); + case ProgressLocation.Extensions: + return this._withViewletProgress('workbench.view.extensions', task); default: console.warn(`Bad progress location: ${location}`); return undefined; diff --git a/src/vs/workbench/services/search/node/fileSearch.ts b/src/vs/workbench/services/search/node/fileSearch.ts index 2e6d6ed3caa..6917c8da877 100644 --- a/src/vs/workbench/services/search/node/fileSearch.ts +++ b/src/vs/workbench/services/search/node/fileSearch.ts @@ -118,7 +118,7 @@ export class FileWalker { this.isCanceled = true; } - public walk(folderQueries: IFolderSearch[], extraFiles: string[], onResult: (result: IRawFileMatch) => void, done: (error: Error, isLimitHit: boolean) => void): void { + public walk(folderQueries: IFolderSearch[], extraFiles: string[], onResult: (result: IRawFileMatch) => void, onMessage: (message: IProgress) => void, done: (error: Error, isLimitHit: boolean) => void): void { this.fileWalkStartTime = Date.now(); // Support that the file pattern is a full path to a file that exists @@ -180,7 +180,7 @@ export class FileWalker { // For each root folder flow.parallel(folderQueries, (folderQuery: IFolderSearch, rootFolderDone: (err: Error, result: void) => void) => { - this.call(traverse, this, folderQuery, onResult, (err?: Error) => { + this.call(traverse, this, folderQuery, onResult, onMessage, (err?: Error) => { if (err) { const errorMessage = toErrorMessage(err); console.error(errorMessage); @@ -205,7 +205,7 @@ export class FileWalker { } } - private cmdTraversal(folderQuery: IFolderSearch, onResult: (result: IRawFileMatch) => void, cb: (err?: Error) => void): void { + private cmdTraversal(folderQuery: IFolderSearch, onResult: (result: IRawFileMatch) => void, onMessage: (message: IProgress) => void, cb: (err?: Error) => void): void { const rootFolder = folderQuery.folder; const isMac = platform.isMacintosh; let cmd: childProcess.ChildProcess; @@ -227,6 +227,18 @@ export class FileWalker { const ripgrep = spawnRipgrepCmd(this.config, folderQuery, this.config.includePattern, this.folderExcludePatterns.get(folderQuery.folder).expression); cmd = ripgrep.cmd; noSiblingsClauses = !Object.keys(ripgrep.siblingClauses).length; + + process.nextTick(() => { + const escapedArgs = ripgrep.rgArgs.args + .map(arg => arg.match(/^-/) ? arg : `'${arg}'`) + .join(' '); + + let rgCmd = `rg ${escapedArgs}\n - cwd: ${ripgrep.cwd}`; + if (ripgrep.rgArgs.siblingClauses) { + rgCmd += `\n - Sibling clauses: ${JSON.stringify(ripgrep.rgArgs.siblingClauses)}`; + } + onMessage({ message: rgCmd }); + }); } else { cmd = this.spawnFindCmd(folderQuery); } @@ -504,7 +516,7 @@ export class FileWalker { matchDirectory(rootEntries); } - private nodeJSTraversal(folderQuery: IFolderSearch, onResult: (result: IRawFileMatch) => void, done: (err?: Error) => void): void { + private nodeJSTraversal(folderQuery: IFolderSearch, onResult: (result: IRawFileMatch) => void, onMessage: (message: IProgress) => void, done: (err?: Error) => void): void { this.directoriesWalked++; extfs.readdir(folderQuery.folder, (error: Error, files: string[]) => { if (error || this.isCanceled || this.isLimitHit) { @@ -730,7 +742,7 @@ export class Engine implements ISearchEngine { } public search(onResult: (result: IRawFileMatch) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISerializedSearchComplete) => void): void { - this.walker.walk(this.folderQueries, this.extraFiles, onResult, (err: Error, isLimitHit: boolean) => { + this.walker.walk(this.folderQueries, this.extraFiles, onResult, onProgress, (err: Error, isLimitHit: boolean) => { done(err, { limitHit: isLimitHit, stats: this.walker.getStats() diff --git a/src/vs/workbench/services/search/node/rawSearchService.ts b/src/vs/workbench/services/search/node/rawSearchService.ts index b4956230b48..82cc34039d1 100644 --- a/src/vs/workbench/services/search/node/rawSearchService.ts +++ b/src/vs/workbench/services/search/node/rawSearchService.ts @@ -367,7 +367,9 @@ export class SearchService implements IRawSearchService { } } }, (progress) => { - p(progress); + process.nextTick(() => { + p(progress); + }); }, (error, stats) => { if (batch.length) { p(batch); diff --git a/src/vs/workbench/services/search/node/ripgrepFileSearch.ts b/src/vs/workbench/services/search/node/ripgrepFileSearch.ts index 50fa1077c40..9b73f7739ec 100644 --- a/src/vs/workbench/services/search/node/ripgrepFileSearch.ts +++ b/src/vs/workbench/services/search/node/ripgrepFileSearch.ts @@ -15,9 +15,12 @@ import { foldersToIncludeGlobs, foldersToRgExcludeGlobs } from './ripgrepTextSea export function spawnRipgrepCmd(config: IRawSearch, folderQuery: IFolderSearch, includePattern: glob.IExpression, excludePattern: glob.IExpression) { const rgArgs = getRgArgs(config, folderQuery, includePattern, excludePattern); + const cwd = folderQuery.folder; return { - cmd: cp.spawn(rgPath, rgArgs.globArgs, { cwd: folderQuery.folder }), - siblingClauses: rgArgs.siblingClauses + cmd: cp.spawn(rgPath, rgArgs.args, { cwd }), + siblingClauses: rgArgs.siblingClauses, + rgArgs, + cwd }; } @@ -57,7 +60,7 @@ function getRgArgs(config: IRawSearch, folderQuery: IFolderSearch, includePatter args.push('.'); - return { globArgs: args, siblingClauses }; + return { args, siblingClauses }; } function anchor(glob: string) { diff --git a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts index 8742487da29..72ecb4b919d 100644 --- a/src/vs/workbench/services/search/node/ripgrepTextSearch.ts +++ b/src/vs/workbench/services/search/node/ripgrepTextSearch.ts @@ -18,10 +18,10 @@ import * as paths from 'vs/base/common/paths'; import * as extfs from 'vs/base/node/extfs'; import * as encoding from 'vs/base/node/encoding'; import * as glob from 'vs/base/common/glob'; -import { ISearchLog } from 'vs/platform/search/common/search'; import { TPromise } from 'vs/base/common/winjs.base'; import { ISerializedFileMatch, ISerializedSearchComplete, IRawSearch, IFolderSearch, LineMatch, FileMatch } from './search'; +import { IProgress } from 'vs/platform/search/common/search'; export class RipgrepEngine { private isDone = false; @@ -44,7 +44,7 @@ export class RipgrepEngine { } // TODO@Rob - make promise-based once the old search is gone, and I don't need them to have matching interfaces anymore - search(onResult: (match: ISerializedFileMatch) => void, onMessage: (message: ISearchLog) => void, done: (error: Error, complete: ISerializedSearchComplete) => void): void { + search(onResult: (match: ISerializedFileMatch) => void, onMessage: (message: IProgress) => void, done: (error: Error, complete: ISerializedSearchComplete) => void): void { if (!this.config.folderQueries.length && !this.config.extraFiles.length) { process.removeListener('exit', this.killRgProcFn); done(null, { @@ -61,17 +61,18 @@ export class RipgrepEngine { const cwd = platform.isWindows ? 'c:/' : '/'; process.nextTick(() => { // Allow caller to register progress callback - const escapedArgs = rgArgs.globArgs + const escapedArgs = rgArgs.args .map(arg => arg.match(/^-/) ? arg : `'${arg}'`) .join(' '); - const rgCmd = `rg ${escapedArgs}\n - cwd: ${cwd}\n`; - onMessage({ message: rgCmd }); + let rgCmd = `rg ${escapedArgs}\n - cwd: ${cwd}`; if (rgArgs.siblingClauses) { - onMessage({ message: ` - Sibling clauses: ${JSON.stringify(rgArgs.siblingClauses)}\n` }); + rgCmd += `\n - Sibling clauses: ${JSON.stringify(rgArgs.siblingClauses)}`; } + + onMessage({ message: rgCmd }); }); - this.rgProc = cp.spawn(rgPath, rgArgs.globArgs, { cwd }); + this.rgProc = cp.spawn(rgPath, rgArgs.args, { cwd }); process.once('exit', this.killRgProcFn); this.ripgrepParser = new RipgrepParser(this.config.maxResults, cwd, this.config.extraFiles); @@ -421,7 +422,7 @@ export function fixDriveC(path: string): string { path; } -function getRgArgs(config: IRawSearch): IRgGlobResult { +function getRgArgs(config: IRawSearch) { const args = ['--hidden', '--heading', '--line-number', '--color', 'ansi', '--colors', 'path:none', '--colors', 'line:none', '--colors', 'match:fg:red', '--colors', 'match:style:nobold']; if (config.contentPattern.isSmartCase) { args.push('--smart-case'); @@ -499,7 +500,7 @@ function getRgArgs(config: IRawSearch): IRgGlobResult { args.push(...config.folderQueries.map(q => q.folder)); args.push(...config.extraFiles); - return { globArgs: args, siblingClauses }; + return { args, siblingClauses }; } function getSiblings(file: string): TPromise { diff --git a/src/vs/workbench/services/search/node/search.ts b/src/vs/workbench/services/search/node/search.ts index 1c5c4947e7a..a1061c52d22 100644 --- a/src/vs/workbench/services/search/node/search.ts +++ b/src/vs/workbench/services/search/node/search.ts @@ -7,7 +7,7 @@ import { PPromise, TPromise } from 'vs/base/common/winjs.base'; import { IExpression } from 'vs/base/common/glob'; -import { IProgress, ILineMatch, IPatternInfo, ISearchStats, ISearchLog } from 'vs/platform/search/common/search'; +import { IProgress, ILineMatch, IPatternInfo, ISearchStats } from 'vs/platform/search/common/search'; import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; export interface IFolderSearch { @@ -71,7 +71,7 @@ export interface ISerializedFileMatch { } // Type of the possible values for progress calls from the engine -export type ISerializedSearchProgressItem = ISerializedFileMatch | ISerializedFileMatch[] | IProgress | ISearchLog; +export type ISerializedSearchProgressItem = ISerializedFileMatch | ISerializedFileMatch[] | IProgress; export type IFileSearchProgressItem = IRawFileMatch | IRawFileMatch[] | IProgress; diff --git a/src/vs/workbench/services/search/node/searchService.ts b/src/vs/workbench/services/search/node/searchService.ts index b6307b38dd4..bbfe0682918 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -22,6 +22,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Schemas } from 'vs/base/common/network'; +import { ILogService } from 'vs/platform/log/common/log'; export class SearchService implements ISearchService { public _serviceBrand: any; @@ -35,7 +36,8 @@ export class SearchService implements ISearchService { @IUntitledEditorService private untitledEditorService: IUntitledEditorService, @IEnvironmentService environmentService: IEnvironmentService, @ITelemetryService private telemetryService: ITelemetryService, - @IConfigurationService private configurationService: IConfigurationService + @IConfigurationService private configurationService: IConfigurationService, + @ILogService private logService: ILogService ) { this.diskSearch = new DiskSearch(!environmentService.isBuilt || environmentService.verbose, /*timeout=*/undefined, environmentService.debugSearch); this.registerSearchResultProvider(this.diskSearch); @@ -104,6 +106,10 @@ export class SearchService implements ISearchService { // Progress onProgress(progress); } + + if (progress.message) { + this.logService.info('SearchService#search', progress.message); + } } )); @@ -158,6 +164,9 @@ export class SearchService implements ISearchService { } // Don't support other resource schemes than files for now + // todo@remote + // why is that? we should search for resources from other + // schemes else if (resource.scheme !== 'file') { return; } diff --git a/src/vs/workbench/services/search/node/textSearch.ts b/src/vs/workbench/services/search/node/textSearch.ts index b5a62eb9023..c2002bb88ed 100644 --- a/src/vs/workbench/services/search/node/textSearch.ts +++ b/src/vs/workbench/services/search/node/textSearch.ts @@ -147,20 +147,22 @@ export class Engine implements ISearchEngine { nextBatch = []; nextBatchBytes = 0; } - }, (error, isLimitHit) => { - this.walkerIsDone = true; - this.walkerError = error; + }, + onProgress, + (error, isLimitHit) => { + this.walkerIsDone = true; + this.walkerError = error; - // Send any remaining paths to a worker, or unwind if we're stopping - if (nextBatch.length) { - if (this.limitReached || this.isCanceled) { - unwind(nextBatchBytes); + // Send any remaining paths to a worker, or unwind if we're stopping + if (nextBatch.length) { + if (this.limitReached || this.isCanceled) { + unwind(nextBatchBytes); + } else { + run(nextBatch, nextBatchBytes); + } } else { - run(nextBatch, nextBatchBytes); + unwind(0); } - } else { - unwind(0); - } - }); + }); } } diff --git a/src/vs/workbench/services/search/test/node/searchService.test.ts b/src/vs/workbench/services/search/test/node/searchService.test.ts index 7fd40591eef..772f4e1e7bb 100644 --- a/src/vs/workbench/services/search/test/node/searchService.test.ts +++ b/src/vs/workbench/services/search/test/node/searchService.test.ts @@ -75,6 +75,8 @@ class TestSearchEngine implements ISearchEngine { } } +const testTimeout = 5000; + suite('SearchService', () => { const rawSearch: IRawSearch = { @@ -94,6 +96,7 @@ suite('SearchService', () => { }; test('Individual results', function () { + this.timeout(testTimeout); let i = 5; const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch); const service = new RawSearchService(); @@ -113,6 +116,7 @@ suite('SearchService', () => { }); test('Batch results', function () { + this.timeout(testTimeout); let i = 25; const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch); const service = new RawSearchService(); @@ -134,6 +138,7 @@ suite('SearchService', () => { }); test('Collect batched results', function () { + this.timeout(testTimeout); const uriPath = '/some/where'; let i = 25; const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch); @@ -151,6 +156,7 @@ suite('SearchService', () => { }); test('Multi-root with include pattern and maxResults', function () { + this.timeout(testTimeout); const service = new RawSearchService(); const query: IRawSearch = { @@ -169,6 +175,7 @@ suite('SearchService', () => { }); test('Multi-root with include pattern and exists', function () { + this.timeout(testTimeout); const service = new RawSearchService(); const query: IRawSearch = { @@ -188,6 +195,7 @@ suite('SearchService', () => { }); test('Sorted results', function () { + this.timeout(testTimeout); const paths = ['bab', 'bbc', 'abb']; const matches: IRawFileMatch[] = paths.map(relativePath => ({ base: normalize('/some/where'), @@ -217,6 +225,7 @@ suite('SearchService', () => { }); test('Sorted result batches', function () { + this.timeout(testTimeout); let i = 25; const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch); const service = new RawSearchService(); @@ -243,6 +252,7 @@ suite('SearchService', () => { }); test('Cached results', function () { + this.timeout(testTimeout); const paths = ['bcb', 'bbc', 'aab']; const matches: IRawFileMatch[] = paths.map(relativePath => ({ base: normalize('/some/where'), diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 62ae927ce42..fc18f6c5656 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -85,10 +85,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil @IHashService private hashService: IHashService ) { super(modelService, modeService); - - // TODO@remote - // assert.ok(resource.scheme === 'file', 'TextFileEditorModel can only handle file:// resources.'); - this.resource = resource; this.toDispose = []; this._onDidContentChange = new Emitter(); @@ -393,8 +389,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil mtime: content.mtime, etag: content.etag, isDirectory: false, - hasChildren: false, - children: void 0, + children: void 0 }; this.updateLastResolvedDiskStat(resolvedStat); diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index 96e31476b70..6e5bf84bf4a 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -413,10 +413,6 @@ export abstract class TextFileService implements ITextFileService { const filesToSave: URI[] = []; const untitledToSave: URI[] = []; toSave.forEach(s => { - // TODO@remote - // if (s.scheme === Schemas.file) { - // filesToSave.push(s); - // } else if ((Array.isArray(arg1) || arg1 === true /* includeUntitled */) && s.scheme === UNTITLED_SCHEMA) { untitledToSave.push(s); } else { diff --git a/src/vs/workbench/services/textfile/electron-browser/textFileService.ts b/src/vs/workbench/services/textfile/electron-browser/textFileService.ts index 4e03d14d2a3..ecf4229c83b 100644 --- a/src/vs/workbench/services/textfile/electron-browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/electron-browser/textFileService.ts @@ -24,7 +24,7 @@ import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textMo import product from 'vs/platform/node/product'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IMessageService } from 'vs/platform/message/common/message'; +import { IMessageService, getConfirmMessage } from 'vs/platform/message/common/message'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; @@ -33,8 +33,6 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; export class TextFileService extends AbstractTextFileService { - private static readonly MAX_CONFIRM_FILES = 10; - constructor( @IWorkspaceContextService contextService: IWorkspaceContextService, @IFileService fileService: IFileService, @@ -80,24 +78,8 @@ export class TextFileService extends AbstractTextFileService { return TPromise.wrap(ConfirmResult.DONT_SAVE); } - const message = [ - resourcesToConfirm.length === 1 ? nls.localize('saveChangesMessage', "Do you want to save the changes you made to {0}?", paths.basename(resourcesToConfirm[0].fsPath)) : nls.localize('saveChangesMessages', "Do you want to save the changes to the following {0} files?", resourcesToConfirm.length) - ]; - - if (resourcesToConfirm.length > 1) { - message.push(''); - message.push(...resourcesToConfirm.slice(0, TextFileService.MAX_CONFIRM_FILES).map(r => paths.basename(r.fsPath))); - - if (resourcesToConfirm.length > TextFileService.MAX_CONFIRM_FILES) { - if (resourcesToConfirm.length - TextFileService.MAX_CONFIRM_FILES === 1) { - message.push(nls.localize('moreFile', "...1 additional file not shown")); - } else { - message.push(nls.localize('moreFiles', "...{0} additional files not shown", resourcesToConfirm.length - TextFileService.MAX_CONFIRM_FILES)); - } - } - - message.push(''); - } + const message = resourcesToConfirm.length === 1 ? nls.localize('saveChangesMessage', "Do you want to save the changes you made to {0}?", paths.basename(resourcesToConfirm[0].fsPath)) + : getConfirmMessage(nls.localize('saveChangesMessages', "Do you want to save the changes to the following {0} files?", resourcesToConfirm.length), resourcesToConfirm); // Button order // Windows: Save | Don't Save | Cancel @@ -119,7 +101,7 @@ export class TextFileService extends AbstractTextFileService { const opts: Electron.MessageBoxOptions = { title: product.nameLong, - message: message.join('\n'), + message, type: 'warning', detail: nls.localize('saveChangesDetail', "Your changes will be lost if you don't save them."), buttons: buttons.map(b => b.label), diff --git a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts index 1a692f0c257..71dea5ec0fd 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts @@ -38,7 +38,7 @@ suite('ExtHostTreeView', function () { let testObject: ExtHostTreeViews; let target: RecordingShape; let onDidChangeTreeNode: Emitter<{ key: string }>; - let onDidChangeTreeKey: Emitter; + let onDidChangeTreeNodeWithId: Emitter<{ key: string }>; let tree, labels, nodes; setup(() => { @@ -68,9 +68,9 @@ suite('ExtHostTreeView', function () { target = new RecordingShape(); testObject = new ExtHostTreeViews(target, new ExtHostCommands(rpcProtocol, new ExtHostHeapService(), new NullLogService())); onDidChangeTreeNode = new Emitter<{ key: string }>(); - onDidChangeTreeKey = new Emitter(); + onDidChangeTreeNodeWithId = new Emitter<{ key: string }>(); testObject.registerTreeDataProvider('testNodeTreeProvider', aNodeTreeDataProvider()); - testObject.registerTreeDataProvider('testStringTreeProvider', aStringTreeDataProvider()); + testObject.registerTreeDataProvider('testNodeWithIdTreeProvider', aNodeWithIdTreeDataProvider()); testObject.$getElements('testNodeTreeProvider').then(elements => { for (const element of elements) { @@ -83,58 +83,71 @@ suite('ExtHostTreeView', function () { return testObject.$getElements('testNodeTreeProvider') .then(elements => { const actuals = elements.map(e => e.handle); - assert.deepEqual(actuals, ['0/0:a', '0/1:b']); + assert.deepEqual(actuals, ['0/0:a', '0/0:b']); return TPromise.join([ testObject.$getChildren('testNodeTreeProvider', '0/0:a') .then(children => { const actuals = children.map(e => e.handle); - assert.deepEqual(actuals, ['0/0:a/0:aa', '0/0:a/1:ab']); + assert.deepEqual(actuals, ['0/0:a/0:aa', '0/0:a/0:ab']); return TPromise.join([ testObject.$getChildren('testNodeTreeProvider', '0/0:a/0:aa').then(children => assert.equal(children.length, 0)), - testObject.$getChildren('testNodeTreeProvider', '0/0:a/1:ab').then(children => assert.equal(children.length, 0)) + testObject.$getChildren('testNodeTreeProvider', '0/0:a/0:ab').then(children => assert.equal(children.length, 0)) ]); }), - testObject.$getChildren('testNodeTreeProvider', '0/1:b') + testObject.$getChildren('testNodeTreeProvider', '0/0:b') .then(children => { const actuals = children.map(e => e.handle); - assert.deepEqual(actuals, ['0/1:b/0:ba', '0/1:b/1:bb']); + assert.deepEqual(actuals, ['0/0:b/0:ba', '0/0:b/0:bb']); return TPromise.join([ - testObject.$getChildren('testNodeTreeProvider', '0/1:b/0:ba').then(children => assert.equal(children.length, 0)), - testObject.$getChildren('testNodeTreeProvider', '0/1:b/1:bb').then(children => assert.equal(children.length, 0)) + testObject.$getChildren('testNodeTreeProvider', '0/0:b/0:ba').then(children => assert.equal(children.length, 0)), + testObject.$getChildren('testNodeTreeProvider', '0/0:b/0:bb').then(children => assert.equal(children.length, 0)) ]); }) ]); }); }); - test('construct string tree', () => { - return testObject.$getElements('testStringTreeProvider') + test('construct id tree', () => { + return testObject.$getElements('testNodeWithIdTreeProvider') .then(elements => { const actuals = elements.map(e => e.handle); - assert.deepEqual(actuals, ['0/0:a', '0/1:b']); + assert.deepEqual(actuals, ['1/a', '1/b']); return TPromise.join([ - testObject.$getChildren('testStringTreeProvider', '0/0:a') + testObject.$getChildren('testNodeWithIdTreeProvider', '1/a') .then(children => { const actuals = children.map(e => e.handle); - assert.deepEqual(actuals, ['0/0:a/0:aa', '0/0:a/1:ab']); + assert.deepEqual(actuals, ['1/aa', '1/ab']); return TPromise.join([ - testObject.$getChildren('testStringTreeProvider', '0/0:a/0:aa').then(children => assert.equal(children.length, 0)), - testObject.$getChildren('testStringTreeProvider', '0/0:a/1:ab').then(children => assert.equal(children.length, 0)) + testObject.$getChildren('testNodeWithIdTreeProvider', '1/aa').then(children => assert.equal(children.length, 0)), + testObject.$getChildren('testNodeWithIdTreeProvider', '1/ab').then(children => assert.equal(children.length, 0)) ]); }), - testObject.$getChildren('testStringTreeProvider', '0/1:b') + testObject.$getChildren('testNodeWithIdTreeProvider', '1/b') .then(children => { const actuals = children.map(e => e.handle); - assert.deepEqual(actuals, ['0/1:b/0:ba', '0/1:b/1:bb']); + assert.deepEqual(actuals, ['1/ba', '1/bb']); return TPromise.join([ - testObject.$getChildren('testStringTreeProvider', '0/1:b/0:ba').then(children => assert.equal(children.length, 0)), - testObject.$getChildren('testStringTreeProvider', '0/1:b/1:bb').then(children => assert.equal(children.length, 0)) + testObject.$getChildren('testNodeWithIdTreeProvider', '1/ba').then(children => assert.equal(children.length, 0)), + testObject.$getChildren('testNodeWithIdTreeProvider', '1/bb').then(children => assert.equal(children.length, 0)) ]); }) ]); }); }); + test('error is thrown if id is not unique', () => { + tree['a'] = { + 'a': {} + }; + return testObject.$getElements('testNodeWithIdTreeProvider') + .then(elements => { + const actuals = elements.map(e => e.handle); + assert.deepEqual(actuals, ['1/a', '1/b']); + return testObject.$getChildren('testNodeWithIdTreeProvider', '1/a') + .then(children => assert.fail('Should fail with duplicate id'), () => null); + }); + }); + test('refresh root', function (done) { target.onRefresh.event(actuals => { assert.equal(undefined, actuals); @@ -146,9 +159,9 @@ suite('ExtHostTreeView', function () { test('refresh a parent node', () => { return new TPromise((c, e) => { target.onRefresh.event(actuals => { - assert.deepEqual(['0/1:b'], Object.keys(actuals)); - assert.deepEqual(removeUnsetKeys(actuals['0/1:b']), { - handle: '0/1:b', + assert.deepEqual(['0/0:b'], Object.keys(actuals)); + assert.deepEqual(removeUnsetKeys(actuals['0/0:b']), { + handle: '0/0:b', label: 'b', }); c(null); @@ -159,10 +172,10 @@ suite('ExtHostTreeView', function () { test('refresh a leaf node', function (done) { target.onRefresh.event(actuals => { - assert.deepEqual(['0/1:b/1:bb'], Object.keys(actuals)); - assert.deepEqual(removeUnsetKeys(actuals['0/1:b/1:bb']), { - handle: '0/1:b/1:bb', - parentHandle: '0/1:b', + assert.deepEqual(['0/0:b/0:bb'], Object.keys(actuals)); + assert.deepEqual(removeUnsetKeys(actuals['0/0:b/0:bb']), { + handle: '0/0:b/0:bb', + parentHandle: '0/0:b', label: 'bb' }); done(); @@ -172,9 +185,9 @@ suite('ExtHostTreeView', function () { test('refresh parent and child node trigger refresh only on parent - scenario 1', function (done) { target.onRefresh.event(actuals => { - assert.deepEqual(['0/1:b', '0/0:a/0:aa'], Object.keys(actuals)); - assert.deepEqual(removeUnsetKeys(actuals['0/1:b']), { - handle: '0/1:b', + assert.deepEqual(['0/0:b', '0/0:a/0:aa'], Object.keys(actuals)); + assert.deepEqual(removeUnsetKeys(actuals['0/0:b']), { + handle: '0/0:b', label: 'b', }); assert.deepEqual(removeUnsetKeys(actuals['0/0:a/0:aa']), { @@ -191,9 +204,9 @@ suite('ExtHostTreeView', function () { test('refresh parent and child node trigger refresh only on parent - scenario 2', function (done) { target.onRefresh.event(actuals => { - assert.deepEqual(['0/0:a/0:aa', '0/1:b'], Object.keys(actuals)); - assert.deepEqual(removeUnsetKeys(actuals['0/1:b']), { - handle: '0/1:b', + assert.deepEqual(['0/0:a/0:aa', '0/0:b'], Object.keys(actuals)); + assert.deepEqual(removeUnsetKeys(actuals['0/0:b']), { + handle: '0/0:b', label: 'b', }); assert.deepEqual(removeUnsetKeys(actuals['0/0:a/0:aa']), { @@ -213,7 +226,7 @@ suite('ExtHostTreeView', function () { target.onRefresh.event(actuals => { assert.deepEqual(['0/0:a'], Object.keys(actuals)); assert.deepEqual(removeUnsetKeys(actuals['0/0:a']), { - handle: '0/0:a', + handle: '0/0:aa', label: 'aa', }); done(); @@ -234,7 +247,7 @@ suite('ExtHostTreeView', function () { test('refresh calls are throttled on elements', function (done) { target.onRefresh.event(actuals => { - assert.deepEqual(['0/0:a', '0/1:b'], Object.keys(actuals)); + assert.deepEqual(['0/0:a', '0/0:b'], Object.keys(actuals)); done(); }); @@ -246,7 +259,7 @@ suite('ExtHostTreeView', function () { test('refresh calls are throttled on unknown elements', function (done) { target.onRefresh.event(actuals => { - assert.deepEqual(['0/0:a', '0/1:b'], Object.keys(actuals)); + assert.deepEqual(['0/0:a', '0/0:b'], Object.keys(actuals)); done(); }); @@ -293,6 +306,50 @@ suite('ExtHostTreeView', function () { }); }); + test('tree with duplicate labels', () => { + + const dupItems = { + 'adup1': 'c', + 'adup2': 'g', + 'bdup1': 'e', + 'hdup1': 'i', + 'hdup2': 'l', + 'jdup1': 'k' + }; + + labels['c'] = 'a'; + labels['e'] = 'b'; + labels['g'] = 'a'; + labels['i'] = 'h'; + labels['l'] = 'h'; + labels['k'] = 'j'; + + tree[dupItems['adup1']] = {}; + tree['d'] = {}; + + const bdup1Tree = {}; + bdup1Tree['h'] = {}; + bdup1Tree[dupItems['hdup1']] = {}; + bdup1Tree['j'] = {}; + bdup1Tree[dupItems['jdup1']] = {}; + bdup1Tree[dupItems['hdup2']] = {}; + + tree[dupItems['bdup1']] = bdup1Tree; + tree['f'] = {}; + tree[dupItems['adup2']] = {}; + + return testObject.$getElements('testNodeTreeProvider') + .then(elements => { + const actuals = elements.map(e => e.handle); + assert.deepEqual(actuals, ['0/0:a', '0/0:b', '0/1:a', '0/0:d', '0/1:b', '0/0:f', '0/2:a']); + return testObject.$getChildren('testNodeTreeProvider', '0/1:b') + .then(elements => { + const actuals = elements.map(e => e.handle); + assert.deepEqual(actuals, ['0/1:b/0:h', '0/1:b/1:h', '0/1:b/0:j', '0/1:b/1:j', '0/1:b/2:h']); + }); + }); + }); + function removeUnsetKeys(obj: any): any { const result = {}; for (const key of Object.keys(obj)) { @@ -315,15 +372,17 @@ suite('ExtHostTreeView', function () { }; } - function aStringTreeDataProvider(): TreeDataProvider { + function aNodeWithIdTreeDataProvider(): TreeDataProvider<{ key: string }> { return { - getChildren: (element: string): string[] => { - return getChildren(element); + getChildren: (element: { key: string }): { key: string }[] => { + return getChildren(element ? element.key : undefined).map(key => getNode(key)); }, - getTreeItem: (element: string): TreeItem => { - return getTreeItem(element); + getTreeItem: (element: { key: string }): TreeItem => { + const treeItem = getTreeItem(element.key); + treeItem.id = element.key; + return treeItem; }, - onDidChangeTreeData: onDidChangeTreeKey.event + onDidChangeTreeData: onDidChangeTreeNodeWithId.event }; } @@ -369,4 +428,4 @@ suite('ExtHostTreeView', function () { return nodes[key]; } -}); +}); \ No newline at end of file diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index cf38082c617..e45bc1a4b10 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -23,7 +23,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { IPartService, Parts, Position as PartPosition, Dimension } from 'vs/workbench/services/part/common/partService'; import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; -import { IEditorInput, IEditorOptions, Position, Direction, IEditor, IResourceInput } from 'vs/platform/editor/common/editor'; +import { IEditorInput, IEditorOptions, Position, IEditor, IResourceInput } from 'vs/platform/editor/common/editor'; import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IMessageService, IConfirmation, IConfirmationResult, IChoiceService } from 'vs/platform/message/common/message'; import { IWorkspaceContextService, IWorkspace as IWorkbenchWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace'; @@ -41,7 +41,7 @@ import { IRawTextContent, ITextFileService } from 'vs/workbench/services/textfil import { parseArgs } from 'vs/platform/environment/node/argv'; import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IWorkbenchEditorService, ICloseEditorsFilter } from 'vs/workbench/services/editor/common/editorService'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; @@ -606,11 +606,12 @@ export class TestEditorService implements IWorkbenchEditorService { return TPromise.as([]); } - public closeEditors(position: Position, filter?: { except?: IEditorInput, direction?: Direction, unmodifiedOnly?: boolean }): TPromise { - return TPromise.as(null); - } - - public closeAllEditors(except?: Position): TPromise { + public closeEditors(positions?: Position[]): TPromise; + public closeEditors(position: Position, filter?: ICloseEditorsFilter): TPromise; + public closeEditors(position: Position, editors: IEditorInput[]): TPromise; + public closeEditors(editors: { positionOne?: ICloseEditorsFilter, positionTwo?: ICloseEditorsFilter, positionThree?: ICloseEditorsFilter }): TPromise; + public closeEditors(editors: { positionOne?: IEditorInput[], positionTwo?: IEditorInput[], positionThree?: IEditorInput[] }): TPromise; + public closeEditors(positionOrEditors: any, filterOrEditors?: any): TPromise { return TPromise.as(null); } @@ -711,7 +712,6 @@ export class TestFileService implements IFileService { encoding: 'utf8', mtime: Date.now(), isDirectory: false, - hasChildren: false, name: paths.basename(resource.fsPath) }); } @@ -763,7 +763,6 @@ export class TestFileService implements IFileService { encoding: 'utf8', mtime: Date.now(), isDirectory: false, - hasChildren: false, name: paths.basename(resource.fsPath) }; }); diff --git a/test/grid.html b/test/grid.html new file mode 100644 index 00000000000..a455621fea8 --- /dev/null +++ b/test/grid.html @@ -0,0 +1,59 @@ + + + + + + + Grid Example + + + + + + + + + + + \ No newline at end of file diff --git a/test/smoke/src/areas/multiroot/multiroot.test.ts b/test/smoke/src/areas/multiroot/multiroot.test.ts index 3575dfedd70..b81df706cf3 100644 --- a/test/smoke/src/areas/multiroot/multiroot.test.ts +++ b/test/smoke/src/areas/multiroot/multiroot.test.ts @@ -14,18 +14,16 @@ export function setup() { const app = this.app as SpectronApplication; - await app.restart([app.workspaceFilePath]); - - // for some reason Code opens 2 windows at this point - // so let's select the last one - await app.webclient.windowByIndex(1); + // restart with preventing additional windows from restoring + // to ensure the window after restart is the multi-root workspace + await app.restart({ workspaceOrFolder: app.workspaceFilePath, extraArgs: ['--disable-restore-windows'] }); }); it('shows results from all folders', async function () { const app = this.app as SpectronApplication; await app.workbench.quickopen.openQuickOpen('*.*'); - await app.workbench.quickopen.waitForQuickOpenElements(names => names.length >= 6); + await app.workbench.quickopen.waitForQuickOpenElements(names => names.length === 6); await app.workbench.quickopen.closeQuickOpen(); }); diff --git a/test/smoke/src/areas/quickopen/quickopen.ts b/test/smoke/src/areas/quickopen/quickopen.ts index 4f70d280c11..c3c5e29562c 100644 --- a/test/smoke/src/areas/quickopen/quickopen.ts +++ b/test/smoke/src/areas/quickopen/quickopen.ts @@ -50,9 +50,6 @@ export class QuickOpen { async waitForQuickOpenOpened(): Promise { await this.spectron.client.waitForActiveElement(QuickOpen.QUICK_OPEN_INPUT); - - // we gotta wait 50 milliseconds due to https://github.com/Microsoft/vscode/blob/master/src/vs/platform/list/browser/listService.ts#L59 - await new Promise(c => setTimeout(c, 50)); } private async waitForQuickOpenClosed(): Promise { diff --git a/test/smoke/src/areas/workbench/localization.test.ts b/test/smoke/src/areas/workbench/localization.test.ts index 14185a13803..0251a9bf964 100644 --- a/test/smoke/src/areas/workbench/localization.test.ts +++ b/test/smoke/src/areas/workbench/localization.test.ts @@ -17,7 +17,7 @@ export function setup() { return; } - await app.restart(['--locale=DE']); + await app.restart({ extraArgs: ['--locale=DE'] }); }); it(`starts with 'DE' locale and verifies title and viewlets text is in German`, async function () { diff --git a/test/smoke/src/spectron/application.ts b/test/smoke/src/spectron/application.ts index 7d8cdadbb9a..a8e8ba2c7d0 100644 --- a/test/smoke/src/spectron/application.ts +++ b/test/smoke/src/spectron/application.ts @@ -116,16 +116,16 @@ export class SpectronApplication { } } - async restart(codeArgs: string[] = []): Promise { + async restart(options: { workspaceOrFolder?: string, extraArgs?: string[] }): Promise { await this.stop(); await new Promise(c => setTimeout(c, 1000)); - await this._start(codeArgs); + await this._start(options.workspaceOrFolder, options.extraArgs); } - private async _start(codeArgs: string[] = []): Promise { + private async _start(workspaceOrFolder = this.options.workspacePath, extraArgs: string[] = []): Promise { await this.retrieveKeybindings(); cp.execSync('git checkout .', { cwd: this.options.workspacePath }); - await this.startApplication(codeArgs); + await this.startApplication(workspaceOrFolder, extraArgs); await this.checkWindowReady(); } @@ -148,7 +148,7 @@ export class SpectronApplication { } } - private async startApplication(codeArgs: string[] = []): Promise { + private async startApplication(workspaceOrFolder: string, extraArgs: string[] = []): Promise { let args: string[] = []; let chromeDriverArgs: string[] = []; @@ -157,7 +157,7 @@ export class SpectronApplication { args.push(process.env.VSCODE_REPOSITORY as string); } - args.push(this.options.workspacePath); + args.push(workspaceOrFolder); // Prevent 'Getting Started' web page from opening on clean user-data-dir args.push('--skip-getting-started'); @@ -182,7 +182,7 @@ export class SpectronApplication { // Ensure that running over custom extensions directory, rather than picking up the one that was used by a tester previously args.push(`--extensions-dir=${this.options.extensionsPath}`); - args.push(...codeArgs); + args.push(...extraArgs); chromeDriverArgs.push(`--user-data-dir=${this.options.userDataDir}`); diff --git a/tslint.json b/tslint.json index 23e3b8f5899..24a7ac86d1b 100644 --- a/tslint.json +++ b/tslint.json @@ -398,6 +398,18 @@ "*" // node modules ] }, + { + "target": "**/vs/code/electron-browser/**", + "restrictions": [ + "vs/nls", + "vs/css!./**/*", + "vs/nls", + "**/vs/base/**", + "**/vs/platform/**", + "**/vs/code/**", + "*" // node modules + ] + }, { "target": "**/vs/code/**", "restrictions": [ diff --git a/yarn.lock b/yarn.lock index 625afd3a6d8..8c4b2723702 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5808,9 +5808,9 @@ vscode-textmate@^3.2.0: fast-plist "^0.1.2" oniguruma "^6.0.1" -vscode-xterm@3.1.0-beta2: - version "3.1.0-beta2" - resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.1.0-beta2.tgz#74adae19283738fab15f0ef145797f2eff5cc608" +vscode-xterm@3.1.0-beta5: + version "3.1.0-beta5" + resolved "https://registry.yarnpkg.com/vscode-xterm/-/vscode-xterm-3.1.0-beta5.tgz#b63c48cacda9c2546f50de550fef973a24df284c" vso-node-api@^6.1.2-preview: version "6.1.2-preview"