diff --git a/.eslintrc b/.eslintrc index 99ba790bd07..e2ca242393d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,9 +1,10 @@ { "env": { - "node": true + "node": true, + "es6": true }, "rules": { - "no-undef": 2, - "no-unused-vars": 1 - } + "no-console": 0 + }, + "extends": "eslint:recommended" } \ No newline at end of file diff --git a/.mention-bot b/.mention-bot index 14bc6a94f44..ea1a170775a 100644 --- a/.mention-bot +++ b/.mention-bot @@ -1,4 +1,7 @@ { "maxReviewers": 2, - "userBlacklistForPR": ["alexandrudima", "aeschli", "weinand", "bpasero", "isidorn", "joaomoreno", "jrieken", "dbaeumer", "egamma"] + "requiredOrgs": ["Microsoft"], + "skipAlreadyAssignedPR": true, + "skipAlreadyMentionedPR": true, + "skipCollaboratorPR": true } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 2ae43c332fa..79885f1dda9 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -25,14 +25,14 @@ "absolute" ], "pattern": { - "regexp": "^\\*\\*\\* Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$", + "regexp": "Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$", "file": 1, "location": 2, "message": 3 }, "watching": { - "beginsPattern": "^\\*\\*\\* Starting\\.\\.\\.$", - "endsPattern": "^\\*\\*\\* Finished" + "beginsPattern": "Starting compilation", + "endsPattern": "Finished compilation" } } }, diff --git a/appveyor.yml b/appveyor.yml index 5978e14c13d..459e550af38 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ environment: - ELECTRON_RUN_AS_NODE: 1 + ATOM_SHELL_INTERNAL_RUN_AS_NODE: 1 install: - ps: Install-Product node 5.10.1 x64 diff --git a/build/gulpfile.common.js b/build/gulpfile.common.js index f0b21202ce8..8939fa31b17 100644 --- a/build/gulpfile.common.js +++ b/build/gulpfile.common.js @@ -17,8 +17,6 @@ var util = require('./lib/util'); var i18n = require('./lib/i18n'); var gulpUtil = require('gulp-util'); -var quiet = !!process.env['VSCODE_BUILD_QUIET']; - function log(prefix, message) { gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message); } @@ -26,25 +24,17 @@ function log(prefix, message) { var root = path.dirname(__dirname); var commit = util.getVersion(root); -var tsOptions = { - target: 'ES5', - module: 'amd', - verbose: !quiet, - preserveConstEnums: true, - experimentalDecorators: true, - sourceMap: true, - rootDir: path.join(path.dirname(__dirname), 'src') -}; - exports.loaderConfig = function (emptyPaths) { var result = { paths: { 'vs': 'out-build/vs', 'vscode': 'empty:' }, - nodeModules: emptyPaths||[] + nodeModules: emptyPaths||[], }; + result['vs/css'] = { inlineResources: true }; + return result; }; @@ -73,7 +63,7 @@ function loader(bundledFileHeader) { .pipe(util.loadSourcemaps()) .pipe(concat('vs/loader.js')) .pipe(es.mapSync(function (f) { - f.sourceMap.sourceRoot = util.toFileUri(tsOptions.rootDir); + f.sourceMap.sourceRoot = util.toFileUri(path.join(path.dirname(__dirname), 'src')); return f; })); } diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index f7553fbff2c..dad634b7e70 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -19,7 +19,6 @@ var glob = require('glob'); var sourcemaps = require('gulp-sourcemaps'); var nlsDev = require('vscode-nls-dev'); -var quiet = !!process.env['VSCODE_BUILD_QUIET']; var extensionsPath = path.join(path.dirname(__dirname), 'extensions'); var compilations = glob.sync('**/tsconfig.json', { @@ -34,7 +33,7 @@ var tasks = compilations.map(function(tsconfigFile) { var relativeDirname = path.dirname(tsconfigFile); var tsOptions = require(absolutePath).compilerOptions; - tsOptions.verbose = !quiet; + tsOptions.verbose = false; tsOptions.sourceMap = true; var name = relativeDirname.replace(/\//g, '-'); @@ -56,15 +55,15 @@ var tasks = compilations.map(function(tsconfigFile) { var i18n = path.join(__dirname, '..', 'i18n'); function createPipeline(build) { - var reporter = quiet ? null : createReporter(); + var reporter = createReporter(); tsOptions.inlineSources = !!build; - var compilation = tsb.create(tsOptions, null, null, quiet ? null : function (err) { reporter(err.toString()); }); + var compilation = tsb.create(tsOptions, null, null, err => reporter(err.toString())); return function () { - var input = es.through(); - var tsFilter = filter(['**/*.ts', '!**/lib/lib*.d.ts', '!**/node_modules/**'], { restore: true }); - var output = input + const input = es.through(); + const tsFilter = filter(['**/*.ts', '!**/lib/lib*.d.ts', '!**/node_modules/**'], { restore: true }); + const output = input .pipe(tsFilter) .pipe(util.loadSourcemaps()) .pipe(compilation()) @@ -73,27 +72,27 @@ var tasks = compilations.map(function(tsconfigFile) { addComment: false, includeContent: !!build, sourceRoot: function(file) { - var levels = file.relative.split(path.sep).length; + const levels = file.relative.split(path.sep).length; return '../'.repeat(levels) + 'src'; } })) .pipe(tsFilter.restore) .pipe(build ? nlsDev.createAdditionalLanguageFiles(languages, i18n, out) : es.through()) - .pipe(quiet ? es.through() : reporter.end()); + .pipe(reporter.end()); return es.duplex(input, output); }; - }; + } - var srcOpts = { cwd: path.dirname(__dirname), base: srcBase }; + const srcOpts = { cwd: path.dirname(__dirname), base: srcBase }; gulp.task(clean, function (cb) { rimraf(out, cb); }); gulp.task(compile, [clean], function () { - var pipeline = createPipeline(false); - var input = gulp.src(src, srcOpts); + const pipeline = createPipeline(false); + const input = gulp.src(src, srcOpts); return input .pipe(pipeline()) @@ -101,9 +100,9 @@ var tasks = compilations.map(function(tsconfigFile) { }); gulp.task(watch, [clean], function () { - var pipeline = createPipeline(false); - var input = gulp.src(src, srcOpts); - var watchInput = watcher(src, srcOpts); + const pipeline = createPipeline(false); + const input = gulp.src(src, srcOpts); + const watchInput = watcher(src, srcOpts); return watchInput .pipe(util.incremental(pipeline, input)) @@ -115,8 +114,8 @@ var tasks = compilations.map(function(tsconfigFile) { }); gulp.task(compileBuild, [clean], function () { - var pipeline = createPipeline(true); - var input = gulp.src(src, srcOpts); + const pipeline = createPipeline(true); + const input = gulp.src(src, srcOpts); return input .pipe(pipeline()) @@ -124,8 +123,9 @@ var tasks = compilations.map(function(tsconfigFile) { }); gulp.task(watchBuild, [clean], function () { - var input = gulp.src(src, srcOpts); - var watchInput = watcher(src, srcOpts); + const pipeline = createPipeline(true); + const input = gulp.src(src, srcOpts); + const watchInput = watcher(src, srcOpts); return watchInput .pipe(util.incremental(function () { return pipeline(true); }, input)) diff --git a/build/lib/i18n.js b/build/lib/i18n.js index 5669ae38a05..b3be39a2c51 100644 --- a/build/lib/i18n.js +++ b/build/lib/i18n.js @@ -1,288 +1,284 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -"use strict"; -var path = require('path'); -var fs = require('fs'); -var event_stream_1 = require('event-stream'); -var File = require('vinyl'); -var Is = require('is'); -var quiet = !!process.env['VSCODE_BUILD_QUIET'] && false; -var util = require('gulp-util'); -function log(message) { - var rest = []; - for (var _i = 1; _i < arguments.length; _i++) { - rest[_i - 1] = arguments[_i]; - } - if (quiet) { - return; - } - util.log.apply(util, [util.colors.cyan('[i18n]'), message].concat(rest)); -} -var LocalizeInfo; -(function (LocalizeInfo) { - function is(value) { - var candidate = value; - return Is.defined(candidate) && Is.string(candidate.key) && (Is.undef(candidate.comment) || (Is.array(candidate.comment) && candidate.comment.every(function (element) { return Is.string(element); }))); - } - LocalizeInfo.is = is; -})(LocalizeInfo || (LocalizeInfo = {})); -var BundledFormat; -(function (BundledFormat) { - function is(value) { - if (Is.undef(value)) { - return false; - } - var candidate = value; - var length = Object.keys(value).length; - return length === 3 && Is.defined(candidate.keys) && Is.defined(candidate.messages) && Is.defined(candidate.bundles); - } - BundledFormat.is = is; -})(BundledFormat || (BundledFormat = {})); -var vscodeLanguages = [ - 'chs', - 'cht', - 'jpn', - 'kor', - 'deu', - 'fra', - 'esn', - 'rus', - 'ita' -]; -var iso639_3_to_2 = { - 'chs': 'zh-cn', - 'cht': 'zh-tw', - 'csy': 'cs-cz', - 'deu': 'de', - 'enu': 'en', - 'esn': 'es', - 'fra': 'fr', - 'hun': 'hu', - 'ita': 'it', - 'jpn': 'ja', - 'kor': 'ko', - 'nld': 'nl', - 'plk': 'pl', - 'ptb': 'pt-br', - 'ptg': 'pt', - 'rus': 'ru', - 'sve': 'sv-se', - 'trk': 'tr' -}; -function sortLanguages(directoryNames) { - return directoryNames.map(function (dirName) { - var lower = dirName.toLowerCase(); - return { - name: lower, - iso639_2: iso639_3_to_2[lower] - }; - }).sort(function (a, b) { - if (!a.iso639_2 && !b.iso639_2) { - return 0; - } - if (!a.iso639_2) { - return -1; - } - if (!b.iso639_2) { - return 1; - } - return a.iso639_2 < b.iso639_2 ? -1 : (a.iso639_2 > b.iso639_2 ? 1 : 0); - }); -} -function stripComments(content) { - /** - * First capturing group matches double quoted string - * Second matches single quotes string - * Third matches block comments - * Fourth matches line comments - */ - var regexp = /("(?:[^\\\"]*(?:\\.)?)*")|('(?:[^\\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g; - var result = content.replace(regexp, function (match, m1, m2, m3, m4) { - // Only one of m1, m2, m3, m4 matches - if (m3) { - // A block comment. Replace with nothing - return ''; - } - else if (m4) { - // A line comment. If it ends in \r?\n then keep it. - var length_1 = m4.length; - if (length_1 > 2 && m4[length_1 - 1] === '\n') { - return m4[length_1 - 2] === '\r' ? '\r\n' : '\n'; - } - else { - return ''; - } - } - else { - // We match a string - return match; - } - }); - return result; -} -; -function escapeCharacters(value) { - var result = []; - for (var i = 0; i < value.length; i++) { - var ch = value.charAt(i); - switch (ch) { - case '\'': - result.push('\\\''); - break; - case '"': - result.push('\\"'); - break; - case '\\': - result.push('\\\\'); - break; - case '\n': - result.push('\\n'); - break; - case '\r': - result.push('\\r'); - break; - case '\t': - result.push('\\t'); - break; - case '\b': - result.push('\\b'); - break; - case '\f': - result.push('\\f'); - break; - default: - result.push(ch); - } - } - return result.join(''); -} -function processCoreBundleFormat(fileHeader, json, emitter) { - var keysSection = json.keys; - var messageSection = json.messages; - var bundleSection = json.bundles; - var statistics = Object.create(null); - var total = 0; - var defaultMessages = Object.create(null); - var modules = Object.keys(keysSection); - modules.forEach(function (module) { - var keys = keysSection[module]; - var messages = messageSection[module]; - if (!messages || keys.length !== messages.length) { - emitter.emit('error', "Message for module " + module + " corrupted. Mismatch in number of keys and messages."); - return; - } - var messageMap = Object.create(null); - defaultMessages[module] = messageMap; - keys.map(function (key, i) { - total++; - if (Is.string(key)) { - messageMap[key] = messages[i]; - } - else { - messageMap[key.key] = messages[i]; - } - }); - }); - var languageDirectory = path.join(__dirname, '..', '..', 'i18n'); - var languages = sortLanguages(fs.readdirSync(languageDirectory).filter(function (item) { return fs.statSync(path.join(languageDirectory, item)).isDirectory(); })); - languages.forEach(function (language) { - if (!language.iso639_2) { - return; - } - log("Generating nls bundles for: " + language.iso639_2); - statistics[language.iso639_2] = 0; - var localizedModules = Object.create(null); - var cwd = path.join(languageDirectory, language.name, 'src'); - modules.forEach(function (module) { - var order = keysSection[module]; - var i18nFile = path.join(cwd, module) + '.i18n.json'; - var messages = null; - if (fs.existsSync(i18nFile)) { - var content = stripComments(fs.readFileSync(i18nFile, 'utf8')); - messages = JSON.parse(content); - } - else { - // log(`No localized messages found for module ${module}. Using default messages.`); - messages = defaultMessages[module]; - statistics[language.iso639_2] = statistics[language.iso639_2] + Object.keys(messages).length; - } - var localizedMessages = []; - order.forEach(function (keyInfo) { - var key = null; - if (Is.string(keyInfo)) { - key = keyInfo; - } - else { - key = keyInfo.key; - } - var message = messages[key]; - if (!message) { - log("No localized message found for key " + key + " in module " + module + ". Using default message."); - message = defaultMessages[module][key]; - statistics[language.iso639_2] = statistics[language.iso639_2] + 1; - } - localizedMessages.push(message); - }); - localizedModules[module] = localizedMessages; - }); - Object.keys(bundleSection).forEach(function (bundle) { - var modules = bundleSection[bundle]; - var contents = [ - fileHeader, - ("define(\"" + bundle + ".nls." + language.iso639_2 + "\", {") - ]; - modules.forEach(function (module, index) { - contents.push("\t\"" + module + "\": ["); - var messages = localizedModules[module]; - if (!messages) { - emitter.emit('error', "Didn't find messages for module " + module + "."); - return; - } - messages.forEach(function (message, index) { - contents.push("\t\t\"" + escapeCharacters(message) + (index < messages.length ? '",' : '"')); - }); - contents.push(index < modules.length - 1 ? '\t],' : '\t]'); - }); - contents.push('});'); - emitter.emit('data', new File({ path: bundle + '.nls.' + language.iso639_2 + '.js', contents: new Buffer(contents.join('\n'), 'utf-8') })); - }); - }); - log("Statistics (total " + total + "):"); - Object.keys(statistics).forEach(function (key) { - var value = statistics[key]; - log("\t" + value + " untranslated strings for locale " + key + " found."); - }); - vscodeLanguages.forEach(function (language) { - var iso639_2 = iso639_3_to_2[language]; - if (!iso639_2) { - log("\tCouldn't find iso639 2 mapping for language " + language + ". Using default language instead."); - } - else { - var stats = statistics[iso639_2]; - if (Is.undef(stats)) { - log("\tNo translations found for language " + language + ". Using default language instead."); - } - } - }); -} -function processNlsFiles(opts) { - return event_stream_1.through(function (file) { - var fileName = path.basename(file.path); - if (fileName === 'nls.metadata.json') { - var json = null; - if (file.isBuffer()) { - json = JSON.parse(file.contents.toString('utf8')); - } - else { - this.emit('error', "Failed to read component file: " + file.relative); - } - if (BundledFormat.is(json)) { - processCoreBundleFormat(opts.fileHeader, json, this); - } - } - this.emit('data', file); - }); -} -exports.processNlsFiles = processNlsFiles; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +"use strict"; +var path = require('path'); +var fs = require('fs'); +var event_stream_1 = require('event-stream'); +var File = require('vinyl'); +var Is = require('is'); +var util = require('gulp-util'); +function log(message) { + var rest = []; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; + } + util.log.apply(util, [util.colors.cyan('[i18n]'), message].concat(rest)); +} +var LocalizeInfo; +(function (LocalizeInfo) { + function is(value) { + var candidate = value; + return Is.defined(candidate) && Is.string(candidate.key) && (Is.undef(candidate.comment) || (Is.array(candidate.comment) && candidate.comment.every(function (element) { return Is.string(element); }))); + } + LocalizeInfo.is = is; +})(LocalizeInfo || (LocalizeInfo = {})); +var BundledFormat; +(function (BundledFormat) { + function is(value) { + if (Is.undef(value)) { + return false; + } + var candidate = value; + var length = Object.keys(value).length; + return length === 3 && Is.defined(candidate.keys) && Is.defined(candidate.messages) && Is.defined(candidate.bundles); + } + BundledFormat.is = is; +})(BundledFormat || (BundledFormat = {})); +var vscodeLanguages = [ + 'chs', + 'cht', + 'jpn', + 'kor', + 'deu', + 'fra', + 'esn', + 'rus', + 'ita' +]; +var iso639_3_to_2 = { + 'chs': 'zh-cn', + 'cht': 'zh-tw', + 'csy': 'cs-cz', + 'deu': 'de', + 'enu': 'en', + 'esn': 'es', + 'fra': 'fr', + 'hun': 'hu', + 'ita': 'it', + 'jpn': 'ja', + 'kor': 'ko', + 'nld': 'nl', + 'plk': 'pl', + 'ptb': 'pt-br', + 'ptg': 'pt', + 'rus': 'ru', + 'sve': 'sv-se', + 'trk': 'tr' +}; +function sortLanguages(directoryNames) { + return directoryNames.map(function (dirName) { + var lower = dirName.toLowerCase(); + return { + name: lower, + iso639_2: iso639_3_to_2[lower] + }; + }).sort(function (a, b) { + if (!a.iso639_2 && !b.iso639_2) { + return 0; + } + if (!a.iso639_2) { + return -1; + } + if (!b.iso639_2) { + return 1; + } + return a.iso639_2 < b.iso639_2 ? -1 : (a.iso639_2 > b.iso639_2 ? 1 : 0); + }); +} +function stripComments(content) { + /** + * First capturing group matches double quoted string + * Second matches single quotes string + * Third matches block comments + * Fourth matches line comments + */ + var regexp = /("(?:[^\\\"]*(?:\\.)?)*")|('(?:[^\\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g; + var result = content.replace(regexp, function (match, m1, m2, m3, m4) { + // Only one of m1, m2, m3, m4 matches + if (m3) { + // A block comment. Replace with nothing + return ''; + } + else if (m4) { + // A line comment. If it ends in \r?\n then keep it. + var length_1 = m4.length; + if (length_1 > 2 && m4[length_1 - 1] === '\n') { + return m4[length_1 - 2] === '\r' ? '\r\n' : '\n'; + } + else { + return ''; + } + } + else { + // We match a string + return match; + } + }); + return result; +} +; +function escapeCharacters(value) { + var result = []; + for (var i = 0; i < value.length; i++) { + var ch = value.charAt(i); + switch (ch) { + case '\'': + result.push('\\\''); + break; + case '"': + result.push('\\"'); + break; + case '\\': + result.push('\\\\'); + break; + case '\n': + result.push('\\n'); + break; + case '\r': + result.push('\\r'); + break; + case '\t': + result.push('\\t'); + break; + case '\b': + result.push('\\b'); + break; + case '\f': + result.push('\\f'); + break; + default: + result.push(ch); + } + } + return result.join(''); +} +function processCoreBundleFormat(fileHeader, json, emitter) { + var keysSection = json.keys; + var messageSection = json.messages; + var bundleSection = json.bundles; + var statistics = Object.create(null); + var total = 0; + var defaultMessages = Object.create(null); + var modules = Object.keys(keysSection); + modules.forEach(function (module) { + var keys = keysSection[module]; + var messages = messageSection[module]; + if (!messages || keys.length !== messages.length) { + emitter.emit('error', "Message for module " + module + " corrupted. Mismatch in number of keys and messages."); + return; + } + var messageMap = Object.create(null); + defaultMessages[module] = messageMap; + keys.map(function (key, i) { + total++; + if (Is.string(key)) { + messageMap[key] = messages[i]; + } + else { + messageMap[key.key] = messages[i]; + } + }); + }); + var languageDirectory = path.join(__dirname, '..', '..', 'i18n'); + var languages = sortLanguages(fs.readdirSync(languageDirectory).filter(function (item) { return fs.statSync(path.join(languageDirectory, item)).isDirectory(); })); + languages.forEach(function (language) { + if (!language.iso639_2) { + return; + } + log("Generating nls bundles for: " + language.iso639_2); + statistics[language.iso639_2] = 0; + var localizedModules = Object.create(null); + var cwd = path.join(languageDirectory, language.name, 'src'); + modules.forEach(function (module) { + var order = keysSection[module]; + var i18nFile = path.join(cwd, module) + '.i18n.json'; + var messages = null; + if (fs.existsSync(i18nFile)) { + var content = stripComments(fs.readFileSync(i18nFile, 'utf8')); + messages = JSON.parse(content); + } + else { + // log(`No localized messages found for module ${module}. Using default messages.`); + messages = defaultMessages[module]; + statistics[language.iso639_2] = statistics[language.iso639_2] + Object.keys(messages).length; + } + var localizedMessages = []; + order.forEach(function (keyInfo) { + var key = null; + if (Is.string(keyInfo)) { + key = keyInfo; + } + else { + key = keyInfo.key; + } + var message = messages[key]; + if (!message) { + log("No localized message found for key " + key + " in module " + module + ". Using default message."); + message = defaultMessages[module][key]; + statistics[language.iso639_2] = statistics[language.iso639_2] + 1; + } + localizedMessages.push(message); + }); + localizedModules[module] = localizedMessages; + }); + Object.keys(bundleSection).forEach(function (bundle) { + var modules = bundleSection[bundle]; + var contents = [ + fileHeader, + ("define(\"" + bundle + ".nls." + language.iso639_2 + "\", {") + ]; + modules.forEach(function (module, index) { + contents.push("\t\"" + module + "\": ["); + var messages = localizedModules[module]; + if (!messages) { + emitter.emit('error', "Didn't find messages for module " + module + "."); + return; + } + messages.forEach(function (message, index) { + contents.push("\t\t\"" + escapeCharacters(message) + (index < messages.length ? '",' : '"')); + }); + contents.push(index < modules.length - 1 ? '\t],' : '\t]'); + }); + contents.push('});'); + emitter.emit('data', new File({ path: bundle + '.nls.' + language.iso639_2 + '.js', contents: new Buffer(contents.join('\n'), 'utf-8') })); + }); + }); + log("Statistics (total " + total + "):"); + Object.keys(statistics).forEach(function (key) { + var value = statistics[key]; + log("\t" + value + " untranslated strings for locale " + key + " found."); + }); + vscodeLanguages.forEach(function (language) { + var iso639_2 = iso639_3_to_2[language]; + if (!iso639_2) { + log("\tCouldn't find iso639 2 mapping for language " + language + ". Using default language instead."); + } + else { + var stats = statistics[iso639_2]; + if (Is.undef(stats)) { + log("\tNo translations found for language " + language + ". Using default language instead."); + } + } + }); +} +function processNlsFiles(opts) { + return event_stream_1.through(function (file) { + var fileName = path.basename(file.path); + if (fileName === 'nls.metadata.json') { + var json = null; + if (file.isBuffer()) { + json = JSON.parse(file.contents.toString('utf8')); + } + else { + this.emit('error', "Failed to read component file: " + file.relative); + } + if (BundledFormat.is(json)) { + processCoreBundleFormat(opts.fileHeader, json, this); + } + } + this.emit('data', file); + }); +} +exports.processNlsFiles = processNlsFiles; diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts index e8cd6ec771a..fdc65def6e1 100644 --- a/build/lib/i18n.ts +++ b/build/lib/i18n.ts @@ -11,13 +11,8 @@ import { ThroughStream } from 'through'; import File = require('vinyl'); import * as Is from 'is'; -const quiet = !!process.env['VSCODE_BUILD_QUIET'] && false; - var util = require('gulp-util'); function log(message: any, ...rest: any[]): void { - if (quiet) { - return; - } util.log(util.colors.cyan('[i18n]'), message, ...rest); } diff --git a/build/lib/nls.js b/build/lib/nls.js index 60407c708fb..b3c881d9e99 100644 --- a/build/lib/nls.js +++ b/build/lib/nls.js @@ -1,350 +1,350 @@ -"use strict"; -var ts = require('./typescript/typescriptServices'); -var lazy = require('lazy.js'); -var event_stream_1 = require('event-stream'); -var File = require('vinyl'); -var sm = require('source-map'); -var assign = require('object-assign'); -var clone = require('clone'); -var path = require('path'); -var CollectStepResult; -(function (CollectStepResult) { - CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes"; - CollectStepResult[CollectStepResult["YesAndRecurse"] = 1] = "YesAndRecurse"; - CollectStepResult[CollectStepResult["No"] = 2] = "No"; - CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse"; -})(CollectStepResult || (CollectStepResult = {})); -function collect(node, fn) { - var result = []; - function loop(node) { - var stepResult = fn(node); - if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) { - result.push(node); - } - if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) { - ts.forEachChild(node, loop); - } - } - loop(node); - return result; -} -function template(lines) { - var indent = '', wrap = ''; - if (lines.length > 1) { - indent = '\t'; - wrap = '\n'; - } - return "/*---------------------------------------------------------\n * Copyright (C) Microsoft Corporation. All rights reserved.\n *--------------------------------------------------------*/\ndefine([], [" + (wrap + lines.map(function (l) { return indent + l; }).join(',\n') + wrap) + "]);"; -} -/** - * Returns a stream containing the patched JavaScript and source maps. - */ -function nls() { - var input = event_stream_1.through(); - var output = input.pipe(event_stream_1.through(function (f) { - var _this = this; - if (!f.sourceMap) { - return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps.")); - } - var source = f.sourceMap.sources[0]; - if (!source) { - return this.emit('error', new Error("File " + f.relative + " does not have a source in the source map.")); - } - var root = f.sourceMap.sourceRoot; - if (root) { - source = path.join(root, source); - } - var typescript = f.sourceMap.sourcesContent[0]; - if (!typescript) { - return this.emit('error', new Error("File " + f.relative + " does not have the original content in the source map.")); - } - nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); }); - })); - return event_stream_1.duplex(input, output); -} -function isImportNode(node) { - return node.kind === 212 /* ImportDeclaration */ || node.kind === 211 /* ImportEqualsDeclaration */; -} -var nls; -(function (nls_1) { - function fileFrom(file, contents, path) { - if (path === void 0) { path = file.path; } - return new File({ - contents: new Buffer(contents), - base: file.base, - cwd: file.cwd, - path: path - }); - } - nls_1.fileFrom = fileFrom; - function mappedPositionFrom(source, lc) { - return { source: source, line: lc.line + 1, column: lc.character }; - } - nls_1.mappedPositionFrom = mappedPositionFrom; - function lcFrom(position) { - return { line: position.line - 1, character: position.column }; - } - nls_1.lcFrom = lcFrom; - var SingleFileServiceHost = (function () { - function SingleFileServiceHost(options, filename, contents) { - var _this = this; - this.options = options; - this.filename = filename; - this.getCompilationSettings = function () { return _this.options; }; - this.getScriptFileNames = function () { return [_this.filename]; }; - this.getScriptVersion = function () { return '1'; }; - this.getScriptSnapshot = function (name) { return name === _this.filename ? _this.file : _this.lib; }; - this.getCurrentDirectory = function () { return ''; }; - this.getDefaultLibFileName = function () { return 'lib.d.ts'; }; - this.file = ts.ScriptSnapshot.fromString(contents); - this.lib = ts.ScriptSnapshot.fromString(''); - } - return SingleFileServiceHost; - }()); - nls_1.SingleFileServiceHost = SingleFileServiceHost; - function isCallExpressionWithinTextSpanCollectStep(textSpan, node) { - if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) { - return CollectStepResult.No; - } - return node.kind === 160 /* CallExpression */ ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; - } - function analyze(contents, options) { - if (options === void 0) { options = {}; } - var filename = 'file.ts'; - var serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents); - var service = ts.createLanguageService(serviceHost); - var sourceFile = service.getSourceFile(filename); - // all imports - var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; })); - // import nls = require('vs/nls'); - var importEqualsDeclarations = imports - .filter(function (n) { return n.kind === 211 /* ImportEqualsDeclaration */; }) - .map(function (n) { return n; }) - .filter(function (d) { return d.moduleReference.kind === 222 /* ExternalModuleReference */; }) - .filter(function (d) { return d.moduleReference.expression.getText() === '\'vs/nls\''; }); - // import ... from 'vs/nls'; - var importDeclarations = imports - .filter(function (n) { return n.kind === 212 /* ImportDeclaration */; }) - .map(function (n) { return n; }) - .filter(function (d) { return d.moduleSpecifier.kind === 8 /* StringLiteral */; }) - .filter(function (d) { return d.moduleSpecifier.getText() === '\'vs/nls\''; }) - .filter(function (d) { return !!d.importClause && !!d.importClause.namedBindings; }); - var nlsExpressions = importEqualsDeclarations - .map(function (d) { return d.moduleReference.expression; }) - .concat(importDeclarations.map(function (d) { return d.moduleSpecifier; })) - .map(function (d) { return ({ - start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()), - end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd()) - }); }); - // `nls.localize(...)` calls - var nlsLocalizeCallExpressions = importDeclarations - .filter(function (d) { return d.importClause.namedBindings.kind === 214 /* NamespaceImport */; }) - .map(function (d) { return d.importClause.namedBindings.name; }) - .concat(importEqualsDeclarations.map(function (d) { return d.name; })) - .map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); }) - .flatten() - .filter(function (r) { return !r.isWriteAccess; }) - .map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); }) - .map(function (a) { return lazy(a).last(); }) - .filter(function (n) { return !!n; }) - .map(function (n) { return n; }) - .filter(function (n) { return n.expression.kind === 158 /* PropertyAccessExpression */ && n.expression.name.getText() === 'localize'; }); - // `localize` named imports - var allLocalizeImportDeclarations = importDeclarations - .filter(function (d) { return d.importClause.namedBindings.kind === 215 /* NamedImports */; }) - .map(function (d) { return d.importClause.namedBindings.elements; }) - .flatten(); - // `localize` read-only references - var localizeReferences = allLocalizeImportDeclarations - .filter(function (d) { return d.name.getText() === 'localize'; }) - .map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); }) - .flatten() - .filter(function (r) { return !r.isWriteAccess; }); - // custom named `localize` read-only references - var namedLocalizeReferences = allLocalizeImportDeclarations - .filter(function (d) { return d.propertyName && d.propertyName.getText() === 'localize'; }) - .map(function (n) { return service.getReferencesAtPosition(filename, n.name.pos + 1); }) - .flatten() - .filter(function (r) { return !r.isWriteAccess; }); - // find the deepest call expressions AST nodes that contain those references - var localizeCallExpressions = localizeReferences - .concat(namedLocalizeReferences) - .map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); }) - .map(function (a) { return lazy(a).last(); }) - .filter(function (n) { return !!n; }) - .map(function (n) { return n; }); - // collect everything - var localizeCalls = nlsLocalizeCallExpressions - .concat(localizeCallExpressions) - .map(function (e) { return e.arguments; }) - .filter(function (a) { return a.length > 1; }) - .sort(function (a, b) { return a[0].getStart() - b[0].getStart(); }) - .map(function (a) { return ({ - keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) }, - key: a[0].getText(), - valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) }, - value: a[1].getText() - }); }); - return { - localizeCalls: localizeCalls.toArray(), - nlsExpressions: nlsExpressions.toArray() - }; - } - nls_1.analyze = analyze; - var TextModel = (function () { - function TextModel(contents) { - var regex = /\r\n|\r|\n/g; - var index = 0; - var match; - this.lines = []; - this.lineEndings = []; - while (match = regex.exec(contents)) { - this.lines.push(contents.substring(index, match.index)); - this.lineEndings.push(match[0]); - index = regex.lastIndex; - } - if (contents.length > 0) { - this.lines.push(contents.substring(index, contents.length)); - this.lineEndings.push(''); - } - } - TextModel.prototype.get = function (index) { - return this.lines[index]; - }; - TextModel.prototype.set = function (index, line) { - this.lines[index] = line; - }; - Object.defineProperty(TextModel.prototype, "lineCount", { - get: function () { - return this.lines.length; - }, - enumerable: true, - configurable: true - }); - /** - * Applies patch(es) to the model. - * Multiple patches must be ordered. - * Does not support patches spanning multiple lines. - */ - TextModel.prototype.apply = function (patch) { - var startLineNumber = patch.span.start.line; - var endLineNumber = patch.span.end.line; - var startLine = this.lines[startLineNumber] || ''; - var endLine = this.lines[endLineNumber] || ''; - this.lines[startLineNumber] = [ - startLine.substring(0, patch.span.start.character), - patch.content, - endLine.substring(patch.span.end.character) - ].join(''); - for (var i = startLineNumber + 1; i <= endLineNumber; i++) { - this.lines[i] = ''; - } - }; - TextModel.prototype.toString = function () { - return lazy(this.lines).zip(this.lineEndings) - .flatten().toArray().join(''); - }; - return TextModel; - }()); - nls_1.TextModel = TextModel; - function patchJavascript(patches, contents, moduleId) { - var model = new nls.TextModel(contents); - // patch the localize calls - lazy(patches).reverse().each(function (p) { return model.apply(p); }); - // patch the 'vs/nls' imports - var firstLine = model.get(0); - var patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1"); - model.set(0, patchedFirstLine); - return model.toString(); - } - nls_1.patchJavascript = patchJavascript; - function patchSourcemap(patches, rsm, smc) { - var smg = new sm.SourceMapGenerator({ - file: rsm.file, - sourceRoot: rsm.sourceRoot - }); - patches = patches.reverse(); - var currentLine = -1; - var currentLineDiff = 0; - var source = null; - smc.eachMapping(function (m) { - var patch = patches[patches.length - 1]; - var original = { line: m.originalLine, column: m.originalColumn }; - var generated = { line: m.generatedLine, column: m.generatedColumn }; - if (currentLine !== generated.line) { - currentLineDiff = 0; - } - currentLine = generated.line; - generated.column += currentLineDiff; - if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) { - var originalLength = patch.span.end.character - patch.span.start.character; - var modifiedLength = patch.content.length; - var lengthDiff = modifiedLength - originalLength; - currentLineDiff += lengthDiff; - generated.column += lengthDiff; - patches.pop(); - } - source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source; - source = source.replace(/\\/g, '/'); - smg.addMapping({ source: source, name: m.name, original: original, generated: generated }); - }, null, sm.SourceMapConsumer.GENERATED_ORDER); - if (source) { - smg.setSourceContent(source, smc.sourceContentFor(source)); - } - return JSON.parse(smg.toString()); - } - nls_1.patchSourcemap = patchSourcemap; - function patch(moduleId, typescript, javascript, sourcemap) { - var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions; - if (localizeCalls.length === 0) { - return { javascript: javascript, sourcemap: sourcemap }; - } - var nlsKeys = template(localizeCalls.map(function (lc) { return lc.key; })); - var nls = template(localizeCalls.map(function (lc) { return lc.value; })); - var smc = new sm.SourceMapConsumer(sourcemap); - var positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]); - var i = 0; - // build patches - var patches = lazy(localizeCalls) - .map(function (lc) { return ([ - { range: lc.keySpan, content: '' + (i++) }, - { range: lc.valueSpan, content: 'null' } - ]); }) - .flatten() - .map(function (c) { - var start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start))); - var end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end))); - return { span: { start: start, end: end }, content: c.content }; - }) - .toArray(); - javascript = patchJavascript(patches, javascript, moduleId); - // since imports are not within the sourcemap information, - // we must do this MacGyver style - if (nlsExpressions.length) { - javascript = javascript.replace(/^define\(.*$/m, function (line) { - return line.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1"); - }); - } - sourcemap = patchSourcemap(patches, sourcemap, smc); - return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls }; - } - nls_1.patch = patch; - function patchFiles(javascriptFile, typescript) { - // hack? - var moduleId = javascriptFile.relative - .replace(/\.js$/, '') - .replace(/\\/g, '/'); - var _a = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap), javascript = _a.javascript, sourcemap = _a.sourcemap, nlsKeys = _a.nlsKeys, nls = _a.nls; - var result = [fileFrom(javascriptFile, javascript)]; - result[0].sourceMap = sourcemap; - if (nlsKeys) { - result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js'))); - } - if (nls) { - result.push(fileFrom(javascriptFile, nls, javascriptFile.path.replace(/\.js$/, '.nls.js'))); - } - return result; - } - nls_1.patchFiles = patchFiles; -})(nls || (nls = {})); -module.exports = nls; +"use strict"; +var ts = require('./typescript/typescriptServices'); +var lazy = require('lazy.js'); +var event_stream_1 = require('event-stream'); +var File = require('vinyl'); +var sm = require('source-map'); +var assign = require('object-assign'); +var clone = require('clone'); +var path = require('path'); +var CollectStepResult; +(function (CollectStepResult) { + CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes"; + CollectStepResult[CollectStepResult["YesAndRecurse"] = 1] = "YesAndRecurse"; + CollectStepResult[CollectStepResult["No"] = 2] = "No"; + CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse"; +})(CollectStepResult || (CollectStepResult = {})); +function collect(node, fn) { + var result = []; + function loop(node) { + var stepResult = fn(node); + if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) { + result.push(node); + } + if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) { + ts.forEachChild(node, loop); + } + } + loop(node); + return result; +} +function template(lines) { + var indent = '', wrap = ''; + if (lines.length > 1) { + indent = '\t'; + wrap = '\n'; + } + return "/*---------------------------------------------------------\n * Copyright (C) Microsoft Corporation. All rights reserved.\n *--------------------------------------------------------*/\ndefine([], [" + (wrap + lines.map(function (l) { return indent + l; }).join(',\n') + wrap) + "]);"; +} +/** + * Returns a stream containing the patched JavaScript and source maps. + */ +function nls() { + var input = event_stream_1.through(); + var output = input.pipe(event_stream_1.through(function (f) { + var _this = this; + if (!f.sourceMap) { + return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps.")); + } + var source = f.sourceMap.sources[0]; + if (!source) { + return this.emit('error', new Error("File " + f.relative + " does not have a source in the source map.")); + } + var root = f.sourceMap.sourceRoot; + if (root) { + source = path.join(root, source); + } + var typescript = f.sourceMap.sourcesContent[0]; + if (!typescript) { + return this.emit('error', new Error("File " + f.relative + " does not have the original content in the source map.")); + } + nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); }); + })); + return event_stream_1.duplex(input, output); +} +function isImportNode(node) { + return node.kind === 212 /* ImportDeclaration */ || node.kind === 211 /* ImportEqualsDeclaration */; +} +var nls; +(function (nls_1) { + function fileFrom(file, contents, path) { + if (path === void 0) { path = file.path; } + return new File({ + contents: new Buffer(contents), + base: file.base, + cwd: file.cwd, + path: path + }); + } + nls_1.fileFrom = fileFrom; + function mappedPositionFrom(source, lc) { + return { source: source, line: lc.line + 1, column: lc.character }; + } + nls_1.mappedPositionFrom = mappedPositionFrom; + function lcFrom(position) { + return { line: position.line - 1, character: position.column }; + } + nls_1.lcFrom = lcFrom; + var SingleFileServiceHost = (function () { + function SingleFileServiceHost(options, filename, contents) { + var _this = this; + this.options = options; + this.filename = filename; + this.getCompilationSettings = function () { return _this.options; }; + this.getScriptFileNames = function () { return [_this.filename]; }; + this.getScriptVersion = function () { return '1'; }; + this.getScriptSnapshot = function (name) { return name === _this.filename ? _this.file : _this.lib; }; + this.getCurrentDirectory = function () { return ''; }; + this.getDefaultLibFileName = function () { return 'lib.d.ts'; }; + this.file = ts.ScriptSnapshot.fromString(contents); + this.lib = ts.ScriptSnapshot.fromString(''); + } + return SingleFileServiceHost; + }()); + nls_1.SingleFileServiceHost = SingleFileServiceHost; + function isCallExpressionWithinTextSpanCollectStep(textSpan, node) { + if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) { + return CollectStepResult.No; + } + return node.kind === 160 /* CallExpression */ ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; + } + function analyze(contents, options) { + if (options === void 0) { options = {}; } + var filename = 'file.ts'; + var serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents); + var service = ts.createLanguageService(serviceHost); + var sourceFile = service.getSourceFile(filename); + // all imports + var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; })); + // import nls = require('vs/nls'); + var importEqualsDeclarations = imports + .filter(function (n) { return n.kind === 211 /* ImportEqualsDeclaration */; }) + .map(function (n) { return n; }) + .filter(function (d) { return d.moduleReference.kind === 222 /* ExternalModuleReference */; }) + .filter(function (d) { return d.moduleReference.expression.getText() === '\'vs/nls\''; }); + // import ... from 'vs/nls'; + var importDeclarations = imports + .filter(function (n) { return n.kind === 212 /* ImportDeclaration */; }) + .map(function (n) { return n; }) + .filter(function (d) { return d.moduleSpecifier.kind === 8 /* StringLiteral */; }) + .filter(function (d) { return d.moduleSpecifier.getText() === '\'vs/nls\''; }) + .filter(function (d) { return !!d.importClause && !!d.importClause.namedBindings; }); + var nlsExpressions = importEqualsDeclarations + .map(function (d) { return d.moduleReference.expression; }) + .concat(importDeclarations.map(function (d) { return d.moduleSpecifier; })) + .map(function (d) { return ({ + start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()), + end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd()) + }); }); + // `nls.localize(...)` calls + var nlsLocalizeCallExpressions = importDeclarations + .filter(function (d) { return d.importClause.namedBindings.kind === 214 /* NamespaceImport */; }) + .map(function (d) { return d.importClause.namedBindings.name; }) + .concat(importEqualsDeclarations.map(function (d) { return d.name; })) + .map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); }) + .flatten() + .filter(function (r) { return !r.isWriteAccess; }) + .map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); }) + .map(function (a) { return lazy(a).last(); }) + .filter(function (n) { return !!n; }) + .map(function (n) { return n; }) + .filter(function (n) { return n.expression.kind === 158 /* PropertyAccessExpression */ && n.expression.name.getText() === 'localize'; }); + // `localize` named imports + var allLocalizeImportDeclarations = importDeclarations + .filter(function (d) { return d.importClause.namedBindings.kind === 215 /* NamedImports */; }) + .map(function (d) { return d.importClause.namedBindings.elements; }) + .flatten(); + // `localize` read-only references + var localizeReferences = allLocalizeImportDeclarations + .filter(function (d) { return d.name.getText() === 'localize'; }) + .map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); }) + .flatten() + .filter(function (r) { return !r.isWriteAccess; }); + // custom named `localize` read-only references + var namedLocalizeReferences = allLocalizeImportDeclarations + .filter(function (d) { return d.propertyName && d.propertyName.getText() === 'localize'; }) + .map(function (n) { return service.getReferencesAtPosition(filename, n.name.pos + 1); }) + .flatten() + .filter(function (r) { return !r.isWriteAccess; }); + // find the deepest call expressions AST nodes that contain those references + var localizeCallExpressions = localizeReferences + .concat(namedLocalizeReferences) + .map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); }) + .map(function (a) { return lazy(a).last(); }) + .filter(function (n) { return !!n; }) + .map(function (n) { return n; }); + // collect everything + var localizeCalls = nlsLocalizeCallExpressions + .concat(localizeCallExpressions) + .map(function (e) { return e.arguments; }) + .filter(function (a) { return a.length > 1; }) + .sort(function (a, b) { return a[0].getStart() - b[0].getStart(); }) + .map(function (a) { return ({ + keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) }, + key: a[0].getText(), + valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) }, + value: a[1].getText() + }); }); + return { + localizeCalls: localizeCalls.toArray(), + nlsExpressions: nlsExpressions.toArray() + }; + } + nls_1.analyze = analyze; + var TextModel = (function () { + function TextModel(contents) { + var regex = /\r\n|\r|\n/g; + var index = 0; + var match; + this.lines = []; + this.lineEndings = []; + while (match = regex.exec(contents)) { + this.lines.push(contents.substring(index, match.index)); + this.lineEndings.push(match[0]); + index = regex.lastIndex; + } + if (contents.length > 0) { + this.lines.push(contents.substring(index, contents.length)); + this.lineEndings.push(''); + } + } + TextModel.prototype.get = function (index) { + return this.lines[index]; + }; + TextModel.prototype.set = function (index, line) { + this.lines[index] = line; + }; + Object.defineProperty(TextModel.prototype, "lineCount", { + get: function () { + return this.lines.length; + }, + enumerable: true, + configurable: true + }); + /** + * Applies patch(es) to the model. + * Multiple patches must be ordered. + * Does not support patches spanning multiple lines. + */ + TextModel.prototype.apply = function (patch) { + var startLineNumber = patch.span.start.line; + var endLineNumber = patch.span.end.line; + var startLine = this.lines[startLineNumber] || ''; + var endLine = this.lines[endLineNumber] || ''; + this.lines[startLineNumber] = [ + startLine.substring(0, patch.span.start.character), + patch.content, + endLine.substring(patch.span.end.character) + ].join(''); + for (var i = startLineNumber + 1; i <= endLineNumber; i++) { + this.lines[i] = ''; + } + }; + TextModel.prototype.toString = function () { + return lazy(this.lines).zip(this.lineEndings) + .flatten().toArray().join(''); + }; + return TextModel; + }()); + nls_1.TextModel = TextModel; + function patchJavascript(patches, contents, moduleId) { + var model = new nls.TextModel(contents); + // patch the localize calls + lazy(patches).reverse().each(function (p) { return model.apply(p); }); + // patch the 'vs/nls' imports + var firstLine = model.get(0); + var patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1"); + model.set(0, patchedFirstLine); + return model.toString(); + } + nls_1.patchJavascript = patchJavascript; + function patchSourcemap(patches, rsm, smc) { + var smg = new sm.SourceMapGenerator({ + file: rsm.file, + sourceRoot: rsm.sourceRoot + }); + patches = patches.reverse(); + var currentLine = -1; + var currentLineDiff = 0; + var source = null; + smc.eachMapping(function (m) { + var patch = patches[patches.length - 1]; + var original = { line: m.originalLine, column: m.originalColumn }; + var generated = { line: m.generatedLine, column: m.generatedColumn }; + if (currentLine !== generated.line) { + currentLineDiff = 0; + } + currentLine = generated.line; + generated.column += currentLineDiff; + if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) { + var originalLength = patch.span.end.character - patch.span.start.character; + var modifiedLength = patch.content.length; + var lengthDiff = modifiedLength - originalLength; + currentLineDiff += lengthDiff; + generated.column += lengthDiff; + patches.pop(); + } + source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source; + source = source.replace(/\\/g, '/'); + smg.addMapping({ source: source, name: m.name, original: original, generated: generated }); + }, null, sm.SourceMapConsumer.GENERATED_ORDER); + if (source) { + smg.setSourceContent(source, smc.sourceContentFor(source)); + } + return JSON.parse(smg.toString()); + } + nls_1.patchSourcemap = patchSourcemap; + function patch(moduleId, typescript, javascript, sourcemap) { + var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions; + if (localizeCalls.length === 0) { + return { javascript: javascript, sourcemap: sourcemap }; + } + var nlsKeys = template(localizeCalls.map(function (lc) { return lc.key; })); + var nls = template(localizeCalls.map(function (lc) { return lc.value; })); + var smc = new sm.SourceMapConsumer(sourcemap); + var positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]); + var i = 0; + // build patches + var patches = lazy(localizeCalls) + .map(function (lc) { return ([ + { range: lc.keySpan, content: '' + (i++) }, + { range: lc.valueSpan, content: 'null' } + ]); }) + .flatten() + .map(function (c) { + var start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start))); + var end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end))); + return { span: { start: start, end: end }, content: c.content }; + }) + .toArray(); + javascript = patchJavascript(patches, javascript, moduleId); + // since imports are not within the sourcemap information, + // we must do this MacGyver style + if (nlsExpressions.length) { + javascript = javascript.replace(/^define\(.*$/m, function (line) { + return line.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1"); + }); + } + sourcemap = patchSourcemap(patches, sourcemap, smc); + return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls }; + } + nls_1.patch = patch; + function patchFiles(javascriptFile, typescript) { + // hack? + var moduleId = javascriptFile.relative + .replace(/\.js$/, '') + .replace(/\\/g, '/'); + var _a = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap), javascript = _a.javascript, sourcemap = _a.sourcemap, nlsKeys = _a.nlsKeys, nls = _a.nls; + var result = [fileFrom(javascriptFile, javascript)]; + result[0].sourceMap = sourcemap; + if (nlsKeys) { + result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js'))); + } + if (nls) { + result.push(fileFrom(javascriptFile, nls, javascriptFile.path.replace(/\.js$/, '.nls.js'))); + } + return result; + } + nls_1.patchFiles = patchFiles; +})(nls || (nls = {})); +module.exports = nls; diff --git a/build/lib/reporter.js b/build/lib/reporter.js index e02bf359558..d9a7de331f4 100644 --- a/build/lib/reporter.js +++ b/build/lib/reporter.js @@ -3,18 +3,23 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -var es = require('event-stream'); -var _ = require('underscore'); +'use strict'; -var allErrors = []; -var count = 0; +const es = require('event-stream'); +const _ = require('underscore'); +const util = require('gulp-util'); + +const allErrors = []; +let startTime = null; +let count = 0; function onStart() { if (count++ > 0) { return; } - console.log('*** Starting...'); + startTime = new Date().getTime(); + util.log(util.colors.green('Starting compilation')); } function onEnd() { @@ -23,8 +28,9 @@ function onEnd() { } var errors = _.flatten(allErrors); - errors.map(function (err) { console.error('*** Error:', err); }); - console.log('*** Finished with', errors.length, 'errors.'); + errors.map(err => util.log(`${ util.colors.red('Error') }: ${ err }`)); + + util.log(`${ util.colors.green('Finished compilation') } with ${ util.colors.red(errors.length + ' errors') } in ${ util.colors.blue((new Date().getTime() - startTime) + 'ms') }.`); } module.exports = function () { diff --git a/build/lib/tslint/noUnexternalizedStringsRule.js b/build/lib/tslint/noUnexternalizedStringsRule.js index b6691ae182d..5440bff536a 100644 --- a/build/lib/tslint/noUnexternalizedStringsRule.js +++ b/build/lib/tslint/noUnexternalizedStringsRule.js @@ -1,168 +1,168 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -"use strict"; -var __extends = (this && this.__extends) || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -}; -var ts = require('typescript'); -var Lint = require('tslint/lib/lint'); -/** - * Implementation of the no-unexternalized-strings rule. - */ -var Rule = (function (_super) { - __extends(Rule, _super); - function Rule() { - _super.apply(this, arguments); - } - Rule.prototype.apply = function (sourceFile) { - return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions())); - }; - return Rule; -}(Lint.Rules.AbstractRule)); -exports.Rule = Rule; -function isStringLiteral(node) { - return node && node.kind === ts.SyntaxKind.StringLiteral; -} -function isObjectLiteral(node) { - return node && node.kind === ts.SyntaxKind.ObjectLiteralExpression; -} -function isPropertyAssignment(node) { - return node && node.kind === ts.SyntaxKind.PropertyAssignment; -} -var NoUnexternalizedStringsRuleWalker = (function (_super) { - __extends(NoUnexternalizedStringsRuleWalker, _super); - function NoUnexternalizedStringsRuleWalker(file, opts) { - var _this = this; - _super.call(this, file, opts); - this.signatures = Object.create(null); - this.ignores = Object.create(null); - this.messageIndex = undefined; - this.keyIndex = undefined; - this.usedKeys = Object.create(null); - var options = this.getOptions(); - var first = options && options.length > 0 ? options[0] : null; - if (first) { - if (Array.isArray(first.signatures)) { - first.signatures.forEach(function (signature) { return _this.signatures[signature] = true; }); - } - if (Array.isArray(first.ignores)) { - first.ignores.forEach(function (ignore) { return _this.ignores[ignore] = true; }); - } - if (typeof first.messageIndex !== 'undefined') { - this.messageIndex = first.messageIndex; - } - if (typeof first.keyIndex !== 'undefined') { - this.keyIndex = first.keyIndex; - } - } - } - NoUnexternalizedStringsRuleWalker.prototype.visitSourceFile = function (node) { - var _this = this; - _super.prototype.visitSourceFile.call(this, node); - Object.keys(this.usedKeys).forEach(function (key) { - var occurences = _this.usedKeys[key]; - if (occurences.length > 1) { - occurences.forEach(function (occurence) { - _this.addFailure((_this.createFailure(occurence.key.getStart(), occurence.key.getWidth(), "Duplicate key " + occurence.key.getText() + " with different message value."))); - }); - } - }); - }; - NoUnexternalizedStringsRuleWalker.prototype.visitStringLiteral = function (node) { - this.checkStringLiteral(node); - _super.prototype.visitStringLiteral.call(this, node); - }; - NoUnexternalizedStringsRuleWalker.prototype.checkStringLiteral = function (node) { - var text = node.getText(); - var doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE; - var info = this.findDescribingParent(node); - // Ignore strings in import and export nodes. - if (info && info.ignoreUsage) { - return; - } - var callInfo = info ? info.callInfo : null; - var functionName = callInfo ? callInfo.callExpression.expression.getText() : null; - if (functionName && this.ignores[functionName]) { - return; - } - if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) { - this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Unexternalized string found: " + node.getText())); - return; - } - // We have a single quoted string outside a localize function name. - if (!doubleQuoted && !this.signatures[functionName]) { - return; - } - // We have a string that is a direct argument into the localize call. - var keyArg = callInfo.argIndex === this.keyIndex - ? callInfo.callExpression.arguments[this.keyIndex] - : null; - if (keyArg) { - if (isStringLiteral(keyArg)) { - this.recordKey(keyArg, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined); - } - else if (isObjectLiteral(keyArg)) { - for (var i = 0; i < keyArg.properties.length; i++) { - var property = keyArg.properties[i]; - if (isPropertyAssignment(property)) { - var name_1 = property.name.getText(); - if (name_1 === 'key') { - var initializer = property.initializer; - if (isStringLiteral(initializer)) { - this.recordKey(initializer, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined); - } - break; - } - } - } - } - } - var messageArg = callInfo.argIndex === this.messageIndex - ? callInfo.callExpression.arguments[this.messageIndex] - : null; - if (messageArg && messageArg !== node) { - this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), "Message argument to '" + callInfo.callExpression.expression.getText() + "' must be a string literal.")); - return; - } - }; - NoUnexternalizedStringsRuleWalker.prototype.recordKey = function (keyNode, messageNode) { - var text = keyNode.getText(); - var occurences = this.usedKeys[text]; - if (!occurences) { - occurences = []; - this.usedKeys[text] = occurences; - } - if (messageNode) { - if (occurences.some(function (pair) { return pair.message ? pair.message.getText() === messageNode.getText() : false; })) { - return; - } - } - occurences.push({ key: keyNode, message: messageNode }); - }; - NoUnexternalizedStringsRuleWalker.prototype.findDescribingParent = function (node) { - var parent; - while ((parent = node.parent)) { - var kind = parent.kind; - if (kind === ts.SyntaxKind.CallExpression) { - var callExpression = parent; - return { callInfo: { callExpression: callExpression, argIndex: callExpression.arguments.indexOf(node) } }; - } - else if (kind === ts.SyntaxKind.ImportEqualsDeclaration || kind === ts.SyntaxKind.ImportDeclaration || kind === ts.SyntaxKind.ExportDeclaration) { - return { ignoreUsage: true }; - } - else if (kind === ts.SyntaxKind.VariableDeclaration || kind === ts.SyntaxKind.FunctionDeclaration || kind === ts.SyntaxKind.PropertyDeclaration - || kind === ts.SyntaxKind.MethodDeclaration || kind === ts.SyntaxKind.VariableDeclarationList || kind === ts.SyntaxKind.InterfaceDeclaration - || kind === ts.SyntaxKind.ClassDeclaration || kind === ts.SyntaxKind.EnumDeclaration || kind === ts.SyntaxKind.ModuleDeclaration - || kind === ts.SyntaxKind.TypeAliasDeclaration || kind === ts.SyntaxKind.SourceFile) { - return null; - } - node = parent; - } - }; - NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"'; - return NoUnexternalizedStringsRuleWalker; -}(Lint.RuleWalker)); +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +"use strict"; +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var ts = require('typescript'); +var Lint = require('tslint/lib/lint'); +/** + * Implementation of the no-unexternalized-strings rule. + */ +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions())); + }; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +function isStringLiteral(node) { + return node && node.kind === ts.SyntaxKind.StringLiteral; +} +function isObjectLiteral(node) { + return node && node.kind === ts.SyntaxKind.ObjectLiteralExpression; +} +function isPropertyAssignment(node) { + return node && node.kind === ts.SyntaxKind.PropertyAssignment; +} +var NoUnexternalizedStringsRuleWalker = (function (_super) { + __extends(NoUnexternalizedStringsRuleWalker, _super); + function NoUnexternalizedStringsRuleWalker(file, opts) { + var _this = this; + _super.call(this, file, opts); + this.signatures = Object.create(null); + this.ignores = Object.create(null); + this.messageIndex = undefined; + this.keyIndex = undefined; + this.usedKeys = Object.create(null); + var options = this.getOptions(); + var first = options && options.length > 0 ? options[0] : null; + if (first) { + if (Array.isArray(first.signatures)) { + first.signatures.forEach(function (signature) { return _this.signatures[signature] = true; }); + } + if (Array.isArray(first.ignores)) { + first.ignores.forEach(function (ignore) { return _this.ignores[ignore] = true; }); + } + if (typeof first.messageIndex !== 'undefined') { + this.messageIndex = first.messageIndex; + } + if (typeof first.keyIndex !== 'undefined') { + this.keyIndex = first.keyIndex; + } + } + } + NoUnexternalizedStringsRuleWalker.prototype.visitSourceFile = function (node) { + var _this = this; + _super.prototype.visitSourceFile.call(this, node); + Object.keys(this.usedKeys).forEach(function (key) { + var occurences = _this.usedKeys[key]; + if (occurences.length > 1) { + occurences.forEach(function (occurence) { + _this.addFailure((_this.createFailure(occurence.key.getStart(), occurence.key.getWidth(), "Duplicate key " + occurence.key.getText() + " with different message value."))); + }); + } + }); + }; + NoUnexternalizedStringsRuleWalker.prototype.visitStringLiteral = function (node) { + this.checkStringLiteral(node); + _super.prototype.visitStringLiteral.call(this, node); + }; + NoUnexternalizedStringsRuleWalker.prototype.checkStringLiteral = function (node) { + var text = node.getText(); + var doubleQuoted = text.length >= 2 && text[0] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE && text[text.length - 1] === NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE; + var info = this.findDescribingParent(node); + // Ignore strings in import and export nodes. + if (info && info.ignoreUsage) { + return; + } + var callInfo = info ? info.callInfo : null; + var functionName = callInfo ? callInfo.callExpression.expression.getText() : null; + if (functionName && this.ignores[functionName]) { + return; + } + if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Unexternalized string found: " + node.getText())); + return; + } + // We have a single quoted string outside a localize function name. + if (!doubleQuoted && !this.signatures[functionName]) { + return; + } + // We have a string that is a direct argument into the localize call. + var keyArg = callInfo.argIndex === this.keyIndex + ? callInfo.callExpression.arguments[this.keyIndex] + : null; + if (keyArg) { + if (isStringLiteral(keyArg)) { + this.recordKey(keyArg, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined); + } + else if (isObjectLiteral(keyArg)) { + for (var i = 0; i < keyArg.properties.length; i++) { + var property = keyArg.properties[i]; + if (isPropertyAssignment(property)) { + var name_1 = property.name.getText(); + if (name_1 === 'key') { + var initializer = property.initializer; + if (isStringLiteral(initializer)) { + this.recordKey(initializer, this.messageIndex ? callInfo.callExpression.arguments[this.messageIndex] : undefined); + } + break; + } + } + } + } + } + var messageArg = callInfo.argIndex === this.messageIndex + ? callInfo.callExpression.arguments[this.messageIndex] + : null; + if (messageArg && messageArg !== node) { + this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), "Message argument to '" + callInfo.callExpression.expression.getText() + "' must be a string literal.")); + return; + } + }; + NoUnexternalizedStringsRuleWalker.prototype.recordKey = function (keyNode, messageNode) { + var text = keyNode.getText(); + var occurences = this.usedKeys[text]; + if (!occurences) { + occurences = []; + this.usedKeys[text] = occurences; + } + if (messageNode) { + if (occurences.some(function (pair) { return pair.message ? pair.message.getText() === messageNode.getText() : false; })) { + return; + } + } + occurences.push({ key: keyNode, message: messageNode }); + }; + NoUnexternalizedStringsRuleWalker.prototype.findDescribingParent = function (node) { + var parent; + while ((parent = node.parent)) { + var kind = parent.kind; + if (kind === ts.SyntaxKind.CallExpression) { + var callExpression = parent; + return { callInfo: { callExpression: callExpression, argIndex: callExpression.arguments.indexOf(node) } }; + } + else if (kind === ts.SyntaxKind.ImportEqualsDeclaration || kind === ts.SyntaxKind.ImportDeclaration || kind === ts.SyntaxKind.ExportDeclaration) { + return { ignoreUsage: true }; + } + else if (kind === ts.SyntaxKind.VariableDeclaration || kind === ts.SyntaxKind.FunctionDeclaration || kind === ts.SyntaxKind.PropertyDeclaration + || kind === ts.SyntaxKind.MethodDeclaration || kind === ts.SyntaxKind.VariableDeclarationList || kind === ts.SyntaxKind.InterfaceDeclaration + || kind === ts.SyntaxKind.ClassDeclaration || kind === ts.SyntaxKind.EnumDeclaration || kind === ts.SyntaxKind.ModuleDeclaration + || kind === ts.SyntaxKind.TypeAliasDeclaration || kind === ts.SyntaxKind.SourceFile) { + return null; + } + node = parent; + } + }; + NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"'; + return NoUnexternalizedStringsRuleWalker; +}(Lint.RuleWalker)); diff --git a/build/lib/util.js b/build/lib/util.js index b3e98dc2baf..07ee3676ec3 100644 --- a/build/lib/util.js +++ b/build/lib/util.js @@ -274,4 +274,17 @@ exports.rebase = function (count) { var parts = f.dirname.split(/[\/\\]/); f.dirname = parts.slice(count).join(path.sep); }); +}; + +exports.filter = fn => { + const result = es.through(function(data) { + if (fn(data)) { + this.emit('data', data); + } else { + result.restore.push(data); + } + }); + + result.restore = es.through(); + return result; }; \ No newline at end of file diff --git a/build/monaco/api.js b/build/monaco/api.js index 97877c63803..4cab80a45a9 100644 --- a/build/monaco/api.js +++ b/build/monaco/api.js @@ -202,7 +202,7 @@ function format(text) { InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: true, PlaceOpenBraceOnNewLineForFunctions: false, - PlaceOpenBraceOnNewLineForControlBlocks: false + PlaceOpenBraceOnNewLineForControlBlocks: false, }; } } diff --git a/extensions/cpp/syntaxes/c++.json b/extensions/cpp/syntaxes/c++.json index 4bde79ba0c4..3919ba6f49d 100644 --- a/extensions/cpp/syntaxes/c++.json +++ b/extensions/cpp/syntaxes/c++.json @@ -14,11 +14,12 @@ "hxx", "h++", "inl", + "ino", "ipp", "tcc", "tpp" ], - "firstLineMatch": "-\\*-\\s*([Mm]ode: )?C\\+\\+;?\\s*-\\*-", + "firstLineMatch": "(?i)-\\*-[^*]*(Mode:\\s*)?C\\+\\+(\\s*;.*?)?\\s*-\\*-", "name": "C++", "patterns": [ { @@ -28,7 +29,7 @@ "include": "source.c" }, { - "match": "\\b(friend|explicit|virtual)\\b", + "match": "\\b(friend|explicit|virtual|override|final|noexcept)\\b", "name": "storage.modifier.cpp" }, { @@ -65,15 +66,15 @@ "name": "keyword.operator.cast.cpp" }, { - "match": "\\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq)\\b", + "match": "\\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\b", "name": "keyword.operator.cpp" }, { - "match": "\\b(class|decltype|wchar_t)\\b", + "match": "\\b(class|decltype|wchar_t|char16_t|char32_t)\\b", "name": "storage.type.cpp" }, { - "match": "\\b(constexpr|export|mutable|typename)\\b", + "match": "\\b(constexpr|export|mutable|typename|thread_local)\\b", "name": "storage.modifier.cpp" }, { diff --git a/extensions/cpp/syntaxes/c.json b/extensions/cpp/syntaxes/c.json index 07e54297d57..00852feba25 100644 --- a/extensions/cpp/syntaxes/c.json +++ b/extensions/cpp/syntaxes/c.json @@ -4,7 +4,7 @@ "c", "h" ], - "firstLineMatch": "-\\*-\\s*([Mm]ode: )?C;?\\s*-\\*-", + "firstLineMatch": "(?i)-\\*-[^*]*(Mode:\\s*)?C(\\s*;.*?)?\\s*-\\*-", "name": "C", "patterns": [ { @@ -58,7 +58,7 @@ "include": "#strings" }, { - "begin": "(?x)\n^\\s* ((\\#)\\s*define) \\s+ # define\n((?[a-zA-Z_][a-zA-Z0-9_]*)) # macro name\n(?:\n (\\()\n (\n \\s* \\g \\s* # first argument\n ((,) \\s* \\g \\s*)* # additional arguments\n (?:\\.\\.\\.)? # varargs ellipsis?\n )\n (\\))\n)?", + "begin": "(?x)\n^\\s* ((\\#)\\s*define) \\s+ # define\n((?[a-zA-Z_$][\\w$]*)) # macro name\n(?:\n (\\()\n (\n \\s* \\g \\s* # first argument\n ((,) \\s* \\g \\s*)* # additional arguments\n (?:\\.\\.\\.)? # varargs ellipsis?\n )\n (\\))\n)?", "beginCaptures": { "1": { "name": "keyword.control.directive.define.c" @@ -258,7 +258,7 @@ "include": "#parens" }, { - "match": "\\b(const|override|final|noexcept)\\b", + "match": "\\b(const)\\b", "name": "storage.modifier.c" }, { @@ -273,14 +273,17 @@ "repository": { "access": { "captures": { - "1": { - "name": "punctuation.separator.variable-access.c" - }, "2": { - "name": "variable.other.dot-access.c" + "name": "punctuation.separator.dot-access.c" + }, + "3": { + "name": "punctuation.separator.pointer-access.c" + }, + "4": { + "name": "variable.other.member.c" } }, - "match": "(\\.)([a-zA-Z_][a-zA-Z_0-9]*)\\b(?!\\s*\\()" + "match": "((\\.)|(->))([a-zA-Z_][a-zA-Z_0-9]*)\\b(?!\\s*\\()" }, "block": { "patterns": [ @@ -470,7 +473,7 @@ "numbers": { "patterns": [ { - "match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b", + "match": "\\b((0(x|X)[0-9a-fA-F]*)|(0(b|B)[01]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b", "name": "constant.numeric.c" } ] diff --git a/extensions/cpp/test/colorize-results/test_cc.json b/extensions/cpp/test/colorize-results/test_cc.json index e696ae20d7f..47eede42cc9 100644 --- a/extensions/cpp/test/colorize-results/test_cc.json +++ b/extensions/cpp/test/colorize-results/test_cc.json @@ -749,7 +749,7 @@ }, { "c": ".", - "t": "block.c.function.meta.punctuation.separator.variable-access", + "t": "block.c.dot-access.function.meta.punctuation.separator", "r": { "dark_plus": ".vs-dark .token rgb(212, 212, 212)", "light_plus": ".vs .token rgb(0, 0, 0)", @@ -760,7 +760,7 @@ }, { "c": "x", - "t": "block.c.dot-access.function.meta.other.variable", + "t": "block.c.function.member.meta.other.variable", "r": { "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.variable rgb(156, 220, 254)", "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.variable rgb(0, 16, 128)", diff --git a/extensions/css/client/src/colorDecorators.ts b/extensions/css/client/src/colorDecorators.ts index ab9f7941bd6..39165bc42dc 100644 --- a/extensions/css/client/src/colorDecorators.ts +++ b/extensions/css/client/src/colorDecorators.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import {window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range} from 'vscode'; +import {window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range, TextDocument, TextEditor} from 'vscode'; let decorationType: DecorationRenderOptions = { before: { @@ -28,56 +28,71 @@ export function activateColorDecorations(decoratorProvider: (uri: string) => The let colorsDecorationType = window.createTextEditorDecorationType(decorationType); disposables.push(colorsDecorationType); - let activeEditor = window.activeTextEditor; - if (activeEditor) { - triggerUpdateDecorations(); - } + let pendingUpdateRequests : { [key:string]:number; } = {}; + // we care about all visible editors + window.visibleTextEditors.forEach(editor => { + if (editor.document) { + triggerUpdateDecorations(editor.document); + } + }); + // to get visible one has to become active window.onDidChangeActiveTextEditor(editor => { - activeEditor = editor; - if (editor && supportedLanguages[activeEditor.document.languageId]) { - triggerUpdateDecorations(); + if (editor) { + triggerUpdateDecorations(editor.document); } }, null, disposables); - workspace.onDidChangeTextDocument(event => { - if (activeEditor && event.document === activeEditor.document && supportedLanguages[activeEditor.document.languageId]) { - triggerUpdateDecorations(); - } - }, null, disposables); + workspace.onDidChangeTextDocument(event => triggerUpdateDecorations(event.document), null, disposables); + workspace.onDidOpenTextDocument(triggerUpdateDecorations, null, disposables); + workspace.onDidCloseTextDocument(triggerUpdateDecorations, null, disposables); - let timeout = null; - function triggerUpdateDecorations() { - if (timeout) { + function triggerUpdateDecorations(document: TextDocument) { + let triggerUpdate = supportedLanguages[document.languageId]; + let uri = document.uri.toString(); + let timeout = pendingUpdateRequests[uri]; + if (typeof timeout !== 'undefined') { clearTimeout(timeout); + triggerUpdate = true; // force update, even if languageId is not supported (anymore) + } + if (triggerUpdate) { + pendingUpdateRequests[uri] = setTimeout(() => { + updateDecorations(uri); + delete pendingUpdateRequests[uri]; + }, 500); } - timeout = setTimeout(updateDecorations, 500); } - function updateDecorations() { - if (!activeEditor) { - return; - } - let document = activeEditor.document; - if (!supportedLanguages[document.languageId]) { - return; - } - let uri = activeEditor.document.uri.toString(); - decoratorProvider(uri).then(ranges => { - - let decorations = ranges.map(range => { - let color = document.getText(range); - return { - range: range, - renderOptions: { - before: { - backgroundColor: color - } - } - }; - }); - activeEditor.setDecorations(colorsDecorationType, decorations); + function updateDecorations(uri: string) { + window.visibleTextEditors.forEach(editor => { + let document = editor.document; + if (document && document.uri.toString() === uri) { + updateDecorationForEditor(editor); + } }); } + + function updateDecorationForEditor(editor: TextEditor) { + let document = editor.document; + if (supportedLanguages[document.languageId]) { + decoratorProvider(document.uri.toString()).then(ranges => { + let decorations = ranges.map(range => { + let color = document.getText(range); + return { + range: range, + renderOptions: { + before: { + backgroundColor: color + } + } + }; + }); + editor.setDecorations(colorsDecorationType, decorations); + }); + } else { + editor.setDecorations(colorsDecorationType, []); + } + } + return Disposable.from(...disposables); } diff --git a/extensions/css/client/src/cssMain.ts b/extensions/css/client/src/cssMain.ts index 21fadbc5144..9c932a2d927 100644 --- a/extensions/css/client/src/cssMain.ts +++ b/extensions/css/client/src/cssMain.ts @@ -54,7 +54,7 @@ export function activate(context: ExtensionContext) { context.subscriptions.push(disposable); languages.setLanguageConfiguration('css', { - wordPattern: /(#?-?\d*\.\d\w*%?)|((::|[@#.!:])?[\w-?]+%?)|::|[@#.!:]/g, + wordPattern: /(#?-?\d*\.\d\w*%?)|(::?[\w-]*(?=[^,{;]*[,{]))|(([@#.!])?[\w-?]+%?|[@#!.])/g, comments: { blockComment: ['/*', '*/'] }, @@ -71,7 +71,7 @@ export function activate(context: ExtensionContext) { }); languages.setLanguageConfiguration('less', { - wordPattern: /(#?-?\d*\.\d\w*%?)|([@#!.:]?[\w-?]+%?)|[@#!.]/g, + wordPattern: /(#?-?\d*\.\d\w*%?)|(::?[\w-]+(?=[^,{;]*[,{]))|(([@#.!])?[\w-?]+%?|[@#!.])/g, comments: { blockComment: ['/*', '*/'], lineComment: '//' @@ -90,7 +90,7 @@ export function activate(context: ExtensionContext) { }); languages.setLanguageConfiguration('scss', { - wordPattern: /(#?-?\d*\.\d\w*%?)|([@#$!.:]?[\w-?]+%?)|[@#!.]/g, + wordPattern: /(#?-?\d*\.\d\w*%?)|(::?[\w-]*(?=[^,{;]*[,{]))|(([@$#.!])?[\w-?]+%?|[@#!$.])/g, comments: { blockComment: ['/*', '*/'], lineComment: '//' diff --git a/extensions/json/server/src/jsonServerMain.ts b/extensions/json/server/src/jsonServerMain.ts index 95e04efc1fe..7ba5700d257 100644 --- a/extensions/json/server/src/jsonServerMain.ts +++ b/extensions/json/server/src/jsonServerMain.ts @@ -169,22 +169,20 @@ function updateConfiguration() { } } if (jsonConfigurationSettings) { - jsonConfigurationSettings.forEach((schema) => { - if (schema.fileMatch) { - let uri = schema.url; - if (!uri && schema.schema) { - uri = schema.schema.id; - if (!uri) { - uri = 'vscode://schemas/custom/' + encodeURIComponent(schema.fileMatch.join('&')); - } - } - if (Strings.startsWith(uri, '.') && workspaceRoot) { + jsonConfigurationSettings.forEach(schema => { + let uri = schema.url; + if (!uri && schema.schema) { + uri = schema.schema.id; + } + if (!uri && schema.fileMatch) { + uri = 'vscode://schemas/custom/' + encodeURIComponent(schema.fileMatch.join('&')); + } + if (uri) { + if (uri[0] === '.' && workspaceRoot) { // workspace relative path uri = URI.file(path.normalize(path.join(workspaceRoot.fsPath, uri))).toString(); } - if (uri) { - languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema }); - } + languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema }); } }); } diff --git a/extensions/markdown/package.json b/extensions/markdown/package.json index f977f79e85c..299de6bebb9 100644 --- a/extensions/markdown/package.json +++ b/extensions/markdown/package.json @@ -96,7 +96,8 @@ { "command": "markdown.showPreview", "key": "shift+ctrl+v", - "mac": "shift+cmd+v" + "mac": "shift+cmd+v", + "when": "!terminalFocus" }, { "command": "markdown.showPreviewToSide", diff --git a/extensions/node-debug/node-debug.azure.json b/extensions/node-debug/node-debug.azure.json index 24a4f834bdd..f3fd4fc5a18 100644 --- a/extensions/node-debug/node-debug.azure.json +++ b/extensions/node-debug/node-debug.azure.json @@ -1,6 +1,6 @@ { "account": "monacobuild", "container": "debuggers", - "zip": "957a1eb/node-debug.zip", + "zip": "e25530c/node-debug.zip", "output": "" } diff --git a/extensions/objective-c/test/colorize-results/test_m.json b/extensions/objective-c/test/colorize-results/test_m.json index a8da3c04b93..5b790e05b03 100644 --- a/extensions/objective-c/test/colorize-results/test_m.json +++ b/extensions/objective-c/test/colorize-results/test_m.json @@ -2245,7 +2245,7 @@ }, { "c": ".", - "t": "block.c.function-with-body.implementation.meta.objc.punctuation.scope.separator.variable-access", + "t": "block.c.dot-access.function-with-body.implementation.meta.objc.punctuation.scope.separator", "r": { "dark_plus": ".vs-dark .token rgb(212, 212, 212)", "light_plus": ".vs .token rgb(0, 0, 0)", @@ -2256,7 +2256,7 @@ }, { "c": "gestureRecognizers", - "t": "block.c.dot-access.function-with-body.implementation.meta.objc.other.scope.variable", + "t": "block.c.function-with-body.implementation.member.meta.objc.other.scope.variable", "r": { "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.variable rgb(156, 220, 254)", "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.variable rgb(0, 16, 128)", diff --git a/extensions/typescript/src/typescriptMain.ts b/extensions/typescript/src/typescriptMain.ts index 5305ae01e86..197559ac318 100644 --- a/extensions/typescript/src/typescriptMain.ts +++ b/extensions/typescript/src/typescriptMain.ts @@ -275,6 +275,7 @@ class LanguageProvider { public syntaxDiagnosticsReceived(file: string, diagnostics: Diagnostic[]): void { this.syntaxDiagnostics[file] = diagnostics; + this.currentDiagnostics.set(Uri.file(file), diagnostics); } public semanticDiagnosticsReceived(file: string, diagnostics: Diagnostic[]): void { diff --git a/extensions/typescript/src/utils/electron.ts b/extensions/typescript/src/utils/electron.ts index c0bda301689..a4e08453f9f 100644 --- a/extensions/typescript/src/utils/electron.ts +++ b/extensions/typescript/src/utils/electron.ts @@ -48,7 +48,7 @@ function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string newEnv['STDIN_PIPE_NAME'] = stdInPipeName; newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName; newEnv['STDERR_PIPE_NAME'] = stdErrPipeName; - newEnv['ELECTRON_RUN_AS_NODE'] = '1'; + newEnv['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = '1'; return newEnv; } diff --git a/extensions/typescript/src/utils/electronForkStart.ts b/extensions/typescript/src/utils/electronForkStart.ts index 83f75724002..46a12506041 100644 --- a/extensions/typescript/src/utils/electronForkStart.ts +++ b/extensions/typescript/src/utils/electronForkStart.ts @@ -31,7 +31,7 @@ var stdErrPipeName = process.env['STDERR_PIPE_NAME']; log('STDIN_PIPE_NAME: ' + stdInPipeName); log('STDOUT_PIPE_NAME: ' + stdOutPipeName); log('STDERR_PIPE_NAME: ' + stdErrPipeName); -log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']); +log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']); // stdout redirection to named pipe (function() { @@ -147,7 +147,7 @@ log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']); delete process.env['STDIN_PIPE_NAME']; delete process.env['STDOUT_PIPE_NAME']; delete process.env['STDERR_PIPE_NAME']; - delete process.env['ELECTRON_RUN_AS_NODE']; + delete process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']; require(program); diff --git a/extensions/typescript/src/utils/projectStatus.ts b/extensions/typescript/src/utils/projectStatus.ts index 8dc39cc28e4..b58fbf0a0e3 100644 --- a/extensions/typescript/src/utils/projectStatus.ts +++ b/extensions/typescript/src/utils/projectStatus.ts @@ -55,13 +55,15 @@ export function create(client: ITypescriptServiceClient, isOpen:(path:string)=>P })); function onEditor(editor: vscode.TextEditor): void { - if (!editor || !vscode.languages.match(selector, editor.document)) { + if (!editor + || !vscode.languages.match(selector, editor.document) + || !client.asAbsolutePath(editor.document.uri)) { + item.hide(); return; } const file = client.asAbsolutePath(editor.document.uri); - isOpen(file).then(value => { if (!value) { return; diff --git a/extensions/typescript/syntaxes/TypeScriptReact.tmLanguage b/extensions/typescript/syntaxes/TypeScriptReact.tmLanguage index 9cae064fd20..b9d77e3f52b 100644 --- a/extensions/typescript/syntaxes/TypeScriptReact.tmLanguage +++ b/extensions/typescript/syntaxes/TypeScriptReact.tmLanguage @@ -1061,48 +1061,6 @@ - known-type-parameters - - begin - (<) - beginCaptures - - 1 - - name - meta.brace.angle.tsx - - - end - (?=$)|(>) - endCaptures - - 2 - - name - meta.brace.angle.tsx - - - name - meta.known.type.parameters.ts - patterns - - - match - \b(extends)\b - name - keyword.other.ts - - - include - #comment - - - include - #type - - - literal name @@ -1431,7 +1389,7 @@ include - #know-type-parameters + #type-parameters include @@ -1979,7 +1937,7 @@ include - #known-type-parameters + #type-parameters include @@ -2038,7 +1996,7 @@ type-declaration begin - \b(type)\b\s+([a-zA-Z_$][\w$]*) + \b(type)\b\s+([a-zA-Z_$][\w$]*)\s* beginCaptures 1 @@ -2060,7 +2018,7 @@ include - #known-type-parameters + #type-parameters include @@ -2171,7 +2129,7 @@ type-parameters begin - ([a-zA-Z_$][\w$]*)?\s*(<)(?=[^<]*(<[^<>]*>)*>\s*[(]) + ([a-zA-Z_$][\w$]*)?(<) beginCaptures 1 diff --git a/extensions/typescript/test/colorize-fixtures/test-brackets.tsx b/extensions/typescript/test/colorize-fixtures/test-brackets.tsx new file mode 100644 index 00000000000..a0ffed64a8f --- /dev/null +++ b/extensions/typescript/test/colorize-fixtures/test-brackets.tsx @@ -0,0 +1,6 @@ +let a = Array(); // Highlight ok here + +interface egGenericsInArray { + a: Array; +} +let s = "nothing should fail here..."; \ No newline at end of file diff --git a/extensions/typescript/test/colorize-results/test-brackets_tsx.json b/extensions/typescript/test/colorize-results/test-brackets_tsx.json new file mode 100644 index 00000000000..c210fed0867 --- /dev/null +++ b/extensions/typescript/test/colorize-results/test-brackets_tsx.json @@ -0,0 +1,343 @@ +[ + { + "c": "let", + "t": "expr.meta.storage.tsx.type.var", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.storage.type rgb(86, 156, 214)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.storage.type rgb(0, 0, 255)", + "dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.storage.type rgb(86, 156, 214)", + "light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.storage.type rgb(0, 0, 255)", + "hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.storage.type rgb(86, 156, 214)" + } + }, + { + "c": " ", + "t": "expr.meta.tsx.var", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "a", + "t": "expr.meta.tsx.var.var-single-variable.variable", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.variable rgb(156, 220, 254)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.variable rgb(0, 16, 128)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": " = ", + "t": "expr.meta.tsx.var.var-single-variable", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "Array", + "t": "entity.expr.meta.name.parameters.tsx.type.var.var-single-variable", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.name.type rgb(78, 201, 176)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.name.type rgb(38, 127, 153)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "<", + "t": "angle.brace.expr.meta.parameters.tsx.type.var.var-single-variable", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "number", + "t": "expr.meta.parameters.primitive.support.tsx.type.var.var-single-variable", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.support.type rgb(78, 201, 176)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.support.type rgb(38, 127, 153)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": ">", + "t": "expr.meta.parameters.tsx.type.var.var-single-variable", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "()", + "t": "brace.expr.meta.paren.tsx.var.var-single-variable", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "; ", + "t": "", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "// Highlight ok here", + "t": "comment.line.tsx", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.comment rgb(96, 139, 78)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.comment rgb(0, 128, 0)", + "dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.comment rgb(96, 139, 78)", + "light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.comment rgb(0, 128, 0)", + "hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.comment rgb(124, 166, 104)" + } + }, + { + "c": "interface", + "t": "declaration.meta.object.storage.tsx.type", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.storage.type rgb(86, 156, 214)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.storage.type rgb(0, 0, 255)", + "dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.storage.type rgb(86, 156, 214)", + "light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.storage.type rgb(0, 0, 255)", + "hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.storage.type rgb(86, 156, 214)" + } + }, + { + "c": " ", + "t": "declaration.meta.object.tsx", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "egGenericsInArray", + "t": "class.declaration.entity.meta.name.object.tsx", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.name.class rgb(78, 201, 176)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.name.class rgb(38, 127, 153)", + "dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.entity.name.class rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": " ", + "t": "declaration.meta.object.tsx", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "{", + "t": "body.brace.curly.declaration.meta.object.tsx", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": " ", + "t": "body.declaration.field.meta.object.tsx", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "a", + "t": "body.declaration.field.meta.object.tsx.variable", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.variable rgb(156, 220, 254)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.variable rgb(0, 16, 128)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": ": ", + "t": "body.declaration.field.meta.object.tsx", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "Array", + "t": "body.declaration.entity.field.meta.name.object.parameters.tsx.type", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.entity.name.type rgb(78, 201, 176)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.entity.name.type rgb(38, 127, 153)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "<", + "t": "angle.body.brace.declaration.field.meta.object.parameters.tsx.type", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "number", + "t": "body.declaration.field.meta.object.parameters.primitive.support.tsx.type", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.support.type rgb(78, 201, 176)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.support.type rgb(38, 127, 153)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": ">", + "t": "body.declaration.field.meta.object.parameters.tsx.type", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": ";", + "t": "body.declaration.meta.object.tsx", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "}", + "t": "body.brace.curly.declaration.meta.object.tsx", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "let", + "t": "expr.meta.storage.tsx.type.var", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.storage.type rgb(86, 156, 214)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.storage.type rgb(0, 0, 255)", + "dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.storage.type rgb(86, 156, 214)", + "light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.storage.type rgb(0, 0, 255)", + "hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.storage.type rgb(86, 156, 214)" + } + }, + { + "c": " ", + "t": "expr.meta.tsx.var", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "s", + "t": "expr.meta.tsx.var.var-single-variable.variable", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.variable rgb(156, 220, 254)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.variable rgb(0, 16, 128)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": " = ", + "t": "expr.meta.tsx.var.var-single-variable", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + }, + { + "c": "\"nothing should fail here...\"", + "t": "double.expr.meta.string.tsx.var.var-single-variable", + "r": { + "dark_plus": ".vs-dark.vscode-theme-defaults-themes-dark_plus-json .token.string rgb(206, 145, 120)", + "light_plus": ".vs.vscode-theme-defaults-themes-light_plus-json .token.string rgb(163, 21, 21)", + "dark_vs": ".vs-dark.vscode-theme-defaults-themes-dark_vs-json .token.string rgb(206, 145, 120)", + "light_vs": ".vs.vscode-theme-defaults-themes-light_vs-json .token.string rgb(163, 21, 21)", + "hc_black": ".hc-black.vscode-theme-defaults-themes-hc_black-json .token.string rgb(206, 145, 120)" + } + }, + { + "c": ";", + "t": "", + "r": { + "dark_plus": ".vs-dark .token rgb(212, 212, 212)", + "light_plus": ".vs .token rgb(0, 0, 0)", + "dark_vs": ".vs-dark .token rgb(212, 212, 212)", + "light_vs": ".vs .token rgb(0, 0, 0)", + "hc_black": ".hc-black .token rgb(255, 255, 255)" + } + } +] \ No newline at end of file diff --git a/extensions/vscode-colorize-tests/.vscode/tasks.json b/extensions/vscode-colorize-tests/.vscode/tasks.json index d31b15910ee..97e40acf632 100644 --- a/extensions/vscode-colorize-tests/.vscode/tasks.json +++ b/extensions/vscode-colorize-tests/.vscode/tasks.json @@ -1,6 +1,7 @@ // Available variables which can be used inside of strings. // ${workspaceRoot}: the root folder of the team // ${file}: the current opened file +// ${relativeFile}: the current opened file relative to cwd // ${fileBasename}: the current opened file's basename // ${fileDirname}: the current opened file's dirname // ${fileExtname}: the current opened file's extension diff --git a/gulpfile.js b/gulpfile.js index 92a511a531d..6966b225307 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,72 +3,53 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + // Increase max listeners for event emitters require('events').EventEmitter.defaultMaxListeners = 100; -var gulp = require('gulp'); -var json = require('gulp-json-editor'); -var buffer = require('gulp-buffer'); -var tsb = require('gulp-tsb'); -var filter = require('gulp-filter'); -var mocha = require('gulp-mocha'); -var es = require('event-stream'); -var watch = require('./build/lib/watch'); -var nls = require('./build/lib/nls'); -var util = require('./build/lib/util'); -var reporter = require('./build/lib/reporter')(); -var remote = require('gulp-remote-src'); -var zip = require('gulp-vinyl-zip'); -var path = require('path'); -var bom = require('gulp-bom'); -var sourcemaps = require('gulp-sourcemaps'); -var _ = require('underscore'); -var assign = require('object-assign'); -var quiet = !!process.env['VSCODE_BUILD_QUIET']; -var monacodts = require('./build/monaco/api'); -var fs = require('fs'); +const gulp = require('gulp'); +const json = require('gulp-json-editor'); +const buffer = require('gulp-buffer'); +const tsb = require('gulp-tsb'); +const filter = require('gulp-filter'); +const mocha = require('gulp-mocha'); +const es = require('event-stream'); +const watch = require('./build/lib/watch'); +const nls = require('./build/lib/nls'); +const util = require('./build/lib/util'); +const reporter = require('./build/lib/reporter')(); +const remote = require('gulp-remote-src'); +const zip = require('gulp-vinyl-zip'); +const path = require('path'); +const bom = require('gulp-bom'); +const sourcemaps = require('gulp-sourcemaps'); +const _ = require('underscore'); +const assign = require('object-assign'); +const monacodts = require('./build/monaco/api'); +const fs = require('fs'); -var rootDir = path.join(__dirname, 'src'); -var tsOptions = { - target: 'ES5', - declaration: true, - module: 'amd', - verbose: !quiet, - preserveConstEnums: true, - experimentalDecorators: true, - sourceMap: true, - rootDir: rootDir, - sourceRoot: util.toFileUri(rootDir) -}; - -function createFastFilter(filterFn) { - var result = es.through(function(data) { - if (filterFn(data)) { - this.emit('data', data); - } else { - result.restore.push(data); - } - }); - result.restore = es.through(); - return result; -} +const rootDir = path.join(__dirname, 'src'); +const options = require('./src/tsconfig.json').compilerOptions; +options.verbose = false; +options.sourceMap = true; +options.rootDir = rootDir; +options.sourceRoot = util.toFileUri(rootDir); function createCompile(build, emitError) { - var opts = _.clone(tsOptions); + const opts = _.clone(options); opts.inlineSources = !!build; opts.noFilesystemLookup = true; - var ts = tsb.create(opts, null, null, quiet ? null : function (err) { - reporter(err.toString()); - }); + const ts = tsb.create(opts, null, null, err => reporter(err.toString())); return function (token) { - var utf8Filter = createFastFilter(function(data) { return /(\/|\\)test(\/|\\).*utf8/.test(data.path); }); - var tsFilter = createFastFilter(function(data) { return /\.ts$/.test(data.path); }); - var noDeclarationsFilter = createFastFilter(function(data) { return !(/\.d\.ts$/.test(data.path)); }); + const utf8Filter = util.filter(data => /(\/|\\)test(\/|\\).*utf8/.test(data.path)); + const tsFilter = util.filter(data => /\.ts$/.test(data.path)); + const noDeclarationsFilter = util.filter(data => !(/\.d\.ts$/.test(data.path))); - var input = es.through(); - var output = input + const input = es.through(); + const output = input .pipe(utf8Filter) .pipe(bom()) .pipe(utf8Filter.restore) @@ -81,20 +62,20 @@ function createCompile(build, emitError) { .pipe(sourcemaps.write('.', { addComment: false, includeContent: !!build, - sourceRoot: tsOptions.sourceRoot + sourceRoot: options.sourceRoot })) .pipe(tsFilter.restore) - .pipe(quiet ? es.through() : reporter.end(emitError)); + .pipe(reporter.end(emitError)); return es.duplex(input, output); }; } function compileTask(out, build) { - var compile = createCompile(build, true); + const compile = createCompile(build, true); return function () { - var src = es.merge( + const src = es.merge( gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts') ); @@ -107,14 +88,14 @@ function compileTask(out, build) { } function watchTask(out, build) { - var compile = createCompile(build); + const compile = createCompile(build); return function () { - var src = es.merge( + const src = es.merge( gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts') ); - var watchSrc = watch('src/**', { base: 'src' }); + const watchSrc = watch('src/**', { base: 'src' }); return watchSrc .pipe(util.incremental(compile, src, true)) @@ -124,10 +105,9 @@ function watchTask(out, build) { } function monacodtsTask(out, isWatch) { + let timer = -1; - var timer = -1; - - var runSoon = function(howSoon) { + const runSoon = function(howSoon) { if (timer !== -1) { clearTimeout(timer); timer = -1; @@ -138,7 +118,7 @@ function monacodtsTask(out, isWatch) { }, howSoon); }; - var runNow = function() { + const runNow = function() { if (timer !== -1) { clearTimeout(timer); timer = -1; @@ -147,7 +127,7 @@ function monacodtsTask(out, isWatch) { // monacodts.complainErrors(); // return; // } - var result = monacodts.run(out); + const result = monacodts.run(out); if (!result.isTheSame) { if (isWatch) { fs.writeFileSync(result.filePath, result.content); @@ -157,11 +137,11 @@ function monacodtsTask(out, isWatch) { } }; - var resultStream; + let resultStream; if (isWatch) { - var filesToWatchMap = {}; + const filesToWatchMap = {}; monacodts.getFilesToWatch(out).forEach(function(filePath) { filesToWatchMap[path.normalize(filePath)] = true; }); @@ -171,7 +151,7 @@ function monacodtsTask(out, isWatch) { })); resultStream = es.through(function(data) { - var filePath = path.normalize(data.path); + const filePath = path.normalize(data.path); if (filesToWatchMap[filePath]) { runSoon(5000); } @@ -180,7 +160,7 @@ function monacodtsTask(out, isWatch) { } else { - resultStream = es.through(null, function(end) { + resultStream = es.through(null, function() { runNow(); this.emit('end'); }); @@ -220,24 +200,24 @@ gulp.task('test', function () { }); gulp.task('mixin', function () { - var repo = process.env['VSCODE_MIXIN_REPO']; + const repo = process.env['VSCODE_MIXIN_REPO']; if (!repo) { console.log('Missing VSCODE_MIXIN_REPO, skipping mixin'); return; } - var quality = process.env['VSCODE_QUALITY']; + const quality = process.env['VSCODE_QUALITY']; if (!quality) { console.log('Missing VSCODE_QUALITY, skipping mixin'); return; } - var url = 'https://github.com/' + repo + '/archive/master.zip'; - var opts = { base: '' }; - var username = process.env['VSCODE_MIXIN_USERNAME']; - var password = process.env['VSCODE_MIXIN_PASSWORD']; + const url = 'https://github.com/' + repo + '/archive/master.zip'; + const opts = { base: '' }; + const username = process.env['VSCODE_MIXIN_USERNAME']; + const password = process.env['VSCODE_MIXIN_PASSWORD']; if (username || password) { opts.auth = { user: username || '', pass: password || '' }; @@ -245,22 +225,22 @@ gulp.task('mixin', function () { console.log('Mixing in sources from \'' + url + '\':'); - var all = remote(url, opts) + let all = remote(url, opts) .pipe(zip.src()) .pipe(filter(function (f) { return !f.isDirectory(); })) .pipe(util.rebase(1)); if (quality) { - var build = all.pipe(filter('build/**')); - var productJsonFilter = filter('product.json', { restore: true }); + const build = all.pipe(filter('build/**')); + const productJsonFilter = filter('product.json', { restore: true }); - var mixin = all + const mixin = all .pipe(filter('quality/' + quality + '/**')) .pipe(util.rebase(2)) .pipe(productJsonFilter) .pipe(buffer()) .pipe(json(function (patch) { - var original = require('./product.json'); + const original = require('./product.json'); return assign(original, patch); })) .pipe(productJsonFilter.restore); diff --git a/i18n/chs/extensions/typescript/out/typescriptServiceClient.i18n.json b/i18n/chs/extensions/typescript/out/typescriptServiceClient.i18n.json index 2d5d71bde4a..c6b75c868c6 100644 --- a/i18n/chs/extensions/typescript/out/typescriptServiceClient.i18n.json +++ b/i18n/chs/extensions/typescript/out/typescriptServiceClient.i18n.json @@ -7,7 +7,7 @@ "channelName": "TypeScript", "noServerFound": "路径 {0} 未指向有效的 tsserver 安装。将禁用 TypeScript 语言功能。", "serverCouldNotBeStarted": "无法启动 TypeScript 语言服务器。错误消息为: {0}", - "serverDied": "在过去 5 分钟内,TypeScript 语言服务意外中止 5 次。请考虑启用 bug 报告。", - "serverDiedAfterStart": "TypeScript 语言服务在其启动后已中止 5 次。服务不会重启。请启用 bug 报告。", + "serverDied": "在过去 5 分钟内,TypeScript 语言服务意外中止了 5 次。请考虑启用 bug 报告。", + "serverDiedAfterStart": "TypeScript 语言服务在其启动后已中止 5 次。将不会重启该服务。请启用 bug 报告。", "versionNumber.custom": "自定义" } \ No newline at end of file diff --git a/i18n/chs/extensions/typescript/package.i18n.json b/i18n/chs/extensions/typescript/package.i18n.json index d3e9e44e275..9afdbb4a589 100644 --- a/i18n/chs/extensions/typescript/package.i18n.json +++ b/i18n/chs/extensions/typescript/package.i18n.json @@ -18,6 +18,7 @@ "javascript.validate.enable": "启用/禁用 JavaScript 验证", "typescript.reloadProjects.title": "重新加载 TypeScript 项目", "typescript.tsdk.desc": "指定包含要使用的 tsserver 和 lib*.d.ts 文件的文件夹路径。", + "typescript.tsserver.experimentalAutoBuild": "启用实验性自动生成。要求安装 1.9 dev 或 2.x tsserver 版本并在更改后重启 VS Code。", "typescript.tsserver.trace": "启用对发送到 TS 服务器的消息进行跟踪", "typescript.useCodeSnippetsOnMethodSuggest.dec": "完成函数的参数签名。", "typescript.validate.enable": "启用/禁用 TypeScript 验证" diff --git a/i18n/chs/src/vs/code/electron-main/menus.i18n.json b/i18n/chs/src/vs/code/electron-main/menus.i18n.json index b6bae35c94a..07ec6c7ff60 100644 --- a/i18n/chs/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/chs/src/vs/code/electron-main/menus.i18n.json @@ -35,6 +35,9 @@ "miExit": "退出(&&X)", "miFind": "查找(&&F)", "miFindInFiles": "在文件中查找(&&I)", + "miFocusFirstGroup": "左侧组(&&L)", + "miFocusSecondGroup": "侧面组(&&S)", + "miFocusThirdGroup": "右侧组(&&R)", "miForward": "前进(&&F)", "miGotoDefinition": "转到定义(&&D)...", "miGotoFile": "转到文件(&&F)...", @@ -43,11 +46,13 @@ "miInstallingUpdate": "正在安装更新...", "miLastCheckedAt": "上次检查时间 {0}", "miLicense": "查看许可证(&&V)", - "miMarker": "错误和警告(&&E)...", + "miMarker": "问题(&&P)", "miMoveSidebar": "移动侧边栏(&&M)", - "miNavigateHistory": "导航历史记录(&&N)", "miNewFile": "新建文件(&&N)", "miNewWindow": "新建窗口(&&N)", + "miNextEditor": "下一个编辑器(&&N)", + "miNextEditorInGroup": "组中下一个使用过的编辑器(&&N)", + "miNextGroup": "下一个组(&&N)", "miOpen": "打开(&&O)...", "miOpenFile": "打开文件(&&O)...", "miOpenFolder": "打开文件夹(&&F)...", @@ -58,11 +63,14 @@ "miOpenWorkspaceSettings": "工作区设置(&&W)", "miPaste": "粘贴(&&P)", "miPreferences": "首选项(&&P)", + "miPreviousEditor": "上一个编辑器(&&P)", + "miPreviousEditorInGroup": "组中上一个使用过的编辑器(&&P)", + "miPreviousGroup": "上一个组(&&P)", "miPrivacyStatement": "隐私声明(&&P)", "miQuit": "退出 {0}", "miRedo": "恢复(&&R)", "miReleaseNotes": "发行说明(&&R)", - "miReopenClosedFile": "&&重新打开已关闭的文件", + "miReopenClosedEditor": "重新打开已关闭的编辑器(&&R)", "miReplace": "替换(&&R)", "miReportIssues": "报告问题(&&I)", "miRestartToUpdate": "重启以更新...", @@ -73,14 +81,18 @@ "miSelectAll": "全选(&&S)", "miSelectTheme": "颜色主题(&&C)", "miSplitEditor": "拆分编辑器(&&E)", - "miToggleDebugConsole": "切换调试控制台(&&B)", + "miSwitchEditor": "切换编辑器(&&E)", + "miSwitchGroup": "切换组(&&G)", + "miToggleDebugConsole": "调试控制台(&&B)", "miToggleDevTools": "切换开发人员工具(&&T)", "miToggleFullScreen": "切换全屏(&&F)", + "miToggleIntegratedTerminal": "集成终端(&&I)", "miToggleMenuBar": "切换菜单栏(&&B)", - "miToggleOutput": "切换输出(&&O)", + "miToggleOutput": "输出(&&O)", "miTogglePanel": "切换面板(&&P)", "miToggleRenderWhitespace": "切换呈现空格(&&R)", "miToggleSidebar": "切换侧边栏(&&T)", + "miToggleStatusbar": "切换状态栏(&&T)", "miToggleWordWrap": "切换自动换行(&&W)", "miTwitter": "在 Twitter 上加入我们(&&J)", "miUndo": "撤消(&&U)", @@ -91,5 +103,6 @@ "miViewSearch": "搜索(&&S)", "miZoomIn": "放大(&&Z)", "miZoomOut": "缩小(&&U)", + "miZoomReset": "重置缩放(&&R)", "okButton": "确定" } \ 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 6d084b0cdcf..e5a5fc448e8 100644 --- a/i18n/chs/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/chs/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -9,7 +9,6 @@ "cursorBlinking": "控制光标闪烁动画,接受的值为'blink'、'visible' 和 'hidden'", "cursorStyle": "控制光标样式,接受的值为 'block' 和 'line'", "detectIndentation": "当打开文件时,将基于文件内容检测 \"editor.tabSize\" 和 \"editor.insertSpaces\"。", - "dismissPeekOnEsc": "按 ESC 时将关闭速览编辑器", "editorConfigurationTitle": "编辑器配置", "folding": "控制编辑器是否启用代码折叠功能", "fontFamily": "控制字体系列。", @@ -25,6 +24,7 @@ "lineNumbers": "控制行号的可见性", "mouseWheelScrollSensitivity": "要对鼠标滚轮滚动事件的 \"deltaX\" 和 \"deltaY\" 使用的乘数 ", "overviewRulerLanes": "控制可在概述标尺同一位置显示的效果数量", + "parameterHints": "启用参数提示", "quickSuggestions": "控制键入时是否应显示快速建议", "quickSuggestionsDelay": "控制延迟多少毫秒后将显示快速建议", "referenceInfos": "控制编辑器是否显示支持它的模式的参考信息", @@ -35,6 +35,7 @@ "selectionClipboard": "控制是否支持 Linux 主剪贴板。", "selectionHighlight": "控制编辑器是否应突出显示选项的近似匹配", "sideBySide": "控制 Diff 编辑器以并排或内联形式显示差异", + "stablePeek": "即使在双击编辑器内容或按 Esc 键时,也要保持速览编辑器的打开状态。", "suggestOnTriggerCharacters": "控制键入触发器字符时是否应自动显示建议", "tabSize": "一个制表符等于的空格数。", "tabSize.errorMessage": "应为 \"number\"。注意,值\"auto\"已由 \"editor.detectIndentation\" 设置替换。", diff --git a/i18n/chs/src/vs/editor/contrib/folding/browser/folding.i18n.json b/i18n/chs/src/vs/editor/contrib/folding/browser/folding.i18n.json index 80d0b1dbf12..0a7e85dd536 100644 --- a/i18n/chs/src/vs/editor/contrib/folding/browser/folding.i18n.json +++ b/i18n/chs/src/vs/editor/contrib/folding/browser/folding.i18n.json @@ -11,6 +11,8 @@ "foldLevel3Action.label": "折叠级别 3", "foldLevel4Action.label": "折叠级别 4", "foldLevel5Action.label": "折叠级别 5", + "foldRecursivelyAction.label": "以递归方式折叠", + "unFoldRecursivelyAction.label": "以递归方式展开", "unfoldAction.label": "展开", "unfoldAllAction.label": "全部展开" } \ No newline at end of file diff --git a/i18n/chs/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json b/i18n/chs/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json index 480732ef883..893962305f1 100644 --- a/i18n/chs/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json +++ b/i18n/chs/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json @@ -7,5 +7,7 @@ "markerAction.next.label": "转到下一个错误或警告", "markerAction.previous.label": "转到上一个错误或警告", "quickfix.multiple.label": "建议的修正:", - "quickfix.single.label": "建议的修正:" + "quickfix.single.label": "建议的修正:", + "title.w_source": "({0}/{1}) [{2}]", + "title.wo_source": "({0}/{1})" } \ No newline at end of file diff --git a/i18n/chs/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/chs/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index c8f193dbe1f..bef60a830df 100644 --- a/i18n/chs/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/chs/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "正在加载...", "meta.titleReference": " – {0} 个引用", - "noResults": "无结果", "references.action.label": "查找所有引用", - "references.action.name": "显示引用" + "references.action.name": "查找所有引用" } \ No newline at end of file diff --git a/i18n/chs/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json b/i18n/chs/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json index 696fc1bfaa6..ccca5c14752 100644 --- a/i18n/chs/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json +++ b/i18n/chs/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json @@ -9,5 +9,6 @@ "peekView.alternateTitle": "引用", "referenceCount": "{0} 个引用", "referencesCount": "{0} 个引用", + "referencesFailre": "解析文件失败。", "treeAriaLabel": "引用" } \ No newline at end of file diff --git a/i18n/chs/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/chs/src/vs/editor/node/textMate/TMSyntax.i18n.json index 3aec9e3e353..2f1291b3d3f 100644 --- a/i18n/chs/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/chs/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -4,11 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "invalid.injectTo": "\"contributes.{0}.injectTo\" 中的值无效。必须为语言范围名称数组。提供的值: {1}", "invalid.language": "“contributes.{0}.language”中存在未知的语言。提供的值: {1}", "invalid.path.0": "“contributes.{0}.path”中应为字符串。提供的值: {1}", "invalid.path.1": "“contributes.{0}.path”({1})应包含在扩展的文件夹({2})内。这可能会使扩展不可移植。", "invalid.scopeName": "“contributes.{0}.scopeName”中应为字符串。提供的值: {1}", "vscode.extension.contributes.grammars": "用于 textmate tokenizer。", + "vscode.extension.contributes.grammars.injectTo": "此语法注入到的语言范围名称列表。", "vscode.extension.contributes.grammars.language": "此语法参与的语言标识符。", "vscode.extension.contributes.grammars.path": "tmLanguage 文件的路径。该路径是相对于扩展文件夹,通常以 \"./syntaxes/\" 开头。", "vscode.extension.contributes.grammars.scopeName": "tmLanguage 文件所用的 textmate 范围名称。" diff --git a/i18n/chs/src/vs/languages/html/common/html.contribution.i18n.json b/i18n/chs/src/vs/languages/html/common/html.contribution.i18n.json index ec828371466..c7f4104500d 100644 --- a/i18n/chs/src/vs/languages/html/common/html.contribution.i18n.json +++ b/i18n/chs/src/vs/languages/html/common/html.contribution.i18n.json @@ -10,7 +10,7 @@ "format.indentInnerHtml": "缩进 和 部分。", "format.maxPreserveNewLines": "要保留在一个区块中的换行符的最大数量。对于无限制使用 \"null\"。", "format.preserveNewLines": "是否要保留元素前面的现有换行符。仅适用于元素前,不适用于标记内或文本。", - "format.unformatted": "标记列表,以逗号分隔,不应重设格式。\"null\" 默认为所有内联标记。", + "format.unformatted": "以逗号分隔的标记列表不应重设格式。\"null\" 默认为所有列于 https://www.w3.org/TR/html5/dom.html#phrasing-content 的标记。", "format.wrapLineLength": "每行最大字符数(0 = 禁用)。", "htmlConfigurationTitle": "HTML 配置" } \ 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 e96ce98422c..9f3c3998899 100644 --- a/i18n/chs/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/chs/src/vs/workbench/electron-browser/actions.i18n.json @@ -15,7 +15,8 @@ "newWindow": "新建窗口", "noFolderOpened": "此实例中没有要关闭的已打开文件夹。", "openRecent": "打开最近的文件", - "openRecentPlaceHolder": "选择要打开的路径", + "openRecentPlaceHolder": "选择要打开的路径(在新窗口中按住 Ctrl 键打开)", + "openRecentPlaceHolderMac": "选择路径(在新窗口中按住 Cmd 键打开)", "reloadWindow": "重新加载窗口", "toggleDevTools": "切换开发人员工具", "toggleFullScreen": "切换全屏", 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 c3bb74e14b5..bb291afec30 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 @@ -8,7 +8,8 @@ "file": "文件", "openFilesInNewWindow": "启用后,将在新窗口中打开文件,而不是重复使用现有实例。", "reopenFolders": "控制重启后重新打开文件夹的方式。选择“none”表示永不重新打开文件夹,选择“one”表示重新打开最后使用的一个文件夹,或选择“all”表示打开上次会话的所有文件夹。", - "updateChannel": "配置从中接收更新的更新频道。更改后需要重启。", + "restoreFullscreen": "如果窗口已退出全屏模式,控制其是否应还原为全屏模式。", + "updateChannel": "配置是否从更新通道接收自动更新。更改后需要重启。", "updateConfigurationTitle": "更新配置", "view": "查看", "windowConfigurationTitle": "窗口配置", diff --git a/i18n/chs/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json index 91a9bafb1b7..15e3d03a48c 100644 --- a/i18n/chs/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json @@ -10,6 +10,7 @@ "debugCategory": "调试", "debugEvaluate": "调试: 评估", "debugPanel": "调试控制台", + "launchConfigDoesNotExist": "启动配置“{0}”不存在。", "runToCursor": "调试: 运行到光标", "showDebugHover": "调试: 显示悬停", "toggleBreakpointAction": "调试: 切换断点", diff --git a/i18n/chs/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json b/i18n/chs/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json index 8358055b175..bf3772460f3 100644 --- a/i18n/chs/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json @@ -6,10 +6,12 @@ { "DebugTaskNotFound": "找不到 preLaunchTask“{0}”。", "NewLaunchConfig": "请设置应用程序的启动配置文件。", + "breakpointAdded": "已添加断点,行 {0}, 文件 {1}", + "breakpointRemoved": "已删除断点,行 {0},文件 {1}", "debugAdapterCrash": "调试适配器进程已意外终止", "debugAnyway": "仍进行调试", "debugSourceNotAvailable": "源 {0} 不可用。", - "debugTypeMissing": "launch.json 中的所选配置缺少属性 \"type\"。", + "debugTypeMissing": "所选的启动配置缺少属性 \"type\"。", "debugTypeNotSupported": "配置的类型“{0}”不受支持。", "debuggingContinued": "已继续调试。", "debuggingPaused": "已暂停调试,原因 {0},{1} {2}", diff --git a/i18n/chs/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json b/i18n/chs/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json index 09d389a3f89..c0d0cc181ec 100644 --- a/i18n/chs/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "debugLinuxConfiguration": "特定于 Linux 的启动配置属性。", "debugName": "配置名称;在启动配置下拉菜单中显示。", + "debugOSXConfiguration": "特定于 OS X 的启动配置属性。", "debugPrelaunchTask": "调试会话开始前要运行的任务。", "debugRequest": "请求配置类型。可以是“启动”或“附加”。", "debugType": "配置类型。", + "debugWindowsConfiguration": "特定于 Windows 的启动配置属性。", "internalConsoleOptions": "内部调试控制台的控制行为。", "relativePathsNotConverted": "相对路径不再自动转换为绝对路径。请考虑使用 ${workspaceRoot} 作为前缀。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/chs/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index 7a223323958..c66c7b89246 100644 --- a/i18n/chs/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -10,6 +10,7 @@ "app.launch.json.version": "此文件格式的版本。", "debugNoType": "不可省略调试适配器“类型”,其类型必须是“字符串”。", "duplicateDebuggerType": "调试类型“{0}”已注册,且具有属性“{1}”,正在忽略属性“{1}”。", + "interactiveVariableNotFound": "适配器 {0} 不提供启动配置中指定的变量 {1}。", "selectDebug": "选择环境", "vscode.extension.contributes.debuggers": "用于调试适配器。", "vscode.extension.contributes.debuggers.args": "要传递给适配器的可选参数。", @@ -26,6 +27,7 @@ "vscode.extension.contributes.debuggers.runtime": "可选运行时,以防程序属性不可执行,但需要运行时。", "vscode.extension.contributes.debuggers.runtimeArgs": "可选运行时参数。", "vscode.extension.contributes.debuggers.type": "此调试适配器的唯一标识符。", + "vscode.extension.contributes.debuggers.variables": "将 \"launch.json\" 中的交互式变量(例如 ${action.pickProcess})映射到命令中。", "vscode.extension.contributes.debuggers.windows": "Windows 特定的设置。", "vscode.extension.contributes.debuggers.windows.runtime": "用于 Windows 的运行时。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index 4ee4b8d4e1d..2d37d9be524 100644 --- a/i18n/chs/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,8 @@ "globalConsoleActionWin": "打开新命令提示符", "scopedConsoleActionMacLinux": "在终端中打开", "scopedConsoleActionWin": "在命令提示符中打开", + "terminal.external.linuxExec": "自定义要在 Linux 上运行的终端。", + "terminal.external.osxExec": "自定义要在 OS X 上运行的终端应用程序。", "terminal.external.windowsExec": "自定义要在 Windows 上运行的终端。", "terminalConfigurationTitle": "外部终端配置" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index 60131049ae9..6c03e184d08 100644 --- a/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "关闭", "deleteSure": "是否确定要卸载“{0}”?", - "installExtension": "安装扩展", - "notFound": "未安装扩展“{0}”。", + "enableAction": "启用", + "installAction": "安装", + "installing": "正在安装", + "restart": "若要启用此扩展,需要重启此 VS Code 窗口。\n\n是否继续?", "restartNow": "立即重启", - "restartNow2": "立即重启", "showExtensionRecommendations": "显示扩展建议", "showInstalledExtensions": "显示已安装扩展", "showOutdatedExtensions": "显示过时扩展", - "success-installed": "已成功安装“{0}”。请重启以启用它。", - "success-uninstalled": "已成功卸载“{0}”。请重启以停用它。 ", - "uninstall": "卸载扩展" + "toggleExtensionsViewlet": "显示扩展", + "uninstall": "卸载", + "updateAction": "更新" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json b/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json index f8d4b3de506..22c5964d316 100644 --- a/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json @@ -5,6 +5,7 @@ // Do not edit this file. It is machine generated. { "extensions": "扩展", + "outdatedExtensions": "{0} 个过时的扩展", "reloadNow": "立即重启", "success": "已成功安装扩展,请重启以启用它们。", "successSingle": "已成功安装 {0} 。请重启以启用它。" diff --git a/i18n/chs/src/vs/workbench/parts/files/browser/fileActions.i18n.json b/i18n/chs/src/vs/workbench/parts/files/browser/fileActions.i18n.json index 9e0164b5d06..f593a1dfac1 100644 --- a/i18n/chs/src/vs/workbench/parts/files/browser/fileActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/browser/fileActions.i18n.json @@ -4,13 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "addToWorkingFiles": "将活动文件添加到工作文件", - "closeAllFiles": "关闭所有文件", - "closeAllLabel": "关闭所有文件", - "closeFile": "关闭文件", - "closeLabel": "关闭文件", - "closeOtherFiles": "关闭其他文件", - "closeOtherLabel": "关闭其他文件", + "collapseExplorerFolders": "在资源管理器中折叠文件夹", "compareFiles": "比较文件", "compareSource": "选择以进行比较", "compareWith": "与“{0}”比较", @@ -31,7 +25,7 @@ "fileNameExistsError": "此位置已存在文件或文件夹 **{0}**。请选择其他名称。", "filePathTooLongError": "名称 **{0}** 导致路径太长。请选择更短的名称。", "focusFilesExplorer": "关注文件资源浏览器", - "focusWorkingFiles": "关注工作文件", + "focusOpenEditors": "专注于“打开的编辑器”视图", "globalCompareFile": "比较活动文件与...", "importFiles": "导入文件", "invalidFileNameError": "名称 **{0}** 作为文件或文件夹名无效。请选择其他名称。", @@ -39,25 +33,21 @@ "newFile": "新建文件", "newFolder": "新建文件夹", "newUntitledFile": "新的无标题文件", - "noFileOpen": "当前没有要关闭的已打开文件。", - "noWorkingFiles": "当前没有工作文件。", - "openFileToAdd": "首先打开文件以将其添加到工作文件。", "openFileToCompare": "首先打开文件以将其与另外一个文件比较。", "openFileToShow": "先打开一个文件以在浏览器中显示它", "openFolderFirst": "先打开一个文件夹,以在其中创建文件或文件夹。", - "openNextWorkingFile": "打开下一个工作文件", - "openPreviousWorkingFile": "打开上一个工作文件", "openToSide": "打开到侧边", "pasteFile": "粘贴", "permDelete": "永久删除", "refresh": "刷新", + "refreshExplorer": "刷新资源管理器", "rename": "重命名", - "reopenClosedFile": "重新打开已关闭的文件", "replaceButtonLabel": "替换(&&R)", "retry": "重试", "revert": "还原文件", "save": "保存", "saveAll": "全部保存", + "saveAllInGroup": "保存组中的全部内容", "saveAs": "另存为...", "saveFiles": "保存已更新文件", "showInExplorer": "在资源管理器中显示活动文件", diff --git a/i18n/chs/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index d508c4bc189..934a0ee7781 100644 --- a/i18n/chs/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -9,7 +9,7 @@ "autoSave": "控制已更新文件的自动保存。接受的值:“{0}”、“{1}”、“{2}”。如果设置为“{3}”,则可在 \"files.autoSaveDelay\" 中配置延迟。", "autoSaveDelay": "控制延迟(以秒为单位),在该延迟后将自动保存更新后的文件。仅在 \"files.autoSave\" 设置为“{0}”时适用。", "binaryFileEditor": "二进制文件编辑器", - "dynamicHeight": "控制工作文件部分的高度是否应动态适应元素数量。", + "dynamicHeight": "控制打开的编辑器部分的高度是否应动态适应元素数量。", "encoding": "读取和编写文件时将使用的默认字符集编码。", "eol": "默认行尾字符。", "exclude": "配置 glob 模式以排除文件和文件夹。", @@ -17,14 +17,11 @@ "explorerConfigurationTitle": "文件资源管理器配置", "files.exclude.boolean": "匹配文件路径所依据的 glob 模式。设置为 true 或 false 可启用或禁用该模式。", "files.exclude.when": "对匹配文件的同级文件的其他检查。使用 $(basename) 作为匹配文件名的变量。", - "filesCategory": "文件", "filesConfigurationTitle": "文件配置", - "maxVisible": "在滚动条出现之前将显示的最大工作文件数目。", - "openWorkingFile": "按名称打开工作文档", + "openEditorsVisible": "在“打开的编辑器”窗格中显示的编辑器数量。将其设置为 0 可隐藏窗格。", "showExplorerViewlet": "显示资源管理器", "textFileEditor": "文本文件编辑器", "trimTrailingWhitespace": "启用后,将在保存文件时剪裁尾随空格。", "view": "查看", - "watcherExclude": "配置文件路径的 glob 模式以从文件监视排除。更改此设置要求重启。如果在启动时遇到 Code 消耗大量 CPU 时间,则可以排除大型文件夹以减少初始加载。", - "workingFilesPicker": "按名称打开工作文档" + "watcherExclude": "配置文件路径的 glob 模式以从文件监视排除。更改此设置要求重启。如果在启动时遇到 Code 消耗大量 CPU 时间,则可以排除大型文件夹以减少初始加载。" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/chs/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index d150fc50177..c4d5594f60a 100644 --- a/i18n/chs/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "使用本地更改并覆盖磁盘内容", + "acceptLocalChanges": "覆盖", "compareChanges": "比较", "conflictingFileHasChanged": "磁盘上的文件内容已更改,比较编辑器的左侧已刷新。请再次审查和解析。", "discard": "放弃", @@ -13,8 +13,8 @@ "readonlySaveError": "无法保存“{0}”: 文件写保护。选择“覆盖”以删除保护。 ", "resolveSaveConflict": "{0} - 解析保存冲突", "retry": "重试", - "revertLocalChanges": "放弃本地更改,还原为磁盘上的内容", + "revertLocalChanges": "还原", "saveConflictDiffLabel": "{0} - 磁盘上 ↔ {1} 中", "staleSaveError": "无法保存“{0}”: 磁盘上的内容较新。单击 **比较** 以比较你的版本和磁盘上的版本。", - "userGuide": "使用编辑器工具栏中的操作 **撤消** 更改或用更改 **覆盖** 磁盘上的内容" + "userGuide": "选择**还原**以放弃所做的更改或使用**覆盖**以将磁盘上的内容替换为所做的更改" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json index c17f6cf89cf..9beaa0268ba 100644 --- a/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json @@ -9,5 +9,8 @@ "openFile": "打开文件", "openInEditor": "切换到编辑器视图", "stageSelectedLines": "暂存选定行", - "switchToChangesView": "切换到更改视图" + "switchToChangesView": "切换到更改视图", + "unstageSelectedLines": "取消暂存选定的行", + "workbenchStage": "暂存", + "workbenchUnstage": "取消暂存" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.i18n.json b/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.i18n.json index 943f084ae24..0e27ba1b0d3 100644 --- a/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/git/browser/gitActions.i18n.json @@ -5,13 +5,11 @@ // Do not edit this file. It is machine generated. { "authFailed": "在 GIT 远程上进行身份验证失败。", - "branch": "Branch", - "branch2": "Branch", - "checkout": "Checkout", "cleanChangesLabel": "清理更改(&&C)", "commit": "Commit", "commitAll": "全部提交", "commitAll2": "全部提交", + "commitMessage": "提交消息", "commitStaged": "提交已暂存的", "commitStaged2": "提交已暂存的", "confirmPublishMessage": "是否确定要将“{0}”发布到“{1}”?", @@ -36,13 +34,9 @@ "openFile": "打开文件", "publish": "发布", "publishPickMessage": "选取要将分支“{0}”发布到的远程:", - "pull": "Pull", - "pullWithRebase": "拉取(变基)", - "push": "Push", "refresh": "刷新", "stageAllChanges": "全部暂存", "stageChanges": "暂存", - "sync": "同步", "synchronizing": "正在同步...", "undoAllChanges": "全部清理", "undoChanges": "清理", diff --git a/i18n/chs/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json b/i18n/chs/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json index f34c664516e..46ff350a9d9 100644 --- a/i18n/chs/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json @@ -7,6 +7,7 @@ "alreadyCheckedOut": "分支 {0} 已是当前分支", "branchAriaLabel": "{0},GIT 分支", "checkoutBranch": "{0} 处的分支", + "checkoutRemoteBranch": "{0} 处的远程分支", "checkoutTag": "{0} 处的 Tag", "createBranch": "创建分支 {0}", "noBranches": "无其他分支", diff --git a/i18n/chs/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/chs/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 9acd540c904..8b44eb4db44 100644 --- a/i18n/chs/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -8,17 +8,23 @@ "cancel": "取消", "cantOpen": "无法打开此 git 资源。", "cantOpenResource": "无法打开此 git 资源。", - "changesFromIndex": "{0} - 对索引的更改", - "changesFromTree": "{0} - 对 {1} 的更改", + "changesFromIndex": "{0}(索引)", + "changesFromIndexDesc": "{0} - 对索引的更改", + "changesFromTree": "{0} ({1})", + "changesFromTreeDesc": "{0} - 对 {1} 的更改", "checkNativeConsole": "运行 GIT 操作存在问题。请审阅输出或使用控制台检查你的存储库的状态。", "configureUsernameEmail": "请配置 GIT 用户名和电子邮件。", "download": "下载", - "gitIndexChanges": "{0} - 对索引的更改", - "gitIndexChangesRenamed": "{0} - 已重命名 - 索引更改", - "gitMergeChanges": "{0} - 合并更改", + "gitIndexChanges": "{0} (索引) ↔ {1}", + "gitIndexChangesDesc": "{0} - 对索引的更改", + "gitIndexChangesRenamed": "{0} ← {1}", + "gitIndexChangesRenamedDesc": "{0} - 已重命名 - 对索引的更改", + "gitMergeChanges": "{0} (合并) ↔ {1}", + "gitMergeChangesDesc": "{0} - 合并更改", "neverShowAgain": "不再显示", "showOutput": "显示输出", "unmergedChanges": "提交更改前,你应首先解决未合并的更改。", "updateGit": "你似乎已安装 git {0}。在 git >=2.0.0 情况下代码工作最佳。", - "workingTreeChanges": "{0} - 对工作树的更改" + "workingTreeChanges": "{0} (标头) ↔ {1}", + "workingTreeChangesDesc": "{0} - 对工作树的更改" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/chs/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index 9561f89d77e..484937bfd05 100644 --- a/i18n/chs/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -9,6 +9,8 @@ "gitCommands": "GIT 命令", "gitConfigurationTitle": "GIT 配置", "gitEnabled": "是否启用了 GIT", + "gitLargeRepos": "始终允许大型存储库由 Code 托管。", + "gitLongCommit": "是否应警告提交长段消息。", "gitPath": "可执行 GIT 的路径", "gitPendingChangesBadge": "{0} 个挂起的更改", "gitProgressBadge": "正在运行 GIT 状态", diff --git a/i18n/chs/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json b/i18n/chs/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json index e704d14e6fb..4d29eeb6a07 100644 --- a/i18n/chs/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json @@ -6,6 +6,7 @@ { "commitMessage": "消息(按 {0} 提交)", "commitMessageAriaLabel": "GIT: 键入提交信息并按 {0} 以提交", + "longCommit": "建议保持提交的第一行在 50 个字符以内。可以随时使用更多行显示额外信息。", "needMessage": "请提供提交消息。您可以始终按下“{0}”以提交更改。如果存在任何暂存的更改,将仅提交这些更改;否则,提交所有更改。", "nothingToCommit": "在有一些更改要提交时,键入提交信息,并按下“{0}”以提交更改。如果存在任何暂存的更改,将仅提交这些更改;否则,提交所有更改。", "showOutput": "显示 GIT 输出", diff --git a/i18n/chs/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/chs/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index d87de403060..9a530a53be8 100644 --- a/i18n/chs/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0}: {1}", "QuickCommandsAction.label": "显示编辑器命令", "actionNotEnabled": "在当前上下文中没有启用命令“{0}”。", "canNotRun": "无法从此处运行命令“{0}”。", diff --git a/i18n/chs/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/chs/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index 07f4dd3092f..e61b55139fb 100644 --- a/i18n/chs/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,26 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "清理搜索结果", - "CollapseAllAction.label": "折叠", - "ConfigureGlobalExclusionsAction.label": "打开设置", - "RefreshAction.label": "刷新", - "RemoveAction.label": "删除", - "SelectOrRemoveAction.removeLabel": "删除", - "SelectOrRemoveAction.selectLabel": "选择", "ariaSearchResultsStatus": "搜索 {1} 文件中返回的 {0} 个结果", - "defaultLabel": "输入", - "fileMatchAriaLabel": "文件夹 {2} 的文件 {1} 中有 {0} 个匹配,搜索结果", - "findInFolder": "在文件夹中查找", - "findPlaceHolder": "按 Enter 进行搜索,按 Esc 取消", "globLabel": "{1} 时为 {0}", "global.searchScope.folders": "通过设置排除的文件", - "label.Search": "搜索: 键入搜索术语,然后按 Enter 进行搜索或按 Escape 取消", "label.excludes": "搜索排除模式", "label.global.excludes": "配置的搜索排除模式", "label.includes": "搜索包含模式", "moreSearch": "切换搜索详细信息", - "noMatches": "无匹配", "noResultsExcludes": "除“{0}”外,未找到任何结果 - ", "noResultsFound": "找不到结果。查看设置中配置的排除项 - ", "noResultsIncludes": "“{0}”中未找到任何结果 - ", "noResultsIncludesExcludes": "在“{0}”中找不到结果(“{1}”除外) - ", "openSettings.message": "打开设置", - "patternDescription": "使用 Glob 模式", - "patternHelpInclude": "要匹配的模式。例如,****/*.js** 与所有 JavaScript 文件匹配,或 **myFolder/**** 与包含所有子级的文件夹匹配。\n\n**Reference**:\n***** 匹配 0 个或更多字符\n**?** 匹配 1 个字符\n****** 匹配零个或更多目录\n**[a-z]** 匹配一系列字符\n**{a,b}** 匹配任何一种模式)", - "regexp.validationFailure": "表达式与所有内容相匹配", + "replaceAll.confirm.button": "替换", + "replaceAll.confirmation.message": "是否替换出现在 {1} 文件中的 {0}?", + "replaceAll.confirmation.title": "全部替换", + "replaceAll.message": "已替换出现在 {1} 文件中的 {0}。", "rerunSearch.message": "再次搜索", "rerunSearchInAll.message": "在所有文件中再次搜索", "searchCanceled": "在找到结果前取消了搜索 - ", - "searchMatch": "已找到 {0} 个匹配项", - "searchMatches": "已找到 {0} 个匹配项", "searchMaxResultsWarning": "结果集仅包含所有匹配项的子集。请使你的搜索更加具体,减少结果。", - "searchResultAria": "{0},搜索结果", "searchScope.excludes": "要排除的文件", "searchScope.includes": "要包含的文件", "treeAriaLabel": "搜索结果" diff --git a/i18n/chs/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json b/i18n/chs/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json index c21a4b6cf25..64de54e631c 100644 --- a/i18n/chs/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json +++ b/i18n/chs/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json @@ -5,7 +5,10 @@ // Do not edit this file. It is machine generated. { "close": "关闭", + "insiderBuilds": "会员版本将成为日常版本!", "license": "读取许可证", "licenseChanged": "我们的许可条款已更改,请检查它们。", + "neverShowAgain": "不再显示", + "readmore": "阅读更多内容", "releaseNotes": "欢迎使用 {0} v{1}! 是否要阅读发布说明?" } \ No newline at end of file diff --git a/i18n/chs/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/chs/src/vs/workbench/services/history/browser/history.i18n.json index 2eb031aa223..b595a10a512 100644 --- a/i18n/chs/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/chs/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[扩展开发主机] - {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} - {1}", "prefixWorkspaceTitle": "{0} - {1} - {2}", "prefixWorkspaceTitleMac": "{0} - {1}", diff --git a/i18n/cht/extensions/typescript/out/typescriptServiceClient.i18n.json b/i18n/cht/extensions/typescript/out/typescriptServiceClient.i18n.json index 6dd77b9dd0e..4db5fcc8c32 100644 --- a/i18n/cht/extensions/typescript/out/typescriptServiceClient.i18n.json +++ b/i18n/cht/extensions/typescript/out/typescriptServiceClient.i18n.json @@ -7,7 +7,7 @@ "channelName": "TypeScript", "noServerFound": "路徑 {0} 未指向有效的 tsserver 安裝。將停用 TypeScript 語言功能。", "serverCouldNotBeStarted": "無法啟動 TypeScript 語言伺服器。錯誤訊息為: {0}", - "serverDied": "Typescript 語言服務在過去 5 分鐘內意外中止 5 次。請考慮開啟問題報告。", - "serverDiedAfterStart": "Typescript 語言服務在啟動後立即中止 5 次。服務將不會重新啟動。請開啟問題報告。", + "serverDied": "TypeScript 語言服務在過去 5 分鐘內意外中止 5 次。請考慮開啟問題報告。", + "serverDiedAfterStart": "TypeScript 語言服務在啟動後立即中止 5 次。服務將不會重新啟動。請開啟問題報告。", "versionNumber.custom": "自訂" } \ No newline at end of file diff --git a/i18n/cht/extensions/typescript/package.i18n.json b/i18n/cht/extensions/typescript/package.i18n.json index 8c3044e1f43..125e405bb48 100644 --- a/i18n/cht/extensions/typescript/package.i18n.json +++ b/i18n/cht/extensions/typescript/package.i18n.json @@ -18,6 +18,7 @@ "javascript.validate.enable": "啟用 / 停用 JavaScript 驗證", "typescript.reloadProjects.title": "重新載入 TypeScript 專案", "typescript.tsdk.desc": "指定資料夾路徑,其中包含要使用的 tsserver 和 lib*.d.ts 檔案。", + "typescript.tsserver.experimentalAutoBuild": "啟用實驗性自動建置。需要 1.9 dev 或 2.x tsserver 版本,且在變更後必須重新啟動 VS Code。", "typescript.tsserver.trace": "允許追蹤傳送到 TS 伺服器的訊息", "typescript.useCodeSnippetsOnMethodSuggest.dec": "使用其參數簽章完成函式。", "typescript.validate.enable": "啟用 / 停用 TypeScript 驗證" diff --git a/i18n/cht/src/vs/code/electron-main/menus.i18n.json b/i18n/cht/src/vs/code/electron-main/menus.i18n.json index 9fc4b2764a9..44ad469c5d8 100644 --- a/i18n/cht/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/cht/src/vs/code/electron-main/menus.i18n.json @@ -35,6 +35,9 @@ "miExit": "結束(&&X)", "miFind": "尋找(&&F)", "miFindInFiles": "在檔案中尋找(&&I)", + "miFocusFirstGroup": "左側群組(&&L)", + "miFocusSecondGroup": "側邊群組(&&S)", + "miFocusThirdGroup": "右側群組(&&R)", "miForward": "轉寄(&&F)", "miGotoDefinition": "移至定義(&&D)", "miGotoFile": "移至檔案(&&F)...", @@ -43,11 +46,13 @@ "miInstallingUpdate": "正在安裝更新...", "miLastCheckedAt": "上次檢查時間為 {0}", "miLicense": "檢視授權(&&V)", - "miMarker": "錯誤與警告(&&E)...", + "miMarker": "問題(&&P)", "miMoveSidebar": "移動提要欄位(&&M)", - "miNavigateHistory": "巡覽歷程記錄(&&N)", "miNewFile": "新增檔案(&&N)", "miNewWindow": "開新視窗(&&N)", + "miNextEditor": "下一個編輯器(&&N)", + "miNextEditorInGroup": "群組中下一個已使用的編輯器(&&N)", + "miNextGroup": "下一個群組(&&N)", "miOpen": "開啟(&&O)...", "miOpenFile": "開啟檔案(&&O)...", "miOpenFolder": "開啟資料夾(&&F)...", @@ -58,11 +63,14 @@ "miOpenWorkspaceSettings": "工作區設定(&&W)", "miPaste": "貼上(&&P)", "miPreferences": "喜好設定(&&P)", + "miPreviousEditor": "上一個編輯器(&&P)", + "miPreviousEditorInGroup": "群組中上一個已使用的編輯器(&&P)", + "miPreviousGroup": "上一個群組(&&P)", "miPrivacyStatement": "隱私權聲明(&&P)", "miQuit": "結束 {0}", "miRedo": "取消復原(&&R)", "miReleaseNotes": "版本資訊(&&R)", - "miReopenClosedFile": "重新開啟已關閉的檔案(&&R)", + "miReopenClosedEditor": "重新開啟已關閉的編輯器(&&R)", "miReplace": "取代(&&R)", "miReportIssues": "回報問題(&&I)", "miRestartToUpdate": "重新啟動以更新...", @@ -73,14 +81,18 @@ "miSelectAll": "全選(&&S)", "miSelectTheme": "色彩佈景主題(&&C)", "miSplitEditor": "分割編輯器(&&E)", - "miToggleDebugConsole": "切換偵錯主控台(&&B)", + "miSwitchEditor": "切換編輯器(&&E)", + "miSwitchGroup": "切換群組(&&G)", + "miToggleDebugConsole": "偵錯主控台(&&B)", "miToggleDevTools": "切換開發人員工具(&&T)", "miToggleFullScreen": "切換全螢幕(&&F)", + "miToggleIntegratedTerminal": "整合式終端機(&&I)", "miToggleMenuBar": "切換功能表列(&&B)", - "miToggleOutput": "切換輸出(&&O)", + "miToggleOutput": "輸出(&&O)", "miTogglePanel": "切換面板(&&P)", "miToggleRenderWhitespace": "切換轉譯空白字元(&&R)", "miToggleSidebar": "切換提要欄位(&&T)", + "miToggleStatusbar": "切換狀態列(&&T)", "miToggleWordWrap": "切換自動換行(&&W)", "miTwitter": "加入我們的 Twitter(&&J)", "miUndo": "復原(&&U)", @@ -91,5 +103,6 @@ "miViewSearch": "搜尋(&&S)", "miZoomIn": "放大(&&Z)", "miZoomOut": "縮小(&&U)", + "miZoomReset": "重設縮放(&&R)", "okButton": "確定" } \ No newline at end of file diff --git a/i18n/cht/src/vs/code/node/cliProcessMain.i18n.json b/i18n/cht/src/vs/code/node/cliProcessMain.i18n.json index a5001eff675..4b3cf88ae8e 100644 --- a/i18n/cht/src/vs/code/node/cliProcessMain.i18n.json +++ b/i18n/cht/src/vs/code/node/cliProcessMain.i18n.json @@ -12,5 +12,5 @@ "successInstall": "已成功安裝擴充功能 '{0}' v{1}!", "successUninstall": "已成功將擴充功能 '{0}' 解除安裝!", "uninstalling": "正在將 {0} 解除安裝...", - "useId": "請確定您使用完整的擴充功能識別碼,例如: {0}" + "useId": "請確定您使用完整的擴充功能識別碼,例如 {0}" } \ 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 b334ef07e9c..9965d0e6ffa 100644 --- a/i18n/cht/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/cht/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -9,7 +9,6 @@ "cursorBlinking": "控制游標閃爍動畫,接受的值為 'blink'、'visible' 和 'hidden'", "cursorStyle": "控制游標樣式,接受的值為 'block' 和 'line'", "detectIndentation": "開啟檔案時,會依據檔案內容來偵測 `editor.tabSize` 及 `editor.insertSpaces`。", - "dismissPeekOnEsc": "按下 ESC 時關閉預覽編輯器", "editorConfigurationTitle": "編輯器組態", "folding": "控制編輯器是否已啟用程式碼摺疊功能", "fontFamily": "控制字型家族。", @@ -25,6 +24,7 @@ "lineNumbers": "控制是否顯示行號", "mouseWheelScrollSensitivity": "滑鼠滾輪捲動事件的 'deltaX' 與 'deltaY' 所使用的乘數", "overviewRulerLanes": "控制可在概觀尺規中相同位置顯示的裝飾項目數", + "parameterHints": "啟用參數提示", "quickSuggestions": "控制輸入時是否應顯示快速建議", "quickSuggestionsDelay": "控制延遲顯示快速建議的毫秒數", "referenceInfos": "控制編輯器是否會顯示支援編輯器的模式之參考資訊", @@ -35,6 +35,7 @@ "selectionClipboard": "控制是否應支援 Linux 主要剪貼簿。", "selectionHighlight": "控制編輯器是否應反白顯示與選取範圍相似的符合項", "sideBySide": "控制 Diff 編輯器要並排或內嵌顯示差異", + "stablePeek": "讓預覽編輯器在使用者按兩下其內容或點擊 Escape 時保持開啟。", "suggestOnTriggerCharacters": "控制輸入觸發字元時,是否應自動顯示建議", "tabSize": "與 Tab 相等的空格數量。", "tabSize.errorMessage": "必須是 'number'。請注意,值 \"auto\" 已由 `editor.detectIndentation` 設定取代。", diff --git a/i18n/cht/src/vs/editor/contrib/folding/browser/folding.i18n.json b/i18n/cht/src/vs/editor/contrib/folding/browser/folding.i18n.json index 5e59d7e0d59..b096890c8f4 100644 --- a/i18n/cht/src/vs/editor/contrib/folding/browser/folding.i18n.json +++ b/i18n/cht/src/vs/editor/contrib/folding/browser/folding.i18n.json @@ -11,6 +11,8 @@ "foldLevel3Action.label": "摺疊層級 3", "foldLevel4Action.label": "摺疊層級 4", "foldLevel5Action.label": "摺疊層級 5", + "foldRecursivelyAction.label": "以遞迴方式摺疊", + "unFoldRecursivelyAction.label": "以遞迴方式展開", "unfoldAction.label": "展開", "unfoldAllAction.label": "全部展開" } \ No newline at end of file diff --git a/i18n/cht/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json b/i18n/cht/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json index ebcab48dcbd..cf4980e59f4 100644 --- a/i18n/cht/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json +++ b/i18n/cht/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json @@ -7,5 +7,7 @@ "markerAction.next.label": "移至下一個錯誤或警告", "markerAction.previous.label": "移至上一個錯誤或警告", "quickfix.multiple.label": "建議的修正程式: ", - "quickfix.single.label": "建議的修正程式: " + "quickfix.single.label": "建議的修正程式: ", + "title.w_source": "({0}/{1}) [{2}]", + "title.wo_source": "({0}/{1})" } \ No newline at end of file diff --git a/i18n/cht/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/cht/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index ec9ecdcd760..c97781b6e48 100644 --- a/i18n/cht/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/cht/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "正在載入...", "meta.titleReference": " - {0} 個參考", - "noResults": "沒有結果", "references.action.label": "尋找所有參考", - "references.action.name": "顯示參考" + "references.action.name": "尋找所有參考" } \ No newline at end of file diff --git a/i18n/cht/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json b/i18n/cht/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json index abf7f689894..8f8535c14bc 100644 --- a/i18n/cht/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json +++ b/i18n/cht/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json @@ -8,5 +8,6 @@ "peekView.alternateTitle": "參考", "referenceCount": "{0} 個參考", "referencesCount": "{0} 個參考", + "referencesFailre": "無法解析檔案。", "treeAriaLabel": "參考" } \ No newline at end of file diff --git a/i18n/cht/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/cht/src/vs/editor/node/textMate/TMSyntax.i18n.json index f5358de39e3..46fac1bfe93 100644 --- a/i18n/cht/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/cht/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -4,11 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "invalid.injectTo": "`contributes.{0}.injectTo` 中的值無效。必須是語言範圍名稱的陣列。提供的值: {1}", "invalid.language": "`contributes.{0}.language` 中的不明語言。提供的值: {1}", "invalid.path.0": "`contributes.{0}.path` 中的預期字串。提供的值: {1}", "invalid.path.1": "要包含在擴充功能資料夾 ({2}) 中的預期 `contributes.{0}.path` ({1})。這可能會使擴充功能無法移植。", "invalid.scopeName": "`contributes.{0}.scopeName` 中的預期字串。提供的值: {1}", "vscode.extension.contributes.grammars": "提供 textmate 權杖化工具。", + "vscode.extension.contributes.grammars.injectTo": "要插入此文法的語言範圍名稱清單。", "vscode.extension.contributes.grammars.language": "要予以提供此語法的語言識別碼。", "vscode.extension.contributes.grammars.path": "tmLanguage 檔案的路徑。此路徑是擴充功能資料夾的相對路徑,而且一般會以 './syntaxes/' 開頭。", "vscode.extension.contributes.grammars.scopeName": "tmLanguage 檔案所使用的 textmate 範圍名稱。" diff --git a/i18n/cht/src/vs/languages/html/common/html.contribution.i18n.json b/i18n/cht/src/vs/languages/html/common/html.contribution.i18n.json index eb82b369bef..53caeaa40e7 100644 --- a/i18n/cht/src/vs/languages/html/common/html.contribution.i18n.json +++ b/i18n/cht/src/vs/languages/html/common/html.contribution.i18n.json @@ -10,7 +10,7 @@ "format.indentInnerHtml": "縮排 及 區段。", "format.maxPreserveNewLines": "一個區塊要保留的最大分行符號數。使用 'null' 表示無限制。", "format.preserveNewLines": "是否應保留項目前方現有的分行符號。僅適用於項目前方,而不適用於標記內或文字。", - "format.unformatted": "不應重新格式化的標記清單,須以逗號分隔。'null' 的預設值為所有內嵌標記。", + "format.unformatted": "不應重新格式化的逗號分隔標記清單。'null' 預設為 https://www.w3.org/TR/html5/dom.html#phrasing-content 中列出的所有標記。", "format.wrapLineLength": "每行的字元數上限 (0 = 停用)。", "htmlConfigurationTitle": "HTML 設定" } \ 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 c310dc38d67..d0b192b0aa4 100644 --- a/i18n/cht/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/cht/src/vs/workbench/electron-browser/actions.i18n.json @@ -15,7 +15,8 @@ "newWindow": "開新視窗", "noFolderOpened": "此執行個體中目前沒有開啟的資料夾可以關閉。", "openRecent": "開啟最近的檔案", - "openRecentPlaceHolder": "選取要開啟的路徑", + "openRecentPlaceHolder": "選取要開啟的路徑 (按住 Ctrl 鍵以在新視窗開啟)", + "openRecentPlaceHolderMac": "選取路徑 (按住 Cmd 鍵以在新視窗開啟)", "reloadWindow": "重新載入視窗", "toggleDevTools": "切換開發人員工具", "toggleFullScreen": "切換全螢幕", 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 b556360ae6e..04108fe7327 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 @@ -8,7 +8,8 @@ "file": "檔案", "openFilesInNewWindow": "啟用時,會在新視窗中開啟檔案,而不是重複使用現有的執行個體。", "reopenFolders": "控制重新啟動後重新開啟資料夾的方式。選取 [none] 永不重新開啟資料夾,選取 [one] 重新開啟最近一個使用的資料夾,或選取 [all] 重新開啟上一個工作階段的所有資料夾。", - "updateChannel": "設定要從中接收更新的更新頻道。變更後需要重新啟動。", + "restoreFullscreen": "控制當視窗在全螢幕模式下結束後,下次是否仍以全螢幕模式開啟。", + "updateChannel": "設定是否要從更新頻道接收自動更新。變更後需要重新啟動。", "updateConfigurationTitle": "更新組態", "view": "檢視", "windowConfigurationTitle": "視窗組態", diff --git a/i18n/cht/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json index fd6e656a80f..1c85395ea24 100644 --- a/i18n/cht/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json @@ -8,8 +8,8 @@ "conditionalBreakpointEditorAction": "偵錯: 條件式中斷點", "debug": "偵錯", "debugCategory": "偵錯", - "debugConsole": "偵錯主控台", "debugEvaluate": "偵錯: 評估", + "launchConfigDoesNotExist": "啟動設定 '{0}' 不存在。", "runToCursor": "偵錯: 執行至游標處", "showDebugHover": "偵錯: 動態顯示", "toggleBreakpointAction": "偵錯: 切換中斷點", diff --git a/i18n/cht/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json b/i18n/cht/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json index 578e10b59c0..27ede2f7d4c 100644 --- a/i18n/cht/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json @@ -6,10 +6,12 @@ { "DebugTaskNotFound": "找不到 preLaunchTask '{0}'。", "NewLaunchConfig": "請為您的應用程式設定啟動組態檔。", + "breakpointAdded": "已新增中斷點,行 {0},檔案 {1}", + "breakpointRemoved": "已移除中斷點,行 {0},檔案 {1}", "debugAdapterCrash": "偵錯配接器處理序已意外終止", "debugAnyway": "仍要偵錯", "debugSourceNotAvailable": "來源 {0} 無法使用。", - "debugTypeMissing": "在 launch.json 中遺漏選取組態的屬性 'type'。", + "debugTypeMissing": "遺漏所選啟動設定的屬性 'type'。", "debugTypeNotSupported": "不支援設定的偵錯類型 '{0}'。", "debuggingContinued": "偵錯已繼續。", "debuggingPaused": "偵錯已暫停,原因 {0},{1} {2}", diff --git a/i18n/cht/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json b/i18n/cht/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json index cdb48b5bf91..ff79c8c7c2d 100644 --- a/i18n/cht/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "debugLinuxConfiguration": "Linux 特定的啟動設定屬性。", "debugName": "組態的名稱; 出現在啟動組態下拉式功能表中。", + "debugOSXConfiguration": "OS X 特定的啟動設定屬性。", "debugPrelaunchTask": "偵錯工作階段啟動前要執行的工作。", "debugRequest": "要求組態的類型。可以是 [啟動] 或 [附加]。", "debugType": "組態的類型。", + "debugWindowsConfiguration": "Windows 特定的啟動設定屬性。", "internalConsoleOptions": "內部偵錯主控台的控制項行為。", "relativePathsNotConverted": "相對路徑將不再自動轉換成絕對路徑。請考慮使用 ${workspaceRoot} 作為前置詞。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/cht/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index c4b8eb835af..af72d206bd2 100644 --- a/i18n/cht/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -10,6 +10,7 @@ "app.launch.json.version": "此檔案格式的版本。", "debugNoType": "偵錯配接器 'type' 不能省略且必須屬於 'string' 類型。", "duplicateDebuggerType": "偵錯類型 '{0}' 已註冊並具有屬性 '{1}',即將略過屬性 '{1}'。", + "interactiveVariableNotFound": "配接器 {0} 未參與在啟動設定中指定的變數 {1}。", "selectDebug": "選取環境", "vscode.extension.contributes.debuggers": "提供偵錯配接器。", "vscode.extension.contributes.debuggers.args": "要傳遞至配接器的選擇性引數。", @@ -26,6 +27,7 @@ "vscode.extension.contributes.debuggers.runtime": "程式屬性不是可執行檔但需要執行階段時的選擇性執行階段。", "vscode.extension.contributes.debuggers.runtimeArgs": "選擇性執行階段引數。", "vscode.extension.contributes.debuggers.type": "此偵錯配接器的唯一識別碼。", + "vscode.extension.contributes.debuggers.variables": "從 `launch.json` 中的互動式變數 (例如 ${action.pickProcess}) 對應到命令。", "vscode.extension.contributes.debuggers.windows": "Windows 特定設定。", "vscode.extension.contributes.debuggers.windows.runtime": "用於 Windows 的執行階段。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index 9354ce37b36..f3e379d9c0d 100644 --- a/i18n/cht/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,8 @@ "globalConsoleActionWin": "開啟新的命令提示字元", "scopedConsoleActionMacLinux": "在終端機中開啟", "scopedConsoleActionWin": "在命令提示字元中開啟", + "terminal.external.linuxExec": "自訂要在 Linux 上執行的終端機。", + "terminal.external.osxExec": "自訂要在 OS X 上執行的終端機應用程式。", "terminal.external.windowsExec": "自訂要在 Windows 上執行的終端機。", "terminalConfigurationTitle": "外部終端機組態" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index 6b00807cd58..198e43e7691 100644 --- a/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "關閉", "deleteSure": "確定要解除安裝 '{0}' 嗎?", - "installExtension": "安裝擴充功能", - "notFound": "擴充功能 '{0}' 未安裝。", + "enableAction": "啟用", + "installAction": "安裝", + "installing": "正在安裝", + "restart": "為了啟用此擴充功能,必須重新啟動此 VS Code 視窗。\n\n要繼續嗎?", "restartNow": "立即重新啟動", - "restartNow2": "立即重新啟動", "showExtensionRecommendations": "顯示擴充功能建議", "showInstalledExtensions": "顯示安裝的擴充功能", "showOutdatedExtensions": "顯示過期的擴充功能", - "success-installed": "已成功安裝 '{0}'。請重新啟動加以啟用。", - "success-uninstalled": "已成功解除安裝 '{0}'。請重新啟動加以停用。", - "uninstall": "解除安裝擴充功能" + "toggleExtensionsViewlet": "顯示擴充功能", + "uninstall": "解除安裝", + "updateAction": "更新" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json b/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json index 844f00e0bfb..423f0b88b70 100644 --- a/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json @@ -5,6 +5,7 @@ // Do not edit this file. It is machine generated. { "extensions": "延伸模組", + "outdatedExtensions": "{0} 過期的擴充功能", "reloadNow": "立即重新啟動", "success": "已成功安裝擴充功能。請重新啟動加以啟用。", "successSingle": "已成功安裝 {0}。請重新啟動加以啟用。" diff --git a/i18n/cht/src/vs/workbench/parts/files/browser/fileActions.i18n.json b/i18n/cht/src/vs/workbench/parts/files/browser/fileActions.i18n.json index 8b4406c3bcc..5bccb620b24 100644 --- a/i18n/cht/src/vs/workbench/parts/files/browser/fileActions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/browser/fileActions.i18n.json @@ -4,13 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "addToWorkingFiles": "將使用中的檔案加入工作檔案中", - "closeAllFiles": "關閉所有檔案", - "closeAllLabel": "關閉所有檔案", - "closeFile": "關閉檔案", - "closeLabel": "關閉檔案", - "closeOtherFiles": "關閉其他檔案", - "closeOtherLabel": "關閉其他檔案", + "collapseExplorerFolders": "摺疊 Explorer 中的資料夾", "compareFiles": "比較檔案", "compareSource": "選取用以比較", "compareWith": "與 '{0}' 比較", @@ -31,7 +25,7 @@ "fileNameExistsError": "這個位置已存在檔案或資料夾 **{0}**。請選擇不同的名稱。", "filePathTooLongError": "名稱 **{0}** 導致路徑太長。請選擇較短的名稱。", "focusFilesExplorer": "將焦點設在檔案總管上", - "focusWorkingFiles": "將焦點放在工作檔案上", + "focusOpenEditors": "聚焦在 [開啟編輯器] 檢視", "globalCompareFile": "使用中檔案的比較對象...", "importFiles": "匯入檔案", "invalidFileNameError": "名稱 **{0}** 不能作為檔案或資料夾名稱。請選擇不同的名稱。", @@ -39,25 +33,21 @@ "newFile": "新增檔案", "newFolder": "新增資料夾", "newUntitledFile": "新增無標題檔案", - "noFileOpen": "目前沒有開啟的檔案可以關閉。", - "noWorkingFiles": "目前沒有工作檔案。", - "openFileToAdd": "先開啟檔案以將其加入工作檔案中", "openFileToCompare": "先開啟檔案以與其他檔案進行比較", "openFileToShow": "先開啟檔案,以在總管中加以顯示", "openFolderFirst": "先開啟資料夾,以在其中建立檔案或資料夾。", - "openNextWorkingFile": "開啟下一個工作檔案", - "openPreviousWorkingFile": "開啟上一個工作檔案", "openToSide": "開至側邊", "pasteFile": "貼上", "permDelete": "永久刪除", "refresh": "重新整理", + "refreshExplorer": "重新整理 Explorer", "rename": "重新命名", - "reopenClosedFile": "重新開啟已關閉的檔案", "replaceButtonLabel": "取代(&&R)", "retry": "重試", "revert": "還原檔案", "save": "儲存", "saveAll": "全部儲存", + "saveAllInGroup": "全部儲存在群組中", "saveAs": "另存新檔...", "saveFiles": "儲存已變更的檔案", "showInExplorer": "在總管中顯示使用中的檔案", diff --git a/i18n/cht/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index 461ff07e1c8..bd9a1fa5a02 100644 --- a/i18n/cht/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -9,7 +9,7 @@ "autoSave": "控制已變更檔案的自動儲存功能。接受的值: \"{0}\"、\"{1}\"、\"{2}\"。如果設定為 \"{3}\",您可以在 \"files.autoSaveDelay\" 中設定延遲時間。", "autoSaveDelay": "控制經過這段延遲時間後會自動儲存已變更檔案的毫秒數。僅適用於 \"files.autoSave\" 設定為 \"{0}\" 時。", "binaryFileEditor": "二進位檔案編輯器", - "dynamicHeight": "控制工作檔案區段的高度是否應依項目數動態調整。", + "dynamicHeight": "控制 [開啟編輯器] 區段的高度是否應依元素數目動態調整。", "encoding": "讀取與寫入檔案時要使用的預設字元集編碼。", "eol": "預設行尾字元。", "exclude": "設定 Glob 模式可包含檔案及資料夾。", @@ -17,14 +17,11 @@ "explorerConfigurationTitle": "檔案總管組態", "files.exclude.boolean": "要符合檔案路徑的 Glob 模式。設為 True 或 False 可啟用或停用模式。", "files.exclude.when": "在相符檔案同層級上額外的檢查。請使用 $(basename) 作為相符檔案名稱的變數。", - "filesCategory": "檔案", "filesConfigurationTitle": "檔案組態", - "maxVisible": "在捲軸出現前可顯示的工作檔案數目上限。", - "openWorkingFile": "開啟工作檔案 (依名稱)", + "openEditorsVisible": "[開啟編輯器] 窗格中顯示的編輯器數目。將其設定為 0 以隱藏窗格。", "showExplorerViewlet": "顯示檔案總管", "textFileEditor": "文字檔編輯器", "trimTrailingWhitespace": "若啟用,將在您儲存檔案時修剪尾端空白。", "view": "檢視", - "watcherExclude": "將檔案路徑的 Glob 模式設定為從檔案監控排除。需要重新啟動才能變更此設定。當您發現 Code 在啟動時使用大量 CPU 時間時,可以排除較大的資料夾以降低初始負載。", - "workingFilesPicker": "開啟工作檔案 (依名稱)" + "watcherExclude": "將檔案路徑的 Glob 模式設定為從檔案監控排除。需要重新啟動才能變更此設定。當您發現 Code 在啟動時使用大量 CPU 時間時,可以排除較大的資料夾以降低初始負載。" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/cht/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index 291ec2e34e6..6a34d3ff696 100644 --- a/i18n/cht/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "使用本機變更並覆寫磁碟內容", + "acceptLocalChanges": "覆寫", "compareChanges": "比較", "conflictingFileHasChanged": "磁碟上的檔案內容已變更,而且已重新整理比較編輯器左側。請重新檢閱並加以解決。", "discard": "捨棄", @@ -13,8 +13,8 @@ "readonlySaveError": "無法儲存 '{0}': 檔案有防寫保護。請選取 [覆寫] 以移除保護。", "resolveSaveConflict": "{0} - 解決儲存衝突", "retry": "重試", - "revertLocalChanges": "捨棄本機變更並還原成磁碟上的內容", + "revertLocalChanges": "還原", "saveConflictDiffLabel": "{0} - 磁碟上 ↔ {1} 中", "staleSaveError": "無法儲存 '{0}': 磁碟上的內容較新。請按一下 [比較],比較您的版本與磁碟上的版本。", - "userGuide": "使用編輯器工具列中的動作來「復原」您的變更,或以您的變更「覆寫」磁碟上的內容" + "userGuide": "請選取 [還原] 捨棄您的變更;或選取 [覆寫],以您的變更取代磁碟上的內容" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json index a12bfcf9197..00e45959b13 100644 --- a/i18n/cht/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json @@ -9,5 +9,8 @@ "openFile": "開啟檔案", "openInEditor": "切換至編輯器檢視", "stageSelectedLines": "將選取的行分段", - "switchToChangesView": "切換至變更檢視" + "switchToChangesView": "切換至變更檢視", + "unstageSelectedLines": "取消分段選取的資料行", + "workbenchStage": "分段", + "workbenchUnstage": "取消分段" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/git/browser/gitActions.i18n.json b/i18n/cht/src/vs/workbench/parts/git/browser/gitActions.i18n.json index 2b6e7be1ea2..d0ce51ae58e 100644 --- a/i18n/cht/src/vs/workbench/parts/git/browser/gitActions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/git/browser/gitActions.i18n.json @@ -5,13 +5,11 @@ // Do not edit this file. It is machine generated. { "authFailed": "Git 遠端的驗證失敗。", - "branch": "Branch", - "branch2": "Branch", - "checkout": "Checkout", "cleanChangesLabel": "清除變更(&&C)", "commit": "Commit", "commitAll": "全部認可", "commitAll2": "全部認可", + "commitMessage": "認可訊息", "commitStaged": "認可已分段", "commitStaged2": "認可已分段", "confirmPublishMessage": "確定要將 '{0}' 發行至 '{1}' 嗎?", @@ -36,13 +34,9 @@ "openFile": "開啟檔案", "publish": "發行", "publishPickMessage": "挑選要發行分支 '{0}' 的目標遠端:", - "pull": "Pull", - "pullWithRebase": "提取 (重訂基底)", - "push": "Push", "refresh": "重新整理", "stageAllChanges": "全部分段", "stageChanges": "分段", - "sync": "同步處理", "synchronizing": "正在同步處理...", "undoAllChanges": "全部清除", "undoChanges": "清除", diff --git a/i18n/cht/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json b/i18n/cht/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json index d814e7bc2d8..6c4d4b76d97 100644 --- a/i18n/cht/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json @@ -7,6 +7,7 @@ "alreadyCheckedOut": "分支 {0} 已是目前的分支", "branchAriaLabel": "{0},Git 分支", "checkoutBranch": "位於 {0} 的分支", + "checkoutRemoteBranch": "位於 {0} 的遠端分支", "checkoutTag": "位於 {0} 的標記", "createBranch": "建立分支 {0}", "noBranches": "沒有其他分支", diff --git a/i18n/cht/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/cht/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 4cbe4c71114..50782c60c49 100644 --- a/i18n/cht/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -8,17 +8,23 @@ "cancel": "取消", "cantOpen": "無法開啟這個 Git 資源。", "cantOpenResource": "無法開啟這個 Git 資源。", - "changesFromIndex": "{0} - 索引上的變更", - "changesFromTree": "{0} - {1} 上的變更", + "changesFromIndex": "{0} (索引)", + "changesFromIndexDesc": "{0} - 索引上的變更", + "changesFromTree": "{0} ({1})", + "changesFromTreeDesc": "{0} - {1} 上的變更", "checkNativeConsole": "執行 Git 作業時發生問題。請檢閱輸出或使用主控台來查看儲存機制的狀態。", "configureUsernameEmail": "請設定您的 Git 使用者名稱及電子郵件。", "download": "下載", - "gitIndexChanges": "{0} - 索引上的變更", - "gitIndexChangesRenamed": "{0} - 已重新命名 - 索引的變更", - "gitMergeChanges": "{0} - 合併變更", + "gitIndexChanges": "{0} (索引) ↔ {1}", + "gitIndexChangesDesc": "{0} - 索引上的變更", + "gitIndexChangesRenamed": "{0} ← {1}", + "gitIndexChangesRenamedDesc": "{0} - 已重新命名 - 索引上的變更", + "gitMergeChanges": "{0} (合併) ↔ {1}", + "gitMergeChangesDesc": "{0} - 合併變更", "neverShowAgain": "不要再顯示", "showOutput": "顯示輸出", "unmergedChanges": "您在認可變更前應先解決未合併的變更。", "updateGit": "您似乎已經安裝 GIT {0}。Code 搭配 GIT >=2.0.0 的成效最佳。", - "workingTreeChanges": "{0} - 工作樹狀目錄上的變更" + "workingTreeChanges": "{0} (HEAD) ↔ {1}", + "workingTreeChangesDesc": "{0} - 工作樹狀上的變更" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/cht/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index 16068277681..f290598e652 100644 --- a/i18n/cht/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -9,6 +9,8 @@ "gitCommands": "Git 命令", "gitConfigurationTitle": "Git 組態", "gitEnabled": "已啟用 Git", + "gitLargeRepos": "一律允許 Code 管理大型儲存機制。", + "gitLongCommit": "是否對長認可訊息發出警告。", "gitPath": "Git 可執行檔的路徑", "gitPendingChangesBadge": "{0} 個暫止的變更", "gitProgressBadge": "正在執行 Git 狀態", diff --git a/i18n/cht/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json b/i18n/cht/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json index 139fb753892..a5d4be1ee87 100644 --- a/i18n/cht/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json @@ -6,6 +6,7 @@ { "commitMessage": "訊息 (按 {0} 認可)", "commitMessageAriaLabel": "Git: 輸入認可訊息並按 {0} 認可", + "longCommit": "建議讓認可訊息的第一行文字少於 50 個字元。但您可在額外的資訊中使用多行文字。", "needMessage": "請提供認可訊息。您可以隨時按下 **[{0}]** 來認可變更。如有任何已分段的變更,將只有那些分段的變更會獲得認可,否則,所有變更都會獲得認可。", "nothingToCommit": "一旦有些變更要進行認可,請在認可訊息中輸入,或者按下 **[{0}]** 來認可變更。如有任何已分段的變更,將只有那些分段的變更會獲得認可,否則,所有變更都會獲得認可。", "showOutput": "顯示 Git 輸出", diff --git a/i18n/cht/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/cht/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index a211c562a34..6d29fd92155 100644 --- a/i18n/cht/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0}: {1}", "QuickCommandsAction.label": "顯示編輯器命令", "actionNotEnabled": "目前內容中未啟用命令 '{0}'。", "canNotRun": "無法從這裡執行命令 '{0}'。", diff --git a/i18n/cht/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/cht/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index 5988f14155d..3b8ed4cbcaf 100644 --- a/i18n/cht/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,26 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "清除搜尋結果", - "CollapseAllAction.label": "摺疊", - "ConfigureGlobalExclusionsAction.label": "開啟設定", - "RefreshAction.label": "重新整理", - "RemoveAction.label": "移除", - "SelectOrRemoveAction.removeLabel": "移除", - "SelectOrRemoveAction.selectLabel": "選取", "ariaSearchResultsStatus": "搜尋傳回 {1} 個檔案中的 {0} 個結果", - "defaultLabel": "輸入", - "fileMatchAriaLabel": "資料夾 {2} 檔案 {1} 中的 {0} 個相符的記錄,搜尋結果", - "findInFolder": "在資料夾中尋找", - "findPlaceHolder": "按 Enter 鍵搜尋或按 Esc 鍵取消", "globLabel": "當 {1} 時為 {0}", "global.searchScope.folders": "透過設定所排除的檔案", - "label.Search": "搜尋: 輸入搜尋字詞,然後按 Enter 鍵搜尋或按 Esc 鍵取消", "label.excludes": "搜尋排除模式", "label.global.excludes": "設定的搜尋排除模式", "label.includes": "搜尋包含模式", "moreSearch": "切換搜尋詳細資料", - "noMatches": "沒有相符項目", "noResultsExcludes": "找不到排除 '{0}' 的結果 - ", "noResultsFound": "找不到結果。請檢閱所設定排除的設定 - ", "noResultsIncludes": "在 '{0}' 中找不到結果 - ", "noResultsIncludesExcludes": "在 '{0}' 中找不到排除 '{1}' 的結果 - ", "openSettings.message": "開啟設定", - "patternDescription": "使用 Glob 模式", - "patternHelpInclude": "要比對的模式。例如 ****/*.js** 可比對所有 JavaScript 檔案,或 **myFolder/**** 可比對資料夾和所有子系。\n\n**參考**:\n***** 比對 0 或多個字元\n**?** 比對 1 個字元\n****** 比對 0 或多個目錄\n**[a-z]** 比對某個範圍的字元\n**{a,b}** 比對任何模式)", - "regexp.validationFailure": "運算式符合所有項目", + "replaceAll.confirm.button": "取代", + "replaceAll.confirmation.message": "要將 {1} 個檔案中的 {0} 個相符項目取代為 '{2}' 嗎?", + "replaceAll.confirmation.title": "全部取代", + "replaceAll.message": "已將取代 {1} 個檔案中的 {0} 個相符項目取代為 {2}。", "rerunSearch.message": "再次搜尋", "rerunSearchInAll.message": "在所有檔案中再次搜尋", "searchCanceled": "在可能找到任何結果之前已取消搜尋 - ", - "searchMatch": "找到 {0} 個符合項", - "searchMatches": "找到 {0} 個符合項", "searchMaxResultsWarning": "結果集只包含所有符合項的子集。請提供更具體的搜尋條件以縮小結果範圍。", - "searchResultAria": "{0},搜尋結果", "searchScope.excludes": "要排除的檔案", "searchScope.includes": "要包含的檔案", "treeAriaLabel": "搜尋結果" diff --git a/i18n/cht/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json b/i18n/cht/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json index 68a103c04b4..c8b367b2dfe 100644 --- a/i18n/cht/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json +++ b/i18n/cht/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json @@ -5,7 +5,10 @@ // Do not edit this file. It is machine generated. { "close": "關閉", + "insiderBuilds": "測試人員組建將成為每日組建!", "license": "閱讀授權", "licenseChanged": "授權條款已有所變更,請仔細閱讀。", + "neverShowAgain": "不要再顯示", + "readmore": "閱讀其他資訊", "releaseNotes": "歡迎使用 {0} v{1}! 您要閱讀版本資訊嗎?" } \ No newline at end of file diff --git a/i18n/cht/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/cht/src/vs/workbench/services/history/browser/history.i18n.json index 221f1a736ec..f0259a675cc 100644 --- a/i18n/cht/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/cht/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[擴充功能開發主機] - {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} - {1}", "prefixWorkspaceTitle": "{0} - {1} - {2}", "prefixWorkspaceTitleMac": "{0} - {1}", diff --git a/i18n/deu/extensions/php/package.i18n.json b/i18n/deu/extensions/php/package.i18n.json index 6d333fcd1e0..410e1e7b2f3 100644 --- a/i18n/deu/extensions/php/package.i18n.json +++ b/i18n/deu/extensions/php/package.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "configuration.title": "PHP-Konfigurationsoptionen", + "configuration.title": "PHP", "configuration.validate.enable": "Gibt an, ob PHP-Überprüfung aktiviert ist.", "configuration.validate.executablePath": "Zeigt auf die ausführbare PHP-Datei.", "configuration.validate.run": "Gibt an, ob der Linter beim Speichern oder bei der Eingabe ausgeführt wird." diff --git a/i18n/deu/extensions/typescript/package.i18n.json b/i18n/deu/extensions/typescript/package.i18n.json index 85a51eebe1b..643e14ce7cb 100644 --- a/i18n/deu/extensions/typescript/package.i18n.json +++ b/i18n/deu/extensions/typescript/package.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "configuration.typescript": "TypeScript-Konfiguration", + "configuration.typescript": "TypeScript", "format.insertSpaceAfterCommaDelimiter": "Definiert die Verarbeitung von Leerzeichen nach einem Kommatrennzeichen.", "format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": "Definiert die Verarbeitung von Leerzeichen nach einem Funktionsschlüsselwort für anonyme Funktionen.", "format.insertSpaceAfterKeywordsInControlFlowStatements": "Definiert die Verarbeitung von Leerzeichen nach Schlüsselwörtern in einer Flusssteuerungsanweisung.", @@ -18,6 +18,7 @@ "javascript.validate.enable": "JavaScript-Überprüfung aktivieren/deaktivieren", "typescript.reloadProjects.title": "TypeScript-Projekt erneut laden", "typescript.tsdk.desc": "Gibt den Ordnerpfad mit den zu verwendenden tsserver- und lib*.d.ts-Dateien an.", + "typescript.tsserver.experimentalAutoBuild": "Ermöglicht experimentelle automatische Buildvorgänge. Erfordert Version 1.9 dev oder 2.x tsserver sowie einen Neustart von VS Code nach der Änderung.", "typescript.tsserver.trace": "Aktiviert die Nachverfolgung von an den TS-Server gesendeten Nachrichten.", "typescript.useCodeSnippetsOnMethodSuggest.dec": "Vervollständigen Sie Funktionen mit deren Parametersignatur.", "typescript.validate.enable": "TypeScript-Überprüfung aktivieren/deaktivieren" diff --git a/i18n/deu/src/vs/code/electron-main/menus.i18n.json b/i18n/deu/src/vs/code/electron-main/menus.i18n.json index e6978b4353c..c9ca0c4f2eb 100644 --- a/i18n/deu/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/deu/src/vs/code/electron-main/menus.i18n.json @@ -35,6 +35,9 @@ "miExit": "&&Beenden", "miFind": "&&Suchen", "miFindInFiles": "&&In Dateien suchen", + "miFocusFirstGroup": "&&Linke Gruppe", + "miFocusSecondGroup": "&&Seitliche Gruppe", + "miFocusThirdGroup": "&&Rechte Gruppe", "miForward": "&&Weiterleiten", "miGotoDefinition": "Gehe &&zu Definition", "miGotoFile": "Gehe zu &&Datei...", @@ -43,11 +46,13 @@ "miInstallingUpdate": "Update wird installiert...", "miLastCheckedAt": "Zuletzt überprüft am {0}", "miLicense": "&&Lizenz anzeigen", - "miMarker": "&&Fehler und Warnungen...", + "miMarker": "&&Probleme", "miMoveSidebar": "&&Randleiste verschieben", - "miNavigateHistory": "&&Im Verlauf navigieren", "miNewFile": "&&Neue Datei", "miNewWindow": "&&Neues Fenster", + "miNextEditor": "&&Nächster Editor", + "miNextEditorInGroup": "&&Nächster verwendeter Editor in der Gruppe", + "miNextGroup": "&&Nächste Gruppe", "miOpen": "&&Öffnen...", "miOpenFile": "&&Datei öffnen...", "miOpenFolder": "&&Ordner öffnen...", @@ -58,12 +63,16 @@ "miOpenWorkspaceSettings": "&&Arbeitsbereichseinstellungen", "miPaste": "&&Einfügen", "miPreferences": "&&Einstellungen", + "miPreviousEditor": "&&Vorheriger Editor", + "miPreviousEditorInGroup": "&&Zuvor verwendeter Editor in der Gruppe", + "miPreviousGroup": "&&Vorherige Gruppe", "miPrivacyStatement": "&&Datenschutzerklärung", "miQuit": "{0} beenden", "miRedo": "&&Wiederholen", "miReleaseNotes": "&&Anmerkungen zu dieser Version", - "miReopenClosedFile": "&&Geschlossene Datei erneut öffnen", + "miReopenClosedEditor": "&&Geschlossenen Editor erneut öffnen", "miReplace": "&&Ersetzen", + "miReplaceInFiles": "&&In Dateien ersetzen", "miReportIssues": "&&Probleme melden", "miRestartToUpdate": "Für Update neu starten...", "miRevert": "D&&atei wiederherstellen", @@ -73,23 +82,30 @@ "miSelectAll": "&&Alles auswählen", "miSelectTheme": "&&Farbdesign", "miSplitEditor": "&&Editor teilen", - "miToggleDebugConsole": "De&&bugkonsole umschalten", + "miSwitchEditor": "&&Editor wechseln", + "miSwitchGroup": "&&Gruppe wechseln", + "miToggleDebugConsole": "De&&bugkonsole", "miToggleDevTools": "&&Entwicklungstools umschalten", "miToggleFullScreen": "&&Vollbild umschalten", + "miToggleIntegratedTerminal": "&&Integriertes Terminal", "miToggleMenuBar": "Men&&üleiste umschalten", - "miToggleOutput": "&&Ausgabe umschalten", + "miToggleOutput": "&&Ausgabe", "miTogglePanel": "&&Bereich umschalten", + "miToggleRenderControlCharacters": "&&Steuerzeichen umschalten", "miToggleRenderWhitespace": "&&Rendern von Leerzeichen umschalten", "miToggleSidebar": "&&Randleiste umschalten", + "miToggleStatusbar": "&&Statusleiste umschalten", "miToggleWordWrap": "&&Zeilenumbruch umschalten", "miTwitter": "&&Twitter", "miUndo": "&&Rückgängig", "miUserVoice": "&&Features anfordern", "miViewDebug": "&&Debuggen", "miViewExplorer": "&&Explorer", + "miViewExtensions": "E&&xtensions", "miViewGit": "&&Git", "miViewSearch": "&&Suchen", "miZoomIn": "&&Vergrößern", "miZoomOut": "Ver&&kleinern", + "miZoomReset": "&&Zoom zurücksetzen", "okButton": "OK" } \ 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 a625f4551a6..c0e33819ea8 100644 --- a/i18n/deu/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/deu/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -9,8 +9,7 @@ "cursorBlinking": "Steuert das Blinken der Cursoranimation. Gültige Werte sind \"blink\", \"visible\" und \"hidden\".", "cursorStyle": "Steuert den Cursorstil. Gültige Werte sind \"block\" und \"line\".", "detectIndentation": "Beim Öffnen einer Datei werden \"editor.tabSize\" und \"editor.insertSpaces\" basierend auf den Dateiinhalten erkannt.", - "dismissPeekOnEsc": "Vorschau-Editor beim Drücken von ESC schließen", - "editorConfigurationTitle": "Editor-Konfiguration", + "editorConfigurationTitle": "Editor", "folding": "Steuert, ob für den Editor Codefaltung aktiviert ist.", "fontFamily": "Steuert die Schriftfamilie.", "fontLigatures": "Aktiviert Schriftartligaturen.", @@ -25,9 +24,12 @@ "lineNumbers": "Steuert die Sichtbarkeit der Zeilennummern.", "mouseWheelScrollSensitivity": "Ein Multiplikator, der für die Mausrad-Bildlaufereignisse \"deltaX\" und \"deltaY\" verwendet werden soll.", "overviewRulerLanes": "Steuert die Anzahl von Dekorationen, die an derselben Position im Übersichtslineal angezeigt werden.", + "parameterHints": "Aktiviert Parameterhinweise.", "quickSuggestions": "Steuert, ob Schnellvorschläge während der Eingabe angezeigt werden.", "quickSuggestionsDelay": "Steuert die Verzögerung in ms für die Anzeige der Schnellvorschläge.", "referenceInfos": "Steuert, ob der Editor Verweisinformationen zu den Modi anzeigt, die dies unterstützen.", + "renderControlCharacters": "Steuert, ob der Editor Steuerzeichen rendern soll.", + "renderIndentGuides": "Steuert, ob der Editor Einzugsführungslinien rendern soll.", "renderWhitespace": "Steuert, ob der Editor Leerzeichen rendert.", "roundedSelection": "Steuert, ob die Auswahl runde Ecken aufweist.", "rulers": "Spalten, an denen vertikale Lineale angezeigt werden sollen", @@ -35,6 +37,7 @@ "selectionClipboard": "Steuert, ob die primäre Linux-Zwischenablage unterstützt werden soll.", "selectionHighlight": "Steuert, ob der Editor der Auswahl ähnelnde Übereinstimmungen hervorheben soll.", "sideBySide": "Steuert, ob der Diff-Editor das Diff nebeneinander oder inline anzeigt.", + "stablePeek": "Vorschau-Editoren geöffnet lassen, auch wenn auf ihren Inhalt doppelgeklickt oder die ESC-TASTE gedrückt wird.", "suggestOnTriggerCharacters": "Steuert, ob Vorschläge automatisch bei der Eingabe von Triggerzeichen angezeigt werden.", "tabSize": "Die Anzahl der Leerzeichen, denen ein Tabstopp entspricht.", "tabSize.errorMessage": "\"number\" wurde erwartet. Beachten Sie, dass der Wert \"auto\" durch die Einstellung \"editor.detectIndentation\" ersetzt wurde.", diff --git a/i18n/deu/src/vs/editor/contrib/folding/browser/folding.i18n.json b/i18n/deu/src/vs/editor/contrib/folding/browser/folding.i18n.json index e4ee8ae996e..871784885ae 100644 --- a/i18n/deu/src/vs/editor/contrib/folding/browser/folding.i18n.json +++ b/i18n/deu/src/vs/editor/contrib/folding/browser/folding.i18n.json @@ -11,6 +11,8 @@ "foldLevel3Action.label": "Faltebene 3", "foldLevel4Action.label": "Faltebene 4", "foldLevel5Action.label": "Faltebene 5", + "foldRecursivelyAction.label": "Rekursiv falten", + "unFoldRecursivelyAction.label": "Faltung rekursiv aufheben", "unfoldAction.label": "Auffalten", "unfoldAllAction.label": "Alle auffalten" } \ No newline at end of file diff --git a/i18n/deu/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json b/i18n/deu/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json index 7838a8ee7a5..dd35e067461 100644 --- a/i18n/deu/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json +++ b/i18n/deu/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json @@ -7,5 +7,7 @@ "markerAction.next.label": "Gehe zum nächsten Fehler oder zur nächsten Warnung", "markerAction.previous.label": "Gehe zum vorherigen Fehler oder zur vorherigen Warnung", "quickfix.multiple.label": "Empfohlene Fehlerbehebungen: ", - "quickfix.single.label": "Empfohlene Fehlerbehebung: " + "quickfix.single.label": "Empfohlene Fehlerbehebung: ", + "title.w_source": "({0}/{1}) [{2}]", + "title.wo_source": "({0}/{1})" } \ No newline at end of file diff --git a/i18n/deu/src/vs/editor/contrib/indentation/common/indentation.i18n.json b/i18n/deu/src/vs/editor/contrib/indentation/common/indentation.i18n.json index a7350ab553e..3ee3e1e38f0 100644 --- a/i18n/deu/src/vs/editor/contrib/indentation/common/indentation.i18n.json +++ b/i18n/deu/src/vs/editor/contrib/indentation/common/indentation.i18n.json @@ -11,5 +11,6 @@ "indentationToSpaces": "Einzug in Leerzeichen konvertieren", "indentationToTabs": "Einzug in Tabstopps konvertieren", "selectTabWidth": "Tabulatorgröße für aktuelle Datei auswählen", + "toggleRenderControlCharacters": "Steuerzeichen umschalten", "toggleRenderWhitespace": "Rendern von Leerzeichen umschalten" } \ No newline at end of file diff --git a/i18n/deu/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/deu/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index 612beac1c3f..1c17a9d16aa 100644 --- a/i18n/deu/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/deu/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "Wird geladen...", "meta.titleReference": " – {0} Verweise", - "noResults": "Keine Ergebnisse", "references.action.label": "Alle Verweise suchen", - "references.action.name": "Verweise anzeigen" + "references.action.name": "Alle Verweise suchen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json b/i18n/deu/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json index c17a2553e99..3e0e6f81c83 100644 --- a/i18n/deu/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json +++ b/i18n/deu/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json @@ -9,5 +9,6 @@ "peekView.alternateTitle": "Verweise", "referenceCount": "{0} Verweis", "referencesCount": "{0} Verweise", + "referencesFailre": "Fehler beim Auflösen der Datei.", "treeAriaLabel": "Verweise" } \ No newline at end of file diff --git a/i18n/deu/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/deu/src/vs/editor/node/textMate/TMSyntax.i18n.json index 9092748f571..2561753b38b 100644 --- a/i18n/deu/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/deu/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -4,11 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "invalid.injectTo": "Ungültiger Wert in \"contributes.{0}.injectTo\". Es muss sich um ein Array von Sprachbereichsnamen handeln. Bereitgestellter Wert: {1}", "invalid.language": "Unbekannte Sprache in \"contributes.{0}.language\". Bereitgestellter Wert: {1}", "invalid.path.0": "In \"contributes.{0}.path\" wurde eine Zeichenfolge erwartet. Bereitgestellter Wert: {1}", "invalid.path.1": "Es wurde erwartet, dass \"contributes.{0}.path\" ({1}) im Ordner ({2}) der Extension enthalten ist. Dies führt ggf. dazu, dass die Extension nicht portierbar ist.", "invalid.scopeName": "In \"contributes.{0}.scopeName\" wurde eine Zeichenfolge erwartet. Bereitgestellter Wert: {1}", "vscode.extension.contributes.grammars": "Trägt TextMate-Tokenizer bei.", + "vscode.extension.contributes.grammars.injectTo": "Die Liste der Sprachbereichsnamen, in die diese Grammatik injiziert wird.", "vscode.extension.contributes.grammars.language": "Der Sprachbezeichner, für den diese Syntax beigetragen wird.", "vscode.extension.contributes.grammars.path": "Der Pfad der tmLanguage-Datei. Der Pfad ist relativ zum Extensionordner und beginnt normalerweise mit \". /syntaxes/\".", "vscode.extension.contributes.grammars.scopeName": "Der TextMate-Bereichsname, der von der tmLanguage-Datei verwendet wird." diff --git a/i18n/deu/src/vs/languages/html/common/html.contribution.i18n.json b/i18n/deu/src/vs/languages/html/common/html.contribution.i18n.json index 478a00796d1..dc30caa18b1 100644 --- a/i18n/deu/src/vs/languages/html/common/html.contribution.i18n.json +++ b/i18n/deu/src/vs/languages/html/common/html.contribution.i18n.json @@ -10,7 +10,7 @@ "format.indentInnerHtml": "Nimmt einen Einzug für - und -Abschnitte vor.", "format.maxPreserveNewLines": "Die maximale Anzahl von Zeilenumbrüchen, die in einem Block beibehalten werden soll. Verwenden Sie \"null\" für eine unbegrenzte Anzahl.", "format.preserveNewLines": "Gibt an, ob vorhandene Zeilenumbrüche vor Elemente beibehalten werden sollen. Funktioniert nur vor Elementen, nicht in Tags oder für Text.", - "format.unformatted": "Die Liste der Tags (durch Kommas getrennt), die nicht erneut formatiert werden sollen. \"null\" bezieht sich standardmäßig auf alle Inlinetags.", + "format.unformatted": "Die Liste der Tags (durch Kommas getrennt), die nicht erneut formatiert werden sollen. \"null\" bezieht sich standardmäßig auf alle Tags, die unter https://www.w3.org/TR/html5/dom.html#phrasing-content aufgeführt werden.", "format.wrapLineLength": "Die maximale Anzahl von Zeichen pro Zeile (0 = deaktiviert).", - "htmlConfigurationTitle": "HTML-Konfiguration" + "htmlConfigurationTitle": "HTML" } \ 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 2d8ab469cda..00201a51d18 100644 --- a/i18n/deu/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/deu/src/vs/workbench/electron-browser/actions.i18n.json @@ -15,7 +15,8 @@ "newWindow": "Neues Fenster", "noFolderOpened": "Zurzeit ist kein Ordner in dieser Instanz geöffnet, der geschlossen werden kann.", "openRecent": "Zuletzt verwendete öffnen", - "openRecentPlaceHolder": "Wählen Sie einen zu öffnenden Pfad aus.", + "openRecentPlaceHolder": "Wählen Sie einen zu öffnenden Pfad aus (halten Sie STRG gedrückt, um ein neues Fenster zu öffnen).", + "openRecentPlaceHolderMac": "Wählen Sie einen Pfad aus (halten Sie die BEFEHLSTASTE gedrückt, um ein neues Fenster zu öffnen).", "reloadWindow": "Fenster erneut laden", "toggleDevTools": "Entwicklertools umschalten", "toggleFullScreen": "Vollbild umschalten", 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 45bfef5f82b..d139cc876f2 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 @@ -8,9 +8,10 @@ "file": "Datei", "openFilesInNewWindow": "Wenn diese Option aktiviert ist, werden Dateien in einem neuen Fenster geöffnet anstatt eine vorhandene Instanz wiederzuverwenden.", "reopenFolders": "Steuert, wie Ordner nach einem Neustart erneut geöffnet werden. Wählen Sie \"none\" aus, um Ordner nie erneut zu öffnen, \"one\", um den zuletzt bearbeiteten Ordner erneut zu öffnen, oder \"all\", um alle Ordner der letzten Sitzung erneut zu öffnen.", - "updateChannel": "Konfiguriert den Updatekanal, aus dem Updates empfangen werden. Erfordert einen Neustart nach der Änderung.", - "updateConfigurationTitle": "Konfiguration aktualisieren", + "restoreFullscreen": "Steuert, ob ein Fenster im Vollbildmodus wiederhergestellt wird, wenn es im Vollbildmodus beendet wurde.", + "updateChannel": "Konfiguriert, ob automatische Updates aus einem Updatekanal empfangen werden sollen. Erfordert einen Neustart nach der Änderung.", + "updateConfigurationTitle": "Update", "view": "Anzeigen", - "windowConfigurationTitle": "Fensterkonfiguration", + "windowConfigurationTitle": "Fenster", "zoomLevel": "Passen Sie den Zoomfaktor des Fensters an. Die ursprüngliche Größe ist 0. Jede Inkrementierung nach oben (z. B. 1) oder unten (z. B. -1) stellt eine Vergrößerung bzw. Verkleinerung um 20 % dar. Sie können auch Dezimalwerte eingeben, um den Zoomfaktor genauer anzupassen." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json index 254fc098318..96e7ccf3028 100644 --- a/i18n/deu/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json @@ -10,6 +10,7 @@ "debugCategory": "Debuggen", "debugEvaluate": "Debuggen: Auswerten", "debugPanel": "Debugkonsole", + "launchConfigDoesNotExist": "Die Startkonfiguration \"{0}\" ist nicht vorhanden.", "runToCursor": "Debuggen: Ausführen bis Cursor", "showDebugHover": "Debuggen: Hover anzeigen", "toggleBreakpointAction": "Debuggen: Haltepunkt umschalten", diff --git a/i18n/deu/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json b/i18n/deu/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json index c0ffa96f75c..4771b6321bd 100644 --- a/i18n/deu/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json @@ -6,10 +6,12 @@ { "DebugTaskNotFound": "Der preLaunchTask \"{0}\" wurde nicht gefunden.", "NewLaunchConfig": "Bitte richten Sie die Startkonfigurationsdatei für Ihre Anwendung ein.", + "breakpointAdded": "Der Haltepunkt wurde hinzugefügt. Zeile {0}, Datei \"{1}\".", + "breakpointRemoved": "Der Haltepunkt wurde entfernt. Zeile {0}, Datei \"{1}\".", "debugAdapterCrash": "Der Debugadapterprozess wurde unerwartet beendet.", "debugAnyway": "Trotzdem debuggen", "debugSourceNotAvailable": "Die Quelle {0} ist nicht verfügbar.", - "debugTypeMissing": "Fehlende Eigenschaft \"type\" für die ausgewählte Konfiguration in \"launch.json\".", + "debugTypeMissing": "Fehlende Eigenschaft \"type\" für die ausgewählte Startkonfiguration.", "debugTypeNotSupported": "Der konfigurierte Debugtyp \"{0}\" wird nicht unterstützt.", "debuggingContinued": "Das Debuggen wurde fortgesetzt.", "debuggingPaused": "Das Debuggen wurde angehalten. Ursache {0}, {1}{2}", diff --git a/i18n/deu/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json b/i18n/deu/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json index b48a29092fc..c6d03109a2c 100644 --- a/i18n/deu/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "debugLinuxConfiguration": "Linux-spezifische Startkonfigurationsattribute.", "debugName": "Der Name der Konfiguration. Er wird im Dropdownmenü der Startkonfiguration angezeigt.", + "debugOSXConfiguration": "OS X-spezifische Startkonfigurationsattribute.", "debugPrelaunchTask": "Ein Task, der ausgeführt werden soll, bevor die Debugsitzung beginnt.", "debugRequest": "Der Anforderungstyp der Konfiguration. Der Wert kann \"launch\" oder \"attach\" sein.", "debugType": "Der Typ der Konfiguration.", + "debugWindowsConfiguration": "Windows-spezifische Startkonfigurationsattribute.", "internalConsoleOptions": "Steuert das Verhalten der internen Debugkonsole.", "relativePathsNotConverted": "Relative Pfade werden nicht mehr automatisch in absolute Pfade konvertiert. Verwenden Sie ggf. ${workspaceRoot} als Präfix." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/deu/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index f9f38184afb..2d059e98099 100644 --- a/i18n/deu/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -6,10 +6,11 @@ { "DebugConfig.failed": "Die Datei \"launch.json\" kann nicht im Ordner \".vscode\" erstellt werden ({0}).", "app.launch.json.configurations": "Die Liste der Konfigurationen. Fügen Sie neue Konfigurationen hinzu, oder bearbeiten Sie vorhandene Konfigurationen.", - "app.launch.json.title": "Startkonfiguration", + "app.launch.json.title": "Starten", "app.launch.json.version": "Die Version dieses Dateiformats.", "debugNoType": "Der \"type\" des Debugadapters kann nicht ausgelassen werden und muss vom Typ \"string\" sein.", "duplicateDebuggerType": "Der Debugtyp \"{0}\" ist bereits registriert und weist das Attribut \"{1}\" auf. Das Attribut \"{1}\" wird ignoriert.", + "interactiveVariableNotFound": "Der Adapter {0} trägt nicht die Variable \"{1}\" bei, die in der Startkonfiguration angegeben ist.", "selectDebug": "Umgebung auswählen", "vscode.extension.contributes.debuggers": "Trägt Debugadapter bei.", "vscode.extension.contributes.debuggers.args": "Optionale Argumente, die an den Adapter übergeben werden sollen.", @@ -26,6 +27,7 @@ "vscode.extension.contributes.debuggers.runtime": "Optionale Laufzeit für den Fall, dass das Programmattribut keine ausführbare Datei ist und eine Laufzeit erfordert.", "vscode.extension.contributes.debuggers.runtimeArgs": "Optionale Laufzeitargumente.", "vscode.extension.contributes.debuggers.type": "Der eindeutige Bezeichner für diese Debugadapter.", + "vscode.extension.contributes.debuggers.variables": "Eine Zuordnung von interaktiven Variablen (z. B. \"${action.pickProcess}\") in \"launch.json\" zu einem Befehl.", "vscode.extension.contributes.debuggers.windows": "Windows-spezifische Einstellungen.", "vscode.extension.contributes.debuggers.windows.runtime": "Die für Windows verwendete Laufzeit." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json index cdbef6a807f..c2b0f6c4ee2 100644 --- a/i18n/deu/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "emmetConfigurationTitle": "Emmet-Konfiguration", - "expandAbbreviationAction": "Emmet: Abkürzung erweitern", + "emmetConfigurationTitle": "Emmet", + "emmetPreferences": "Einstellungen, die zum Ändern des Verhaltens einiger Aktionen und Konfliktlöser von Emmet verwendet werden.", + "emmetSyntaxProfiles": "Definieren Sie das Profil für die angegebene Syntax, oder verwenden Sie Ihr eigenes Profil mit bestimmten Regeln.", "triggerExpansionOnTab": "Wenn aktiviert, werden Emmet-Abkürzungen beim Drücken der TAB-TASTE erweitert." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index 57f9b98eae6..b6e24062da3 100644 --- a/i18n/deu/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,8 @@ "globalConsoleActionWin": "Neue Eingabeaufforderung öffnen", "scopedConsoleActionMacLinux": "In Terminal öffnen", "scopedConsoleActionWin": "In Eingabeaufforderung öffnen", + "terminal.external.linuxExec": "Passt an, welches Terminal unter Linux ausgeführt werden soll.", + "terminal.external.osxExec": "Passt an, welche Terminalanwendung unter OS X ausgeführt werden soll.", "terminal.external.windowsExec": "Passt an, welches Terminal für Windows ausgeführt werden soll.", - "terminalConfigurationTitle": "Externe Terminalkonfiguration" + "terminalConfigurationTitle": "Externes Terminal" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index a1d60c41e22..4dba5e45639 100644 --- a/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,20 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "Schließen", + "clearExtensionsInput": "Extensioneingabe löschen", "deleteSure": "Möchten Sie \"{0}\" deinstallieren?", - "installExtension": "Extension installieren", - "notFound": "Die Extension \"{0}\" ist nicht installiert.", + "enableAction": "Aktivieren", + "installAction": "Installieren", + "installExtensions": "Extensions installieren", + "installing": "Wird installiert.", + "postUninstallMessage": "{0} wurde erfolgreich deinstalliert. Führen Sie zur Deaktivierung einen Neustart aus.", + "restart": "Damit diese Extension aktiviert wird, muss dieses Fenster von VS Code neu gestartet werden.\n\nMöchten Sie fortfahren?", "restartNow": "Jetzt neu starten", - "restartNow2": "Jetzt neu starten", "showExtensionRecommendations": "Extensionempfehlungen anzeigen", "showInstalledExtensions": "Installierte Extensions anzeigen", "showOutdatedExtensions": "Veraltete Extensions anzeigen", - "success-installed": "{0} wurde erfolgreich installiert. Führen Sie zur Aktivierung einen Neustart aus.", - "success-uninstalled": "{0} wurde erfolgreich deinstalliert. Führen Sie zur Deaktivierung einen Neustart aus.", - "uninstall": "Extension deinstallieren" + "showPopularExtensions": "Beliebte Extensions anzeigen", + "toggleExtensionsViewlet": "Extensions anzeigen", + "uninstall": "Deinstallieren", + "updateAction": "Aktualisieren" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.i18n.json b/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.i18n.json index faf47802b3e..0b0f9f710c0 100644 --- a/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.i18n.json @@ -4,26 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "author": "Autor", - "cancel": "Abbrechen", - "description": "Beschreibung", - "extensionAriaLabel": "{0}, {1}, Extensionauswahl", - "galleryExtensionsHandlerAriaLabel": "Nehmen Sie eine Eingabe vor, um die Liste der Extensions aus dem Katalog einzuschränken.", - "install": "Extension installieren", - "installCountMultiple": "{0} wurde {1} Mal heruntergeladen.", - "installCountOne": "{0} wurde ein Mal heruntergeladen.", - "installCountZero": "{0} wurde nicht noch heruntergeladen.", - "installNow": "Jetzt installieren", - "installPrompt": "Möchten Sie \"{0}\" installieren?", - "license": "Lizenz", - "localExtensionsHandlerAriaLabel": "Nehmen Sie eine Eingabe vor, um die Liste der installierten Extensions einzuschränken.", - "name": "Name", - "noExtensionsInstalled": "Es wurden keine Extensions gefunden.", - "noExtensionsToInstall": "Es wurden keine Extensions gefunden.", - "noOutdatedExtensions": "Es wurden keine veralteten Extensions gefunden.", - "noRecommendedExtensions": "Keine empfohlenen Extensions", - "nowInstalling": "{0} wird installiert...", - "outdatedExtensionsHandlerAriaLabel": "Nehmen Sie eine Eingabe vor, um die Liste der veralteten Extensions einzuschränken.", - "readme": "Infodatei", - "update": "Extension aktualisieren" + "manage": "Drücken Sie die EINGABETASTE, um Ihre Extensions zu verwalten.", + "noExtensionsToInstall": "Geben Sie einen Extensionnamen ein.", + "searchFor": "Drücken Sie die EINGABETASTE, um nach \"{0}\" in Marketplace zu suchen." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json b/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json index a28c01c4ee4..3e06abd1b19 100644 --- a/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json @@ -5,6 +5,7 @@ // Do not edit this file. It is machine generated. { "extensions": "Extensions", + "outdatedExtensions": "{0} veraltete Extensions", "reloadNow": "Jetzt neu starten", "success": "Extensions wurden erfolgreich installiert. Führen Sie einen Neustart aus, um sie zu aktivieren.", "successSingle": "{0} wurde erfolgreich installiert. Führen Sie zur Aktivierung einen Neustart aus." diff --git a/i18n/deu/src/vs/workbench/parts/files/browser/fileActions.i18n.json b/i18n/deu/src/vs/workbench/parts/files/browser/fileActions.i18n.json index c31ab192289..8225bb78e5a 100644 --- a/i18n/deu/src/vs/workbench/parts/files/browser/fileActions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/browser/fileActions.i18n.json @@ -4,13 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "addToWorkingFiles": "Aktive Datei den Arbeitsdateien hinzufügen", - "closeAllFiles": "Alle Dateien schließen", - "closeAllLabel": "Alle Dateien schließen", - "closeFile": "Datei schließen", - "closeLabel": "Datei schließen", - "closeOtherFiles": "Andere Dateien schließen", - "closeOtherLabel": "Andere Dateien schließen", + "collapseExplorerFolders": "Ordner im Explorer zuklappen", "compareFiles": "Dateien vergleichen", "compareSource": "Für Vergleich auswählen", "compareWith": "Mit '{0}' vergleichen", @@ -31,7 +25,7 @@ "fileNameExistsError": "Eine Datei oder ein Ordner **{0}** ist an diesem Ort bereits vorhanden. Wählen Sie einen anderen Namen.", "filePathTooLongError": "Der Name **{0}** führt zu einem Pfad, der zu lang ist. Wählen Sie einen kürzeren Namen.", "focusFilesExplorer": "Fokus auf Datei-Explorer", - "focusWorkingFiles": "Fokus auf Arbeitsdateien", + "focusOpenEditors": "Fokus auf Ansicht \"Geöffnete Editoren\"", "globalCompareFile": "Aktive Datei vergleichen mit...", "importFiles": "Dateien importieren", "invalidFileNameError": "Der Name **{0}** ist als Datei- oder Ordnername ungültig. Bitte wählen Sie einen anderen Namen aus.", @@ -39,25 +33,21 @@ "newFile": "Neue Datei", "newFolder": "Neuer Ordner", "newUntitledFile": "Neue unbenannte Datei", - "noFileOpen": "Zurzeit ist keine Datei geöffnet, die geschlossen werden kann.", - "noWorkingFiles": "Zurzeit sind keine Arbeitsdateien vorhanden.", - "openFileToAdd": "Zuerst eine Datei öffnen, um diese den Arbeitsdateien hinzuzufügen", "openFileToCompare": "Zuerst eine Datei öffnen, um diese mit einer anderen Datei zu vergleichen", "openFileToShow": "Öffnet zuerst eine Datei, um sie im Explorer anzuzeigen.", "openFolderFirst": "Öffnet zuerst einen Ordner, in dem Dateien oder Ordner erstellt werden.", - "openNextWorkingFile": "Nächste Arbeitsdatei öffnen", - "openPreviousWorkingFile": "Vorherige Arbeitsdatei öffnen", "openToSide": "Zur Seite öffnen", "pasteFile": "Einfügen", "permDelete": "Endgültig löschen", "refresh": "Aktualisieren", + "refreshExplorer": "Explorer aktualisieren", "rename": "Umbenennen", - "reopenClosedFile": "Geschlossene Datei erneut öffnen", "replaceButtonLabel": "&&Ersetzen", "retry": "Wiederholen", "revert": "Datei wiederherstellen", "save": "Speichern", "saveAll": "Alle speichern", + "saveAllInGroup": "Alle in der Gruppe speichern", "saveAs": "Speichern unter...", "saveFiles": "Geänderte Dateien speichern", "showInExplorer": "Aktive Datei im Explorer anzeigen", diff --git a/i18n/deu/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index 787abfd6684..e1bfeb974b0 100644 --- a/i18n/deu/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -9,22 +9,19 @@ "autoSave": "Steuert die automatische Speicherung geänderter Dateien. Zulässige Werte: \"{0}\", \"{1}\", \"{2}\". Wenn diese Angabe auf \"{3}\" festgelegt ist, können Sie die Verzögerung in \"files.autoSaveDelay\" konfigurieren.", "autoSaveDelay": "Steuert die Verzögerung in Millisekunden, nach der eine geänderte Datei automatisch gespeichert wird. Nur gültig, wenn \"files.autoSave\" auf \"{0}\" festgelegt ist.", "binaryFileEditor": "Binärdatei-Editor", - "dynamicHeight": "Steuert, ob sich die Höhe des Arbeitsdateienabschnitts dynamisch an die Anzahl der Elemente anpassen soll.", + "dynamicHeight": "Steuert, ob sich die Höhe des Abschnitts \"Geöffnete Editoren\" dynamisch an die Anzahl der Elemente anpassen soll.", "encoding": "Die Standardzeichensatz-Codierung, die beim Lesen und Schreiben von Dateien verwendet werden soll.", "eol": "Das Zeilenende-Standardzeichen.", "exclude": "Konfiguriert die Globmuster zum Ausschließen von Dateien und Ordnern.", "explore": "Explorer", - "explorerConfigurationTitle": "Datei-Explorer-Konfiguration", + "explorerConfigurationTitle": "Datei-Explorer", "files.exclude.boolean": "Das Globmuster, mit dem Dateipfade verglichen werden sollen. Legen Sie diesen Wert auf \"true\" oder \"false\" fest, um das Muster zu aktivieren bzw. zu deaktivieren.", "files.exclude.when": "Zusätzliche Überprüfung der gleichgeordneten Elemente einer entsprechenden Datei. Verwenden Sie \"$(basename)\" als Variable für den entsprechenden Dateinamen.", - "filesCategory": "Dateien", - "filesConfigurationTitle": "Dateikonfiguration", - "maxVisible": "Die maximale Anzahl von Arbeitsdateien, die angezeigt werden, bevor Bildlaufleisten angezeigt werden.", - "openWorkingFile": "Arbeitsdatei nach Name öffnen", + "filesConfigurationTitle": "Dateien", + "openEditorsVisible": "Die Anzahl der Editoren, die im Bereich \"Geöffnete Editoren\" angezeigt werden. Legen Sie diesen Wert auf 0 fest, um den Bereich auszublenden.", "showExplorerViewlet": "Explorer anzeigen", "textFileEditor": "Textdatei-Editor", "trimTrailingWhitespace": "Wenn diese Option aktiviert ist, werden nachgestellte Leerzeichen beim Speichern einer Datei gekürzt.", "view": "Anzeigen", - "watcherExclude": "Konfigurieren Sie Globmuster von Dateipfaden, die aus der Dateiüberwachung ausgeschlossen werden sollen. Das Ändern dieser Einstellung erfordert einen Neustart. Wenn Ihr Code beim Starten viel CPU-Zeit benötigt, können Sie große Ordner ausschließen, um die Anfangslast zu verringern.", - "workingFilesPicker": "Arbeitsdatei nach Name öffnen" + "watcherExclude": "Konfigurieren Sie Globmuster von Dateipfaden, die aus der Dateiüberwachung ausgeschlossen werden sollen. Das Ändern dieser Einstellung erfordert einen Neustart. Wenn Ihr Code beim Starten viel CPU-Zeit benötigt, können Sie große Ordner ausschließen, um die Anfangslast zu verringern." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/deu/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index ff1e037629e..9bf3939a661 100644 --- a/i18n/deu/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "Lokale Änderungen verwenden und Datenträgerinhalte überschreiben", + "acceptLocalChanges": "Überschreiben", "compareChanges": "Vergleichen", "conflictingFileHasChanged": "Der Inhalt der Datei auf dem Datenträger hat sich geändert, und die linke Seite des Vergleichs-Editors wurde aktualisiert. Bitte überprüfen Sie die Datei, und lösen Sie Konflikte erneut auf.", "discard": "Verwerfen", @@ -13,8 +13,8 @@ "readonlySaveError": "Fehler beim Speichern von \"{0}\": Die Datei ist schreibgeschützt. Wählen Sie 'Überschreiben' aus, um den Schutz aufzuheben.", "resolveSaveConflict": "{0} – Speicherkonflikt auflösen", "retry": "Wiederholen", - "revertLocalChanges": "Lokale Änderungen verwerfen und Inhalt auf dem Datenträger wiederherstellen", + "revertLocalChanges": "Wiederherstellen", "saveConflictDiffLabel": "{0}– auf Datenträger ↔ in{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.", - "userGuide": "Verwenden Sie die Aktionen in der Editor-Symbolleiste, um Ihre Änderungen **rückgängig zu machen** oder den Inhalt auf dem Datenträger mit Ihren Änderungen zu **überschreiben**." + "userGuide": "Wählen Sie **Wiederherstellen** aus, um Ihre Änderungen zu verwerfen, oder **Überschreiben**, um den Inhalt auf dem Datenträger durch Ihre Änderungen zu ersetzen." } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/files/electron-browser/textFileServices.i18n.json b/i18n/deu/src/vs/workbench/parts/files/electron-browser/textFileServices.i18n.json index 47267ad9904..f1317f91b48 100644 --- a/i18n/deu/src/vs/workbench/parts/files/electron-browser/textFileServices.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/files/electron-browser/textFileServices.i18n.json @@ -7,9 +7,11 @@ "allFiles": "Alle Dateien", "cancel": "Abbrechen", "dontSave": "&&Nicht speichern", + "moreFile": "...1 weitere Datei wird nicht angezeigt", + "moreFiles": "...{0} weitere Dateien werden nicht angezeigt", "save": "&&Speichern", "saveAll": "&&Alle speichern", "saveChangesDetail": "Ihre Änderungen gehen verloren, wenn Sie diese nicht speichern.", "saveChangesMessage": "Möchten Sie die Änderungen speichern, die Sie an \"{0}\" vorgenommen haben?", - "saveChangesMessages": "Möchten Sie die an den folgenden Dateien vorgenommenen Änderungen speichern?" + "saveChangesMessages": "Möchten Sie die an den folgenden {0}-Dateien vorgenommenen Änderungen speichern?" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json index 0c8cf134e4f..91345426988 100644 --- a/i18n/deu/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json @@ -9,5 +9,8 @@ "openFile": "Datei öffnen", "openInEditor": "Zur Editor-Ansicht wechseln", "stageSelectedLines": "Ausgewählte Zeilen bereitstellen", - "switchToChangesView": "Zur Änderungsansicht wechseln" + "switchToChangesView": "Zur Änderungsansicht wechseln", + "unstageSelectedLines": "Bereitstellung ausgewählter Zeilen aufheben", + "workbenchStage": "Stufe", + "workbenchUnstage": "Bereitstellung aufheben" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/git/browser/gitActions.i18n.json b/i18n/deu/src/vs/workbench/parts/git/browser/gitActions.i18n.json index ea2f660f4e0..ee764403a42 100644 --- a/i18n/deu/src/vs/workbench/parts/git/browser/gitActions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/git/browser/gitActions.i18n.json @@ -5,13 +5,11 @@ // Do not edit this file. It is machine generated. { "authFailed": "Fehler bei der Authentifizierung für den Git-Remotespeicherort.", - "branch": "Branch", - "branch2": "Branch", - "checkout": "Checkout", "cleanChangesLabel": "&&Änderungen bereinigen", "commit": "Commit", "commitAll": "Commit für alle ausführen", "commitAll2": "Commit für alle ausführen", + "commitMessage": "Commit der Nachricht", "commitStaged": "Commit bereitgestellt", "commitStaged2": "Commit bereitgestellt", "confirmPublishMessage": "Möchten Sie \"{0}\" unter \"{1}\" veröffentlichen?", @@ -36,13 +34,9 @@ "openFile": "Datei öffnen", "publish": "Veröffentlichen", "publishPickMessage": "Remotespeicherort auswählen, an dem der Branch \"{0}\" veröffentlicht wird:", - "pull": "Pull", - "pullWithRebase": "Pull (Rebase)", - "push": "Push", "refresh": "Aktualisieren", "stageAllChanges": "Alle bereitstellen", "stageChanges": "Phase", - "sync": "Synchronisierung", "synchronizing": "Wird synchronisiert...", "undoAllChanges": "Alle bereinigen", "undoChanges": "Bereinigen", diff --git a/i18n/deu/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json b/i18n/deu/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json index 92aac5e703d..ab643c8b724 100644 --- a/i18n/deu/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json @@ -7,6 +7,7 @@ "alreadyCheckedOut": "Branch {0} ist bereits der aktuelle Branch.", "branchAriaLabel": "{0}, Git-Branch", "checkoutBranch": "Branch unter {0}", + "checkoutRemoteBranch": "Remotebranch unter {0}", "checkoutTag": "Tag bei {0}", "createBranch": "Branch {0} erstellen", "noBranches": "Keine anderen Branches", diff --git a/i18n/deu/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/deu/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 8f5c54dc5f5..3b54a79b727 100644 --- a/i18n/deu/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -8,17 +8,23 @@ "cancel": "Abbrechen", "cantOpen": "Diese Git-Ressource kann nicht geöffnet werden.", "cantOpenResource": "Diese Git-Ressource kann nicht geöffnet werden.", - "changesFromIndex": "{0} - Änderungen am Index", - "changesFromTree": "{0} - Änderungen in {1}", + "changesFromIndex": "{0} (Index)", + "changesFromIndexDesc": "{0} – Änderungen am Index", + "changesFromTree": "{0} ({1})", + "changesFromTreeDesc": "{0} – Änderungen in {1}", "checkNativeConsole": "Fehler beim Ausführen eines Git-Vorgangs. Bitte überprüfen Sie die Ausgabe, oder verwenden Sie eine Konsole, um den Repositorystatus zu überprüfen.", "configureUsernameEmail": "Konfigurieren Sie Ihren Git-Benutzernamen und Ihre E-Mail-Adresse.", "download": "Herunterladen", - "gitIndexChanges": "{0} - Änderungen am Index", - "gitIndexChangesRenamed": "{0} – Umbenannt – Änderungen für Index", - "gitMergeChanges": "{0} - Änderungen zusammenführen", + "gitIndexChanges": "{0} (Index) ↔ {1}", + "gitIndexChangesDesc": "{0} – Änderungen am Index", + "gitIndexChangesRenamed": "{0} ← {1}", + "gitIndexChangesRenamedDesc": "{0} – Umbenannt – Änderungen für Index", + "gitMergeChanges": "{0} (mergen) ↔ {1}", + "gitMergeChangesDesc": "{0} – Änderungen mergen", "neverShowAgain": "Nicht mehr anzeigen", "showOutput": "Ausgabe anzeigen", "unmergedChanges": "Sie müssen nicht zusammengeführte Änderungen lösen, bevor Sie Ihre Änderungen bestätigen.", "updateGit": "Git {0} scheint installiert zu sein. Code funktioniert am besten mit Git >= 2.0.0.", - "workingTreeChanges": "{0} - Änderungen an der Arbeitsstruktur" + "workingTreeChanges": "{0} (KOPF) ↔ {1}", + "workingTreeChangesDesc": "{0} – Änderungen am Arbeitsbaum" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/deu/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index 3eac93db0ab..1fd3ddc4a8b 100644 --- a/i18n/deu/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -7,8 +7,10 @@ "git": "Git", "gitAutoFetch": "Gibt an, ob automatischer Abruf aktiviert ist.", "gitCommands": "Git-Befehle", - "gitConfigurationTitle": "Git-Konfiguration", + "gitConfigurationTitle": "Git", "gitEnabled": "Ist für Git aktiviert", + "gitLargeRepos": "Die Verwaltung großer Repositorys durch Code immer zulassen.", + "gitLongCommit": "Gibt an, ob Warnungen zu langen Commitnachrichten erfolgen sollen.", "gitPath": "Der Pfad zur ausführbaren Git-Datei.", "gitPendingChangesBadge": "{0} ausstehende Änderungen", "gitProgressBadge": "Ausführungsstatus Git", diff --git a/i18n/deu/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json b/i18n/deu/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json index 3b962942283..bc39974545b 100644 --- a/i18n/deu/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json @@ -6,6 +6,7 @@ { "commitMessage": "Nachricht (drücken Sie {0}, um den Commit auszuführen)", "commitMessageAriaLabel": "Git: Geben Sie die Commitnachricht ein, und drücken Sie {0}, um den Commit auszuführen.", + "longCommit": "Es wird empfohlen, dass die erste Zeile des Commits weniger als 50 Zeichen lang ist. Sie können weitere Zeilen für zusätzliche Informationen verwenden.", "needMessage": "Geben Sie eine Commit-Meldung an. Sie können jederzeit **{0}** drücken, um einen Commit für die Änderungen auszuführen. Wenn bereitgestellte Änderungen vorliegen, wird nur für diese ein Commit ausgeführt; andernfalls für alle Änderungen.", "nothingToCommit": "Sobald Änderungen für einen Commit vorliegen, geben Sie die Commit-Meldung ein, und drücken Sie **{0}**, um den Commit für die Änderungen auszuführen. Wenn bereitgestellte Änderungen vorliegen, wird nur für diese ein Commit ausgeführt; andernfalls für alle Änderungen.", "showOutput": "Git-Ausgabe anzeigen", diff --git a/i18n/deu/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/deu/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index ee356b9d9b9..8eeee366f10 100644 --- a/i18n/deu/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0}: {1}", "QuickCommandsAction.label": "Editor-Befehle anzeigen", "actionNotEnabled": "Der Befehl \"{0}\" ist im aktuellen Kontext nicht aktiviert.", "canNotRun": "Der Befehl '{0}' kann nicht an dieser Stelle ausgeführt werden.", 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 4e7f0c45f31..8d68268b4ea 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 @@ -5,12 +5,9 @@ // Do not edit this file. It is machine generated. { "commandsHandlerDescriptionDefault": "Befehle anzeigen und ausführen", - "desc.mac": "Fehler oder Warnungen anzeigen", - "desc.win": "Fehler und Warnungen anzeigen", "gotoLineDescriptionMac": "Gehe zu Zeile", "gotoLineDescriptionWin": "Gehe zu Zeile", - "gotoSymbolDescriptionNormalMac": "Gehe zu Symbol", - "gotoSymbolDescriptionNormalWin": "Gehe zu Symbol", - "gotoSymbolDescriptionScoped": "Gehe zu Symbol nach Kategorie", + "gotoSymbolDescription": "Gehe zu Symbol in Datei", + "gotoSymbolDescriptionScoped": "Gehe zu Symbol in Datei nach Kategorie", "helpDescription": "Hilfe anzeigen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/search/browser/search.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/search/browser/search.contribution.i18n.json index 408423b440d..5aed8ca1514 100644 --- a/i18n/deu/src/vs/workbench/parts/search/browser/search.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/search/browser/search.contribution.i18n.json @@ -9,10 +9,9 @@ "exclude.when": "Zusätzliche Überprüfung der gleichgeordneten Elemente einer übereinstimmenden Datei. Verwenden Sie \"$(basename)\" als Variable für den übereinstimmenden Dateinamen.", "findInFolder": "In Ordner suchen", "name": "Suchen", - "openAnythingHandlerDescription": "Öffnet Dateien und Symbole nach Name.", - "openSymbolDescriptionNormal": "Öffnet das Symbol nach Name.", - "searchConfigurationTitle": "Suchkonfiguration", - "showSearchViewlet": "Suche anzeigen", + "openAnythingHandlerDescription": "Öffnet Dateien und globale Symbole anhand des Namens.", + "openSymbolDescriptionNormal": "Öffnet ein beliebiges Symbol anhand des Namens.", + "searchConfigurationTitle": "Suchen", "showTriggerActions": "Alle Symbole anzeigen", "view": "Anzeigen" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/deu/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index 0a65d663d11..e70b57acbd3 100644 --- a/i18n/deu/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,28 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "Suchergebnisse löschen", - "CollapseAllAction.label": "Reduzieren", - "ConfigureGlobalExclusionsAction.label": "Einstellungen öffnen", - "RefreshAction.label": "Aktualisieren", - "RemoveAction.label": "Entfernen", - "SelectOrRemoveAction.removeLabel": "Entfernen", - "SelectOrRemoveAction.selectLabel": "Auswählen", "ariaSearchResultsStatus": "Die Suche hat {0} Ergebnisse in {1} Dateien zurückgegeben.", - "defaultLabel": "Eingabe", - "fileMatchAriaLabel": "{0} stimmt in der Datei \"{1}\" des Ordners \"{2}\" überein, Suchergebnis", - "findInFolder": "In Ordner suchen", - "findPlaceHolder": "Drücken Sie die EINGABETASTE, um den Suchvorgang zu starten oder ESC zum Abbrechen.", "globLabel": "{0} wenn {1}", "global.searchScope.folders": "Durch Einstellungen ausgeschlossene Dateien", - "label.Search": "Suche: Geben Sie den Suchbegriff ein, und drücken Sie die EINGABETASTE, um zu suchen, oder ESC, um den Vorgang abzubrechen.", "label.excludes": "Suchausschlussmuster", "label.global.excludes": "Konfigurierte Suchausschlussmuster", "label.includes": "Sucheinschlussmuster", "moreSearch": "Suchdetails umschalten", - "noMatches": "Keine Übereinstimmungen", "noResultsExcludes": "Keine Ergebnisse gefunden, die \"{0}\" ausschließen – ", "noResultsFound": "Es wurden keine Ergebnisse gefunden. Überprüfen Sie Ihre Einstellungen für konfigurierte Ausschlüsse – ", "noResultsIncludes": "Keine Ergebnisse in \"{0}\" gefunden – ", "noResultsIncludesExcludes": "Keine Ergebnisse in \"{0}\" unter Ausschluss von \"{1}\" gefunden – ", "openSettings.message": "Einstellungen öffnen", - "patternDescription": "Globmuster verwenden", - "patternHelpInclude": "Das Muster, mit dem eine Übereinstimmung vorliegen soll, z. B. ****/*.js** für alle JavaScript-Dateien oder **meinOrdner/**** für eine Übereinstimmung mit diesem Ordner und allen seinen untergeordneten Elementen.\n\n**Referenz**:\n***** stimmt mit 0 oder mehr Zeichen überein.\n**?** stimmt mit 1 Zeichen überein.\n****** stimmt mit null oder mehr Verzeichnissen überein.\n**[a-z]** stimmt mit einem Zeichenbereich überein.\n**{a,b}** stimmt mit einem beliebigen Muster überein.", - "regexp.validationFailure": "Der Ausdruck stimmt mit allem überein.", + "removeAll.confirmation.message": "{0} Vorkommen in {1} Dateien entfernen?", + "removeAll.message": "Es wurden {0} Vorkommen in {1} Dateien entfernt.", + "replaceAll.confirm.button": "Ersetzen", + "replaceAll.confirmation.message": "{0} Vorkommen in {1} Dateien durch \"{2}\" ersetzen?", + "replaceAll.confirmation.title": "Alle ersetzen", + "replaceAll.message": "Es wurden {0} Vorkommen in {1} Dateien durch \"{2}\" ersetzt.", "rerunSearch.message": "Erneut suchen", "rerunSearchInAll.message": "Erneut in allen Dateien suchen", "searchCanceled": "Die Suche wurde abgebrochen, bevor Ergebnisse gefunden werden konnten – ", - "searchMatch": "{0} Übereinstimmung gefunden", - "searchMatches": "{0} Übereinstimmungen gefunden", "searchMaxResultsWarning": "Das Resultset enthält nur eine Teilmenge aller Übereinstimmungen. Verfeinern Sie Ihre Suche, um die Ergebnisse einzugrenzen.", - "searchResultAria": "{0}, Suchergebnis", "searchScope.excludes": "Auszuschließende Dateien", "searchScope.includes": "Einzuschließende Dateien", "treeAriaLabel": "Suchergebnisse" diff --git a/i18n/deu/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json b/i18n/deu/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json index 7a21037ca0d..857989c0c3b 100644 --- a/i18n/deu/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json +++ b/i18n/deu/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json @@ -5,7 +5,10 @@ // Do not edit this file. It is machine generated. { "close": "Schließen", + "insiderBuilds": "Insider-Builds werden zu täglichen Builds!", "license": "Lizenz lesen", "licenseChanged": "Unsere Lizenzbedingungen haben sich geändert. Bitte lesen Sie sie.", + "neverShowAgain": "Nicht mehr anzeigen", + "readmore": "Weitere Informationen", "releaseNotes": "Willkommen bei {0} v{1}! Möchten Sie die Hinweise zu dieser Version lesen?" } \ No newline at end of file diff --git a/i18n/deu/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/deu/src/vs/workbench/services/history/browser/history.i18n.json index bd717869e97..8f96affe271 100644 --- a/i18n/deu/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/deu/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[Extensionentwicklungshost] – {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} - {1}", "prefixWorkspaceTitle": "{0} - {1} - {2}", "prefixWorkspaceTitleMac": "{0} - {1}", diff --git a/i18n/deu/src/vs/workbench/services/request/node/requestService.i18n.json b/i18n/deu/src/vs/workbench/services/request/node/requestService.i18n.json index b2bb675e894..c97bf615dba 100644 --- a/i18n/deu/src/vs/workbench/services/request/node/requestService.i18n.json +++ b/i18n/deu/src/vs/workbench/services/request/node/requestService.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "httpConfigurationTitle": "HTTP-Konfiguration", + "httpConfigurationTitle": "HTTP", "localFileNotFound": "Die Datei wurde nicht gefunden.", "proxy": "Die zu verwendende Proxyeinstellung. Wenn diese Option nicht festgelegt wird, wird der Wert aus den Umgebungsvariablen \"http_proxy\" und \"https_proxy\" übernommen.", "strictSSL": "Gibt an, ob das Proxyserverzertifikat anhand der Liste der bereitgestellten Zertifizierungsstellen überprüft werden soll." diff --git a/i18n/esn/extensions/typescript/out/typescriptServiceClient.i18n.json b/i18n/esn/extensions/typescript/out/typescriptServiceClient.i18n.json index 9e322c3f37c..16e2c6828c1 100644 --- a/i18n/esn/extensions/typescript/out/typescriptServiceClient.i18n.json +++ b/i18n/esn/extensions/typescript/out/typescriptServiceClient.i18n.json @@ -8,6 +8,6 @@ "noServerFound": "La ruta de acceso {0} no apunta a una instalación válida de tsserver. Las características del lenguaje TypeScript se deshabilitan.", "serverCouldNotBeStarted": "El servidor del lenguaje TypeScript no se pudo iniciar. El mensaje de error es: {0}", "serverDied": "El servicio de lenguaje Typescript finalizó de forma inesperada cinco veces en los últimos cinco minutos. Considere la posibilidad de abrir un informe de errores.", - "serverDiedAfterStart": "El servicio de lenguaje Typescript finalizó de forma inesperada cinco veces después de haberse iniciado y no se reiniciará. Abra un informe de errores.", + "serverDiedAfterStart": "El servicio de lenguaje TypeScript finalizó de forma inesperada cinco veces después de haberse iniciado y no se reiniciará. Abra un informe de errores.", "versionNumber.custom": "personalizada" } \ No newline at end of file diff --git a/i18n/esn/extensions/typescript/package.i18n.json b/i18n/esn/extensions/typescript/package.i18n.json index c9055aef564..3f31d329544 100644 --- a/i18n/esn/extensions/typescript/package.i18n.json +++ b/i18n/esn/extensions/typescript/package.i18n.json @@ -18,6 +18,7 @@ "javascript.validate.enable": "Habilitar o deshabilitar la validación de JavaScript", "typescript.reloadProjects.title": "Recargar proyecto de TypeScript", "typescript.tsdk.desc": "Especifica la ruta de acceso de carpeta que contiene los archivos lib*.d.ts y tsserver que se van a usar.", + "typescript.tsserver.experimentalAutoBuild": "Permite la generación automática experimental. Requiere la versión de desarrollo 1.9 o tsserver 2.x y un reinicio de VS Code después de modificarlo.", "typescript.tsserver.trace": "Habilita el seguimiento de los mensajes enviados al servidor de TS.", "typescript.useCodeSnippetsOnMethodSuggest.dec": "Complete las funciones con la signatura de parámetro.", "typescript.validate.enable": "Habilitar o deshabilitar la validación de TypeScript" diff --git a/i18n/esn/src/vs/code/electron-main/menus.i18n.json b/i18n/esn/src/vs/code/electron-main/menus.i18n.json index 6ddc2ee41cc..a2a4ce36efb 100644 --- a/i18n/esn/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/esn/src/vs/code/electron-main/menus.i18n.json @@ -35,6 +35,9 @@ "miExit": "S&&alir", "miFind": "&&Buscar", "miFindInFiles": "Buscar &&en archivos", + "miFocusFirstGroup": "&&Grupo izquierdo", + "miFocusSecondGroup": "&&Grupo lateral", + "miFocusThirdGroup": "&&Grupo derecho", "miForward": "&&Reenviar", "miGotoDefinition": "Ir a &&definición", "miGotoFile": "Ir a &&archivo...", @@ -43,11 +46,13 @@ "miInstallingUpdate": "Instalando actualización...", "miLastCheckedAt": "Última comprobación: {0}", "miLicense": "&&Ver licencia", - "miMarker": "&&Errores y advertencias...", + "miMarker": "&&Problemas", "miMoveSidebar": "&&Mover barra lateral", - "miNavigateHistory": "&&Explorar historial", "miNewFile": "&&Nuevo archivo", "miNewWindow": "&&Nueva ventana", + "miNextEditor": "&&Editor siguiente", + "miNextEditorInGroup": "&&Editor siguiente usado del grupo", + "miNextGroup": "&&Grupo siguiente", "miOpen": "&&Abrir...", "miOpenFile": "&&Abrir archivo...", "miOpenFolder": "Abrir &&carpeta...", @@ -58,11 +63,14 @@ "miOpenWorkspaceSettings": "&&Configuración del área de trabajo", "miPaste": "&&Pegar", "miPreferences": "&&Preferencias", + "miPreviousEditor": "&&Editor anterior", + "miPreviousEditorInGroup": "&&Editor anterior usado del grupo", + "miPreviousGroup": "&&Grupo anterior", "miPrivacyStatement": "&&Declaración de privacidad", "miQuit": "Salir de {0}", "miRedo": "&&Rehacer", "miReleaseNotes": "&&Notas de la versión", - "miReopenClosedFile": "&&Volver a abrir el archivo cerrado", + "miReopenClosedEditor": "&&Volver a abrir el editor cerrado", "miReplace": "&&Reemplazar", "miReportIssues": "&&Notificar problemas", "miRestartToUpdate": "Reiniciar para actualizar...", @@ -73,14 +81,18 @@ "miSelectAll": "&&Seleccionar todo", "miSelectTheme": "&&Tema de color", "miSplitEditor": "Dividir &&editor", - "miToggleDebugConsole": "Alternar consola de &&depuración", + "miSwitchEditor": "Cambiar &&editor", + "miSwitchGroup": "Cambiar &&grupo", + "miToggleDebugConsole": "Consola de de&&puración", "miToggleDevTools": "&&Alternar herramientas de desarrollo", "miToggleFullScreen": "Alternar &&pantalla completa", + "miToggleIntegratedTerminal": "&&Terminal integrado", "miToggleMenuBar": "Alternar &&barra de menús", - "miToggleOutput": "Alternar &&salida", + "miToggleOutput": "&&Salida", "miTogglePanel": "Alternar &&panel", "miToggleRenderWhitespace": "Alternar &&representación de espacio en blanco", "miToggleSidebar": "&&Alternar barra lateral", + "miToggleStatusbar": "&&Alternar barra de estado", "miToggleWordWrap": "Alternar &&ajuste automático de línea", "miTwitter": "&&Síganos en Twitter", "miUndo": "&&Deshacer", @@ -91,5 +103,6 @@ "miViewSearch": "&&Buscar", "miZoomIn": "&&Ampliar", "miZoomOut": "Redu&&cir", + "miZoomReset": "Restablecer zoom", "okButton": "Aceptar" } \ No newline at end of file diff --git a/i18n/esn/src/vs/code/node/cliProcessMain.i18n.json b/i18n/esn/src/vs/code/node/cliProcessMain.i18n.json index 8b6ad71cd4e..7aed287ea24 100644 --- a/i18n/esn/src/vs/code/node/cliProcessMain.i18n.json +++ b/i18n/esn/src/vs/code/node/cliProcessMain.i18n.json @@ -3,4 +3,6 @@ * 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 +{ + "useId": "Asegúrese de usar el identificador de extensión completo, por ejemplo: {0}" +} \ 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 f172f65bda3..5678130ee1a 100644 --- a/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/esn/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -24,6 +24,7 @@ "lineNumbers": "Controla la visibilidad de los números de línea", "mouseWheelScrollSensitivity": "Se utilizará un multiplicador en los eventos de desplazamiento de la rueda del mouse `deltaX` y `deltaY`", "overviewRulerLanes": "Controla el número de decoraciones que pueden aparecer en la misma posición en la regla de visión general", + "parameterHints": "Habilita sugerencias de parámetro", "quickSuggestions": "Controla si van a aparecer sugerencias rápidas mientras se escribe", "quickSuggestionsDelay": "Controla el retardo en ms tras el cual aparecerán sugerencias rápidas", "referenceInfos": "Controla si el editor muestra información de referencia para los modos compatibles", diff --git a/i18n/esn/src/vs/editor/contrib/folding/browser/folding.i18n.json b/i18n/esn/src/vs/editor/contrib/folding/browser/folding.i18n.json index e4c79512cff..9483cc0e0c5 100644 --- a/i18n/esn/src/vs/editor/contrib/folding/browser/folding.i18n.json +++ b/i18n/esn/src/vs/editor/contrib/folding/browser/folding.i18n.json @@ -11,6 +11,8 @@ "foldLevel3Action.label": "Nivel de plegamiento 3", "foldLevel4Action.label": "Nivel de plegamiento 4", "foldLevel5Action.label": "Nivel de plegamiento 5", + "foldRecursivelyAction.label": "Plegar de forma recursiva", + "unFoldRecursivelyAction.label": "Desplegar de forma recursiva", "unfoldAction.label": "Desplegar", "unfoldAllAction.label": "Desplegar todo" } \ No newline at end of file diff --git a/i18n/esn/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json b/i18n/esn/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json index 00eb3004040..8eb4efff443 100644 --- a/i18n/esn/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json +++ b/i18n/esn/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json @@ -7,5 +7,7 @@ "markerAction.next.label": "Ir al error o la advertencia siguiente", "markerAction.previous.label": "Ir al error o la advertencia anterior", "quickfix.multiple.label": "Correcciones recomendadas: ", - "quickfix.single.label": "Corrección recomendada: " + "quickfix.single.label": "Corrección recomendada: ", + "title.w_source": "({0}/{1}) [{2}]", + "title.wo_source": "({0}/{1})" } \ No newline at end of file diff --git a/i18n/esn/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/esn/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index c14457e8907..e7241d558db 100644 --- a/i18n/esn/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/esn/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "Cargando...", "meta.titleReference": " – {0} referencias", - "noResults": "No hay ningún resultado", "references.action.label": "Buscar todas las referencias", - "references.action.name": "Mostrar referencias" + "references.action.name": "Buscar todas las referencias" } \ No newline at end of file diff --git a/i18n/esn/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json b/i18n/esn/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json index 8b6ad71cd4e..91c699801ff 100644 --- a/i18n/esn/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json +++ b/i18n/esn/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json @@ -3,4 +3,6 @@ * 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 +{ + "referencesFailre": "Error al resolver el archivo." +} \ No newline at end of file diff --git a/i18n/esn/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/esn/src/vs/editor/node/textMate/TMSyntax.i18n.json index 7ccc2b32658..cdd8b0b9fbe 100644 --- a/i18n/esn/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/esn/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -4,11 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "invalid.injectTo": "Valor no válido en `contributes.{0}.injectTo`. Debe ser una matriz de nombres de ámbito de lenguaje. Valor proporcionado: {1}", "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.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.", "invalid.scopeName": "Se esperaba una cadena en \"contributes.{0}.scopeName\". Valor proporcionado: {1}", "vscode.extension.contributes.grammars": "Aporta tokenizadores de TextMate.", + "vscode.extension.contributes.grammars.injectTo": "Lista de nombres de ámbito de lenguaje al que se inyecta esta gramática.", "vscode.extension.contributes.grammars.language": "Identificador del lenguaje al que se aporta esta sintaxis.", "vscode.extension.contributes.grammars.path": "Ruta de acceso del archivo tmLanguage. La ruta es relativa a la carpeta de extensión y normalmente empieza por \"./syntaxes/\".", "vscode.extension.contributes.grammars.scopeName": "Nombre del ámbito de TextMate que el archivo tmLanguage usa." diff --git a/i18n/esn/src/vs/languages/html/common/html.contribution.i18n.json b/i18n/esn/src/vs/languages/html/common/html.contribution.i18n.json index 0bb5326b5ed..8cb2f7b4ffc 100644 --- a/i18n/esn/src/vs/languages/html/common/html.contribution.i18n.json +++ b/i18n/esn/src/vs/languages/html/common/html.contribution.i18n.json @@ -10,7 +10,7 @@ "format.indentInnerHtml": "Aplicar sangría a las secciones y .", "format.maxPreserveNewLines": "Número máximo de saltos de línea que deben conservarse en un fragmento. Use \"null\" para que el número sea ilimitado.", "format.preserveNewLines": "Indica si los saltos de línea existentes delante de los elementos deben conservarse. Solo funciona delante de los elementos, no dentro de las etiquetas o con texto.", - "format.unformatted": "Lista de etiquetas, separadas por comas, a las que no se debe volver a aplicar formato. El valor predeterminado de \"null\" son todas las etiquetas alineadas.", + "format.unformatted": "Lista de etiquetas, separadas por comas, a las que no se debe volver a aplicar formato. El valor predeterminado de \"null\" son todas las etiquetas mostradas en https://www.w3.org/TR/html5/dom.html#phrasing-content.", "format.wrapLineLength": "Cantidad máxima de caracteres por línea (0 = deshabilitar).", "htmlConfigurationTitle": "Configuración HTML" } \ 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 f6ccfb0cf53..4c11fb9d1ed 100644 --- a/i18n/esn/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/esn/src/vs/workbench/electron-browser/actions.i18n.json @@ -14,7 +14,8 @@ "newWindow": "Nueva ventana", "noFolderOpened": "No hay ninguna carpeta abierta en esta instancia para cerrar.", "openRecent": "Abrir recientes", - "openRecentPlaceHolder": "Seleccionar una ruta de acceso para abrir", + "openRecentPlaceHolder": "Seleccione una ruta de acceso para abrir (mantenga presionada la tecla Ctrl para abrirla en una nueva ventana)", + "openRecentPlaceHolderMac": "Seleccione una ruta de acceso (mantenga presionada la tecla Cmd para abrirla en una nueva ventana)", "reloadWindow": "Recargar ventana", "toggleDevTools": "Alternar herramientas de desarrollo", "toggleFullScreen": "Alternar pantalla completa", 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 fc5a54e4911..85547b6719e 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 @@ -8,7 +8,8 @@ "file": "Archivo", "openFilesInNewWindow": "Si está habilitado, los archivos se abrirán en una nueva ventana en lugar de volver a usar una instancia existente.", "reopenFolders": "Controla cómo se vuelven a abrir las carpetas tras un reinicio. Seleccione \"none\" para no volver a abrir jamás una carpeta, \"one\" para volver a abrir la última carpeta en la que trabajó o seleccione \"all\" para volver a abrir todas las carpetas de la última sesión.", - "updateChannel": "Configure el canal de actualización del que se van a recibir las actualizaciones. Es necesario reiniciar tras el cambio.", + "restoreFullscreen": "Controla si una ventana se debe restaurar al modo de pantalla completa si se salió de ella en dicho modo.", + "updateChannel": "Configure si recibirá actualizaciones automáticas de un canal de actualización. Es necesario reiniciar tras el cambio.", "updateConfigurationTitle": "Actualizar configuración", "view": "Ver", "windowConfigurationTitle": "Configuración de ventana", diff --git a/i18n/esn/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json index 18b77ee65cf..474b6e8ea90 100644 --- a/i18n/esn/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json @@ -8,8 +8,8 @@ "conditionalBreakpointEditorAction": "Depuración: Punto de interrupción condicional", "debug": "Depurar", "debugCategory": "Depurar", - "debugConsole": "Consola de depuración", "debugEvaluate": "Depuración: Evaluar", + "launchConfigDoesNotExist": "La configuración de inicio '{0}' no existe.", "runToCursor": "Depuración: Ejecutar hasta el cursor", "showDebugHover": "Depuración: Mostrar al mantener el puntero", "toggleBreakpointAction": "Depuración: Alternar punto de interrupción", diff --git a/i18n/esn/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json b/i18n/esn/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json index d8a4b8f0edf..5009ed1786c 100644 --- a/i18n/esn/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json @@ -6,10 +6,12 @@ { "DebugTaskNotFound": "No se encontró el elemento preLaunchTask '{0}'.", "NewLaunchConfig": "Defina los valores del archivo de configuración de inicio para la aplicación.", + "breakpointAdded": "Punto de interrupción agregado, línea {0}, archivo {1}", + "breakpointRemoved": "Punto de interrupción quitado, línea {0}, archivo {1}", "debugAdapterCrash": "El proceso de adaptación del depurador finalizó inesperadamente", "debugAnyway": "Depurar de todos modos", "debugSourceNotAvailable": "El origen {0} no está disponible.", - "debugTypeMissing": "Falta la propiedad \"type\" de la configuración seleccionada en launch.json.", + "debugTypeMissing": "Falta la propiedad \"type\" en la configuración de inicio seleccionada.", "debugTypeNotSupported": "El tipo de depuración '{0}' configurado no es compatible.", "debuggingContinued": "La depuración continúa.", "debuggingPaused": "La depuración se ha pausado. Motivo: {0}, {1} {2}", diff --git a/i18n/esn/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json b/i18n/esn/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json index bf504c92f57..90a82a5bd73 100644 --- a/i18n/esn/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json @@ -4,9 +4,12 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "debugLinuxConfiguration": "Atributos de configuración de inicio específicos de Linux.", "debugName": "Nombre de la configuración. Aparece en el menú desplegable de la configuración de inicio.", + "debugOSXConfiguration": "Atributos de configuración de inicio específicos de OS X.", "debugPrelaunchTask": "Tarea que se va a ejecutar antes de iniciarse la sesión de depuración.", "debugRequest": "Tipo de solicitud de la configuración. Puede ser \"launch\" o \"attach\".", "debugType": "Tipo de configuración.", + "debugWindowsConfiguration": "Atributos de configuración de inicio específicos de Windows.", "relativePathsNotConverted": "Las rutas de acceso relativas ya no se convertirán en absolutas automáticamente. Considere la posibilidad de usar ${workspaceRoot} como prefijo." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/esn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index 6f73f35d4ba..64e58e1cb88 100644 --- a/i18n/esn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -10,6 +10,7 @@ "app.launch.json.version": "Versión de este formato de archivo.", "debugNoType": "El valor \"type\" del adaptador de depuración no se puede omitir y debe ser de tipo \"string\".", "duplicateDebuggerType": "El tipo de depuración '{0}' ya está registrado y tiene el atributo '{1}', se ignora el atributo '{1}'.", + "interactiveVariableNotFound": "El adaptador {0} no contribuye a la variable {1} que se especifica en la configuración de inicio.", "selectDebug": "Seleccionar entorno", "vscode.extension.contributes.debuggers": "Aporta adaptadores de depuración.", "vscode.extension.contributes.debuggers.args": "Argumentos opcionales que se pasarán al adaptador.", @@ -26,6 +27,7 @@ "vscode.extension.contributes.debuggers.runtime": "Runtime opcional en caso de que el atributo del programa no sea un ejecutable pero requiera un runtime.", "vscode.extension.contributes.debuggers.runtimeArgs": "Argumentos de runtime opcionales.", "vscode.extension.contributes.debuggers.type": "Identificador único de este adaptador de depuración.", + "vscode.extension.contributes.debuggers.variables": "Asignación de variables interactivas (por ejemplo, ${action.pickProcess}) en `launch.json` a un comando.", "vscode.extension.contributes.debuggers.windows": "Configuración específica de Windows.", "vscode.extension.contributes.debuggers.windows.runtime": "Runtime que se usa para Windows." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index 2b7de7db262..7633b87d181 100644 --- a/i18n/esn/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,8 @@ "globalConsoleActionWin": "Abrir nuevo símbolo del sistema", "scopedConsoleActionMacLinux": "Abrir en terminal", "scopedConsoleActionWin": "Abrir en símbolo del sistema", + "terminal.external.linuxExec": "Personaliza qué terminal debe ejecutarse en Linux.", + "terminal.external.osxExec": "Personaliza qué aplicación terminal se ejecutará en OS X.", "terminal.external.windowsExec": "Personaliza qué terminal debe ejecutarse en Windows.", "terminalConfigurationTitle": "Configuración de terminal" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index cf3d5d2726c..d0fc44cce2a 100644 --- a/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "Cerrar", "deleteSure": "¿Seguro que quiere desinstalar '{0}'?", - "installExtension": "Instalar extensión", - "notFound": "La extensión '{0}' no está instalada.", + "enableAction": "Habilitar", + "installAction": "Instalar", + "installing": "Instalando", + "restart": "Para habilitar esta extensión, esta ventana de VS Code se debe reiniciar.\n\n¿Desea continuar?", "restartNow": "Reiniciar ahora", - "restartNow2": "Reiniciar ahora", "showExtensionRecommendations": "Mostrar recomendaciones de extensión", "showInstalledExtensions": "Mostrar extensiones instaladas", "showOutdatedExtensions": "Mostrar extensiones obsoletas", - "success-installed": "'{0}' se instaló correctamente. Reinicie para habilitarlo.", - "success-uninstalled": "'{0}' se desinstaló correctamente. Reinicie para desactivarlo.", - "uninstall": "Desinstalar extensión" + "toggleExtensionsViewlet": "Mostrar extensiones", + "uninstall": "Desinstalación", + "updateAction": "Actualizar" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json b/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json index c85fb0ffdbf..80055eb7e85 100644 --- a/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json @@ -5,6 +5,7 @@ // Do not edit this file. It is machine generated. { "extensions": "Extensiones", + "outdatedExtensions": "{0} extensiones obsoletas", "reloadNow": "Reiniciar ahora", "success": "Las extensiones se instalaron correctamente. Reinicie para habilitarlas.", "successSingle": "{0} se instaló correctamente. Reinicie para habilitarla." diff --git a/i18n/esn/src/vs/workbench/parts/files/browser/fileActions.i18n.json b/i18n/esn/src/vs/workbench/parts/files/browser/fileActions.i18n.json index dd036ddf9b5..71b3ce091a5 100644 --- a/i18n/esn/src/vs/workbench/parts/files/browser/fileActions.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/browser/fileActions.i18n.json @@ -4,13 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "addToWorkingFiles": "Agregar archivo activo a archivos de trabajo", - "closeAllFiles": "Cerrar todos los archivos", - "closeAllLabel": "Cerrar todos los archivos", - "closeFile": "Cerrar archivo", - "closeLabel": "Cerrar archivo", - "closeOtherFiles": "Cerrar otros archivos", - "closeOtherLabel": "Cerrar otros archivos", + "collapseExplorerFolders": "Contraer carpetas en el Explorador", "compareFiles": "Comparar archivos", "compareSource": "Seleccionar para comparar", "compareWith": "Comparar con '{0}'", @@ -31,7 +25,7 @@ "fileNameExistsError": "Ya existe el archivo o carpeta **{0}** en esta ubicación. Elija un nombre diferente.", "filePathTooLongError": "El nombre **{0}** da como resultado una ruta de acceso demasiado larga. Elija un nombre más corto.", "focusFilesExplorer": "Enfocar Explorador de archivos", - "focusWorkingFiles": "Enfocar archivos de trabajo", + "focusOpenEditors": "Foco sobre la vista de editores abiertos", "globalCompareFile": "Comparar archivo activo con...", "importFiles": "Importar archivos", "invalidFileNameError": "El nombre **{0}** no es válido para el archivo o la carpeta. Elija un nombre diferente.", @@ -39,25 +33,21 @@ "newFile": "Nuevo archivo", "newFolder": "Nueva carpeta", "newUntitledFile": "Nuevo archivo sin título", - "noFileOpen": "No hay ningún archivo abierto para cerrar.", - "noWorkingFiles": "Actualmente no hay archivos de trabajo.", - "openFileToAdd": "Abrir un archivo antes para agregarlo a los archivos de trabajo", "openFileToCompare": "Abrir un archivo antes para compararlo con otro archivo.", "openFileToShow": "Abra primero un archivo para mostrarlo en el explorador.", "openFolderFirst": "Abra primero una carpeta para crear archivos o carpetas en ella.", - "openNextWorkingFile": "Abrir archivo de trabajo siguiente", - "openPreviousWorkingFile": "Abrir archivo de trabajo anterior", "openToSide": "Abrir en el lateral", "pasteFile": "Pegar", "permDelete": "Eliminar permanentemente", "refresh": "Actualizar", + "refreshExplorer": "Actualizar Explorador", "rename": "Cambiar nombre", - "reopenClosedFile": "Volver a abrir el archivo cerrado", "replaceButtonLabel": "&&Reemplazar", "retry": "Reintentar", "revert": "Revertir archivo", "save": "Guardar", "saveAll": "Guardar todos", + "saveAllInGroup": "Guardar todo en el grupo", "saveAs": "Guardar como...", "saveFiles": "Guardar archivos con modificaciones", "showInExplorer": "Mostrar el archivo activo en el explorador", diff --git a/i18n/esn/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index 79e9fb8fb50..a8c343291c2 100644 --- a/i18n/esn/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -9,7 +9,7 @@ "autoSave": "Controla el guardado automático de los archivos con modificaciones. Valores aceptados: \"{0}\", \"{1}\", \"{2}\". Si se establece en \"{3}\", puede configurar el retraso en \"files.autoSaveDelay\".", "autoSaveDelay": "Controla el retraso en MS tras el cual un archivo con modificaciones se guarda automáticamente. Solo se aplica si \"files.autoSave\" está establecido en \"{0}\".", "binaryFileEditor": "Editor de archivos binarios", - "dynamicHeight": "Controla si la altura de la sección de los archivos de trabajo debería adaptarse o no de forma dinámica al número de elementos.", + "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.", "encoding": "La codificación del juego de caracteres predeterminada que debe utilizarse al leer y escribir archivos.", "eol": "Carácter predeterminado de final de línea.", "exclude": "Configurar patrones globales para excluir archivos y carpetas.", @@ -17,14 +17,11 @@ "explorerConfigurationTitle": "Configuración del Explorador de archivos", "files.exclude.boolean": "El patrón global con el que se harán coincidir las rutas de acceso de los archivos. Establézcalo en true o false para habilitarlo o deshabilitarlo.", "files.exclude.when": "Comprobación adicional de los elementos del mismo nivel de un archivo coincidente. Use $(nombreBase) como variable para el nombre de archivo que coincide.", - "filesCategory": "Archivos", "filesConfigurationTitle": "Configuración de los archivos", - "maxVisible": "Número máximo de archivos de trabajo que se mostrarán antes de que aparezcan las barras de desplazamiento.", - "openWorkingFile": "Abrir archivo de trabajo por nombre", + "openEditorsVisible": "Número de editores mostrados en el panel Editores abiertos. Establezca este valor en 0 para ocultar el panel.", "showExplorerViewlet": "Mostrar explorador", "textFileEditor": "Editor de archivos de texto", "trimTrailingWhitespace": "Si está habilitado, se recortará el espacio final cuando guarde un archivo.", "view": "Ver", - "watcherExclude": "Configure patrones globales de las rutas de acceso de archivo que se van a excluir de la inspección de archivos. Al cambiar esta configuración, es necesario reiniciar. Si observa que Code consume mucho tiempo de CPU al iniciarse, puede excluir las carpetas grandes para reducir la carga inicial.", - "workingFilesPicker": "Abrir archivo de trabajo por nombre" + "watcherExclude": "Configure patrones globales de las rutas de acceso de archivo que se van a excluir de la inspección de archivos. Al cambiar esta configuración, es necesario reiniciar. Si observa que Code consume mucho tiempo de CPU al iniciarse, puede excluir las carpetas grandes para reducir la carga inicial." } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/esn/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index 2ce0e31f5be..fe5275dfdd6 100644 --- a/i18n/esn/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "Usar cambios locales y sobrescribir contenido del disco", + "acceptLocalChanges": "Sobrescribir", "compareChanges": "Comparar", "conflictingFileHasChanged": "El contenido del archivo en el disco ha cambiado y se ha actualizado la parte izquierda del editor de comparación. Revíselo y resuelva de nuevo.", "discard": "Descartar", @@ -13,8 +13,8 @@ "readonlySaveError": "No se pudo guardar '{0}': El archivo está protegido contra escritura. Seleccione \"Sobrescribir\" para quitar la protección.", "resolveSaveConflict": "{0} - Resolver conflicto al guardar", "retry": "Reintentar", - "revertLocalChanges": "Descartar cambios locales y revertir al contenido del disco", + "revertLocalChanges": "Revertir", "saveConflictDiffLabel": "{0} - en el disco ↔ en {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.", - "userGuide": "Use las acciones de la barra de herramientas del editor para **deshacer** los cambios o **sobrescribir** el contenido del disco con sus cambios." + "userGuide": "Seleccione **Revertir** para descartar los cambios o **Sobrescribir** para reemplazar el contenido del disco por los cambios" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json index 2390b26a402..22b3ff863e9 100644 --- a/i18n/esn/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json @@ -9,5 +9,8 @@ "openFile": "Abrir archivo", "openInEditor": "Cambiar a la vista de editor", "stageSelectedLines": "Almacenar provisionalmente las líneas seleccionadas", - "switchToChangesView": "Cambiar a la vista de cambios" + "switchToChangesView": "Cambiar a la vista de cambios", + "unstageSelectedLines": "Deshacer la preparación de las líneas seleccionadas", + "workbenchStage": "Almacenar provisionalmente", + "workbenchUnstage": "Cancelar almacenamiento provisional" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/git/browser/gitActions.i18n.json b/i18n/esn/src/vs/workbench/parts/git/browser/gitActions.i18n.json index 36f60c431fe..8b514a7e01b 100644 --- a/i18n/esn/src/vs/workbench/parts/git/browser/gitActions.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/git/browser/gitActions.i18n.json @@ -5,13 +5,11 @@ // Do not edit this file. It is machine generated. { "authFailed": "Error de autenticación en GIT remoto.", - "branch": "Branch", - "branch2": "Branch", - "checkout": "Checkout", "cleanChangesLabel": "&&Limpiar cambios", "commit": "Commit", "commitAll": "Confirmar todo", "commitAll2": "Confirmar todo", + "commitMessage": "Mensaje de confirmación", "commitStaged": "Confirmar elementos almacenados provisionalmente", "commitStaged2": "Confirmar elementos almacenados provisionalmente", "confirmPublishMessage": "¿Seguro que quiere publicar '{0}' en '{1}'?", @@ -36,13 +34,9 @@ "openFile": "Abrir archivo", "publish": "Publicar", "publishPickMessage": "Seleccionar un elemento remoto para publicar la rama '{0}':", - "pull": "Pull", - "pullWithRebase": "Extraer (rebase)", - "push": "Push", "refresh": "Actualizar", "stageAllChanges": "Almacenar todo provisionalmente", "stageChanges": "Almacenar provisionalmente", - "sync": "Sincronizar", "synchronizing": "Sincronizando...", "undoAllChanges": "Limpiar todo", "undoChanges": "Limpiar", diff --git a/i18n/esn/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json b/i18n/esn/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json index 8d8472528bd..40e30d55100 100644 --- a/i18n/esn/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json @@ -7,6 +7,7 @@ "alreadyCheckedOut": "{0} ya es la rama actual", "branchAriaLabel": "{0}, rama de GIT", "checkoutBranch": "Rama en {0}", + "checkoutRemoteBranch": "Sucursal remota en {0}", "checkoutTag": "Etiqueta en {0}", "createBranch": "Crear la rama {0}", "noBranches": "No hay otras ramas", diff --git a/i18n/esn/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/esn/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 2f91c069117..b0825cca978 100644 --- a/i18n/esn/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -8,17 +8,23 @@ "cancel": "Cancelar", "cantOpen": "No se puede abrir este recurso de Git.", "cantOpenResource": "No se puede abrir este recurso de Git.", - "changesFromIndex": "{0} - Cambios del índice", - "changesFromTree": "{0} - Cambios de {1}", + "changesFromIndex": "{0} (índice)", + "changesFromIndexDesc": "{0} - Cambios del índice", + "changesFromTree": "{0} ({1})", + "changesFromTreeDesc": "{0} - Cambios de {1}", "checkNativeConsole": "Se ha producido un problema al ejecutar la operación GIT. Revise la salida o use una consola para comprobar el estado del repositorio.", "configureUsernameEmail": "Configure su nombre de usuario de GIT y su correo electrónico.", "download": "Descargar", - "gitIndexChanges": "{0} - Cambios del índice", - "gitIndexChangesRenamed": "{0} - Cambiado de nombre - Cambios en el índice", - "gitMergeChanges": "{0} - Combinar cambios", + "gitIndexChanges": "{0} (índice) ↔ {1}", + "gitIndexChangesDesc": "{0} - Cambios del índice", + "gitIndexChangesRenamed": "{0} - {1}", + "gitIndexChangesRenamedDesc": "{0} - Cambiado de nombre - Cambios en el índice", + "gitMergeChanges": "{0} (combinar) ↔ {1}", + "gitMergeChangesDesc": "{0} - Combinar cambios", "neverShowAgain": "No volver a mostrar", "showOutput": "Mostrar salida", "unmergedChanges": "Debe resolver los cambios sin combinar antes de confirmar sus cambios.", "updateGit": "Parece que tiene GIT {0} instalado. Code funciona mejor con GIT >=2.0.0.", - "workingTreeChanges": "{0} - Cambios del árbol de trabajo" + "workingTreeChanges": "{0} (ENCABEZADO) ↔ {1}", + "workingTreeChangesDesc": "{0} - Cambios del árbol de trabajo" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/esn/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index be68e94ee07..52d5f7a668b 100644 --- a/i18n/esn/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -9,6 +9,8 @@ "gitCommands": "Comandos Git", "gitConfigurationTitle": "Configuración Git", "gitEnabled": "Habilitado para GIT", + "gitLargeRepos": "Permitir siempre que Code administre grandes repositorios.", + "gitLongCommit": "Si se debe advertir sobre los mensajes de confirmación largos.", "gitPath": "Ruta del Git ejecutable", "gitPendingChangesBadge": "{0} cambios pendientes", "gitProgressBadge": "Estado del Git en ejecución", diff --git a/i18n/esn/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json b/i18n/esn/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json index fb54cf00502..8fe126fc1a7 100644 --- a/i18n/esn/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json @@ -6,6 +6,7 @@ { "commitMessage": "Mensaje (presione {0} para confirmar)", "commitMessageAriaLabel": "GIT: Escriba un mensaje de confirmación y presione {0} para confirmar", + "longCommit": "Se recomienda mantener la primera línea de la confirmación por debajo de 50 caracteres. Puede usar más líneas para información adicional.", "needMessage": "Especifique un mensaje de confirmación. Siempre puede presionar **{0}** para confirmar los cambios. Si hay cambios almacenados provisionalmente, solo se confirmarán dichos cambios; de lo contrario, se confirmarán todos los cambios.", "nothingToCommit": "Cuando haya cambios para confirmar, escriba el mensaje de confirmación y presione **{0}** para confirmarlos. Si hay cambios almacenados provisionalmente, solo se confirmarán estos cambios; de lo contrario, se confirmarán todos los cambios.", "showOutput": "Mostrar salida de GIT", diff --git a/i18n/esn/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/esn/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index 9b76924e781..8c462190349 100644 --- a/i18n/esn/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0}: {1}", "QuickCommandsAction.label": "Mostrar comandos del editor", "actionNotEnabled": "El comando '{0}' no está habilitado en el contexto actual.", "canNotRun": "El comando '{0}' no puede ejecutarse desde aquí.", diff --git a/i18n/esn/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/esn/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index fbd201ce5f9..6dc9bf6a04f 100644 --- a/i18n/esn/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,26 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "Borrar resultados de la búsqueda", - "CollapseAllAction.label": "Contraer", - "ConfigureGlobalExclusionsAction.label": "Abrir configuración", - "RefreshAction.label": "Actualizar", - "RemoveAction.label": "Quitar", - "SelectOrRemoveAction.removeLabel": "Quitar", - "SelectOrRemoveAction.selectLabel": "Seleccionar", "ariaSearchResultsStatus": "La búsqueda devolvió {0} resultados en {1} archivos", - "defaultLabel": "entrada", - "fileMatchAriaLabel": "{0} coincidencias en el archivo {1} de la carpeta {2}, resultados de la búsqueda", - "findInFolder": "Buscar en carpeta", - "findPlaceHolder": "Presionar Entrar para buscar, Esc para cancelar", "globLabel": "{0} cuando {1}", "global.searchScope.folders": "archivos excluidos a través de la configuración", - "label.Search": "Búsqueda: Escriba el término de búsqueda y presione Entrar para buscar o Esc para cancelar", "label.excludes": "Buscar patrones de exclusión", "label.global.excludes": "Patrones de exclusión de búsqueda configurados", "label.includes": "Buscar patrones de inclusión", "moreSearch": "Alternar detalles de la búsqueda", - "noMatches": "no hay coincidencias", "noResultsExcludes": "No se encontraron resultados con exclusión de '{0}' - ", "noResultsFound": "No se encontraron resultados. Revise los ajustes de las exclusiones configuradas - ", "noResultsIncludes": "No se encontraron resultados en '{0}' - ", "noResultsIncludesExcludes": "No se encontraron resultados en '{0}' con exclusión de '{1}' - ", "openSettings.message": "Abrir configuración", - "patternDescription": "Usar patrones globales", - "patternHelpInclude": "El patrón de coincidencia, por ejemplo, ****/*.js** para todos los archivos JavaScript o **miCarpeta/**** para encontrar coincidencias de esa carpeta con todos los elementos secundarios.\n\n**Referencia**:\n***** encuentra coincidencias con 0 o más caracteres\n**?** encuentra coincidencias con 1 carácter\n****** encuentra coincidencias con cero o más directorios\n**[a-z]** encuentra coincidencias con un rango de caracteres\n**{a,b}** encuentra coincidencias con cualquiera de los patrones", - "regexp.validationFailure": "La expresión coincide con todo", + "replaceAll.confirm.button": "Reemplazar", + "replaceAll.confirmation.message": "¿Reemplazar {0} apariciones en {1} archivos?", + "replaceAll.confirmation.title": "Reemplazar todo", + "replaceAll.message": "{0} apariciones reemplazadas en {1} archivos.", "rerunSearch.message": "Buscar de nuevo", "rerunSearchInAll.message": "Buscar de nuevo en todos los archivos", "searchCanceled": "La búsqueda se canceló antes de poder encontrar resultados - ", - "searchMatch": "{0} coincidencia encontrada", - "searchMatches": "{0} coincidencias encontradas", "searchMaxResultsWarning": "El conjunto de resultados solo contiene un subconjunto de todas las coincidencias. Sea más específico en la búsqueda para acotar los resultados.", - "searchResultAria": "{0}, resultado de la búsqueda", "searchScope.excludes": "archivos para excluir", "searchScope.includes": "archivos para incluir", "treeAriaLabel": "Resultados de la búsqueda" diff --git a/i18n/esn/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json b/i18n/esn/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json index 5b301e89369..ee69c4a5c82 100644 --- a/i18n/esn/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json +++ b/i18n/esn/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json @@ -5,7 +5,10 @@ // Do not edit this file. It is machine generated. { "close": "Cerrar", + "insiderBuilds": "Las compilaciones de Insider se están volviendo compilaciones diarias.", "license": "Leer licencia", "licenseChanged": "Los términos de licencia han cambiado, revíselos.", + "neverShowAgain": "No volver a mostrar", + "readmore": "Más información", "releaseNotes": "{0} v{1}. ¿Quiere leer las notas de la versión?" } \ No newline at end of file diff --git a/i18n/esn/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/esn/src/vs/workbench/services/history/browser/history.i18n.json index de94d7127f3..1d2fc781869 100644 --- a/i18n/esn/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/esn/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[Host de desarrollo de extensiones] - {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} - {1}", "prefixWorkspaceTitle": "{0} - {1} - {2}", "prefixWorkspaceTitleMac": "{0} - {1}", diff --git a/i18n/fra/extensions/typescript/package.i18n.json b/i18n/fra/extensions/typescript/package.i18n.json index daaa7ca4668..31d30f52c65 100644 --- a/i18n/fra/extensions/typescript/package.i18n.json +++ b/i18n/fra/extensions/typescript/package.i18n.json @@ -18,6 +18,7 @@ "javascript.validate.enable": "Activer/désactiver la validation JavaScript", "typescript.reloadProjects.title": "Recharger le projet TypeScript", "typescript.tsdk.desc": "Spécifie le chemin de dossier contenant les fichiers tsserver et lib*.d.ts à utiliser.", + "typescript.tsserver.experimentalAutoBuild": "Active la build automatique expérimentale. Nécessite la version 1.9 dev ou 2.x tsserver et le redémarrage du code VS une fois celui-ci modifié.", "typescript.tsserver.trace": "Active le traçage de l'envoi des messages au serveur TS", "typescript.useCodeSnippetsOnMethodSuggest.dec": "Fonctions complètes avec leur signature de paramètre.", "typescript.validate.enable": "Activer/désactiver la validation TypeScript" diff --git a/i18n/fra/src/vs/code/electron-main/menus.i18n.json b/i18n/fra/src/vs/code/electron-main/menus.i18n.json index be51199c690..558cdb5993a 100644 --- a/i18n/fra/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/fra/src/vs/code/electron-main/menus.i18n.json @@ -35,6 +35,9 @@ "miExit": "&&Quitter", "miFind": "&&Rechercher", "miFindInFiles": "Rechercher dans les f&&ichiers", + "miFocusFirstGroup": "Groupe g&&auche", + "miFocusSecondGroup": "&&Groupe latéral", + "miFocusThirdGroup": "&&Groupe droit", "miForward": "&&Suivant", "miGotoDefinition": "Atteindre la &&définition", "miGotoFile": "Atteindre le &&fichier...", @@ -43,11 +46,13 @@ "miInstallingUpdate": "Installation de la mise à jour...", "miLastCheckedAt": "Dernière vérification le {0}", "miLicense": "Affic&&her la licence", - "miMarker": "&&Erreurs et avertissements...", + "miMarker": "&&Problèmes", "miMoveSidebar": "Déplacer la &&barre latérale", - "miNavigateHistory": "&&Naviguer dans l'historique", "miNewFile": "&&Nouveau fichier", "miNewWindow": "&&Nouvelle fenêtre", + "miNextEditor": "Éditeur &&suivant", + "miNextEditorInGroup": "Éditeur &&utilisé suivant dans le groupe", + "miNextGroup": "Groupe &&suivant", "miOpen": "&&Ouvrir...", "miOpenFile": "&&Ouvrir le fichier...", "miOpenFolder": "Ou&&vrir le dossier...", @@ -58,11 +63,14 @@ "miOpenWorkspaceSettings": "Para&&mètres de l'espace de travail", "miPaste": "Co&&ller", "miPreferences": "Pr&&éférences", + "miPreviousEditor": "Éditeur pré&&cédent", + "miPreviousEditorInGroup": "É&&diteur utilisé précédent dans le groupe", + "miPreviousGroup": "Groupe pré&&cédent", "miPrivacyStatement": "Déc&&laration de confidentialité", "miQuit": "Quitter {0}", "miRedo": "&&Rétablir", "miReleaseNotes": "Notes de pu&&blication", - "miReopenClosedFile": "&&Rouvrir le fichier fermé", + "miReopenClosedEditor": "&&Rouvrir l'éditeur fermé", "miReplace": "&&Remplacer", "miReportIssues": "S&&ignaler les problèmes", "miRestartToUpdate": "Redémarrer pour mettre à jour...", @@ -73,14 +81,18 @@ "miSelectAll": "&&Sélectionner tout", "miSelectTheme": "Thème de &&couleur", "miSplitEditor": "Fractionner l'édit&&eur", - "miToggleDebugConsole": "Activer/désactiver la console de dé&&bogage", + "miSwitchEditor": "Changer d'é&&diteur", + "miSwitchGroup": "Changer de gr&&oupe", + "miToggleDebugConsole": "Console de dé&&bogage", "miToggleDevTools": "Activer/désactiver les ou&&tils de développement", "miToggleFullScreen": "Plei&&n écran", + "miToggleIntegratedTerminal": "&&Terminal intégré", "miToggleMenuBar": "Activer/désactiver la &&barre de menus", - "miToggleOutput": "Activer/désactiver la s&&ortie", + "miToggleOutput": "&&Sortie", "miTogglePanel": "Activer/désactiver le &&panneau", "miToggleRenderWhitespace": "Activer/désactiver &&Restituer l'espace", "miToggleSidebar": "Activer/désactiver la &&barre latérale", + "miToggleStatusbar": "&&Activer/désactiver la barre d'état", "miToggleWordWrap": "Activer/désactiver le retour automatique à la &&ligne", "miTwitter": "Re&&joignez-nous sur Twitter", "miUndo": "Ann&&uler", @@ -91,5 +103,6 @@ "miViewSearch": "&&Rechercher", "miZoomIn": "&&Zoom avant", "miZoomOut": "Zoo&&m arrière", + "miZoomReset": "&&Réinitialiser le zoom", "okButton": "OK" } \ No newline at end of file diff --git a/i18n/fra/src/vs/code/node/cliProcessMain.i18n.json b/i18n/fra/src/vs/code/node/cliProcessMain.i18n.json index 93d88563105..c43c56298a3 100644 --- a/i18n/fra/src/vs/code/node/cliProcessMain.i18n.json +++ b/i18n/fra/src/vs/code/node/cliProcessMain.i18n.json @@ -4,5 +4,6 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "installing": "Installation..." + "installing": "Installation...", + "useId": "Veillez à utiliser l'ID d'extension complet. Exemple : {0}" } \ 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 6c08d56fce6..b62ee7fcdde 100644 --- a/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/fra/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -24,6 +24,7 @@ "lineNumbers": "Contrôle la visibilité des numéros de ligne", "mouseWheelScrollSensitivity": "Multiplicateur à utiliser pour le 'deltaX' et le 'deltaY' des événements de défilement de la roulette de la souris", "overviewRulerLanes": "Contrôle le nombre d'ornements pouvant s'afficher à la même position dans la règle d'aperçu", + "parameterHints": "Active les indicateurs de paramètres", "quickSuggestions": "Contrôle si les suggestions rapides doivent s'afficher ou non pendant la saisie", "quickSuggestionsDelay": "Contrôle le délai en ms au bout duquel les suggestions rapides s'affichent", "referenceInfos": "Contrôle si l'éditeur affiche des informations de référence pour les modes qui le prennent en charge", @@ -34,6 +35,7 @@ "selectionClipboard": "Contrôle si le presse-papiers primaire Linux doit être pris en charge.", "selectionHighlight": "Détermine si l'éditeur doit surligner les correspondances similaires à la sélection", "sideBySide": "Contrôle si l'éditeur de différences affiche les différences en mode côte à côte ou inline", + "stablePeek": "Garder les éditeurs d'aperçu ouverts même si l'utilisateur double-clique sur son contenu ou appuie sur la touche Échap.", "suggestOnTriggerCharacters": "Contrôle si les suggestions doivent s'afficher automatiquement durant la saisie de caractères de déclenchement", "tabSize": "Nombre d'espaces correspondant à une tabulation.", "tabSize.errorMessage": "'number' attendu. Notez que la valeur \"auto\" a été remplacée par le paramètre 'editor.detectIndentation'.", diff --git a/i18n/fra/src/vs/editor/contrib/folding/browser/folding.i18n.json b/i18n/fra/src/vs/editor/contrib/folding/browser/folding.i18n.json index fee7473ff7c..cc841d00cb5 100644 --- a/i18n/fra/src/vs/editor/contrib/folding/browser/folding.i18n.json +++ b/i18n/fra/src/vs/editor/contrib/folding/browser/folding.i18n.json @@ -11,6 +11,8 @@ "foldLevel3Action.label": "Niveau de pli 3", "foldLevel4Action.label": "Niveau de pli 4", "foldLevel5Action.label": "Niveau de pli 5", + "foldRecursivelyAction.label": "Plier de manière récursive", + "unFoldRecursivelyAction.label": "Déplier de manière récursive", "unfoldAction.label": "Déplier", "unfoldAllAction.label": "Déplier tout" } \ No newline at end of file diff --git a/i18n/fra/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json b/i18n/fra/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json index fc132bc9361..e0f7e3415bc 100644 --- a/i18n/fra/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json +++ b/i18n/fra/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json @@ -7,5 +7,7 @@ "markerAction.next.label": "Accéder à l'erreur ou l'avertissement suivant", "markerAction.previous.label": "Accéder à l'erreur ou l'avertissement précédent", "quickfix.multiple.label": "Corrections suggérées : ", - "quickfix.single.label": "Correction suggérée : " + "quickfix.single.label": "Correction suggérée : ", + "title.w_source": "({0}/{1}) [{2}]", + "title.wo_source": "({0}/{1})" } \ No newline at end of file diff --git a/i18n/fra/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/fra/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index 0059867cf59..050fa164c13 100644 --- a/i18n/fra/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/fra/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "Chargement en cours...", "meta.titleReference": " – {0} références", - "noResults": "Aucun résultat", "references.action.label": "Rechercher toutes les références", - "references.action.name": "Afficher les références" + "references.action.name": "Rechercher toutes les références" } \ No newline at end of file diff --git a/i18n/fra/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json b/i18n/fra/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json index abc2681c92a..71f2f1a06e8 100644 --- a/i18n/fra/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json +++ b/i18n/fra/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json @@ -8,5 +8,6 @@ "peekView.alternateTitle": "Références", "referenceCount": "{0} référence", "referencesCount": "{0} références", + "referencesFailre": "Échec de la résolution du fichier.", "treeAriaLabel": "Références" } \ No newline at end of file diff --git a/i18n/fra/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/fra/src/vs/editor/node/textMate/TMSyntax.i18n.json index 84cb155db9c..f0ff1264051 100644 --- a/i18n/fra/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/fra/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -4,11 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "invalid.injectTo": "Valeur non valide dans 'contributes.{0}.injectTo'. Il doit s'agir d'un tableau de noms de portées de langage. Valeur fournie : {1}", "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.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.", "invalid.scopeName": "Chaîne attendue dans 'contributes.{0}.scopeName'. Valeur fournie : {1}", "vscode.extension.contributes.grammars": "Ajoute des générateurs de jetons TextMate.", + "vscode.extension.contributes.grammars.injectTo": "Liste de noms des portées de langage auxquelles cette grammaire est injectée.", "vscode.extension.contributes.grammars.language": "ID de langage pour lequel cette syntaxe est ajoutée.", "vscode.extension.contributes.grammars.path": "Chemin du fichier tmLanguage. Le chemin est relatif au dossier d'extensions et commence généralement par './syntaxes/'.", "vscode.extension.contributes.grammars.scopeName": "Nom de portée TextMate utilisé par le fichier tmLanguage." diff --git a/i18n/fra/src/vs/languages/html/common/html.contribution.i18n.json b/i18n/fra/src/vs/languages/html/common/html.contribution.i18n.json index 7cd8dc5556c..d8e2d9340e6 100644 --- a/i18n/fra/src/vs/languages/html/common/html.contribution.i18n.json +++ b/i18n/fra/src/vs/languages/html/common/html.contribution.i18n.json @@ -10,7 +10,7 @@ "format.indentInnerHtml": "Mettez en retrait les sections et .", "format.maxPreserveNewLines": "Nombre maximal de sauts de ligne à conserver dans un bloc. Utilisez 'null' pour indiquer une valeur illimitée.", "format.preserveNewLines": "Spécifie si les sauts de ligne existants qui précèdent les éléments doivent être conservés. Fonctionne uniquement devant les éléments, pas dans les balises, ni pour du texte.", - "format.unformatted": "Liste des balises, séparées par des virgules, qui ne doivent pas être remises en forme. 'null' correspond par défaut à toutes les balises intralignes.", + "format.unformatted": "Liste des balises, séparées par des virgules, qui ne doivent pas être remises en forme. 'null' correspond par défaut à toutes les balises répertoriées à l'adresse https://www.w3.org/TR/html5/dom.html#phrasing-content.", "format.wrapLineLength": "Nombre maximal de caractères par ligne (0 = désactiver).", "htmlConfigurationTitle": "Configuration HTML" } \ 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 8887320c11d..d3ec3f4e080 100644 --- a/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/fra/src/vs/workbench/electron-browser/actions.i18n.json @@ -14,7 +14,8 @@ "newWindow": "Nouvelle fenêtre", "noFolderOpened": "Il n'existe actuellement aucun dossier ouvert à fermer dans cette instance.", "openRecent": "Ouvrir les éléments récents", - "openRecentPlaceHolder": "Sélectionner un chemin à ouvrir", + "openRecentPlaceHolder": "Sélectionner un chemin à ouvrir (maintenir la touche Ctrl enfoncée pour l'ouvrir dans une nouvelle fenêtre)", + "openRecentPlaceHolderMac": "Sélectionner un chemin (maintenir la touche Cmd enfoncée pour l'ouvrir dans une nouvelle fenêtre)", "reloadWindow": "Recharger la fenêtre", "toggleDevTools": "Activer/désactiver les outils de développement", "toggleFullScreen": "Plein écran", 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 eb0163f2efe..bfa3d6715c3 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 @@ -8,7 +8,8 @@ "file": "Fichier", "openFilesInNewWindow": "Après activation, les fichiers s'ouvrent dans une nouvelle fenêtre au lieu de réutiliser une instance existante.", "reopenFolders": "Contrôle la façon dont les dossiers sont rouverts après un redémarrage. Sélectionnez 'none' pour ne jamais rouvrir un dossier, 'one' pour rouvrir le dernier dossier utilisé, ou 'all' pour rouvrir tous les dossiers de votre dernière session.", - "updateChannel": "Configurez le canal de réception des mises à jour. Nécessite un redémarrage après une modification.", + "restoreFullscreen": "Contrôle si une fenêtre doit être restaurée en mode plein écran si elle a été fermée dans ce mode.", + "updateChannel": "Indiquez si vous recevez des mises à jour automatiques en provenance d'un canal de mises à jour. Un redémarrage est nécessaire en cas de modification.", "updateConfigurationTitle": "Mettre à jour la configuration", "view": "Affichage", "windowConfigurationTitle": "Configuration de la fenêtre", diff --git a/i18n/fra/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json index 90ff0c54172..56408a4d999 100644 --- a/i18n/fra/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json @@ -8,8 +8,8 @@ "conditionalBreakpointEditorAction": "Déboguer : point d'arrêt conditionnel", "debug": "Déboguer", "debugCategory": "Déboguer", - "debugConsole": "Console de débogage", "debugEvaluate": "Déboguer : évaluer", + "launchConfigDoesNotExist": "La configuration de lancement '{0}' n'existe pas.", "runToCursor": "Déboguer : exécuter jusqu'au curseur", "showDebugHover": "Déboguer : afficher par pointage", "toggleBreakpointAction": "Déboguer : activer/désactiver un point d'arrêt", diff --git a/i18n/fra/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json b/i18n/fra/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json index 8191be65c49..7d4644fa0d2 100644 --- a/i18n/fra/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json @@ -6,10 +6,12 @@ { "DebugTaskNotFound": "preLaunchTask '{0}' introuvable.", "NewLaunchConfig": "Paramétrez le fichier de configuration de lancement pour votre application.", + "breakpointAdded": "Point d'arrêt ajouté, ligne {0}, fichier {1}", + "breakpointRemoved": "Point d'arrêt supprimé, ligne {0}, fichier {1}", "debugAdapterCrash": "Le processus de l'adaptateur de débogage s'est terminé de manière inattendue", "debugAnyway": "Déboguer quand même", "debugSourceNotAvailable": "La source {0} n'est pas disponible.", - "debugTypeMissing": "Propriété 'type' manquante pour la configuration sélectionnée dans launch.json.", + "debugTypeMissing": "Propriété 'type' manquante pour la configuration de lancement choisie.", "debugTypeNotSupported": "Le type de débogage '{0}' configuré n'est pas pris en charge.", "debuggingContinued": "Le débogage s'est poursuivi.", "debuggingPaused": "Débogage en pause. Raison : {0}, {1} {2}", diff --git a/i18n/fra/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json b/i18n/fra/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json index 089e08834c1..4b06f07cec3 100644 --- a/i18n/fra/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json @@ -4,9 +4,12 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "debugLinuxConfiguration": "Attributs de configuration de lancement spécifiques à Linux.", "debugName": "Le nom de la configuration s'affiche dans le menu déroulant de la configuration de lancement.", + "debugOSXConfiguration": "Attributs de configuration de lancement spécifiques à OS X.", "debugPrelaunchTask": "Tâche à exécuter avant le démarrage de la session de débogage.", "debugRequest": "Type de requête de configuration. Il peut s'agir de \"launch\" ou \"attach\".", "debugType": "Type de configuration.", + "debugWindowsConfiguration": "Attributs de configuration de lancement spécifiques à Windows.", "relativePathsNotConverted": "Les chemins relatifs ne sont plus convertis automatiquement en chemins absolus. Utilisez ${workspaceRoot} comme préfixe." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/fra/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index 0b9293388d1..cce714e3f6c 100644 --- a/i18n/fra/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -10,6 +10,7 @@ "app.launch.json.version": "Version de ce format de fichier.", "debugNoType": "Le 'type' de l'adaptateur de débogage ne peut pas être omis. Il doit s'agir du type 'string'.", "duplicateDebuggerType": "Le type de débogage '{0}' est déjà inscrit et a pour attribut '{1}'. Attribut '{1}' ignoré.", + "interactiveVariableNotFound": "L'adaptateur {0} ne contribue pas à la variable {1} spécifiée dans la configuration de lancement.", "selectDebug": "Sélectionner l'environnement", "vscode.extension.contributes.debuggers": "Ajoute des adaptateurs de débogage.", "vscode.extension.contributes.debuggers.args": "Arguments facultatifs à passer à l'adaptateur.", @@ -26,6 +27,7 @@ "vscode.extension.contributes.debuggers.runtime": "Runtime facultatif, si l'attribut de programme n'est pas un exécutable, mais qu'il nécessite un exécutable.", "vscode.extension.contributes.debuggers.runtimeArgs": "Arguments du runtime facultatif.", "vscode.extension.contributes.debuggers.type": "Identificateur unique de cet adaptateur de débogage.", + "vscode.extension.contributes.debuggers.variables": "Mappage à partir de variables interactives (par exemple, ${action.pickProcess}) dans 'launch.json' vers une commande.", "vscode.extension.contributes.debuggers.windows": "Paramètres spécifiques à Windows.", "vscode.extension.contributes.debuggers.windows.runtime": "Runtime utilisé pour Windows." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index a8212927be4..90367cce2f1 100644 --- a/i18n/fra/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,8 @@ "globalConsoleActionWin": "Ouvrir une nouvelle invite de commandes", "scopedConsoleActionMacLinux": "Ouvrir dans Terminal", "scopedConsoleActionWin": "Ouvrir dans l'invite de commandes", + "terminal.external.linuxExec": "Personnalise le terminal à exécuter sur Linux.", + "terminal.external.osxExec": "Personnalise l'application de terminal à exécuter sur OS X.", "terminal.external.windowsExec": "Personnalise le terminal à exécuter sur Windows.", "terminalConfigurationTitle": "Configuration du terminal" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index e079bb5916b..c303fd5c246 100644 --- a/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "Fermer", "deleteSure": "Voulez-vous vraiment désinstaller '{0}' ?", - "installExtension": "Installer l'extension", - "notFound": "Extension '{0}' non installée.", + "enableAction": "Activer", + "installAction": "Installer", + "installing": "Installation", + "restart": "Pour activer cette extension, cette fenêtre de code VS doit être redémarrée.\n\nVoulez-vous continuer ?", "restartNow": "Redémarrer maintenant", - "restartNow2": "Redémarrer maintenant", "showExtensionRecommendations": "Afficher les extensions recommandées", "showInstalledExtensions": "Afficher les extensions installées", "showOutdatedExtensions": "Afficher les extensions obsolètes", - "success-installed": "'{0}' a été installé correctement. Redémarrez pour l'activer.", - "success-uninstalled": "'{0}' a été désinstallé correctement. Redémarrez pour le désactiver.", - "uninstall": "Désinstaller l'extension" + "toggleExtensionsViewlet": "Afficher les extensions", + "uninstall": "Désinstaller", + "updateAction": "Mettre à jour" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json b/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json index d7ad76d4184..88e0225f70e 100644 --- a/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json @@ -5,6 +5,7 @@ // Do not edit this file. It is machine generated. { "extensions": "Extensions", + "outdatedExtensions": "{0} extensions obsolètes", "reloadNow": "Redémarrer maintenant", "success": "Les extensions ont été installées correctement. Redémarrez pour les activer.", "successSingle": "{0} a été installé correctement. Redémarrez pour l'activer." diff --git a/i18n/fra/src/vs/workbench/parts/files/browser/fileActions.i18n.json b/i18n/fra/src/vs/workbench/parts/files/browser/fileActions.i18n.json index cc84bac33b6..b724bbda2ac 100644 --- a/i18n/fra/src/vs/workbench/parts/files/browser/fileActions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/browser/fileActions.i18n.json @@ -4,13 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "addToWorkingFiles": "Ajouter le fichier actif aux fichiers de travail", - "closeAllFiles": "Fermer tous les fichiers", - "closeAllLabel": "Fermer tous les fichiers", - "closeFile": "Fermer le fichier", - "closeLabel": "Fermer le fichier", - "closeOtherFiles": "Fermer les autres fichiers", - "closeOtherLabel": "Fermer les autres fichiers", + "collapseExplorerFolders": "Réduire les dossiers dans l'explorateur", "compareFiles": "Comparer des fichiers", "compareSource": "Sélectionner pour comparer", "compareWith": "Comparer à '{0}'", @@ -31,7 +25,7 @@ "fileNameExistsError": "Un fichier ou dossier **{0}** existe déjà à cet emplacement. Choisissez un autre nom.", "filePathTooLongError": "Le nom **{0}** correspond à un chemin d'accès trop long. Choisissez un nom plus court.", "focusFilesExplorer": "Focus sur l'Explorateur de fichiers", - "focusWorkingFiles": "Focus sur les fichiers de travail", + "focusOpenEditors": "Mettre le focus sur la vue des éditeurs ouverts", "globalCompareFile": "Comparer le fichier actif à...", "importFiles": "Importer des fichiers", "invalidFileNameError": "Le nom **{0}** est non valide en tant que nom de fichier ou de dossier. Choisissez un autre nom.", @@ -39,25 +33,21 @@ "newFile": "Nouveau fichier", "newFolder": "Nouveau dossier", "newUntitledFile": "Nouveau fichier sans titre", - "noFileOpen": "Il n'existe actuellement aucun fichier ouvert à fermer.", - "noWorkingFiles": "Il n'existe actuellement aucun fichier de travail.", - "openFileToAdd": "Ouvrir d'abord un fichier pour l'ajouter aux fichiers de travail", "openFileToCompare": "Ouvrez d'abord un fichier pour le comparer à un autre fichier.", "openFileToShow": "Ouvrir d'abord un fichier pour l'afficher dans l'Explorateur", "openFolderFirst": "Ouvrez d'abord un dossier pour y créer des fichiers ou des dossiers.", - "openNextWorkingFile": "Ouvrir le fichier de travail suivant", - "openPreviousWorkingFile": "Ouvrir le fichier de travail précédent", "openToSide": "Ouvrir sur le côté", "pasteFile": "Coller", "permDelete": "Supprimer définitivement", "refresh": "Actualiser", + "refreshExplorer": "Actualiser l'explorateur", "rename": "Renommer", - "reopenClosedFile": "Rouvrir le fichier fermé", "replaceButtonLabel": "&&Remplacer", "retry": "Réessayer", "revert": "Rétablir le fichier", "save": "Enregistrer", "saveAll": "Enregistrer tout", + "saveAllInGroup": "Enregistrer tout dans le groupe", "saveAs": "Enregistrer sous...", "saveFiles": "Enregistrer les fichiers à l'intégrité compromise", "showInExplorer": "Afficher le fichier actif dans l'Explorateur", diff --git a/i18n/fra/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index 42ebe33cec9..a150066eef5 100644 --- a/i18n/fra/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -9,7 +9,7 @@ "autoSave": "Contrôle l'enregistrement automatique des fichiers à l'intégrité comprise. Valeur acceptées : \"{0}\", \"{1}\", \"{2}\". Si la valeur est \"{3}\", vous pouvez configurer le délai dans \"files.autoSaveDelay\".", "autoSaveDelay": "Contrôle le délai en ms au bout duquel un fichier à l'intégrité compromise est enregistré automatiquement. S'applique uniquement quand \"files.autoSave\" a la valeur \"{0}\"", "binaryFileEditor": "Éditeur de fichier binaire", - "dynamicHeight": "Contrôle si la hauteur de la section des fichiers de travail doit s'adapter dynamiquement ou non au nombre d'éléments.", + "dynamicHeight": "Contrôle si la hauteur de la section des éditeurs ouverts doit s'adapter dynamiquement ou non au nombre d'éléments.", "encoding": "Encodage du jeu de caractères par défaut à utiliser durant la lecture et l'écriture des fichiers.", "eol": "Caractère de fin de ligne par défaut.", "exclude": "Configurez les modèles Glob pour l'exclusion des fichiers et des dossiers.", @@ -17,14 +17,11 @@ "explorerConfigurationTitle": "Configuration de l'Explorateur de fichiers", "files.exclude.boolean": "Modèle Glob auquel les chemins de fichiers doivent correspondre. Affectez la valeur true ou false pour activer ou désactiver le modèle.", "files.exclude.when": "Vérification supplémentaire des frères d'un fichier correspondant. Utilisez $(basename) comme variable pour le nom de fichier correspondant.", - "filesCategory": "Fichiers", "filesConfigurationTitle": "Configuration des fichiers", - "maxVisible": "Nombre maximal de fichiers de travail à afficher avant l'apparition des barres de défilement.", - "openWorkingFile": "Ouvrir un fichier de travail par le nom", + "openEditorsVisible": "Nombre d'éditeurs affichés dans le volet Éditeurs ouverts. Définissez la valeur 0 pour masquer le volet.", "showExplorerViewlet": "Afficher l'Explorateur", "textFileEditor": "Éditeur de fichier texte", "trimTrailingWhitespace": "Si l'option est activée, l'espace blanc de fin est découpé quand vous enregistrez un fichier.", "view": "Affichage", - "watcherExclude": "Configurez les modèles Glob des chemins de fichiers à exclure de la surveillance des fichiers. La modification de ce paramètre nécessite un redémarrage. Si vous constatez que le code consomme beaucoup de temps processeur au démarrage, excluez les dossiers volumineux pour réduire la charge initiale.", - "workingFilesPicker": "Ouvrir un fichier de travail par le nom" + "watcherExclude": "Configurez les modèles Glob des chemins de fichiers à exclure de la surveillance des fichiers. La modification de ce paramètre nécessite un redémarrage. Si vous constatez que le code consomme beaucoup de temps processeur au démarrage, excluez les dossiers volumineux pour réduire la charge initiale." } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/fra/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index 811f66dd719..88f96521ca5 100644 --- a/i18n/fra/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "Utiliser les modifications locales et remplacer le contenu du disque", + "acceptLocalChanges": "Remplacer", "compareChanges": "Comparer", "conflictingFileHasChanged": "Le contenu du fichier sur disque a changé. Le côté gauche de l'éditeur de comparaison a été actualisé. Passez le contenu en revue, puis résolvez à nouveau les conflits.", "discard": "Abandonner", @@ -13,8 +13,8 @@ "readonlySaveError": "Échec de l'enregistrement de '{0}' : le fichier est protégé en écriture. Sélectionnez 'Remplacer' pour supprimer la protection.", "resolveSaveConflict": "{0} - Résoudre le conflit d'enregistrement", "retry": "Réessayer", - "revertLocalChanges": "Ignorer les modifications locales et restaurer le contenu sur disque", + "revertLocalChanges": "Rétablir", "saveConflictDiffLabel": "{0} - sur disque ↔ dans {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.", - "userGuide": "Utilisez les actions de la barre d'outils de l'éditeur pour **annuler** vos modifications, ou pour **remplacer** le contenu sur disque par le contenu incluant vos changements" + "userGuide": "Sélectionnez **Rétablir** pour abandonner vos modifications ou **Remplacer** pour remplacer le contenu sur disque par vos modifications" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/git/browser/gitActions.i18n.json b/i18n/fra/src/vs/workbench/parts/git/browser/gitActions.i18n.json index 7a119e47daa..6f731c0f804 100644 --- a/i18n/fra/src/vs/workbench/parts/git/browser/gitActions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/git/browser/gitActions.i18n.json @@ -5,13 +5,11 @@ // Do not edit this file. It is machine generated. { "authFailed": "Échec de l'authentification durant l'opération git remote.", - "branch": "Branch", - "branch2": "Branch", - "checkout": "Checkout", "cleanChangesLabel": "&&Supprimer les modifications", "commit": "Commit", "commitAll": "Valider tout", "commitAll2": "Valider tout", + "commitMessage": "Valider le message", "commitStaged": "Valider le contenu en zone de transit", "commitStaged2": "Valider le contenu en zone de transit", "confirmPublishMessage": "Voulez-vous vraiment publier '{0}' sur '{1}' ?", @@ -36,13 +34,9 @@ "openFile": "Ouvrir le fichier", "publish": "Publier", "publishPickMessage": "Choisissez un dépôt distant où publier la branche '{0}' :", - "pull": "Pull", - "pullWithRebase": "Tirer (rebaser)", - "push": "Push", "refresh": "Actualiser", "stageAllChanges": "Stocker tout en zone de transit", "stageChanges": "Étape", - "sync": "Synchroniser", "synchronizing": "Synchronisation...", "undoAllChanges": "Nettoyer tout", "undoChanges": "Nettoyer", diff --git a/i18n/fra/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json b/i18n/fra/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json index a9a3b9b867a..c09f2b404d9 100644 --- a/i18n/fra/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json @@ -7,6 +7,7 @@ "alreadyCheckedOut": "La branche {0} est déjà la branche active", "branchAriaLabel": "{0}, branche git", "checkoutBranch": "Branche sur {0}", + "checkoutRemoteBranch": "Branche distante à {0}", "checkoutTag": "Balise sur {0}", "createBranch": "Créer une branche {0}", "noBranches": "Aucune autre branche", diff --git a/i18n/fra/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/fra/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 5e3e8ea7bb0..a8370f65759 100644 --- a/i18n/fra/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -8,17 +8,23 @@ "cancel": "Annuler", "cantOpen": "Impossible d'ouvrir cette ressource git.", "cantOpenResource": "Impossible d'ouvrir cette ressource git.", - "changesFromIndex": "{0} - Modifications de l'index", - "changesFromTree": "{0} - Modifications sur {1}", + "changesFromIndex": "{0} (index)", + "changesFromIndexDesc": "{0} - Modifications de l'index", + "changesFromTree": "{0} ({1})", + "changesFromTreeDesc": "{0} - Modifications sur {1}", "checkNativeConsole": "Un problème s'est produit durant l'exécution d'une opération git. Examinez la sortie, ou utilisez une console pour vérifier l'état de votre dépôt.", "configureUsernameEmail": "Configurez votre nom d'utilisateur et votre adresse de messagerie git.", "download": "Télécharger", - "gitIndexChanges": "{0} - Modifications de l'index", - "gitIndexChangesRenamed": "{0} - Renommé - Modifications de l'index", - "gitMergeChanges": "{0} - Fusionner les modifications", + "gitIndexChanges": "{0} (index) ↔ {1}", + "gitIndexChangesDesc": "{0} - Modifications de l'index", + "gitIndexChangesRenamed": "{0} ← {1}", + "gitIndexChangesRenamedDesc": "{0} - Renommé - Modifications de l'index", + "gitMergeChanges": "{0} (fusion) ↔ {1}", + "gitMergeChangesDesc": "{0} - Fusionner les modifications", "neverShowAgain": "Ne plus afficher", "showOutput": "Afficher la sortie", "unmergedChanges": "Vous devez tout d'abord résoudre les modifications non fusionnées avant de valider vos modifications.", "updateGit": "Il semble que git {0} soit installé. Code fonctionne mieux avec git >=2.0.0.", - "workingTreeChanges": "{0} - Modifications de l'arborescence de travail" + "workingTreeChanges": "{0} (TÊTE) ↔ {1}", + "workingTreeChangesDesc": "{0} - Modifications de l'arborescence de travail" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/fra/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index ae513cce6c6..8cb1d5d9927 100644 --- a/i18n/fra/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -9,6 +9,8 @@ "gitCommands": "Commandes Git", "gitConfigurationTitle": "Configuration Git", "gitEnabled": "Vérification de l'activation de git", + "gitLargeRepos": "Toujours autoriser la gestion des grands référentiels par le code.", + "gitLongCommit": "Si les messages de validation longs doivent faire l'objet d'un avertissement.", "gitPath": "Chemin d'accès à l'exécutable git", "gitPendingChangesBadge": "{0} changements en attente", "gitProgressBadge": "État d'exécution de git", diff --git a/i18n/fra/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json b/i18n/fra/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json index a011d433e83..6c27976029c 100644 --- a/i18n/fra/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json @@ -6,6 +6,7 @@ { "commitMessage": "Message (appuyez sur {0} pour valider)", "commitMessageAriaLabel": "Git : tapez le message de validation, puis appuyez sur {0} pour valider", + "longCommit": "Il est recommandé de limiter la première ligne de la validation à 50 caractères. N'hésitez pas à utiliser d'autres lignes pour ajouter des informations.", "needMessage": "Indiquez un message de validation. Vous pouvez toujours appuyer sur **{0}** pour valider les modifications. S'il existe des modifications en zone de transit, seules ces dernières sont validées ; sinon, toutes les modifications sont validées.", "nothingToCommit": "Quand il existe des modifications à valider, tapez le message de validation et appuyez sur **{0}** pour valider les modifications. S'il existe des modifications en zone de transit, seules ces dernières sont validées ; sinon, toutes les modifications sont validées.", "showOutput": "Afficher la sortie Git", diff --git a/i18n/fra/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/fra/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index 5dee045f091..9a73c458e79 100644 --- a/i18n/fra/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0} : {1}", "QuickCommandsAction.label": "Afficher les commandes de l'éditeur", "actionNotEnabled": "La commande '{0}' n'est pas activée dans le contexte actuel.", "canNotRun": "La commande '{0}' ne peut pas être exécutée à partir d'ici.", diff --git a/i18n/fra/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/fra/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index b0557b6a37c..12269085828 100644 --- a/i18n/fra/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,24 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "Effacer les résultats de la recherche", - "CollapseAllAction.label": "Réduire", - "ConfigureGlobalExclusionsAction.label": "Ouvrir les paramètres", - "RefreshAction.label": "Actualiser", - "RemoveAction.label": "Supprimer", - "SelectOrRemoveAction.removeLabel": "Supprimer", - "SelectOrRemoveAction.selectLabel": "Sélectionner", "ariaSearchResultsStatus": "La recherche a retourné {0} résultats dans {1} fichiers", - "defaultLabel": "entrée", - "fileMatchAriaLabel": "{0} correspondances dans le fichier {1} du dossier {2}, Résultat de la recherche", - "findInFolder": "Rechercher dans le dossier", - "findPlaceHolder": "Appuyez sur Entrée pour effectuer la recherche, ou sur Échap pour l'annuler", "globLabel": "{0} quand {1}", "global.searchScope.folders": "fichiers exclus via les paramètres", - "label.Search": "Rechercher : tapez le terme de recherche, puis appuyez sur Entrée pour lancer la recherche, ou sur Échap pour l'annuler", "label.excludes": "Modèles d'exclusion de recherche", "label.global.excludes": "Modèles d'exclusion de recherche configurés", "label.includes": "Modèles d'inclusion de recherche", "moreSearch": "Activer/désactiver les détails de la recherche", - "noMatches": "aucune correspondance", "noResultsExcludes": "Résultats introuvables avec l'exclusion de '{0}' - ", "noResultsFound": "Résultats introuvables. Vérifiez les paramètres d'exclusion configurés - ", "noResultsIncludes": "Résultats introuvables dans '{0}' - ", "noResultsIncludesExcludes": "Résultats introuvables pour '{0}' excluant '{1}' - ", "openSettings.message": "Ouvrir les paramètres", - "patternDescription": "Utiliser des modèles Glob", - "patternHelpInclude": "Modèle de correspondance. Exemple : ****/*.js** pour établir une correspondance avec tous les fichiers JavaScript, ou **myFolder/**** pour établir une correspondance avec le dossier indiqué et tous ses enfants.\n\n**Référence** :\n***** correspond à 0 caractère ou plus\n**?** correspond à 1 caractère\n****** correspond à zéro répertoire ou plus\n**[a-z]** correspond à une plage de caractères\n**{a,b}** correspond à tous les modèles)", - "regexp.validationFailure": "L'expression correspond à tout", + "replaceAll.confirm.button": "Remplacer", + "replaceAll.confirmation.title": "Remplacer tout", "rerunSearch.message": "Rechercher à nouveau", "rerunSearchInAll.message": "Rechercher à nouveau dans tous les fichiers", "searchCanceled": "La recherche a été annulée avant l'obtention de résultats - ", - "searchMatch": "{0} correspondance trouvée", - "searchMatches": "{0} correspondances trouvées", "searchMaxResultsWarning": "Le jeu de résultats contient uniquement un sous-ensemble de toutes les correspondances. Soyez plus précis dans votre recherche de façon à limiter les résultats retournés.", - "searchResultAria": "{0}, Résultat de la recherche", "searchScope.excludes": "fichiers à exclure", "searchScope.includes": "fichiers à inclure", "treeAriaLabel": "Résultats de la recherche" diff --git a/i18n/fra/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json b/i18n/fra/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json index 6585b65718e..2c935428bfd 100644 --- a/i18n/fra/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json +++ b/i18n/fra/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json @@ -5,7 +5,10 @@ // Do not edit this file. It is machine generated. { "close": "Fermer", + "insiderBuilds": "Les builds Insider deviennent des builds quotidiennes !", "license": "Lire la licence", "licenseChanged": "Nos termes du contrat de licence ont changé. Prenez un instant pour les consulter.", + "neverShowAgain": "Ne plus jamais afficher", + "readmore": "Lire la suite", "releaseNotes": "Bienvenue dans {0} v{1} ! Voulez-vous lire les notes de publication ?" } \ No newline at end of file diff --git a/i18n/fra/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/fra/src/vs/workbench/services/history/browser/history.i18n.json index 96f1e8eb0c5..09569428fbb 100644 --- a/i18n/fra/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/fra/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[Hôte de développement d'extension] - {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} - {1}", "prefixWorkspaceTitle": "{0} - {1} - {2}", "prefixWorkspaceTitleMac": "{0} - {1}", diff --git a/i18n/ita/extensions/php/package.i18n.json b/i18n/ita/extensions/php/package.i18n.json index dad08d06721..25737db8047 100644 --- a/i18n/ita/extensions/php/package.i18n.json +++ b/i18n/ita/extensions/php/package.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "configuration.title": "Opzioni di configurazione PHP", + "configuration.title": "PHP", "configuration.validate.enable": "Indica se la convalida PHP è abilitata o meno.", "configuration.validate.executablePath": "Punta all'eseguibile di PHP.", "configuration.validate.run": "Indica se il linter viene eseguito durante il salvataggio o la digitazione." diff --git a/i18n/ita/extensions/typescript/package.i18n.json b/i18n/ita/extensions/typescript/package.i18n.json index 031cbae4bc1..a4d03817253 100644 --- a/i18n/ita/extensions/typescript/package.i18n.json +++ b/i18n/ita/extensions/typescript/package.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "configuration.typescript": "Configurazione di TypeScript", + "configuration.typescript": "TypeScript", "format.insertSpaceAfterCommaDelimiter": "Consente di definire la gestione dello spazio dopo una virgola di delimitazione", "format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": "Consente di definire la gestione dello spazio dopo la parola chiave function per funzioni anonime", "format.insertSpaceAfterKeywordsInControlFlowStatements": "Consente di definire la gestione dello spazio dopo le parole chiave nell'istruzione del flusso di controllo", diff --git a/i18n/ita/src/vs/code/electron-main/menus.i18n.json b/i18n/ita/src/vs/code/electron-main/menus.i18n.json index 65eb52ea0fa..51fe6cd094c 100644 --- a/i18n/ita/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/ita/src/vs/code/electron-main/menus.i18n.json @@ -45,7 +45,6 @@ "miLicense": "&&Visualizza licenza", "miMarker": "&&Errori e avvisi...", "miMoveSidebar": "&&Sposta barra laterale", - "miNavigateHistory": "&&Esplora cronologia", "miNewFile": "&&Nuovo file", "miNewWindow": "&&Nuova finestra", "miOpen": "&&Apri...", @@ -62,8 +61,8 @@ "miQuit": "Chiudi {0}", "miRedo": "&&Ripeti", "miReleaseNotes": "&&Note sulla versione", - "miReopenClosedFile": "&&Riapri un file chiuso", "miReplace": "&&Sostituisci", + "miReplaceInFiles": "Sostituisci nei &&file", "miReportIssues": "&&Segnala problemi", "miRestartToUpdate": "Riavvia per aggiornare...", "miRevert": "Ripristina f&&ile", @@ -79,6 +78,7 @@ "miToggleMenuBar": "Attiva/Disattiva &&barra dei menu", "miToggleOutput": "Attiva/Disattiva &&output", "miTogglePanel": "Attiva/Disattiva &&pannello", + "miToggleRenderControlCharacters": "Attiva/Disattiva &&caratteri di controllo", "miToggleRenderWhitespace": "Attiva/Disattiva rendering &&spazi vuoti", "miToggleSidebar": "Attiva/Disattiva &&barra laterale", "miToggleWordWrap": "Attiva/Disattiva &&ritorno a capo automatico", @@ -87,6 +87,7 @@ "miUserVoice": "&&Richiedi funzionalità", "miViewDebug": "&&Debug", "miViewExplorer": "&&Esplora risorse", + "miViewExtensions": "E&&stensioni", "miViewGit": "&&GIT", "miViewSearch": "&&Cerca", "miZoomIn": "&&Zoom avanti", diff --git a/i18n/ita/src/vs/code/node/cliProcessMain.i18n.json b/i18n/ita/src/vs/code/node/cliProcessMain.i18n.json index 8b6ad71cd4e..5845d1dc263 100644 --- a/i18n/ita/src/vs/code/node/cliProcessMain.i18n.json +++ b/i18n/ita/src/vs/code/node/cliProcessMain.i18n.json @@ -3,4 +3,6 @@ * 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 +{ + "useId": "Assicurarsi di usare l'ID estensione completo, ad esempio {0}" +} \ 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 f9549f5a399..79cabce2f8c 100644 --- a/i18n/ita/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/ita/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -9,7 +9,7 @@ "cursorBlinking": "Controlla l'animazione per l'intermittenza del cursore. I valori accettati sono: 'blink', 'visible' e 'hidden'", "cursorStyle": "Controlla lo stile del cursore. I valori accettati sono 'block' e 'line'", "detectIndentation": "All'apertura di un file, `editor.tabSize` e `editor.insertSpaces` verranno rilevati in base al contenuto del file.", - "editorConfigurationTitle": "Configurazione editor", + "editorConfigurationTitle": "Editor", "folding": "Controlla se per l'editor è abilitata la riduzione del codice", "fontFamily": "Controlla la famiglia di caratteri.", "fontLigatures": "Abilita i caratteri legatura", @@ -27,6 +27,8 @@ "quickSuggestions": "Controlla se durante la digitazione verranno o meno visualizzati i suggerimenti rapidi", "quickSuggestionsDelay": "Controlla il ritardo in ms dopo il quale verranno visualizzati i suggerimenti rapidi", "referenceInfos": "Controlla se l'editor visualizza le informazioni di riferimento per le modalità supportate", + "renderControlCharacters": "Controlla se l'editor deve eseguire il rendering dei caratteri di controllo", + "renderIndentGuides": "Controlla se l'editor deve eseguire il rendering delle guide con rientro", "renderWhitespace": "Controlla se l'editor deve eseguire il rendering dei spazi vuoti", "roundedSelection": "Controlla se gli angoli delle selezioni sono arrotondati", "rulers": "Colonne in corrispondenza delle quali visualizzare i righelli verticali", diff --git a/i18n/ita/src/vs/editor/contrib/indentation/common/indentation.i18n.json b/i18n/ita/src/vs/editor/contrib/indentation/common/indentation.i18n.json index 7d3d96e1d8e..83a5ac0b48b 100644 --- a/i18n/ita/src/vs/editor/contrib/indentation/common/indentation.i18n.json +++ b/i18n/ita/src/vs/editor/contrib/indentation/common/indentation.i18n.json @@ -11,5 +11,6 @@ "indentationToSpaces": "Converti rientro in spazi", "indentationToTabs": "Converti rientro in tabulazioni", "selectTabWidth": "Seleziona dimensione tabulazione per il file corrente", + "toggleRenderControlCharacters": "Attiva/Disattiva caratteri di controllo", "toggleRenderWhitespace": "Attiva/Disattiva rendering spazi vuoti" } \ No newline at end of file diff --git a/i18n/ita/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/ita/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index c873febae5b..6f29d157555 100644 --- a/i18n/ita/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/ita/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "Caricamento...", "meta.titleReference": " - Riferimenti di {0}", - "noResults": "Nessun risultato", "references.action.label": "Trova tutti i riferimenti", - "references.action.name": "Mostra i riferimenti" + "references.action.name": "Trova tutti i riferimenti" } \ No newline at end of file diff --git a/i18n/ita/src/vs/languages/html/common/html.contribution.i18n.json b/i18n/ita/src/vs/languages/html/common/html.contribution.i18n.json index 5fecc78042a..5c27bee4e68 100644 --- a/i18n/ita/src/vs/languages/html/common/html.contribution.i18n.json +++ b/i18n/ita/src/vs/languages/html/common/html.contribution.i18n.json @@ -12,5 +12,5 @@ "format.preserveNewLines": "Indica se è necessario mantenere interruzioni di riga esistenti prima degli elementi. Funziona solo prima degli elementi e non all'interno di tag o per il testo.", "format.unformatted": "Elenco di tag, separati da virgole, che non devono essere riformattati. Con 'null' viene usata l'impostazione predefinita che prevede l'uso di tutti tag inline.", "format.wrapLineLength": "Numero massimo di caratteri per riga (0 = disabilita).", - "htmlConfigurationTitle": "Configurazione HTML" + "htmlConfigurationTitle": "HTML" } \ 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 adc786eb626..ea45841bdbe 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 @@ -9,8 +9,8 @@ "openFilesInNewWindow": "Se abilitata, apre i file in una nuova finestra invece di riutilizzare un'istanza esistente.", "reopenFolders": "Controlla la modalità di riapertura delle cartelle dopo un riavvio. Selezionare 'none' per non riaprire mai una cartella, 'one' per riaprire l'ultima cartella usata oppure 'all' per riaprire tutte le cartelle dell'ultima sessione.", "updateChannel": "Consente di configurare il canale di aggiornamento da cui ricevere gli aggiornamenti. Richiede un riavvio dopo la modifica.", - "updateConfigurationTitle": "Configurazione aggiornamenti", + "updateConfigurationTitle": "Aggiorna", "view": "Visualizza", - "windowConfigurationTitle": "Configurazione finestre", + "windowConfigurationTitle": "Finestra", "zoomLevel": "Consente di modificare il livello di zoom della finestra. Il valore originale è 0 e ogni incremento superiore (ad esempio 1) o inferiore (ad esempio -1) rappresenta un aumento o una diminuzione del 20% della percentuale di zoom. È anche possibile immettere valori decimali per modificare il livello di zoom con maggiore granularità." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/ita/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index 80ec77e935b..cb41f7d663c 100644 --- a/i18n/ita/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -6,7 +6,7 @@ { "DebugConfig.failed": "Non è possibile creare il file 'launch.json' all'interno della cartella '.vscode' ({0}).", "app.launch.json.configurations": "Elenco delle configurazioni. Aggiungere nuove configurazioni o modificare quelle esistenti.", - "app.launch.json.title": "Configurazione di avvio", + "app.launch.json.title": "Avvia", "app.launch.json.version": "Versione di questo formato di file.", "debugNoType": "L'adattatore di debug 'type' non può essere omesso e deve essere di tipo 'string'.", "duplicateDebuggerType": "Il tipo di debug '{0}' è già registrato e include l'attributo '{1}'. L'attributo '{1}' verrà ignorato.", diff --git a/i18n/ita/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json index 7631bc6a2a1..b366af252ef 100644 --- a/i18n/ita/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/emmet/node/emmet.contribution.i18n.json @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "emmetConfigurationTitle": "Configurazione Emmet", - "expandAbbreviationAction": "Emmet: Espandi abbreviazione", + "emmetConfigurationTitle": "Emmet", + "emmetPreferences": "Preferenze usate per modificare il comportamento di alcune azioni e i resolver di Emmet.", + "emmetSyntaxProfiles": "Consente di definire il profilo per la sintassi specificata oppure di usare un profilo personalizzato con regole specifiche.", "triggerExpansionOnTab": "Se abilitate, le abbreviazioni Emmet vengono espanse quando si preme TAB." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index 2e6840386c2..ad1645e74a8 100644 --- a/i18n/ita/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,7 @@ "globalConsoleActionWin": "Apri nuovo prompt dei comandi", "scopedConsoleActionMacLinux": "Apri nel terminale", "scopedConsoleActionWin": "Apri nel prompt dei comandi", + "terminal.external.linuxExec": "Personalizza il terminale da eseguire in Linux.", "terminal.external.windowsExec": "Personalizza il terminale da eseguire in Windows.", - "terminalConfigurationTitle": "Configurazione del terminale" + "terminalConfigurationTitle": "Terminale esterno" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index 1bf7c1c4515..df22ab6073d 100644 --- a/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,18 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "Chiudi", + "clearExtensionsInput": "Cancella input estensioni", "deleteSure": "Disinstallare '{0}'?", - "installExtension": "Installa estensione", - "notFound": "L'estensione '{0}' non è installata.", + "enableAction": "Abilita", + "installAction": "Installa", + "installExtensions": "Installa estensioni", + "installing": "Installazione", + "postUninstallMessage": "{0} è stato disinstallato. Riavviare per disattivarlo.", "restartNow": "Riavvia ora", - "restartNow2": "Riavvia ora", "showExtensionRecommendations": "Mostra suggerimenti per estensioni", "showInstalledExtensions": "Mostra estensioni installate", "showOutdatedExtensions": "Mostra estensioni obsolete", - "success-installed": "'{0}' è stato installato. Riavviare per abilitarlo.", - "success-uninstalled": "'{0}' è stato disinstallato. Riavviare per disattivarlo.", - "uninstall": "Disinstalla estensione" + "showPopularExtensions": "Mostra estensioni più richieste", + "uninstall": "Disinstalla", + "updateAction": "Aggiorna" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.i18n.json b/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.i18n.json index 97a2a17c7c1..0ea7de6cf90 100644 --- a/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/extensions/electron-browser/extensionsQuickOpen.i18n.json @@ -4,26 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "author": "Autore", - "cancel": "Annulla", - "description": "Descrizione", - "extensionAriaLabel": "{0}, {1}, selezione estensioni", - "galleryExtensionsHandlerAriaLabel": "Digitare per ridurre il numero di estensioni elencate nella raccolta", - "install": "Installa estensione", - "installCountMultiple": "{0} è stato scaricato {1} volte.", - "installCountOne": "{0} è stato scaricato una sola volta.", - "installCountZero": "{0} non è stato ancora scaricato.", - "installNow": "Installa ora", - "installPrompt": "Installare '{0}'?", - "license": "Licenza", - "localExtensionsHandlerAriaLabel": "Digitare per ridurre il numero di estensioni installate elencate", - "name": "Nome", - "noExtensionsInstalled": "Non sono state trovate estensioni", - "noExtensionsToInstall": "Non sono state trovate estensioni", - "noOutdatedExtensions": "Non sono state trovate estensioni obsolete", - "noRecommendedExtensions": "Non ci sono estensioni suggerite", - "nowInstalling": "È in corso l'installazione di '{0}'...", - "outdatedExtensionsHandlerAriaLabel": "Digitare per ridurre il numero di estensioni obsolete elencate", - "readme": "Leggimi", - "update": "Aggiorna estensione" + "manage": "Premere INVIO per gestire le estensioni.", + "noExtensionsToInstall": "Digitare un nome di estensione", + "searchFor": "Premere INVIO per cercare '{0}' nel Marketplace." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index 232aa9a6e9b..20c298d3c56 100644 --- a/i18n/ita/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -14,17 +14,13 @@ "eol": "Carattere di fine riga predefinito.", "exclude": "Consente di configurare i criteri di ricerca GLOB per escludere file e cartelle.", "explore": "Esplora risorse", - "explorerConfigurationTitle": "Configurazione di Esplora file", + "explorerConfigurationTitle": "Esplora file", "files.exclude.boolean": "Criterio GLOB da usare per trovare percorsi file. Impostare su True o False per abilitare o disabilitare il criterio.", "files.exclude.when": "Controllo aggiuntivo sugli elementi di pari livello di un file corrispondente. Usare $(basename) come variabile del nome file corrispondente.", - "filesCategory": "File", - "filesConfigurationTitle": "Configurazione file", - "maxVisible": "Numero massimo di file di lavoro da visualizzare prima che appaiano le barre di scorrimento.", - "openWorkingFile": "Apri file di lavoro per nome", + "filesConfigurationTitle": "File", "showExplorerViewlet": "Mostra Esplora risorse", "textFileEditor": "Editor file di testo", "trimTrailingWhitespace": "Se è abilitato, taglierà lo spazio vuoto quando si salva un file.", "view": "Visualizza", - "watcherExclude": "Consente di configurare i criteri GLOB dei percorsi file da escludere dal controllo dei file. Se si modifica questa impostazione, è necessario riavviare. Quando si nota che Code consuma troppo tempo della CPU all'avvio, è possibile escludere le cartelle di grandi dimensioni per ridurre il carico iniziale.", - "workingFilesPicker": "Apri file di lavoro per nome" + "watcherExclude": "Consente di configurare i criteri GLOB dei percorsi file da escludere dal controllo dei file. Se si modifica questa impostazione, è necessario riavviare. Quando si nota che Code consuma troppo tempo della CPU all'avvio, è possibile escludere le cartelle di grandi dimensioni per ridurre il carico iniziale." } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/ita/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index fa8ea10d96f..a3f9bca7948 100644 --- a/i18n/ita/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "Usa modifiche locali e sovrascrivi contenuto del disco", + "acceptLocalChanges": "Sovrascrivi", "compareChanges": "Confronta", "conflictingFileHasChanged": "Il contenuto del file su disco è cambiato e il lato sinistro dell'editor di confronto è stato aggiornato. Rivedere e risolvere di nuovo.", "discard": "Rimuovi", diff --git a/i18n/ita/src/vs/workbench/parts/files/electron-browser/textFileServices.i18n.json b/i18n/ita/src/vs/workbench/parts/files/electron-browser/textFileServices.i18n.json index b9c9ff5498f..6b9d94c484d 100644 --- a/i18n/ita/src/vs/workbench/parts/files/electron-browser/textFileServices.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/files/electron-browser/textFileServices.i18n.json @@ -7,9 +7,11 @@ "allFiles": "Tutti i file", "cancel": "Annulla", "dontSave": "&&Non salvare", + "moreFile": "...1 altro file non visualizzato", + "moreFiles": "...{0} altri file non visualizzati", "save": "&&Salva", "saveAll": "&&Salva tutto", "saveChangesDetail": "Le modifiche apportate andranno perse se non vengono salvate.", "saveChangesMessage": "Salvare le modifiche apportate a {0}?", - "saveChangesMessages": "Salvare le modifiche apportate ai file seguenti?" + "saveChangesMessages": "Salvare le modifiche apportate ai file seguenti di {0}?" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json index 073cc3b9be4..da051b07db5 100644 --- a/i18n/ita/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json @@ -9,5 +9,7 @@ "openFile": "Apri file", "openInEditor": "Passa alla visualizzazione editor", "stageSelectedLines": "Gestisci temporaneamente le righe selezionate", - "switchToChangesView": "Passa alla visualizzazione modifiche" + "switchToChangesView": "Passa alla visualizzazione modifiche", + "workbenchStage": "Prepara", + "workbenchUnstage": "Annulla preparazione" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/ita/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 68915ab8efe..68dd6009d9a 100644 --- a/i18n/ita/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -9,16 +9,22 @@ "cantOpen": "Non è possibile aprire questa risorsa GIT.", "cantOpenResource": "Non è possibile aprire questa risorsa GIT.", "changesFromIndex": "{0} - Modifiche nell'indice", - "changesFromTree": "{0} - Modifiche in {1}", + "changesFromIndexDesc": "{0} - Modifiche nell'indice", + "changesFromTree": "{0} ({1})", + "changesFromTreeDesc": "{0} - Modifiche in {1}", "checkNativeConsole": "Si è verificato un errore durante l'esecuzione di un'operazione git. Esaminare l'output oppure usare la console per controllare lo stato del repository.", "configureUsernameEmail": "Configurare il nome utente e l'indirizzo di posta elettronica di GIT.", "download": "Scarica", "gitIndexChanges": "{0} - Modifiche nell'indice", + "gitIndexChangesDesc": "{0} - Modifiche nell'indice", "gitIndexChangesRenamed": "{0} - Rinominato - Modifiche nell'indice", + "gitIndexChangesRenamedDesc": "{0} - Rinominato - Modifiche nell'indice", "gitMergeChanges": "{0} - Esegui merge delle modifiche", + "gitMergeChangesDesc": "{0} - Esegui merge delle modifiche", "neverShowAgain": "Non visualizzare più questo messaggio", "showOutput": "Mostra output", "unmergedChanges": "Prima di eseguire il commit delle modifiche, è necessario risolvere le modifiche non sottoposte a merge.", "updateGit": "La versione installata di GIT è la {0}. Per il corretto funzionamento di Code è consigliabile usare una versione di GIT non inferiore alla 2.0.0.", - "workingTreeChanges": "{0} - Modifiche nell'albero di lavoro" + "workingTreeChanges": "{0} - Modifiche nell'albero di lavoro", + "workingTreeChangesDesc": "{0} - Modifiche nell'albero di lavoro" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/ita/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index db11633c281..6c66f955fd0 100644 --- a/i18n/ita/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -7,7 +7,7 @@ "git": "GIT", "gitAutoFetch": "Indica se il recupero automatico è abilitato.", "gitCommands": "Comandi GIT", - "gitConfigurationTitle": "Configurazione GIT", + "gitConfigurationTitle": "GIT", "gitEnabled": "GIT abilitato", "gitPath": "Percorso dell'eseguibile di GIT", "gitPendingChangesBadge": "{0} modifiche in sospeso", diff --git a/i18n/ita/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/ita/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index 82a6e1e43e8..4b2aadbb0f1 100644 --- a/i18n/ita/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0}: {1}", "QuickCommandsAction.label": "Mostra comandi dell'editor", "actionNotEnabled": "Il comando '{0}' non è abilitato nel contesto corrente.", "canNotRun": "Non è possibile eseguire il comando '{0}' da questa posizione.", 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 46619300330..a0ad288e6db 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 @@ -5,12 +5,9 @@ // Do not edit this file. It is machine generated. { "commandsHandlerDescriptionDefault": "Mostra ed esegui comandi", - "desc.mac": "Mostra errori o avvisi", - "desc.win": "Mostra errori e avvisi", "gotoLineDescriptionMac": "Vai alla riga", "gotoLineDescriptionWin": "Vai alla riga", - "gotoSymbolDescriptionNormalMac": "Vai al simbolo", - "gotoSymbolDescriptionNormalWin": "Vai al simbolo", - "gotoSymbolDescriptionScoped": "Vai al simbolo per categoria", + "gotoSymbolDescription": "Vai al simbolo nel file", + "gotoSymbolDescriptionScoped": "Vai al simbolo nel file per categoria", "helpDescription": "Visualizza la Guida" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/search/browser/search.contribution.i18n.json b/i18n/ita/src/vs/workbench/parts/search/browser/search.contribution.i18n.json index fb013400c42..ff68d805702 100644 --- a/i18n/ita/src/vs/workbench/parts/search/browser/search.contribution.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/search/browser/search.contribution.i18n.json @@ -9,10 +9,9 @@ "exclude.when": "Controllo aggiuntivo sugli elementi di pari livello di un file corrispondente. Usare $(basename) come variabile del nome file corrispondente.", "findInFolder": "Trova nella cartella", "name": "Cerca", - "openAnythingHandlerDescription": "Apri file e simboli per nome", - "openSymbolDescriptionNormal": "Apri simbolo per nome", - "searchConfigurationTitle": "Configurazione ricerca", - "showSearchViewlet": "Mostra Cerca", + "openAnythingHandlerDescription": "Apri file e simboli globali per nome", + "openSymbolDescriptionNormal": "Apri qualsiasi simbolo per nome", + "searchConfigurationTitle": "Cerca", "showTriggerActions": "Mostra tutti i simboli", "view": "Visualizza" } \ No newline at end of file diff --git a/i18n/ita/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/ita/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index e461030d944..5a5dc1cd25c 100644 --- a/i18n/ita/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/ita/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,26 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "Cancella risultati della ricerca", - "CollapseAllAction.label": "Comprimi", - "ConfigureGlobalExclusionsAction.label": "Apri impostazioni", - "RefreshAction.label": "Aggiorna", - "RemoveAction.label": "Rimuovi", - "SelectOrRemoveAction.removeLabel": "Rimuovi", - "SelectOrRemoveAction.selectLabel": "Seleziona", "ariaSearchResultsStatus": "La ricerca ha restituito {0} risultati in {1} file", - "defaultLabel": "input", - "fileMatchAriaLabel": "{0} corrispondenze nel file {1} della cartella {2}, risultato della ricerca", - "findInFolder": "Trova nella cartella", - "findPlaceHolder": "Premere INVIO per cercare o ESC per annullare", "globLabel": "{0} quando {1}", "global.searchScope.folders": "file esclusi tramite impostazioni", - "label.Search": "Cerca: digitare il termine di ricerca e premere INVIO per cercare oppure ESC per annullare", "label.excludes": "Criteri di esclusione per la ricerca", "label.global.excludes": "Criteri di esclusione per la ricerca configurati", "label.includes": "Criteri di inclusione per la ricerca", "moreSearch": "Attiva/Disattiva dettagli ricerca", - "noMatches": "nessuna corrispondenza", "noResultsExcludes": "Non sono stati trovati risultati escludendo '{0}' - ", "noResultsFound": "Non sono stati trovati risultati. Rivedere le impostazioni relative alle esclusioni configurate - ", "noResultsIncludes": "Non sono stati trovati risultati in '{0}' - ", "noResultsIncludesExcludes": "Non sono stati trovati risultati in '{0}' escludendo '{1}' - ", "openSettings.message": "Apri impostazioni", - "patternDescription": "Usa criteri GLOB", - "patternHelpInclude": "Criterio da usare per la ricerca, ad esempio ****/*.js** per cercare tutti i file JavaScript oppure **cartellaPersonale/**** per cercare la cartella specificata con tutti gli elementi figlio.\n\n**Informazioni di riferimento**:\n***** consente di cercare 0 o più caratteri\n**?** consente di cercare 1 carattere\n****** consente di cercare zero o più directory\n**[a-z]** consente di cercare un intervallo di caratteri\n**{a,b}** consente di cercare uno qualsiasi dei criteri", - "regexp.validationFailure": "Espressione corrispondente a qualsiasi valore", + "removeAll.confirmation.message": "Rimuovere {0} occorrenze in {1} file?", + "removeAll.message": "Sono state rimosse {0} occorrenze in {1} file.", + "replaceAll.confirm.button": "Sostituisci", + "replaceAll.confirmation.title": "Sostituisci tutto", "rerunSearch.message": "Cerca di nuovo", "rerunSearchInAll.message": "Cerca di nuovo in tutti i file", "searchCanceled": "La ricerca è stata annullata prima della visualizzazione dei risultati - ", - "searchMatch": "{0} corrispondenza trovata", - "searchMatches": "{0} corrispondenze trovate", "searchMaxResultsWarning": "Il set di risultati contiene solo un subset di tutte le corrispondenze. Eseguire una ricerca più specifica per ridurre il numero di risultati.", - "searchResultAria": "{0}, risultato della ricerca", "searchScope.excludes": "file da escludere", "searchScope.includes": "file da includere", "treeAriaLabel": "Risultati ricerca" diff --git a/i18n/ita/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/ita/src/vs/workbench/services/history/browser/history.i18n.json index 58059cfdfb7..4f80a69a114 100644 --- a/i18n/ita/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/ita/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[Host di sviluppo estensione] - {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} - {1}", "prefixWorkspaceTitle": "{0} - {1} - {2}", "prefixWorkspaceTitleMac": "{0} - {1}", diff --git a/i18n/ita/src/vs/workbench/services/request/node/requestService.i18n.json b/i18n/ita/src/vs/workbench/services/request/node/requestService.i18n.json index ffd266f1040..8278149a73d 100644 --- a/i18n/ita/src/vs/workbench/services/request/node/requestService.i18n.json +++ b/i18n/ita/src/vs/workbench/services/request/node/requestService.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "httpConfigurationTitle": "Configurazione HTTP", + "httpConfigurationTitle": "HTTP", "localFileNotFound": "Il file non è stato trovato.", "proxy": "Impostazione proxy da usare. Se non è impostata, verrà ottenuta dalle variabili di ambiente http_proxy e https_proxy", "strictSSL": "Indica se il certificato del server proxy deve essere verificato in base all'elenco di CA specificate." diff --git a/i18n/jpn/extensions/typescript/out/typescriptServiceClient.i18n.json b/i18n/jpn/extensions/typescript/out/typescriptServiceClient.i18n.json index 2c8a66fdf93..5e890c469ca 100644 --- a/i18n/jpn/extensions/typescript/out/typescriptServiceClient.i18n.json +++ b/i18n/jpn/extensions/typescript/out/typescriptServiceClient.i18n.json @@ -7,7 +7,7 @@ "channelName": "TypeScript", "noServerFound": "パス {0} は、有効な tsserver インストールを指していません。TypeScript 言語機能は使用できなくなります。", "serverCouldNotBeStarted": "TypeScript 言語サーバーを起動できません。エラー メッセージ: {0}", - "serverDied": "Typescript 言語サービスは、直前の 5 分間に 5 回、予期せずに停止しました。障害報告を開くことをご検討ください。", - "serverDiedAfterStart": "Typesrript 言語サービスは、開始直後に 5 回停止しました。サービスは再開されません。障害報告を開いてください。", + "serverDied": "TypeScript 言語サービスは、直前の 5 分間に 5 回、予期せずに停止しました。バグ報告を開くことをご検討ください。", + "serverDiedAfterStart": "TypeScript 言語サービスは、開始直後に 5 回停止しました。サービスは再開されません。バグ報告を開いてください。", "versionNumber.custom": "カスタム" } \ 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 d73d61268f6..f6df4d2917f 100644 --- a/i18n/jpn/extensions/typescript/package.i18n.json +++ b/i18n/jpn/extensions/typescript/package.i18n.json @@ -18,6 +18,7 @@ "javascript.validate.enable": "JavaScript の検証を有効/無効にします", "typescript.reloadProjects.title": "TypeScript プロジェクトを再度読み込みます", "typescript.tsdk.desc": "使用する tsserver と lib*.d.ts ファイルが含まれているフォルダーのパスを指定します。", + "typescript.tsserver.experimentalAutoBuild": "試験的な自動ビルドを有効にします。1.9 dev または 2.x tsserver バージョンと、変更後に VS Code の再起動が必要です。", "typescript.tsserver.trace": "TS サーバーに送信されるメッセージのトレースをオンにします", "typescript.useCodeSnippetsOnMethodSuggest.dec": "パラメーター シグネチャを含む完全な関数。", "typescript.validate.enable": "TypeScript の検証を有効/無効にします" 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 f13623133a8..520cfbfcf6a 100644 --- a/i18n/jpn/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/jpn/src/vs/code/electron-main/menus.i18n.json @@ -35,6 +35,9 @@ "miExit": "終了(&&X)", "miFind": "検索(&&F)", "miFindInFiles": "ファイル内を検索(&&I)", + "miFocusFirstGroup": "左のグループ(&&L)", + "miFocusSecondGroup": "横のグループ(&&S)", + "miFocusThirdGroup": "右のグループ(&&R)", "miForward": "転送(&&F)", "miGotoDefinition": "定義に移動(&&D)", "miGotoFile": "ファイルに移動(&&F)...", @@ -43,11 +46,13 @@ "miInstallingUpdate": "更新プログラムをインストールしています...", "miLastCheckedAt": "最終確認: {0}", "miLicense": "ライセンスを表示(&&V)", - "miMarker": "エラーと警告(&&E)...", + "miMarker": "問題(&&P)", "miMoveSidebar": "サイドバーを移動(&&M)", - "miNavigateHistory": "履歴を参照(&&N)", "miNewFile": "新規ファイル(&&N)", "miNewWindow": "新しいウィンドウ(&&N)", + "miNextEditor": "次のエディター(&&N)", + "miNextEditorInGroup": "グループ内の次の使用されているエディター(&&N)", + "miNextGroup": "次のグループ(&&N)", "miOpen": "開く(&&O)...", "miOpenFile": "ファイルを開く(&&O)...", "miOpenFolder": "フォルダーを開く(&&F)...", @@ -58,11 +63,14 @@ "miOpenWorkspaceSettings": "ワークスペース設定(&&W)", "miPaste": "貼り付け(&&P)", "miPreferences": "基本設定(&&P)", + "miPreviousEditor": "前のエディター(&&P)", + "miPreviousEditorInGroup": "グループ内の前の使用されているエディター(&&P)", + "miPreviousGroup": "前のグループ(&&P)", "miPrivacyStatement": "プライバシーについて(&&P)", "miQuit": "{0} を終了", "miRedo": "やり直し(&&R)", "miReleaseNotes": "リリース ノート(&&R)", - "miReopenClosedFile": "閉じたファイルをもう一度開く(&&R)", + "miReopenClosedEditor": "閉じたエディターを再度開く(&&R)", "miReplace": "置換(&&R)", "miReportIssues": "問題の報告(&&I)", "miRestartToUpdate": "更新のために再起動します...", @@ -73,14 +81,18 @@ "miSelectAll": "すべて選択(&&S)", "miSelectTheme": "配色テーマ(&&C)", "miSplitEditor": "エディターを分割(&&E)", - "miToggleDebugConsole": "デバッグ コンソールの切り替え(&&B)", + "miSwitchEditor": "エディターの切り替え(&&E)", + "miSwitchGroup": "グループの切り替え(&&G)", + "miToggleDebugConsole": "デバッグ コンソール(&&B)", "miToggleDevTools": "開発者ツールの切り替え(&&T)", "miToggleFullScreen": "全画面表示の切り替え(&&F)", + "miToggleIntegratedTerminal": "統合ターミナル(&&I)", "miToggleMenuBar": "メニュー バーの切り替え(&&B)", - "miToggleOutput": "出力の切り替え(&&O)", + "miToggleOutput": "出力(&&O)", "miTogglePanel": "パネルの切り替え(&&P)", "miToggleRenderWhitespace": "空白文字の表示の切り替え(&&R)", "miToggleSidebar": "サイドバーの切り替え(&&T)", + "miToggleStatusbar": "ステータス バーの表示切り替え(&&T)", "miToggleWordWrap": "折り返しの切り替え(&&W)", "miTwitter": "ツイッターに参加(&&J)", "miUndo": "元に戻す(&&U)", @@ -91,5 +103,6 @@ "miViewSearch": "検索(&&S)", "miZoomIn": "拡大(&&Z)", "miZoomOut": "縮小(&&U)", + "miZoomReset": "ズームのリセット(&&R)", "okButton": "OK" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/code/node/cliProcessMain.i18n.json b/i18n/jpn/src/vs/code/node/cliProcessMain.i18n.json index 99e4e22e1bf..4139f4103a5 100644 --- a/i18n/jpn/src/vs/code/node/cliProcessMain.i18n.json +++ b/i18n/jpn/src/vs/code/node/cliProcessMain.i18n.json @@ -12,5 +12,5 @@ "successInstall": "拡張機能 '{0}' v{1} が正常にインストールされました!", "successUninstall": "拡張機能 '{0}' が正常にアンインストールされました!", "uninstalling": "{0} をアンインストールしています...", - "useId": "完全な拡張 ID を使用していることを確認してください。例: {0}" + "useId": "完全な拡張機能 ID を使用していることを確認してください。例: {0}" } \ No newline at end of file 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 a6dbcc98ae0..803767b0de2 100644 --- a/i18n/jpn/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/jpn/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -9,7 +9,6 @@ "cursorBlinking": "カーソルのアニメーションの点滅を制御します。指定できる値は 'blink'、'visible'、'hidden' です", "cursorStyle": "カーソルのスタイルを制御します。指定できる値は 'block' と 'line' です", "detectIndentation": "ファイルを開くと、そのファイルの内容に基づいて `editor.tabSize` と `editor.insertSpaces` が検出されます。", - "dismissPeekOnEsc": "ESC キーを押すと、プレビュー エディターが閉じます", "editorConfigurationTitle": "エディターの構成", "folding": "エディターでコードの折りたたみを有効にするかどうかを制御します", "fontFamily": "フォント ファミリを制御します。", @@ -25,6 +24,7 @@ "lineNumbers": "行番号の表示を制御します", "mouseWheelScrollSensitivity": "マウス ホイール スクロール イベントの `deltaX` と `deltaY` で使用される乗数", "overviewRulerLanes": "概要ルーラーの同じ位置に表示できる装飾の数を制御します", + "parameterHints": "パラメーター ヒントを有効にする", "quickSuggestions": "入力中にクイック候補を表示するかどうかを制御します", "quickSuggestionsDelay": "クイック候補が表示されるまでの待ち時間 (ミリ秒) を制御します", "referenceInfos": "サポートしているモードについての参照情報をエディターで表示するかどうかを制御します", @@ -35,6 +35,7 @@ "selectionClipboard": "Linux の PRIMARY クリップボードをサポートするかどうかを制御します。", "selectionHighlight": "エディターで選択範囲に類似する一致箇所を強調表示するかどうかを制御します", "sideBySide": "差分エディターが差分を横に並べて表示するか、行内に表示するかを制御します", + "stablePeek": "エディターのコンテンツをダブルクリックするか、Esc キーを押しても、ピーク エディターを開いたままにします。", "suggestOnTriggerCharacters": "トリガー文字の入力時に候補が自動的に表示されるようにするかどうかを制御します", "tabSize": "タブ 1 つに相当するスペースの数。", "tabSize.errorMessage": "'number' が必要です。`editor.detectIndentation` 設定によって値 \"auto\" が置き換えられていることに注意してください。", diff --git a/i18n/jpn/src/vs/editor/contrib/folding/browser/folding.i18n.json b/i18n/jpn/src/vs/editor/contrib/folding/browser/folding.i18n.json index 50345f227e7..e7c045d6804 100644 --- a/i18n/jpn/src/vs/editor/contrib/folding/browser/folding.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/folding/browser/folding.i18n.json @@ -11,6 +11,8 @@ "foldLevel3Action.label": "折りたたみレベル 3", "foldLevel4Action.label": "折りたたみレベル 4", "foldLevel5Action.label": "折りたたみレベル 5", + "foldRecursivelyAction.label": "再帰的に折りたたむ", + "unFoldRecursivelyAction.label": "再帰的に展開する", "unfoldAction.label": "展開", "unfoldAllAction.label": "すべて展開" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json b/i18n/jpn/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json index 8c250694ecd..b6883832003 100644 --- a/i18n/jpn/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json @@ -7,5 +7,7 @@ "markerAction.next.label": "次のエラーまたは警告へ移動", "markerAction.previous.label": "前のエラーまたは警告へ移動", "quickfix.multiple.label": "修正候補: ", - "quickfix.single.label": "修正候補: " + "quickfix.single.label": "修正候補: ", + "title.w_source": "({0}/{1}) [{2}]", + "title.wo_source": "({0}/{1})" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/jpn/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index 8f85178b9d6..0d587daaad5 100644 --- a/i18n/jpn/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "読み込んでいます...", "meta.titleReference": " - {0} の参照", - "noResults": "結果がありません", "references.action.label": "すべての参照の検索", - "references.action.name": "参照の表示" + "references.action.name": "すべての参照の検索" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json b/i18n/jpn/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json index ee2cfa0dc20..f7611ef055e 100644 --- a/i18n/jpn/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json +++ b/i18n/jpn/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json @@ -9,5 +9,6 @@ "peekView.alternateTitle": "参照", "referenceCount": "{0} 個の参照", "referencesCount": "{0} 個の参照", + "referencesFailre": "ファイルを解決できませんでした。", "treeAriaLabel": "参照" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/jpn/src/vs/editor/node/textMate/TMSyntax.i18n.json index 860ec75db7b..273bed17a38 100644 --- a/i18n/jpn/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/jpn/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -4,11 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "invalid.injectTo": "`contributes.{0}.injectTo` の値が無効です。言語の範囲名の配列である必要があります。指定された値: {1}", "invalid.language": "`contributes.{0}.language` で不明な言語です。提供された値: {1}", "invalid.path.0": "`contributes.{0}.path` に文字列が必要です。提供された値: {1}", "invalid.path.1": "拡張機能のフォルダー ({2}) の中に `contributes.{0}.path` ({1}) が含まれている必要があります。これにより拡張を移植できなくなる可能性があります。", "invalid.scopeName": "`contributes.{0}.scopeName` には文字列が必要です。提供された値: {1}", "vscode.extension.contributes.grammars": "TextMate トークナイザーを提供します。", + "vscode.extension.contributes.grammars.injectTo": "この文法が挿入される言語の範囲名の一覧。", "vscode.extension.contributes.grammars.language": "この構文の提供先の言語識別子です。", "vscode.extension.contributes.grammars.path": "tmLanguage ファイルのパス。拡張機能フォルダーの相対パスであり、通常 './syntaxes/' で始まります。", "vscode.extension.contributes.grammars.scopeName": "tmLanguage ファイルにより使用される TextMate スコープ名。" diff --git a/i18n/jpn/src/vs/languages/html/common/html.contribution.i18n.json b/i18n/jpn/src/vs/languages/html/common/html.contribution.i18n.json index 990054b5d3c..de7ba11edfc 100644 --- a/i18n/jpn/src/vs/languages/html/common/html.contribution.i18n.json +++ b/i18n/jpn/src/vs/languages/html/common/html.contribution.i18n.json @@ -10,7 +10,7 @@ "format.indentInnerHtml": " セクションと セクションをインデントします。", "format.maxPreserveNewLines": "1 つのチャンク内に保持できる改行の最大数。無制限にするには、'null' を使います。", "format.preserveNewLines": "要素の前にある既存の改行を保持するかどうか。要素の前でのみ機能し、タグの内側やテキストに対しては機能しません。", - "format.unformatted": "再フォーマットしてはならないタグを、コンマで区切ってリストにします。'null' は、既定値の \"すべてのインライン タグ\" を表します。", + "format.unformatted": "再フォーマットしてはならないタグの、コンマ区切りの一覧。'null' の場合、既定で https://www.w3.org/TR/html5/dom.html#phrasing-content にリストされているすべてのタグになります。", "format.wrapLineLength": "1 行あたりの最大文字数 (0 = 無効にする)。", "htmlConfigurationTitle": "HTML 構成" } \ 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 52a4dec6d85..3f68cbe6ada 100644 --- a/i18n/jpn/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/jpn/src/vs/workbench/electron-browser/actions.i18n.json @@ -15,7 +15,8 @@ "newWindow": "新しいウィンドウ", "noFolderOpened": "このインスタンスで現在開いているフォルダーがないので、閉じられません。", "openRecent": "最近開いた項目", - "openRecentPlaceHolder": "開くにはパスを選択します", + "openRecentPlaceHolder": "パスを選択して開く (Ctrl キーを押しながら新しいウィンドウで開く)", + "openRecentPlaceHolderMac": "パスを選択 (Cmd キーを押しながら新しいウィンドウで開く)", "reloadWindow": "ウィンドウの再読み込み", "toggleDevTools": "開発者ツールの切り替え", "toggleFullScreen": "全画面表示の切り替え", 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 6b6a9295ed0..3bb9d07a4ca 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 @@ -8,7 +8,8 @@ "file": "ファイル", "openFilesInNewWindow": "有効にすると、既存のインスタンスを再利用せずに新しいウィンドウでファイルを開きます。", "reopenFolders": "再起動後にフォルダーを再度開く方法を制御します。'none' を選択するとフォルダーを再度開くことはありません。'one' を選択すると最後に作業したフォルダーを再度開きます。'all' を選択すると前回のセッションのフォルダーすべてを再度開きます。", - "updateChannel": "更新プログラムの受信元の更新チャネルを構成します。変更後に再起動が必要です。", + "restoreFullscreen": "全画面表示モードで終了した場合に、ウィンドウを全画面表示モードに復元するかどうかを制御します。", + "updateChannel": "更新チャネルから自動更新を受信するかどうかを構成します。変更後に再起動が必要です。", "updateConfigurationTitle": "更新構成", "view": "表示", "windowConfigurationTitle": "ウィンドウ構成", diff --git a/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json index a039074cdb5..b3c4d20a118 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json @@ -10,6 +10,7 @@ "debugCategory": "デバッグ", "debugEvaluate": "デバッグ: 評価", "debugPanel": "デバッグ コンソール", + "launchConfigDoesNotExist": "起動の構成 '{0}' がありません。", "runToCursor": "デバッグ: カーソル行の前まで実行", "showDebugHover": "デバッグ: ホバーの表示", "toggleBreakpointAction": "デバッグ: ブレークポイントの切り替え", diff --git a/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json index ecd31f7d253..2265a6cb67b 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json @@ -6,10 +6,12 @@ { "DebugTaskNotFound": "preLaunchTask '{0}' が見つかりませんでした。", "NewLaunchConfig": "アプリケーションの起動構成ファイルをセットアップしてください。", + "breakpointAdded": "ブレークポイントを追加しました。行 {0}、ファイル {1}", + "breakpointRemoved": "ブレークポイントを削除しました。行 {0}、ファイル {1}", "debugAdapterCrash": "デバッグ アダプター プロセスが予期せず終了しました", "debugAnyway": "このままデバッグを続ける", "debugSourceNotAvailable": "ソース {0} を利用できません。", - "debugTypeMissing": "選択された構成のプロパティ 'type' が launch.json にありません。", + "debugTypeMissing": "選択された起動構成のプロパティ 'type' がありません。", "debugTypeNotSupported": "構成されているデバッグの種類 '{0}' はサポートされていません。", "debuggingContinued": "デバッグは続行されました。", "debuggingPaused": "デバッグは一時停止されました、理由 {0}、{1} {2}", diff --git a/i18n/jpn/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json index 42c25147ad3..562d89209a5 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "debugLinuxConfiguration": "Linux 固有の起動構成の属性。", "debugName": "構成の名前。起動構成のドロップダウン メニューに表示されます。", + "debugOSXConfiguration": "OS X 固有の起動構成の属性。", "debugPrelaunchTask": "デバッグ セッションの開始前に実行するタスク。", "debugRequest": "構成の要求の種類。\"launch\" または \"attach\" です。", "debugType": "構成の種類。", + "debugWindowsConfiguration": "Windows 固有の起動構成の属性。", "internalConsoleOptions": "内部デバッグ コンソールの動作を制御します。", "relativePathsNotConverted": "相対パスが絶対パスに自動的に変換されなくなります。${workspaceRoot} をプレフィックスとして使用することを考慮してください。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/jpn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index 9a77d443d50..4b85fe998a6 100644 --- a/i18n/jpn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -10,6 +10,7 @@ "app.launch.json.version": "このファイル形式のバージョン。", "debugNoType": "デバッグ アダプター 'type' は省略不可で、型 'string' でなければなりません。", "duplicateDebuggerType": "デバッグの種類 '{0}' は既に登録されており、属性 '{1}' があります、属性 '{1}' は無視されます。", + "interactiveVariableNotFound": "アダプター {0} は、起動構成で指定されている変数 {1} を反映していません。", "selectDebug": "環境の選択", "vscode.extension.contributes.debuggers": "デバッグ アダプターを提供します。", "vscode.extension.contributes.debuggers.args": "アダプターに渡すオプションの引数。", @@ -26,6 +27,7 @@ "vscode.extension.contributes.debuggers.runtime": "プログラム属性が実行可能でなく、ランタイムが必要な場合のオプション ランタイム。", "vscode.extension.contributes.debuggers.runtimeArgs": "オプションのランタイム引数。", "vscode.extension.contributes.debuggers.type": "このデバッグ アダプターの一意識別子。", + "vscode.extension.contributes.debuggers.variables": "`launch.json` 内の対話型の変数 (例: ${action.pickProcess}) からコマンドへマッピングしています。", "vscode.extension.contributes.debuggers.windows": "Windows 固有の設定。", "vscode.extension.contributes.debuggers.windows.runtime": "Windows で使用されるランタイム。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index 003c7164787..9aab792c5bc 100644 --- a/i18n/jpn/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,8 @@ "globalConsoleActionWin": "新しいコマンド プロンプトを開く", "scopedConsoleActionMacLinux": "ターミナルで開く", "scopedConsoleActionWin": "コマンド プロンプトで開く", + "terminal.external.linuxExec": "どのターミナルを Linux で実行するかをカスタマイズします。", + "terminal.external.osxExec": "どのターミナル アプリケーションを OS X で実行するかをカスタマイズします。", "terminal.external.windowsExec": "どのターミナルを Windows で実行するかをカスタマイズします。", "terminalConfigurationTitle": "外部ターミナルの構成" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index 090fcc6d9ea..dbf0e118f44 100644 --- a/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "閉じる", "deleteSure": "'{0}' をアンインストールしてもよろしいですか?", - "installExtension": "拡張機能のインストール", - "notFound": "拡張機能 '{0}' がインストールされていません。", + "enableAction": "有効", + "installAction": "インストール", + "installing": "インストールしています", + "restart": "この拡張機能を有効にするには、VS Code のこのウィンドウを再起動する必要があります。\n\n続行しますか?", "restartNow": "今すぐ再起動", - "restartNow2": "今すぐ再起動", "showExtensionRecommendations": "拡張機能のおすすめの表示", "showInstalledExtensions": "インストール済みの拡張機能の表示", "showOutdatedExtensions": "古くなった拡張機能の表示", - "success-installed": "'{0}' は正常にインストールされました。有効にするには再起動してください。", - "success-uninstalled": "'{0}' は正常にアンインストールされました。非アクティブ化するには再起動してください。", - "uninstall": "拡張機能のアンインストール" + "toggleExtensionsViewlet": "拡張機能を表示する", + "uninstall": "アンインストール", + "updateAction": "更新" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json b/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json index d20a73f619c..7c92ed531b4 100644 --- a/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json @@ -5,6 +5,7 @@ // Do not edit this file. It is machine generated. { "extensions": "拡張機能", + "outdatedExtensions": "{0} 古くなった拡張機能", "reloadNow": "今すぐ再起動", "success": "拡張機能は正常にインストールされました。有効にするには再起動してください。", "successSingle": "{0} は正常にインストールされました。有効にするには再起動してください。" diff --git a/i18n/jpn/src/vs/workbench/parts/files/browser/fileActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/browser/fileActions.i18n.json index 895553803a6..2d93d2209bc 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/browser/fileActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/browser/fileActions.i18n.json @@ -4,13 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "addToWorkingFiles": "アクティブ ファイルを作業ファイルに追加する", - "closeAllFiles": "すべてのファイルを閉じる", - "closeAllLabel": "すべてのファイルを閉じる", - "closeFile": "ファイルを閉じる", - "closeLabel": "ファイルを閉じる", - "closeOtherFiles": "その他のファイルを閉じる", - "closeOtherLabel": "その他のファイルを閉じる", + "collapseExplorerFolders": "エクスプローラーのフォルダーを折りたたむ", "compareFiles": "ファイルの比較", "compareSource": "比較対象の選択", "compareWith": "'{0}' と比較", @@ -31,7 +25,7 @@ "fileNameExistsError": "**{0}** というファイルまたはフォルダーはこの場所に既に存在します。別の名前を指定してください。", "filePathTooLongError": "名前 **{0}** のパスが長すぎます。名前を短くしてください。", "focusFilesExplorer": "ファイル エクスプローラーにフォーカスを置く", - "focusWorkingFiles": "作業ファイルにフォーカス", + "focusOpenEditors": "開いているエディターのビューにフォーカスする", "globalCompareFile": "アクティブ ファイルを比較しています...", "importFiles": "ファイルのインポート", "invalidFileNameError": "名前 **{0}** がファイル名またはフォルダー名として無効です。別の名前を指定してください。", @@ -39,25 +33,21 @@ "newFile": "新しいファイル", "newFolder": "新しいフォルダー", "newUntitledFile": "無題の新規ファイル", - "noFileOpen": "開いており閉じるファイルが現在ありません。", - "noWorkingFiles": "作業ファイルが現在ありません。", - "openFileToAdd": "まずファイルを開いてから作業ファイルに追加してください", "openFileToCompare": "まずファイルを開いてから別のファイルと比較してください", "openFileToShow": "エクスプローラーでファイルを表示するには、ファイルをまず開く必要があります", "openFolderFirst": "フォルダー内にファイルやフォルダーを作成するには、フォルダーをまず開く必要があります。", - "openNextWorkingFile": "次の作業ファイルを開く", - "openPreviousWorkingFile": "前の作業ファイルを開く", "openToSide": "横に並べて開く", "pasteFile": "貼り付け", "permDelete": "完全に削除", "refresh": "最新の情報に更新", + "refreshExplorer": "エクスプローラーを最新表示する", "rename": "名前変更", - "reopenClosedFile": "閉じたファイルをもう一度開く", "replaceButtonLabel": "置換(&&R)", "retry": "再試行", "revert": "ファイルを元に戻す", "save": "保存", "saveAll": "すべて保存", + "saveAllInGroup": "グループ内のすべてを保存する", "saveAs": "名前を付けて保存...", "saveFiles": "ダーティ ファイルを保存", "showInExplorer": "アクティブ ファイルをエクスプローラーで表示", diff --git a/i18n/jpn/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index fbc75edefa6..8f56fd73674 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -9,7 +9,7 @@ "autoSave": "ダーティ ファイルの自動保存を制御します。有効な値: \"{0}\"、\"{1}\"、\"{2}\"。\"{3}\" に設定すると、\"files.autoSaveDelay\" で遅延を構成できます。", "autoSaveDelay": "ダーティ ファイルの自動保存の遅延をミリ秒単位で制御します。\"files.autoSave\" が \"{0}\" に設定されている場合のみ適用されます", "binaryFileEditor": "バイナリ ファイル エディター", - "dynamicHeight": "作業ファイル セクションの高さを要素数に合わせて動的に調整するかどうか制御します。", + "dynamicHeight": "開いているエディターのセクションの高さを要素の数に合わせて動的に調整するかどうかを制御します。", "encoding": "ファイルの読み取り/書き込みで使用する既定の文字セット エンコーディング。", "eol": "既定の改行文字。", "exclude": "ファイルとフォルダーを除外するための glob パターンを構成します。", @@ -17,14 +17,11 @@ "explorerConfigurationTitle": "ファイル エクスプローラー構成", "files.exclude.boolean": "ファイル パスの照合基準となる glob パターン。これを true または false に設定すると、パターンがそれぞれ有効/無効になります。", "files.exclude.when": "一致するファイルの兄弟をさらにチェックします。一致するファイル名の変数として $(basename) を使用します。", - "filesCategory": "ファイル", "filesConfigurationTitle": "ファイル構成", - "maxVisible": "スクロールバーなしで表示される作業ファイルの最大数。", - "openWorkingFile": "名前で作業ファイルを開く", + "openEditorsVisible": "[開いているエディター] ウィンドウに表示されているエディターの数。0 に設定するとウィンドウが非表示になります。", "showExplorerViewlet": "エクスプローラーを表示", "textFileEditor": "テキスト ファイル エディター", "trimTrailingWhitespace": "有効にすると、ファイルの保存時に末尾の空白をトリミングします。", "view": "表示", - "watcherExclude": "ファイル モニタリングから除外するファイル パスの glob パターンを構成します。この設定を変更すると、再起動が必要になります。始動時に Code が消費する CPU 時間が多い場合は、大規模なフォルダーを除外して初期ロードを減らせます。", - "workingFilesPicker": "名前で作業ファイルを開く" + "watcherExclude": "ファイル モニタリングから除外するファイル パスの glob パターンを構成します。この設定を変更すると、再起動が必要になります。始動時に Code が消費する CPU 時間が多い場合は、大規模なフォルダーを除外して初期ロードを減らせます。" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/jpn/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index 43096b4b661..af7c8691e92 100644 --- a/i18n/jpn/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "ローカルでの変更を使ってディスクの内容を上書きします", + "acceptLocalChanges": "上書き", "compareChanges": "比較", "conflictingFileHasChanged": "ディスク上のファイルの内容が変更され、比較エディターの左側が最新の情報に更新されました。確認して再度解決してください。", "discard": "破棄", @@ -13,8 +13,8 @@ "readonlySaveError": "'{0}' の保存に失敗しました。ファイルが書き込み禁止になっています。[上書き] を選択して保護を解除してください。", "resolveSaveConflict": "{0} - 保存時の競合の解決", "retry": "再試行", - "revertLocalChanges": "ローカルでの変更を破棄してディスクの内容に戻します", + "revertLocalChanges": "元に戻す", "saveConflictDiffLabel": "{0} - ディスク上 ↔ {1} 内", "staleSaveError": "'{0} の保存に失敗しました。ディスクの内容の方が新しくなっています。[比較] をクリックしてご使用のバージョンをディスク上のバージョンと比較してください。", - "userGuide": "エディター ツール バーの操作で、変更を [元に戻す] か、ディスクの内容を変更内容で [上書き] します" + "userGuide": "[元に戻す] を選択して変更を破棄するか、または [上書き] を選択してディスクの内容を変更内容に置き換えてください" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json index 05bd1c12fdb..24cd6351d5e 100644 --- a/i18n/jpn/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json @@ -9,5 +9,8 @@ "openFile": "ファイルを開く", "openInEditor": "エディター ビューに切り替える", "stageSelectedLines": "選択した行のステージング", - "switchToChangesView": "変更の表示に切り替え" + "switchToChangesView": "変更の表示に切り替え", + "unstageSelectedLines": "選択した行のステージング解除", + "workbenchStage": "ステージ", + "workbenchUnstage": "ステージング解除" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/git/browser/gitActions.i18n.json b/i18n/jpn/src/vs/workbench/parts/git/browser/gitActions.i18n.json index 02af3e33c33..0b1c6718e2f 100644 --- a/i18n/jpn/src/vs/workbench/parts/git/browser/gitActions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/git/browser/gitActions.i18n.json @@ -5,13 +5,11 @@ // Do not edit this file. It is machine generated. { "authFailed": "Git リモートで認証が失敗しました。", - "branch": "Branch", - "branch2": "Branch", - "checkout": "Checkout", "cleanChangesLabel": "変更を取り除く(&&C)", "commit": "Commit", "commitAll": "すべてコミット", "commitAll2": "すべてコミット", + "commitMessage": "コミット メッセージ", "commitStaged": "ステージング済みをコミット", "commitStaged2": "ステージング済みをコミット", "confirmPublishMessage": "'{0}' を '{1}' に発行してよろしいですか?", @@ -36,13 +34,9 @@ "openFile": "ファイルを開く", "publish": "公開", "publishPickMessage": "リモートを選んで、ブランチ '{0}' を次に公開します:", - "pull": "Pull", - "pullWithRebase": "プル (リベース)", - "push": "Push", "refresh": "最新の情報に更新", "stageAllChanges": "すべてステージング", "stageChanges": "ステージ", - "sync": "同期", "synchronizing": "同期しています...", "undoAllChanges": "すべて取り除く", "undoChanges": "取り除く", diff --git a/i18n/jpn/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json b/i18n/jpn/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json index 75805c9c002..a994bcbfb72 100644 --- a/i18n/jpn/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json @@ -7,6 +7,7 @@ "alreadyCheckedOut": "ブランチ {0} は既に現在のブランチになっています", "branchAriaLabel": "{0}、Git ブランチ", "checkoutBranch": "{0} のブランチ", + "checkoutRemoteBranch": "{0} でのリモート ブランチ", "checkoutTag": "{0} のタグ", "createBranch": "ブランチ {0} を作成します", "noBranches": "他のブランチがありません", diff --git a/i18n/jpn/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/jpn/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 0a7c3657c3c..f0beb29e213 100644 --- a/i18n/jpn/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -8,17 +8,23 @@ "cancel": "キャンセル", "cantOpen": "この Git リソースを開けません。", "cantOpenResource": "この Git リソースを開けません。", - "changesFromIndex": "{0} - インデックスでの変更", - "changesFromTree": "{0} - {1} での変更", + "changesFromIndex": "{0} (インデックス)", + "changesFromIndexDesc": "{0} - インデックスでの変更", + "changesFromTree": "{0} ({1})", + "changesFromTreeDesc": "{0} - {1} での変更", "checkNativeConsole": "Git の操作を実行しているときに問題が発生しました。出力を確認するか、コンソールを使用してリポジトリの状態を確認してください。", "configureUsernameEmail": "Git ユーザー名と電子メールを構成してください。", "download": "ダウンロード", - "gitIndexChanges": "{0} - インデックスでの変更", - "gitIndexChangesRenamed": "{0} - 名前変更済み - インデックスでの変更", - "gitMergeChanges": "{0} - 変更のマージ", + "gitIndexChanges": "{0} (インデックス) ↔ {1}", + "gitIndexChangesDesc": "{0} - インデックスでの変更", + "gitIndexChangesRenamed": "{0} ← {1}", + "gitIndexChangesRenamedDesc": "{0} - 名前変更済み - インデックスでの変更", + "gitMergeChanges": "{0} (マージ) ↔ {1}", + "gitMergeChangesDesc": "{0} - 変更のマージ", "neverShowAgain": "今後は表示しない", "showOutput": "出力の表示", "unmergedChanges": "変更をコミットする前に、まずマージされていない変更を解決する必要があります。", "updateGit": "git {0} がインストールされているようです。Code は 2.0.0 以上の git で最適に動作します。", - "workingTreeChanges": "{0} - 作業ツリーでの変更" + "workingTreeChanges": "{0} (見出し) ↔ {1}", + "workingTreeChangesDesc": "{0} - 作業ツリーでの変更" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/jpn/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index 30ddfcaf197..818434f742b 100644 --- a/i18n/jpn/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -9,6 +9,8 @@ "gitCommands": "Git コマンド", "gitConfigurationTitle": "Git 構成", "gitEnabled": "は Git 対応です", + "gitLargeRepos": "Code による大規模なリポジトリの管理を常に許可します。", + "gitLongCommit": "長いコミット メッセージを警告するかどうか。", "gitPath": "Git 実行可能ファイルのパス", "gitPendingChangesBadge": "{0} 個の保留中の変更", "gitProgressBadge": "実行中の Git の状態", diff --git a/i18n/jpn/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json b/i18n/jpn/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json index fd12809fade..0d19887205e 100644 --- a/i18n/jpn/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json @@ -6,6 +6,7 @@ { "commitMessage": "メッセージ ({0} を押してコミット)", "commitMessageAriaLabel": "Git: コミット メッセージを入力し、{0} を押してコミットしてください", + "longCommit": "コミットの最初の行は 50 文字を超えない長さにすることをお勧めします。補足情報は追加の行を使用して記載できます。", "needMessage": "コミット メッセージを入力してください。**{0}** を押すといつでも変更をコミットできます。ステージング済みの変更がある場合は、それらの変更だけがコミットされます。それ以外の場合は、すべての変更がコミットされます。", "nothingToCommit": "コミットする変更があった時点で、コミット メッセージを入力するか、**{0}** を押して変更をコミットしてください。ステージング済みの変更がある場合は、それらの変更だけがコミットされます。それ以外の場合は、すべての変更がコミットされます。", "showOutput": "Git 出力の表示", diff --git a/i18n/jpn/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/jpn/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index 4b06472259a..e67feb8d7d8 100644 --- a/i18n/jpn/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0}: {1}", "QuickCommandsAction.label": "エディター コマンドの表示", "actionNotEnabled": "コマンド '{0}' は現在のコンテキストでは無効です。", "canNotRun": "コマンド '{0}' はここからは実行できません。", diff --git a/i18n/jpn/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/jpn/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index 85a280dd589..8fdc9b535db 100644 --- a/i18n/jpn/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,26 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "検索結果のクリア", - "CollapseAllAction.label": "折りたたむ", - "ConfigureGlobalExclusionsAction.label": "設定を開く", - "RefreshAction.label": "最新の情報に更新", - "RemoveAction.label": "削除", - "SelectOrRemoveAction.removeLabel": "削除", - "SelectOrRemoveAction.selectLabel": "選択", "ariaSearchResultsStatus": "検索により {1} 個のファイル内の {0} 件の結果が返されました", - "defaultLabel": "入力", - "fileMatchAriaLabel": "フォルダー {2} のファイル {1} 内で {0} 件の一致、検索結果", - "findInFolder": "フォルダー内を検索", - "findPlaceHolder": "Enter を押して検索するか、Esc を押して取り消します", "globLabel": "{1} のとき {0}", "global.searchScope.folders": "設定で除外されたファイル", - "label.Search": "検索: 検索語句を入力し Enter を押して検索するか、Esc を押して取り消します", "label.excludes": "検索除外パターン", "label.global.excludes": "検索除外パターンを構成しました", "label.includes": "検索包含パターン", "moreSearch": "詳細検索の切り替え", - "noMatches": "一致なし", "noResultsExcludes": "'{0}' を除外した結果はありませんでした - ", "noResultsFound": "結果はありません。構成された除外の設定を確認してください - ", "noResultsIncludes": "'{0}' に結果はありません - ", "noResultsIncludesExcludes": "'{0}' に '{1}' を除外した結果はありません - ", "openSettings.message": "設定を開く", - "patternDescription": "glob パターンを使用する", - "patternHelpInclude": "一致するパターン。たとえば、****/*.js** はすべての JavaScript ファイルと一致し、**myFolder/**** は当該フォルダーとすべての子と一致します。\n\n**参照情報**:\n***** は 0 個以上の文字と一致します\n**?** は 1 文字と一致します\n****** は 0 個以上のディレクトリと一致します\n**[a-z]** は文字の範囲と一致します\n**{a,b}** は任意のパターンと一致します)", - "regexp.validationFailure": "この式はすべてに一致します", + "replaceAll.confirm.button": "置換", + "replaceAll.confirmation.message": "{1} ファイルで {0} 件の出現箇所を置換しますか?", + "replaceAll.confirmation.title": "すべて置換", + "replaceAll.message": "{1} ファイルで {0} 件の出現箇所を置換しました。", "rerunSearch.message": "もう一度検索してください", "rerunSearchInAll.message": "すべてのファイルでもう一度検索してください", "searchCanceled": "結果が見つかる前に検索が取り消されました - ", - "searchMatch": "一致する項目が {0} 件見つかりました", - "searchMatches": "一致する項目が {0} 件見つかりました", "searchMaxResultsWarning": "結果セットにはすべての一致項目のサブセットのみが含まれています。より限定的な検索条件を入力して、検索結果を絞り込んでください。", - "searchResultAria": "{0}、検索結果", "searchScope.excludes": "除外するファイル", "searchScope.includes": "含めるファイル", "treeAriaLabel": "検索結果" diff --git a/i18n/jpn/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json b/i18n/jpn/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json index 614ffe8b724..c5c74fe9adb 100644 --- a/i18n/jpn/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json +++ b/i18n/jpn/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json @@ -5,7 +5,10 @@ // Do not edit this file. It is machine generated. { "close": "閉じる", + "insiderBuilds": "Insider ビルドがデイリー ビルドになります!", "license": "ライセンスの閲覧", "licenseChanged": "ライセンス条項が変更されました。内容をご確認ください。", + "neverShowAgain": "次回から表示しない", + "readmore": "詳細を参照", "releaseNotes": "{0} v{1} へようこそ! リリース ノートを確認しますか?" } \ No newline at end of file diff --git a/i18n/jpn/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/jpn/src/vs/workbench/services/history/browser/history.i18n.json index 2e86ea8c341..8765cebcc49 100644 --- a/i18n/jpn/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/jpn/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[拡張機能開発ホスト] - {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} - {1}", "prefixWorkspaceTitle": "{0} - {1} - {2}", "prefixWorkspaceTitleMac": "{0} - {1}", diff --git a/i18n/kor/extensions/typescript/out/typescriptServiceClient.i18n.json b/i18n/kor/extensions/typescript/out/typescriptServiceClient.i18n.json index ada75321bf5..54beefbe920 100644 --- a/i18n/kor/extensions/typescript/out/typescriptServiceClient.i18n.json +++ b/i18n/kor/extensions/typescript/out/typescriptServiceClient.i18n.json @@ -7,7 +7,7 @@ "channelName": "TypeScript", "noServerFound": "경로 {0}이(가) 올바른 tsserver 설치를 가리키지 않습니다. TypeScript 언어 기능이 사용되지 않도록 설정됩니다.", "serverCouldNotBeStarted": "TypeScript 언어 서버를 시작할 수 없습니다. 오류 메시지: {0}", - "serverDied": "Typescript 언어 서비스가 지난 5분 동안 예기치 않게 5번 종료되었습니다. 버그 보고서를 열어 보세요.", - "serverDiedAfterStart": "Typescript 언어 서비스가 시작된 직후 5번 종료되었습니다. 서비스가 다시 시작되지 않습니다. 버그 보고서를 열어 보세요.", + "serverDied": "TypeScript 언어 서비스가 지난 5분 동안 예기치 않게 5번 종료되었습니다. 버그 보고서를 열어 보세요.", + "serverDiedAfterStart": "TypeScript 언어 서비스가 시작된 직후 5번 종료되었습니다. 서비스가 다시 시작되지 않습니다. 버그 보고서를 열어 보세요.", "versionNumber.custom": "사용자 지정" } \ No newline at end of file diff --git a/i18n/kor/extensions/typescript/package.i18n.json b/i18n/kor/extensions/typescript/package.i18n.json index 8c46e7abfc9..c35d81a5a69 100644 --- a/i18n/kor/extensions/typescript/package.i18n.json +++ b/i18n/kor/extensions/typescript/package.i18n.json @@ -18,6 +18,7 @@ "javascript.validate.enable": "JavaScript 유효성 검사 사용/사용 안 함", "typescript.reloadProjects.title": "TypeScript 프로젝트 다시 로드", "typescript.tsdk.desc": "사용할 tsserver 및 lib*.d.ts 파일이 들어 있는 폴더 경로를 지정합니다.", + "typescript.tsserver.experimentalAutoBuild": "실험적 자동 빌드를 사용하도록 설정합니다. 1.9 dev 또는 2.x tsserver 버전이 필요하며 변경 후에는 VS Code를 다시 시작해야 합니다.", "typescript.tsserver.trace": "TS 서버에 보내는 메시지를 추적하도록 설정합니다.", "typescript.useCodeSnippetsOnMethodSuggest.dec": "매개 변수 서명으로 함수를 완료하세요.", "typescript.validate.enable": "TypeScript 유효성 검사 사용/사용 안 함" diff --git a/i18n/kor/src/vs/code/electron-main/menus.i18n.json b/i18n/kor/src/vs/code/electron-main/menus.i18n.json index c1516ffc9be..4f31b5b6c8b 100644 --- a/i18n/kor/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/kor/src/vs/code/electron-main/menus.i18n.json @@ -35,6 +35,9 @@ "miExit": "끝내기(&&X)", "miFind": "찾기(&&F)", "miFindInFiles": "파일에서 찾기(&&I)", + "miFocusFirstGroup": "왼쪽 그룹(&&L)", + "miFocusSecondGroup": "측면 그룹(&&S)", + "miFocusThirdGroup": "오른쪽 그룹(&&R)", "miForward": "앞으로(&&F)", "miGotoDefinition": "정의로 이동(&&D)", "miGotoFile": "파일로 이동(&&F)...", @@ -43,11 +46,13 @@ "miInstallingUpdate": "업데이트를 설치하는 중...", "miLastCheckedAt": "마지막 확인 시간: {0}", "miLicense": "라이선스 보기(&&V)", - "miMarker": "오류 및 경고(&&E)", + "miMarker": "문제(&&P)", "miMoveSidebar": "사이드바 이동(&&M)", - "miNavigateHistory": "기록 탐색(&&N)", "miNewFile": "새 파일(&&N)", "miNewWindow": "새 창(&&N)", + "miNextEditor": "다음 편집기(&&N)", + "miNextEditorInGroup": "그룹에서 다음에 사용되는 편집기(&&N)", + "miNextGroup": "다음 그룹(&&N)", "miOpen": "열기(&&O)...", "miOpenFile": "파일 열기(&&O)...", "miOpenFolder": "폴더 열기(&&F)...", @@ -58,11 +63,14 @@ "miOpenWorkspaceSettings": "작업 영역 설정(&&W)", "miPaste": "붙여넣기(&&P)", "miPreferences": "기본 설정(&&P)", + "miPreviousEditor": "이전 편집기(&&P)", + "miPreviousEditorInGroup": "그룹에서 이전에 사용된 편집기(&&P)", + "miPreviousGroup": "이전 그룹(&&P)", "miPrivacyStatement": "개인정보취급방침(&&P)", "miQuit": "{0} 종료", "miRedo": "다시 실행(&&R)", "miReleaseNotes": "릴리스 정보(&&R)", - "miReopenClosedFile": "&&닫은 파일 다시 열기", + "miReopenClosedEditor": "닫힌 편집기 다시 열기(&&R)", "miReplace": "바꾸기(&&R)", "miReportIssues": "문제 보고(&&I)", "miRestartToUpdate": "업데이트하기 위해 다시 시작...", @@ -73,14 +81,18 @@ "miSelectAll": "모두 선택(&&S)", "miSelectTheme": "색 테마(&&C)", "miSplitEditor": "편집기 분할(&&E)", - "miToggleDebugConsole": "디버그 콘솔 설정/해제(&&B)", + "miSwitchEditor": "편집기 전환(&&E)", + "miSwitchGroup": "그룹 전환(&&G)", + "miToggleDebugConsole": "디버그 콘솔(&&B)", "miToggleDevTools": "개발자 도구 설정/해제(&&T)", "miToggleFullScreen": "전체 화면 설정/해제(&&F)", + "miToggleIntegratedTerminal": "통합 터미널(&&I)", "miToggleMenuBar": "메뉴 모음 설정/해제(&&B)", - "miToggleOutput": "출력 설정/해제(&&O)", + "miToggleOutput": "출력(&&O)", "miTogglePanel": "패널 설정/해제(&&P)", "miToggleRenderWhitespace": "공백 설정/해제 및 렌더링(&&R)", "miToggleSidebar": "사이드바 설정/해제(&&T)", + "miToggleStatusbar": "상태 표시줄 설정/해제(&&T)", "miToggleWordWrap": "자동 줄 바꿈 설정/해제(&&W)", "miTwitter": "Twitter에서 참여(&&J)", "miUndo": "실행 취소(&&U)", @@ -91,5 +103,6 @@ "miViewSearch": "검색(&&S)", "miZoomIn": "확대(&&Z)", "miZoomOut": "축소(&&U)", + "miZoomReset": "확대/축소 다시 설정(&&R)", "okButton": "확인" } \ 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 931a33758a2..d96e2ddcccf 100644 --- a/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json +++ b/i18n/kor/src/vs/editor/common/config/commonEditorConfig.i18n.json @@ -9,7 +9,6 @@ "cursorBlinking": "커서 깜박임 애니메이션을 제어합니다. 허용되는 값은 '깜박임', '표시' 및 '숨김'입니다.", "cursorStyle": "커서 스타일을 제어합니다. 허용되는 값은 '블록' 및 '줄'입니다.", "detectIndentation": "파일을 열면 파일 콘텐츠를 기반으로 하여 'editor.tabSize'와 'editor.insertSpaces'가 검색됩니다.", - "dismissPeekOnEsc": "를 누를 때 피킹 편집기 닫기", "editorConfigurationTitle": "편집기 구성", "folding": "편집기에서 코드 접기를 사용할지 여부를 제어합니다.", "fontFamily": "글꼴 패밀리를 제어합니다.", @@ -25,6 +24,7 @@ "lineNumbers": "줄 번호의 표시 여부를 제어합니다.", "mouseWheelScrollSensitivity": "마우스 휠 스크롤 이벤트의 `deltaX` 및 `deltaY`에서 사용할 승수", "overviewRulerLanes": "개요 눈금자에서 동일한 위치에 표시될 수 있는 장식 수를 제어합니다.", + "parameterHints": "매개 변수 힌트를 사용하도록 설정합니다.", "quickSuggestions": "입력하는 동안 빠른 제안을 표시할지 여부를 제어합니다.", "quickSuggestionsDelay": "빠른 제안을 표시할 지연 시간(밀리초)을 제어합니다.", "referenceInfos": "편집기에서 지원하는 모드에 대한 참조 정보가 표시되는지 여부를 제어합니다.", @@ -35,6 +35,7 @@ "selectionClipboard": "Linux 주 클립보드의 지원 여부를 제어합니다.", "selectionHighlight": "편집기에서 선택 항목과 유사한 일치 항목을 강조 표시할지 여부를 제어합니다.", "sideBySide": "diff 편집기에서 diff를 나란히 표시할지 인라인으로 표시할지 여부를 제어합니다.", + "stablePeek": "해당 콘텐츠를 두 번 클릭하거나 Esc 키를 누르더라도 미리 보기 편집기를 열린 상태로 유지합니다.", "suggestOnTriggerCharacters": "트리거 문자를 입력할 때 제안을 자동으로 표시할지 여부를 제어합니다.", "tabSize": "탭 한 개에 해당하는 공백 수입니다.", "tabSize.errorMessage": "'number'가 필요합니다. 값 \"auto\"는 `editor.detectIndentation` 설정에 의해 바뀌었습니다.", diff --git a/i18n/kor/src/vs/editor/contrib/folding/browser/folding.i18n.json b/i18n/kor/src/vs/editor/contrib/folding/browser/folding.i18n.json index 61c72d94a81..badfdd110b6 100644 --- a/i18n/kor/src/vs/editor/contrib/folding/browser/folding.i18n.json +++ b/i18n/kor/src/vs/editor/contrib/folding/browser/folding.i18n.json @@ -11,6 +11,8 @@ "foldLevel3Action.label": "수준 3 접기", "foldLevel4Action.label": "수준 4 접기", "foldLevel5Action.label": "수준 5 접기", + "foldRecursivelyAction.label": "재귀적으로 접기", + "unFoldRecursivelyAction.label": "재귀적으로 펼치기", "unfoldAction.label": "펼치기", "unfoldAllAction.label": "모두 펼치기" } \ No newline at end of file diff --git a/i18n/kor/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json b/i18n/kor/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json index 3255bd0817a..d8ed3243933 100644 --- a/i18n/kor/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json +++ b/i18n/kor/src/vs/editor/contrib/gotoError/browser/gotoError.i18n.json @@ -7,5 +7,7 @@ "markerAction.next.label": "다음 오류 또는 경고로 이동", "markerAction.previous.label": "이전 오류 또는 경고로 이동", "quickfix.multiple.label": "제안 수정:", - "quickfix.single.label": "제안 수정: " + "quickfix.single.label": "제안 수정: ", + "title.w_source": "({0}/{1}) [{2}]", + "title.wo_source": "({0}/{1})" } \ No newline at end of file diff --git a/i18n/kor/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/kor/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index 65c06576f10..b849715062e 100644 --- a/i18n/kor/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/kor/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "로드 중...", "meta.titleReference": " – 참조 {0}개", - "noResults": "결과 없음", "references.action.label": "모든 참조 찾기", - "references.action.name": "참조 표시" + "references.action.name": "모든 참조 찾기" } \ No newline at end of file diff --git a/i18n/kor/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json b/i18n/kor/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json index a1c1664f6d8..42c33416646 100644 --- a/i18n/kor/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json +++ b/i18n/kor/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.i18n.json @@ -8,5 +8,6 @@ "peekView.alternateTitle": "참조", "referenceCount": "참조 {0}개", "referencesCount": "참조 {0}개", + "referencesFailre": "파일을 확인하지 못했습니다.", "treeAriaLabel": "참조" } \ No newline at end of file diff --git a/i18n/kor/src/vs/editor/node/textMate/TMSyntax.i18n.json b/i18n/kor/src/vs/editor/node/textMate/TMSyntax.i18n.json index 51c87646447..990bcc3a590 100644 --- a/i18n/kor/src/vs/editor/node/textMate/TMSyntax.i18n.json +++ b/i18n/kor/src/vs/editor/node/textMate/TMSyntax.i18n.json @@ -4,11 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "invalid.injectTo": "`contributes.{0}.injectTo`의 값이 잘못되었습니다. 언어 범위 이름 배열이어야 합니다. 제공된 값: {1}", "invalid.language": "`contributes.{0}.language`에 알 수 없는 언어가 있습니다. 제공된 값: {1}", "invalid.path.0": "`contributes.{0}.path`에 문자열이 필요합니다. 제공된 값: {1}", "invalid.path.1": "확장 폴더({2})에 포함할 `contributes.{0}.path`({1})가 필요합니다. 확장이 이식 불가능해질 수 있습니다.", "invalid.scopeName": "`contributes.{0}.scopeName`에 문자열이 필요합니다. 제공된 값: {1}", "vscode.extension.contributes.grammars": "textmate 토크나이저를 적용합니다.", + "vscode.extension.contributes.grammars.injectTo": "이 문법이 삽입되는 언어 범위 이름 목록입니다.", "vscode.extension.contributes.grammars.language": "이 구문이 적용되는 언어 식별자입니다.", "vscode.extension.contributes.grammars.path": "tmLanguage 파일의 경로입니다. 이 경로는 확장 폴더에 상대적이며 일반적으로 './syntaxes/'로 시작합니다.", "vscode.extension.contributes.grammars.scopeName": "tmLanguage 파일에 사용되는 Textmate 범위 이름입니다." diff --git a/i18n/kor/src/vs/languages/html/common/html.contribution.i18n.json b/i18n/kor/src/vs/languages/html/common/html.contribution.i18n.json index 5b3cd6c1856..5d48fdc3de7 100644 --- a/i18n/kor/src/vs/languages/html/common/html.contribution.i18n.json +++ b/i18n/kor/src/vs/languages/html/common/html.contribution.i18n.json @@ -10,7 +10,7 @@ "format.indentInnerHtml": " 및 섹션을 들여쓰기합니다.", "format.maxPreserveNewLines": "청크 한 개에 유지할 수 있는 최대 줄 바꿈 수입니다. 무제한일 때는 'null'을 사용합니다.", "format.preserveNewLines": "요소 앞에 있는 기존 줄 바꿈의 유지 여부입니다. 요소 앞에만 적용되며 태그 안이나 텍스트에는 적용되지 않습니다.", - "format.unformatted": "쉼표로 분리된 태그 목록으로, 서식을 다시 지정해서는 안 됩니다. 모든 인라인 태그의 기본값은 'null'로 설정됩니다.", + "format.unformatted": "쉼표로 분리된 태그 목록으로, 서식을 다시 지정해서는 안 됩니다. https://www.w3.org/TR/html5/dom.html#phrasing-content에 나열된 모든 태그의 기본값은 'null'로 설정됩니다.", "format.wrapLineLength": "한 줄당 최대 문자 수입니다(0 = 사용 안 함).", "htmlConfigurationTitle": "HTML 구성" } \ 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 2a5d54a7b5c..e78a6e91268 100644 --- a/i18n/kor/src/vs/workbench/electron-browser/actions.i18n.json +++ b/i18n/kor/src/vs/workbench/electron-browser/actions.i18n.json @@ -15,7 +15,8 @@ "newWindow": "새 창", "noFolderOpened": "이 인스턴스에 현재 열려 있는 닫을 폴더가 없습니다.", "openRecent": "최근 파일 열기", - "openRecentPlaceHolder": "열기 경로 선택", + "openRecentPlaceHolder": "열기 경로 선택(새 창에서 열려면 Ctrl 키를 길게 누름)", + "openRecentPlaceHolderMac": "경로 선택(새 창에서 열려면 Cmd 키를 길게 누름)", "reloadWindow": "창 다시 로드", "toggleDevTools": "개발자 도구 설정/해제", "toggleFullScreen": "전체 화면 설정/해제", 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 8e4f3ec9419..122a80beacd 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 @@ -8,7 +8,8 @@ "file": "파일", "openFilesInNewWindow": "사용하도록 설정한 경우 기존 인스턴스를 재사용하지 않고 파일이 새 창에서 열립니다.", "reopenFolders": "다시 시작한 이후에 폴더를 다시 여는 방법을 제어합니다. 폴더를 다시 열지 않으려면 'none'을 선택하고, 마지막으로 작업한 폴더를 다시 열려면 'one'을 선택하고, 마지막 세션의 모든 폴더를 다시 열려면 'all'을 선택합니다.", - "updateChannel": "업데이트를 수신할 업데이트 채널을 구성합니다. 변경 후 다시 시작해야 합니다.", + "restoreFullscreen": "창이 전체 화면 모드에서 종료된 경우 창을 전체 화면 모드로 복원할지 여부를 제어합니다.", + "updateChannel": "업데이트 채널에서 자동 업데이트를 받을지 여부를 구성합니다. 변경 후 다시 시작해야 합니다.", "updateConfigurationTitle": "구성 업데이트", "view": "보기", "windowConfigurationTitle": "창 구성", diff --git a/i18n/kor/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json index 0e39491746e..00064c0a14c 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/electron-browser/debug.contribution.i18n.json @@ -8,8 +8,8 @@ "conditionalBreakpointEditorAction": "디버그: 조건부 중단점", "debug": "디버그", "debugCategory": "디버그", - "debugConsole": "콘솔 디버그", "debugEvaluate": "디버그: 평가", + "launchConfigDoesNotExist": "시작 구성 '{0}'이(가) 없습니다.", "runToCursor": "디버그: 커서까지 실행", "showDebugHover": "디버그: 가리키기 표시", "toggleBreakpointAction": "디버그: 중단점 설정/해제", diff --git a/i18n/kor/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json index 7047726d81a..5be42706910 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/electron-browser/debugService.i18n.json @@ -6,10 +6,12 @@ { "DebugTaskNotFound": "preLaunchTask '{0}'을(를) 찾을 수 없습니다.", "NewLaunchConfig": "응용 프로그램에 사용할 구성 시작 파일을 설정하세요.", + "breakpointAdded": "파일 {1}, 줄 {0}에 중단점이 추가되었습니다.", + "breakpointRemoved": "파일 {1}, 줄 {0}에서 중단점이 제거되었습니다.", "debugAdapterCrash": "디버그 어댑터 프로세스가 예기치 않게 종료되었습니다.", "debugAnyway": "디버그", "debugSourceNotAvailable": "소스 {0}을(를) 사용할 수 없습니다.", - "debugTypeMissing": "launch.json에서 선택된 구성에 대한 '형식' 속성이 없습니다.", + "debugTypeMissing": "선택한 시작 구성에 대한 'type' 속성이 없습니다.", "debugTypeNotSupported": "구성된 디버그 형식 '{0}'은(는) 지원되지 않습니다.", "debuggingContinued": "디버그를 계속합니다.", "debuggingPaused": "디버그가 일시 중지되었습니다. 이유 {0}, {1} {2}", diff --git a/i18n/kor/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json index 52658f0842f..05168f93b8d 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/node/debugAdapter.i18n.json @@ -4,10 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "debugLinuxConfiguration": "Linux 특정 시작 구성 특성입니다.", "debugName": "구성 이름이며, 구성 시작 드롭다운 메뉴에 표시됩니다.", + "debugOSXConfiguration": "OS X 특정 시작 구성 특성입니다.", "debugPrelaunchTask": "디버그 세션이 시작되기 이전에 실행할 작업입니다.", "debugRequest": "구성 형식을 요청합니다. \"시작\" 또는 \"연결\"일 수 있습니다.", "debugType": "구성의 형식입니다.", + "debugWindowsConfiguration": "Windows 특정 시작 구성 특성입니다.", "internalConsoleOptions": "내부 디버그 콘솔의 동작을 제어합니다.", "relativePathsNotConverted": "상대 경로는 더 이상 절대 경로로 자동으로 변환되지 않습니다. ${workspaceRoot}를 접두사로 사용해 보세요." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json b/i18n/kor/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json index 8cf5dcd353e..75c7137fcb9 100644 --- a/i18n/kor/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/debug/node/debugConfigurationManager.i18n.json @@ -10,6 +10,7 @@ "app.launch.json.version": "이 파일 형식의 버전입니다.", "debugNoType": "디버그 어댑터 '형식'은 생략할 수 없으며 '문자열' 형식이어야 합니다.", "duplicateDebuggerType": "디버그 형식 '{0}'은(는) 이미 등록되어 있고 '{1}' 특성을 포함합니다. '{1}' 특성을 무시합니다.", + "interactiveVariableNotFound": "{0} 어댑터가 시작 구성에 지정된 {1} 변수에 영향을 주지 않습니다.", "selectDebug": "환경 선택", "vscode.extension.contributes.debuggers": "디버그 어댑터를 적용합니다.", "vscode.extension.contributes.debuggers.args": "어댑터에 전달할 선택적 인수입니다.", @@ -26,6 +27,7 @@ "vscode.extension.contributes.debuggers.runtime": "프로그램 특성이 실행 파일이 아니지만 런타임이 필요한 경우의 선택적 런타임입니다.", "vscode.extension.contributes.debuggers.runtimeArgs": "선택적 런타임 인수입니다.", "vscode.extension.contributes.debuggers.type": "이 디버그 어댑터에 대한 고유한 식별자입니다.", + "vscode.extension.contributes.debuggers.variables": "`launch.json`의 대화형 변수(예: ${action.pickProcess})에서 명령으로의 매핑입니다.", "vscode.extension.contributes.debuggers.windows": "Windows 특정 설정", "vscode.extension.contributes.debuggers.windows.runtime": "Windows에 사용되는 런타임입니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index eb8f3bfeef3..360f026b74f 100644 --- a/i18n/kor/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,8 @@ "globalConsoleActionWin": "새 명령 프롬프트 열기", "scopedConsoleActionMacLinux": "터미널에서 열기", "scopedConsoleActionWin": "명령 프롬프트에서 열기", + "terminal.external.linuxExec": "Linux에서 실행할 터미널을 사용자 지정합니다.", + "terminal.external.osxExec": "OS X에서 실행할 터미널 응용 프로그램을 사용자 지정합니다.", "terminal.external.windowsExec": "Windows에서 실행할 터미널을 사용자 지정합니다.", "terminalConfigurationTitle": "외부 터미널 구성" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index f24713ca3cb..4b7cb22a423 100644 --- a/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,16 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "닫기", "deleteSure": "'{0}'을(를) 제거할까요?", - "installExtension": "확장 설치", - "notFound": "확장 '{0}'이(가) 설치되지 않았습니다.", + "enableAction": "사용", + "installAction": "설치", + "installing": "설치 중", + "restart": "이 확장을 사용하도록 설정하려면 이 VS Code 창을 다시 시작해야 합니다.\n\n계속할까요?", "restartNow": "지금 다시 시작", - "restartNow2": "지금 다시 시작", "showExtensionRecommendations": "확장 권장 사항 표시", "showInstalledExtensions": "설치된 확장 표시", "showOutdatedExtensions": "만료된 확장 표시", - "success-installed": "'{0}'이(가) 설치되었습니다. 사용하도록 설정하려면 다시 시작하세요.", - "success-uninstalled": "'{0}'이(가) 제거되었습니다. 비활성화하려면 다시 시작하세요.", - "uninstall": "확장 제거" + "toggleExtensionsViewlet": "확장 표시", + "uninstall": "제거", + "updateAction": "업데이트" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json b/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json index bc42d43c5b9..3498c6899e9 100644 --- a/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.i18n.json @@ -5,6 +5,7 @@ // Do not edit this file. It is machine generated. { "extensions": "확장", + "outdatedExtensions": "{0}개의 만료된 확장", "reloadNow": "지금 다시 시작", "success": "확장이 설치되었습니다. 확장을 사용하려면 다시 시작하세요.", "successSingle": "{0}이(가) 설치되었습니다. 사용하도록 설정하려면 다시 시작하세요." diff --git a/i18n/kor/src/vs/workbench/parts/files/browser/fileActions.i18n.json b/i18n/kor/src/vs/workbench/parts/files/browser/fileActions.i18n.json index 15c8b957bd8..58d6d97d59d 100644 --- a/i18n/kor/src/vs/workbench/parts/files/browser/fileActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/browser/fileActions.i18n.json @@ -4,13 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "addToWorkingFiles": "작업 파일에 활성 파일 추가", - "closeAllFiles": "모든 파일 닫기", - "closeAllLabel": "모든 파일 닫기", - "closeFile": "파일 닫기", - "closeLabel": "파일 닫기", - "closeOtherFiles": "다른 파일 닫기", - "closeOtherLabel": "다른 파일 닫기", + "collapseExplorerFolders": "탐색기에서 폴더 축소", "compareFiles": "파일 비교", "compareSource": "비교를 위해 선택", "compareWith": "'{0}'과(와) 비교", @@ -31,7 +25,7 @@ "fileNameExistsError": "파일 또는 폴더 **{0}**이(가) 이 위치에 이미 있습니다. 다른 이름을 선택하세요.", "filePathTooLongError": "**{0}**(이)라는 이름을 사용하면 경로가 너무 길어집니다. 짧은 이름을 선택하세요.", "focusFilesExplorer": "파일 탐색기에 포커스 설정", - "focusWorkingFiles": "작업 파일에 포커스 설정", + "focusOpenEditors": "열려 있는 편집기 뷰에 포커스 설정", "globalCompareFile": "활성 파일을 다음과 비교...", "importFiles": "파일 가져오기", "invalidFileNameError": "**{0}**(이)라는 이름은 파일 또는 폴더 이름으로 올바르지 않습니다. 다른 이름을 선택하세요.", @@ -39,25 +33,21 @@ "newFile": "새 파일", "newFolder": "새 폴더", "newUntitledFile": "제목이 없는 새 파일", - "noFileOpen": "현재 열려 있는 닫을 파일이 없습니다.", - "noWorkingFiles": "현재 작업 파일이 없습니다.", - "openFileToAdd": "첫 번째 파일을 열어서 작업 파일에 추가합니다.", "openFileToCompare": "첫 번째 파일을 열어서 다른 파일과 비교합니다.", "openFileToShow": "탐색기에 표시하려면 먼저 파일을 엽니다.", "openFolderFirst": "안에 파일이나 폴더를 만들려면 먼저 폴더를 엽니다.", - "openNextWorkingFile": "새 작업 파일 열기", - "openPreviousWorkingFile": "이전 작업 파일 열기", "openToSide": "측면에서 열기", "pasteFile": "붙여넣기", "permDelete": "영구히 삭제", "refresh": "새로 고침", + "refreshExplorer": "탐색기 새로 고침", "rename": "이름 바꾸기", - "reopenClosedFile": "닫은 파일 다시 열기", "replaceButtonLabel": "바꾸기(&&R)", "retry": "다시 시도", "revert": "파일 되돌리기", "save": "저장", "saveAll": "모두 저장", + "saveAllInGroup": "그룹의 모든 항목 저장", "saveAs": "다른 이름으로 저장...", "saveFiles": "더티 파일 저장", "showInExplorer": "탐색기에서 활성 파일 표시", diff --git a/i18n/kor/src/vs/workbench/parts/files/browser/files.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/files/browser/files.contribution.i18n.json index 68c1e16a926..f787d69173c 100644 --- a/i18n/kor/src/vs/workbench/parts/files/browser/files.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/browser/files.contribution.i18n.json @@ -9,7 +9,7 @@ "autoSave": "더티 파일 자동 저장을 제어합니다. 허용되는 값은 \"{0}\", \"{1}\", \"{2}\"입니다. \"{3}\"(으)로 설정한 경우 \"files.autoSaveDelay\"에서 지연을 구성할 수 있습니다.", "autoSaveDelay": "더티 파일을 자동으로 저장할 때까지의 지연(밀리초)을 제어합니다. \"files.autoSave\"를 \"{0}\"(으)로 설정한 경우에만 적용됩니다.", "binaryFileEditor": "이진 파일 편집기", - "dynamicHeight": "작업 파일 섹션의 높이가 요소 수에 따라 동적으로 조정되는지 여부를 제어합니다.", + "dynamicHeight": "열려 있는 편집기 섹션의 높이가 요소 수에 따라 동적으로 조정되는지 여부를 제어합니다.", "encoding": "파일을 읽고 쓸 때 사용할 기본 문자 집합 인코딩입니다.", "eol": "줄 바꿈 문자의 기본 끝입니다.", "exclude": "파일과 폴더를 제외하기 위한 GLOB 패턴을 구성합니다.", @@ -17,14 +17,11 @@ "explorerConfigurationTitle": "파일 탐색기 구성", "files.exclude.boolean": "파일 경로를 일치시킬 GLOB 패턴입니다. 패턴을 사용하거나 사용하지 않도록 설정하려면 true 또는 false로 설정하세요.", "files.exclude.when": "일치하는 파일의 형제에 대한 추가 검사입니다. $(basename)을 일치하는 파일 이름에 대한 변수로 사용하세요.", - "filesCategory": "파일", "filesConfigurationTitle": "파일 구성", - "maxVisible": "스크롤 막대가 나타나기 전에 표시할 작업 파일의 최대 수입니다.", - "openWorkingFile": "이름으로 작업 파일 열기", + "openEditorsVisible": "열려 있는 편집기 창에 표시되는 편집기 수입니다. 창을 숨기려면 0으로 설정합니다.", "showExplorerViewlet": "탐색기 표시", "textFileEditor": "텍스트 파일 편집기", "trimTrailingWhitespace": "사용하도록 설정되면 파일을 저장할 때 후행 공백이 잘립니다.", "view": "보기", - "watcherExclude": "파일 감시에서 제외할 파일 경로의 GLOB 패턴을 구성하세요. 이 설정을 변경하려면 다시 시작해야 합니다. 시작 시 Code에서 CPU 시간을 많이 차지하면 대용량 폴더를 제외하여 초기 로드를 줄일 수 있습니다.", - "workingFilesPicker": "이름으로 작업 파일 열기" + "watcherExclude": "파일 감시에서 제외할 파일 경로의 GLOB 패턴을 구성하세요. 이 설정을 변경하려면 다시 시작해야 합니다. 시작 시 Code에서 CPU 시간을 많이 차지하면 대용량 폴더를 제외하여 초기 로드를 줄일 수 있습니다." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/kor/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index dea8a739f68..396d9b89b19 100644 --- a/i18n/kor/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "로컬 변경 사용 및 디스크 콘텐츠 덮어쓰기", + "acceptLocalChanges": "덮어쓰기", "compareChanges": "비교", "conflictingFileHasChanged": "디스크에 있는 파일의 내용이 변경되고 비교 편집기의 왼쪽이 새로 고쳐졌습니다. 검토하고 다시 확인하세요.", "discard": "삭제", @@ -13,8 +13,8 @@ "readonlySaveError": "'{0}'을(를) 저장하지 못했습니다. 파일이 쓰기 보호되어 있습니다. 보호를 제거하려면 '덮어쓰기'를 선택하세요.", "resolveSaveConflict": "{0} - 저장 충돌 해결", "retry": "다시 시도", - "revertLocalChanges": "로컬 변경을 취소하고 디스크의 콘텐츠로 되돌리기", + "revertLocalChanges": "되돌리기", "saveConflictDiffLabel": "{0} - 디스크 ↔ {1}에 있음", "staleSaveError": "'{0}'을(를) 저장하지 못했습니다. 디스크의 내용이 최신 버전입니다. 버전을 디스크에 있는 버전과 비교하려면 **비교**를 클릭하세요.", - "userGuide": "편집기 도구 모음의 작업을 사용하여 변경 내용을 **실행 취소**하거나 디스크의 콘텐츠를 변경 내용으로 **덮어쓰기**" + "userGuide": "변경 내용을 취소하려면 **되돌리기**를 선택하고, 디스크의 콘텐츠를 변경 내용으로 바꾸려면 **덮어쓰기**를 선택하세요." } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json index 740f2a3cf1c..ce182db719f 100644 --- a/i18n/kor/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json @@ -9,5 +9,8 @@ "openFile": "파일 열기", "openInEditor": "편집기 보기로 전환", "stageSelectedLines": "선택한 줄 스테이징", - "switchToChangesView": "변경 내용 보기로 전환" + "switchToChangesView": "변경 내용 보기로 전환", + "unstageSelectedLines": "선택한 줄 스테이징 취소", + "workbenchStage": "스테이징", + "workbenchUnstage": "스테이징 취소" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/git/browser/gitActions.i18n.json b/i18n/kor/src/vs/workbench/parts/git/browser/gitActions.i18n.json index 735da8d6e9a..fe968d9d732 100644 --- a/i18n/kor/src/vs/workbench/parts/git/browser/gitActions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/browser/gitActions.i18n.json @@ -5,13 +5,11 @@ // Do not edit this file. It is machine generated. { "authFailed": "원격 git에 대한 인증이 실패했습니다.", - "branch": "Branch", - "branch2": "Branch", - "checkout": "Checkout", "cleanChangesLabel": "변경 내용 정리(&&C)", "commit": "Commit", "commitAll": "모두 커밋", "commitAll2": "모두 커밋", + "commitMessage": "커밋 메시지", "commitStaged": "스테이징된 항목 커밋", "commitStaged2": "스테이징된 항목 커밋", "confirmPublishMessage": "'{0}'을(를) '{1}'에 게시할까요?", @@ -36,13 +34,9 @@ "openFile": "파일 열기", "publish": "게시", "publishPickMessage": "'{0}' 분기를 다음에 게시하려면 원격을 선택합니다.", - "pull": "Pull", - "pullWithRebase": "풀(다시 지정)", - "push": "Push", "refresh": "새로 고침", "stageAllChanges": "모두 스테이징", "stageChanges": "단계", - "sync": "동기화", "synchronizing": "동기화 중...", "undoAllChanges": "모두 정리", "undoChanges": "정리", diff --git a/i18n/kor/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json b/i18n/kor/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json index 95b728bc379..1c270a31bcd 100644 --- a/i18n/kor/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/browser/gitQuickOpen.i18n.json @@ -7,6 +7,7 @@ "alreadyCheckedOut": "{0} 분기는 이미 현재 분기입니다.", "branchAriaLabel": "{0}, git 분기", "checkoutBranch": "{0}의 분기", + "checkoutRemoteBranch": "{0}에서 원격 분기", "checkoutTag": "{0}의 태그", "createBranch": "분기 {0} 만들기", "noBranches": "다른 분기 없음", diff --git a/i18n/kor/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/kor/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 0e6b59b26ba..9e4a1f3bbac 100644 --- a/i18n/kor/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -8,17 +8,23 @@ "cancel": "취소", "cantOpen": "이 Git 리소스를 열 수 없습니다.", "cantOpenResource": "이 Git 리소스를 열 수 없습니다.", - "changesFromIndex": "{0} - 인덱스 변경 내용", - "changesFromTree": "{0} - {1} 변경 내용", + "changesFromIndex": "{0}(인덱스)", + "changesFromIndexDesc": "{0} - 인덱스 변경 내용", + "changesFromTree": "{0}({1})", + "changesFromTreeDesc": "{0} - {1} 변경 내용", "checkNativeConsole": "git 작업을 실행하는 동안 문제가 발생했습니다. 출력을 검토하거나 콘솔을 사용하여 리포지토리의 상태를 확인하세요.", "configureUsernameEmail": "git 사용자 이름 및 메일을 구성하세요.", "download": "다운로드", - "gitIndexChanges": "{0} - 인덱스 변경 내용", - "gitIndexChangesRenamed": "{0} - 이름 바꿈 - 인덱스의 변경 내용", - "gitMergeChanges": "{0} - 변경 내용 병합", + "gitIndexChanges": "{0}(인덱스) ↔ {1}", + "gitIndexChangesDesc": "{0} - 인덱스 변경 내용", + "gitIndexChangesRenamed": "{0} ← {1}", + "gitIndexChangesRenamedDesc": "{0} - 이름 바꿈 - 인덱스 변경 내용", + "gitMergeChanges": "{0}(병합) ↔ {1}", + "gitMergeChangesDesc": "{0} - 변경 내용 병합", "neverShowAgain": "다시 표시 안 함", "showOutput": "출력 표시", "unmergedChanges": "변경 내용을 커밋하기 전에 먼저 병합되지 않은 변경 내용을 확인해야 합니다.", "updateGit": "Git {0}이(가) 설치된 것 같습니다. Code는 2.0.0 이하의 Git에서 최적으로 작동합니다.", - "workingTreeChanges": "{0} - 작업 트리 변경 내용" + "workingTreeChanges": "{0}(헤드) ↔ {1}", + "workingTreeChangesDesc": "{0} - 작업 트리 변경 내용" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json b/i18n/kor/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json index 43ea4348393..e43ae287500 100644 --- a/i18n/kor/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.i18n.json @@ -9,6 +9,8 @@ "gitCommands": "Git 명령", "gitConfigurationTitle": "Git 구성", "gitEnabled": "git를 사용하도록 설정할까요?", + "gitLargeRepos": "항상 대규모 리포지토리가 코드로 관리되도록 허용합니다.", + "gitLongCommit": "긴 커밋 메시지에 대해 경고할지 여부입니다.", "gitPath": "Git 실행 파일의 경로", "gitPendingChangesBadge": "{0}이(가) 변경 내용을 보류 중입니다.", "gitProgressBadge": "실행 중인 Git 상태", diff --git a/i18n/kor/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json b/i18n/kor/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json index 64759fdd016..3fccab49e4d 100644 --- a/i18n/kor/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/git/browser/views/changes/changesView.i18n.json @@ -6,6 +6,7 @@ { "commitMessage": "메시지(커밋하려면 {0} 누름)", "commitMessageAriaLabel": "Git: 커밋하려면 커밋 메시지를 입력하고 {0}을(를) 누르세요.", + "longCommit": "커밋의 첫 번째 줄은 50자 미만으로 유지하는 것이 좋습니다. 추가 정보를 위해 자유롭게 더 많은 줄을 사용하세요.", "needMessage": "커밋 메시지를 입력하세요. 언제든지 **{0}**을(를) 눌러 변경 내용을 커밋할 수 있습니다. 스테이징된 변경 내용이 있으면 해당 변경 내용만 커밋되고 그렇지 않으면 모든 변경 내용이 커밋됩니다.", "nothingToCommit": "커밋할 변경 내용이 있으면 커밋 메시지를 입력하고 **{0}**을(를) 눌러 변경 내용을 커밋하세요. 스테이징된 변경 내용이 있으면 해당 변경 내용만 커밋되고 그렇지 않으면 모든 변경 내용이 커밋됩니다.", "showOutput": "Git 출력 표시", diff --git a/i18n/kor/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/kor/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index 9a735fad4cc..cadcfa5c1b3 100644 --- a/i18n/kor/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0}: {1}", "QuickCommandsAction.label": "편집기 명령 표시", "actionNotEnabled": "'{0}' 명령은 현재 컨텍스트에서 사용할 수 없습니다.", "canNotRun": "'{0}' 명령은 여기에서 실행할 수 없습니다.", diff --git a/i18n/kor/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/kor/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index bef586bc7de..7cdec7bf70e 100644 --- a/i18n/kor/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,26 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "검색 결과 지우기", - "CollapseAllAction.label": "축소", - "ConfigureGlobalExclusionsAction.label": "설정 열기", - "RefreshAction.label": "새로 고침", - "RemoveAction.label": "제거", - "SelectOrRemoveAction.removeLabel": "제거", - "SelectOrRemoveAction.selectLabel": "선택", "ariaSearchResultsStatus": "검색에서 {1}개의 파일에 {0}개의 결과를 반환했습니다.", - "defaultLabel": "입력", - "fileMatchAriaLabel": "{2} 폴더의 {1} 파일에 {0}개의 일치 항목이 있음, 검색 결과", - "findInFolder": "폴더에서 찾기", - "findPlaceHolder": "검색하려면 Enter 키를 누르고, 취소하려면 ESC 키를 누르세요.", "globLabel": "{0}({1}인 경우)", "global.searchScope.folders": "설정을 통해 제외된 파일", - "label.Search": "검색: 검색어를 입력하고 Enter 키를 눌러서 검색하세요. 취소하려면 Esc 키를 누르세요.", "label.excludes": "패턴 제외 검색", "label.global.excludes": "구성된 검색 제외 패턴", "label.includes": "패턴 포함 검색", "moreSearch": "검색 세부 정보 설정/해제", - "noMatches": "일치 항목 없음", "noResultsExcludes": "'{0}'을(를) 제외하는 결과가 없음 - ", "noResultsFound": "결과가 없습니다. 구성된 확장에 대한 설정을 검토하세요. - ", "noResultsIncludes": "'{0}'에 결과 없음 - ", "noResultsIncludesExcludes": "'{0}'에 '{1}'을(를) 제외한 결과 없음 - ", "openSettings.message": "설정 열기", - "patternDescription": "Glob 패턴 사용", - "patternHelpInclude": "일치 패턴입니다. 예: ****/*.js** - 모든 JavaScript 파일을 일치시킵니다. **myFolder/**** - 해당 폴더와 모든 자식을 일치시킵니다.\n\n**참조**:\n*****은 0개 이상의 문자를 일치시킵니다.\n**?**은 1개의 문자를 일치시킵니다.\n******은 0개 이상의 디렉터리를 일치시킵니다.\n**[a-z]**는 문자 범위를 일치시킵니다.\n**{a,b}**는 패턴을 일치시킵니다.", - "regexp.validationFailure": "식이 모든 항목과 일치", + "replaceAll.confirm.button": "바꾸기", + "replaceAll.confirmation.message": "{1}개 파일에서 {0}개를 바꿀까요?", + "replaceAll.confirmation.title": "모두 바꾸기", + "replaceAll.message": "{1}개 파일에서 {0}개를 바꿨습니다.", "rerunSearch.message": "다시 검색", "rerunSearchInAll.message": "모든 파일에서 다시 검색", "searchCanceled": "결과를 찾기 이전에 검색이 취소되었습니다. -", - "searchMatch": "일치하는 {0}개 항목을 찾음", - "searchMatches": "일치하는 {0}개 항목을 찾음", "searchMaxResultsWarning": "결과 집합에는 모든 일치 항목의 하위 집합만 포함됩니다. 결과 범위를 좁히려면 검색을 더 세분화하세요.", - "searchResultAria": "{0}, 검색 결과", "searchScope.excludes": "제외할 파일", "searchScope.includes": "포함할 파일", "treeAriaLabel": "검색 결과" diff --git a/i18n/kor/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json b/i18n/kor/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json index 9dbaa0353f9..d39e182a3e9 100644 --- a/i18n/kor/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json +++ b/i18n/kor/src/vs/workbench/parts/update/electron-browser/update.contribution.i18n.json @@ -5,7 +5,10 @@ // Do not edit this file. It is machine generated. { "close": "닫기", + "insiderBuilds": "참가자 빌드가 일일 빌드가 되고 있습니다!", "license": "라이선스 읽기", "licenseChanged": "사용 조건이 변경되었습니다. 자세히 읽어보세요.", + "neverShowAgain": "다시 표시 안 함", + "readmore": "자세히 알아보기", "releaseNotes": "{0} v{1}을(를) 시작합니다. 릴리스 정보를 확인하시겠습니까?" } \ No newline at end of file diff --git a/i18n/kor/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/kor/src/vs/workbench/services/history/browser/history.i18n.json index e7219ec13c8..0b9ee46e13e 100644 --- a/i18n/kor/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/kor/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[확장 개발 호스트] - {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} - {1}", "prefixWorkspaceTitle": "{0} - {1} - {2}", "prefixWorkspaceTitleMac": "{0} - {1}", diff --git a/i18n/rus/src/vs/code/electron-main/menus.i18n.json b/i18n/rus/src/vs/code/electron-main/menus.i18n.json index 92437a78db6..6093eb52388 100644 --- a/i18n/rus/src/vs/code/electron-main/menus.i18n.json +++ b/i18n/rus/src/vs/code/electron-main/menus.i18n.json @@ -45,7 +45,6 @@ "miLicense": "&&Просмотреть лицензию", "miMarker": "&&Ошибки и предупреждения...", "miMoveSidebar": "&&Переместить боковую панель", - "miNavigateHistory": "&&Журнал навигации", "miNewFile": "&&Новый файл", "miNewWindow": "&&Новое окно", "miOpen": "&&Открыть...", @@ -62,7 +61,6 @@ "miQuit": "Выйти из {0}", "miRedo": "&&Повторить", "miReleaseNotes": "&&Заметки о выпуске", - "miReopenClosedFile": "&&Повторно открыть файл", "miReplace": "&&Заменить", "miReportIssues": "&&Сообщить о проблемах", "miRestartToUpdate": "Перезапустить для обновления...", diff --git a/i18n/rus/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json b/i18n/rus/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json index 66f2061265c..9114cbf4830 100644 --- a/i18n/rus/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json +++ b/i18n/rus/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.i18n.json @@ -4,9 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "labelLoading": "Загрузка...", "meta.titleReference": " — ссылки {0}", - "noResults": "Результаты отсутствуют", "references.action.label": "Найти все ссылки", - "references.action.name": "Показать ссылки" + "references.action.name": "Найти все ссылки" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json index 95bf26ce9df..d5ae2f65594 100644 --- a/i18n/rus/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.i18n.json @@ -8,6 +8,7 @@ "globalConsoleActionWin": "Открыть новую командную строку", "scopedConsoleActionMacLinux": "Открыть в терминале", "scopedConsoleActionWin": "Открыть в командной строке", + "terminal.external.linuxExec": "Настройка терминала для запуска в Linux.", "terminal.external.windowsExec": "Настройка терминала, который будет запущен в Windows.", "terminalConfigurationTitle": "Конфигурация внешнего терминала" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json b/i18n/rus/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json index c938a9fa7cc..1cb07eac4e8 100644 --- a/i18n/rus/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.i18n.json @@ -4,16 +4,13 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "close": "Закрыть", "deleteSure": "Действительно удалить \"{0}\"?", - "installExtension": "Установить расширение", - "notFound": "Расширение \"{0}\" не установлено.", + "enableAction": "Включить", + "installAction": "Установить", + "installing": "Идет установка", "restartNow": "Перезагрузка", - "restartNow2": "Перезагрузка", "showExtensionRecommendations": "Показать рекомендуемые расширения", "showInstalledExtensions": "Показать установленные расширения", "showOutdatedExtensions": "Показать устаревшие расширения", - "success-installed": "Расширение \"{0}\" было успешно установлено. Чтобы включить его, выполните перезапуск.", - "success-uninstalled": "Расширение \"{0}\" было успешно удалено. Чтобы отключить его, выполните перезапуск.", "uninstall": "Удалить расширение" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json b/i18n/rus/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json index 438d12c0f06..8de2f445788 100644 --- a/i18n/rus/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/files/browser/saveErrorHandler.i18n.json @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "acceptLocalChanges": "Использовать локальные изменения и перезаписать содержимое на диске", + "acceptLocalChanges": "Перезаписать", "compareChanges": "Сравнить", "conflictingFileHasChanged": "Содержимое файла на диске изменилось, и левая часть редактора сравнения обновилась. Проверьте данные и устраните проблему.", "discard": "Отмена", diff --git a/i18n/rus/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json b/i18n/rus/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json index 8cd29c1cb99..e3d2ca61644 100644 --- a/i18n/rus/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/git/browser/gitActions.contribution.i18n.json @@ -9,5 +9,6 @@ "openFile": "Открыть файл", "openInEditor": "Переключиться в представление редактора", "stageSelectedLines": "Промежуточно сохранить выделенные строки", - "switchToChangesView": "Переключиться в представление изменений" + "switchToChangesView": "Переключиться в представление изменений", + "workbenchUnstage": "Отменить промежуточное сохранение" } \ No newline at end of file diff --git a/i18n/rus/src/vs/workbench/parts/git/browser/gitServices.i18n.json b/i18n/rus/src/vs/workbench/parts/git/browser/gitServices.i18n.json index 946e931a270..3ca9fdaf075 100644 --- a/i18n/rus/src/vs/workbench/parts/git/browser/gitServices.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/git/browser/gitServices.i18n.json @@ -9,7 +9,7 @@ "cantOpen": "Невозможно открыть этот ресурс GIT.", "cantOpenResource": "Невозможно открыть этот ресурс GIT.", "changesFromIndex": "{0} — изменения в индексе", - "changesFromTree": "{0} — изменения в {1}", + "changesFromTree": "{0} ({1})", "checkNativeConsole": "Ошибка при выполнении операции GIT. Проверьте выходные данные или используйте консоль для проверки состояния репозитория.", "configureUsernameEmail": "Настройте ваши имя пользователя и электронную почту GIT.", "download": "Скачать", diff --git a/i18n/rus/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json b/i18n/rus/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json index e4c915f248b..c7b11154825 100644 --- a/i18n/rus/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/quickopen/browser/commandsHandler.i18n.json @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { + "": "{0}: {1}", "QuickCommandsAction.label": "Показать команды редактора", "actionNotEnabled": "Команда {0} не разрешена в текущем контексте.", "canNotRun": "Выполнить команду {0} отсюда невозможно.", diff --git a/i18n/rus/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json b/i18n/rus/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json index 518faeea3fe..1b9f554afe6 100644 --- a/i18n/rus/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json +++ b/i18n/rus/src/vs/workbench/parts/search/browser/searchViewlet.i18n.json @@ -4,41 +4,24 @@ *--------------------------------------------------------------------------------------------*/ // Do not edit this file. It is machine generated. { - "ClearSearchResultsAction.label": "Очистить результаты поиска", - "CollapseAllAction.label": "Свернуть", - "ConfigureGlobalExclusionsAction.label": "Открыть параметры", - "RefreshAction.label": "Обновить", - "RemoveAction.label": "Удалить", - "SelectOrRemoveAction.removeLabel": "Удалить", - "SelectOrRemoveAction.selectLabel": "Выделить", "ariaSearchResultsStatus": "Поиск вернул результатов: {0} в файлах: {1}", - "defaultLabel": "ввод", - "fileMatchAriaLabel": "Совпадений {0} в файле {1} в папке {2}, результат поиска", - "findInFolder": "Найти в папке", - "findPlaceHolder": "Нажмите клавишу ВВОД, чтобы выполнить поиск, или ESCAPE для отмены", "globLabel": "{0}, когда {1}", "global.searchScope.folders": "файлы, исключенные в параметрах", - "label.Search": "Поиск: введите условие поиска и нажмите клавишу ВВОД, чтобы выполнить поиск, или ESCAPE для отмены", "label.excludes": "Шаблоны исключения из поиска", "label.global.excludes": "Настроенные шаблоны исключения из поиска", "label.includes": "Шаблоны включения в поиск", "moreSearch": "Переключить сведения о поиске", - "noMatches": "нет совпадений", "noResultsExcludes": "Результаты не найдены за исключением \"{0}\" — ", "noResultsFound": "Результаты не найдены. Проверьте параметры настроенных исключений — ", "noResultsIncludes": "Результаты в \"{0}\" не найдены — ", "noResultsIncludesExcludes": "Не найдено результатов в \"{0}\", исключая \"{1}\", — ", "openSettings.message": "Открыть параметры", - "patternDescription": "Использовать стандартные маски", - "patternHelpInclude": "Шаблон для сопоставления. Например, ****/*.js** соответствует всем файлам JavaScript, а **myFolder/**** соответствует этой папке со всеми дочерними элементами.\n\n**Ссылка**:\n***** соответствует 0 или более символов\n**?** соответствует 1 символу\n****** соответствует 0 или более каталогов\n**[a-z]** соответствует диапазону символов\n**{a,b}** соответствует любому из шаблонов", - "regexp.validationFailure": "Выражение сопоставляет все", + "replaceAll.confirm.button": "Заменить", + "replaceAll.confirmation.title": "Заменить все", "rerunSearch.message": "Выполнить поиск еще раз", "rerunSearchInAll.message": "Выполните поиск во всех файлах", "searchCanceled": "Поиск был отменен до того, как были найдены какие-либо результаты — ", - "searchMatch": "Найдено {0} соответствие", - "searchMatches": "Найдено {0} соответствий", "searchMaxResultsWarning": "Результирующий набор включает только подмножество всех соответствий. Чтобы уменьшить число результатов, сузьте условия поиска.", - "searchResultAria": "{0}, результат поиска", "searchScope.excludes": "исключаемые файлы", "searchScope.includes": "включаемые файлы", "treeAriaLabel": "Результаты поиска" diff --git a/i18n/rus/src/vs/workbench/services/history/browser/history.i18n.json b/i18n/rus/src/vs/workbench/services/history/browser/history.i18n.json index 7476d5b9f4d..4d57d0152ec 100644 --- a/i18n/rus/src/vs/workbench/services/history/browser/history.i18n.json +++ b/i18n/rus/src/vs/workbench/services/history/browser/history.i18n.json @@ -5,7 +5,7 @@ // Do not edit this file. It is machine generated. { "devExtensionWindowTitle": "[Узел разработки расширения] — {0}", - "prefixDecoration": "{0} {1}", + "prefixDecoration": "● {0}", "prefixTitle": "{0} — {1}", "prefixWorkspaceTitle": "{0} — {1} — {2}", "prefixWorkspaceTitleMac": "{0} — {1}", diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index e9139c3cf38..66d0cb5a188 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,17 +1,12 @@ { "name": "code-oss-dev", - "version": "1.3.0", + "version": "1.4.0", "dependencies": { "agent-base": { "version": "1.0.2", "from": "agent-base@>=1.0.1 <1.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-1.0.2.tgz" }, - "ansi-regex": { - "version": "2.0.0", - "from": "ansi-regex@latest", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" - }, "anymatch": { "version": "1.3.0", "from": "anymatch@>=1.1.0 <2.0.0", @@ -434,8 +429,8 @@ }, "xterm": { "version": "0.33.0", - "from": "git+https://github.com/sourcelair/xterm.js.git#39edbfb", - "resolved": "git+https://github.com/sourcelair/xterm.js.git#39edbfb6558343dc556b094470a84448d6a7a4d2" + "from": "git+https://github.com/sourcelair/xterm.js.git#8790a94", + "resolved": "git+https://github.com/sourcelair/xterm.js.git#8790a94a56cd68a7188eef9ec47c05d2fd69cc41" }, "yauzl": { "version": "2.3.1", diff --git a/package.json b/package.json index 8c8cd589392..7563e984cea 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "watch": "gulp watch" }, "dependencies": { - "ansi-regex": "^2.0.0", "applicationinsights": "0.15.6", "chokidar": "1.0.5", "emmet": "1.3.1", @@ -23,15 +22,15 @@ "http-proxy-agent": "0.2.7", "https-proxy-agent": "0.3.6", "iconv-lite": "0.4.13", - "minimist": "^1.2.0", + "minimist": "1.2.0", "native-keymap": "0.1.2", "pty.js": "https://github.com/Tyriar/pty.js/tarball/fffbf86eb9e8051b5b2be4ba9c7b07faa018ce8d", "sax": "1.1.2", "semver": "4.3.6", - "vscode-debugprotocol": "^1.11.0-pre.0", + "vscode-debugprotocol": "1.10.0", "vscode-textmate": "2.0.1", "winreg": "1.2.0", - "xterm": "git+https://github.com/sourcelair/xterm.js.git#39edbfb", + "xterm": "git+https://github.com/sourcelair/xterm.js.git#8790a94", "yauzl": "2.3.1" }, "devDependencies": { @@ -66,7 +65,7 @@ "gulp-uglify": "^1.4.1", "gulp-util": "^3.0.6", "gulp-vinyl-zip": "^1.2.2", - "gulp-watch": "^4.2.4", + "gulp-watch": "4.3.6", "innosetup-compiler": "^5.5.60", "is": "^3.1.0", "istanbul": "^0.3.17", diff --git a/resources/darwin/bin/code.sh b/resources/darwin/bin/code.sh index 9dba3f8e378..ac498810000 100755 --- a/resources/darwin/bin/code.sh +++ b/resources/darwin/bin/code.sh @@ -7,5 +7,5 @@ function realpath() { /usr/bin/python -c "import os,sys; print os.path.realpath( CONTENTS="$(dirname "$(dirname "$(dirname "$(dirname "$(realpath "$0")")")")")" ELECTRON="$CONTENTS/MacOS/Electron" CLI="$CONTENTS/Resources/app/out/cli.js" -ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" +ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" exit $? \ No newline at end of file diff --git a/resources/linux/bin/code.sh b/resources/linux/bin/code.sh index f0877aa4c9f..77fa49722f7 100755 --- a/resources/linux/bin/code.sh +++ b/resources/linux/bin/code.sh @@ -33,5 +33,5 @@ fi ELECTRON="$VSCODE_PATH/@@NAME@@" CLI="$VSCODE_PATH/resources/app/out/cli.js" -ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" +ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" exit $? \ No newline at end of file diff --git a/resources/linux/debian/control.template b/resources/linux/debian/control.template index 1d1cc3c4a83..28991e92188 100644 --- a/resources/linux/debian/control.template +++ b/resources/linux/debian/control.template @@ -7,6 +7,8 @@ Architecture: @@ARCHITECTURE@@ Maintainer: Microsoft Corporation Homepage: https://code.visualstudio.com/ Installed-Size: @@INSTALLEDSIZE@@ +Provides: visual-studio-@@NAME@@ +Conflicts: visual-studio-@@NAME@@ Replaces: visual-studio-@@NAME@@ Description: Code editing. Redefined. Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle. See https://code.visualstudio.com/docs/setup/linux for installation instructions and FAQ. diff --git a/resources/win32/bin/code.cmd b/resources/win32/bin/code.cmd index 54f206831a9..a975610eb31 100644 --- a/resources/win32/bin/code.cmd +++ b/resources/win32/bin/code.cmd @@ -1,6 +1,6 @@ @echo off setlocal set VSCODE_DEV= -set ELECTRON_RUN_AS_NODE=1 +set ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 call "%~dp0..\@@NAME@@.exe" "%~dp0..\resources\\app\\out\\cli.js" %* endlocal \ No newline at end of file diff --git a/resources/win32/bin/code.sh b/resources/win32/bin/code.sh index a9bab00a6d2..fd9f4bd0ffc 100644 --- a/resources/win32/bin/code.sh +++ b/resources/win32/bin/code.sh @@ -7,5 +7,5 @@ NAME="@@NAME@@" VSCODE_PATH="$(dirname "$(dirname "$(realpath "$0")")")" ELECTRON="$VSCODE_PATH/$NAME.exe" CLI="$VSCODE_PATH/resources/app/out/cli.js" -ELECTRON_NO_ATTACH_CONSOLE=1 ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" +ELECTRON_NO_ATTACH_CONSOLE=1 ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@" exit $? diff --git a/scripts/code-cli.sh b/scripts/code-cli.sh index eb1ed814f5a..2719ec4d4b7 100755 --- a/scripts/code-cli.sh +++ b/scripts/code-cli.sh @@ -26,7 +26,7 @@ function code() { CLI="$ROOT/out/cli.js" - ELECTRON_RUN_AS_NODE=1 \ + ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 \ NODE_ENV=development \ VSCODE_DEV=1 \ ELECTRON_ENABLE_LOGGING=1 \ diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat index fddb23d1dff..87dec89d1a1 100644 --- a/scripts/test-integration.bat +++ b/scripts/test-integration.bat @@ -4,7 +4,7 @@ setlocal rem APPVEYOR Builds if not "%APPVEYOR%" == "" ( set ELECTRON_NO_ATTACH_CONSOLE=1 - set ELECTRON_RUN_AS_NODE= + set ATOM_SHELL_INTERNAL_RUN_AS_NODE= ) :: Integration Tests diff --git a/scripts/test.bat b/scripts/test.bat index 15a4aaea84a..d62f7aba5eb 100644 --- a/scripts/test.bat +++ b/scripts/test.bat @@ -1,7 +1,7 @@ @echo off setlocal -set ELECTRON_RUN_AS_NODE=1 +set ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 rem TFS Builds if not "%BUILD_BUILDID%" == "" ( diff --git a/scripts/test.sh b/scripts/test.sh index 9910abbeb57..6df7101b848 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -21,11 +21,11 @@ test -d out || ./node_modules/.bin/gulp compile # Unit Tests if [[ "$OSTYPE" == "darwin"* ]]; then - cd $ROOT ; ulimit -n 4096 ; ELECTRON_RUN_AS_NODE=1 \ + cd $ROOT ; ulimit -n 4096 ; ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 \ ./.build/electron/Electron.app/Contents/MacOS/Electron \ node_modules/mocha/bin/_mocha $* else - cd $ROOT ; ELECTRON_RUN_AS_NODE=1 \ + cd $ROOT ; ATOM_SHELL_INTERNAL_RUN_AS_NODE=1 \ ./.build/electron/electron \ node_modules/mocha/bin/_mocha $* fi diff --git a/src/vs/base/browser/builder.ts b/src/vs/base/browser/builder.ts index 0b37f2f6527..231deb5e553 100644 --- a/src/vs/base/browser/builder.ts +++ b/src/vs/base/browser/builder.ts @@ -1624,6 +1624,15 @@ export class Builder implements IDisposable { return new MultiBuilder(builders); } + /** + * Returns a new builder with the child at the given index. + */ + public child(index = 0): Builder { + let children = this.currentElement.children; + + return withElement(children.item(index)); + } + /** * Removes the current HTMLElement from the given builder from this builder if this builders * current HTMLElement is the direct parent. diff --git a/src/vs/base/browser/event.ts b/src/vs/base/browser/event.ts index 34c37b47102..c99881b224f 100644 --- a/src/vs/base/browser/event.ts +++ b/src/vs/base/browser/event.ts @@ -6,113 +6,115 @@ import _Event, { Emitter } from 'vs/base/common/event'; +export type EventHandler = HTMLElement | HTMLDocument | Window; + export interface IDomEvent { - (element: HTMLElement, type: "MSContentZoom", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSGestureChange", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSGestureDoubleTap", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSGestureEnd", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSGestureHold", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSGestureStart", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSGestureTap", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSGotPointerCapture", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSInertiaStart", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSLostPointerCapture", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSManipulationStateChanged", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSPointerCancel", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSPointerDown", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSPointerEnter", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSPointerLeave", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSPointerMove", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSPointerOut", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSPointerOver", useCapture?: boolean): _Event; - (element: HTMLElement, type: "MSPointerUp", useCapture?: boolean): _Event; - (element: HTMLElement, type: "abort", useCapture?: boolean): _Event; - (element: HTMLElement, type: "activate", useCapture?: boolean): _Event; - (element: HTMLElement, type: "ariarequest", useCapture?: boolean): _Event; - (element: HTMLElement, type: "beforeactivate", useCapture?: boolean): _Event; - (element: HTMLElement, type: "beforecopy", useCapture?: boolean): _Event; - (element: HTMLElement, type: "beforecut", useCapture?: boolean): _Event; - (element: HTMLElement, type: "beforedeactivate", useCapture?: boolean): _Event; - (element: HTMLElement, type: "beforepaste", useCapture?: boolean): _Event; - (element: HTMLElement, type: "blur", useCapture?: boolean): _Event; - (element: HTMLElement, type: "canplay", useCapture?: boolean): _Event; - (element: HTMLElement, type: "canplaythrough", useCapture?: boolean): _Event; - (element: HTMLElement, type: "change", useCapture?: boolean): _Event; - (element: HTMLElement, type: "click", useCapture?: boolean): _Event; - (element: HTMLElement, type: "command", useCapture?: boolean): _Event; - (element: HTMLElement, type: "contextmenu", useCapture?: boolean): _Event; - (element: HTMLElement, type: "copy", useCapture?: boolean): _Event; - (element: HTMLElement, type: "cuechange", useCapture?: boolean): _Event; - (element: HTMLElement, type: "cut", useCapture?: boolean): _Event; - (element: HTMLElement, type: "dblclick", useCapture?: boolean): _Event; - (element: HTMLElement, type: "deactivate", useCapture?: boolean): _Event; - (element: HTMLElement, type: "drag", useCapture?: boolean): _Event; - (element: HTMLElement, type: "dragend", useCapture?: boolean): _Event; - (element: HTMLElement, type: "dragenter", useCapture?: boolean): _Event; - (element: HTMLElement, type: "dragleave", useCapture?: boolean): _Event; - (element: HTMLElement, type: "dragover", useCapture?: boolean): _Event; - (element: HTMLElement, type: "dragstart", useCapture?: boolean): _Event; - (element: HTMLElement, type: "drop", useCapture?: boolean): _Event; - (element: HTMLElement, type: "durationchange", useCapture?: boolean): _Event; - (element: HTMLElement, type: "emptied", useCapture?: boolean): _Event; - (element: HTMLElement, type: "ended", useCapture?: boolean): _Event; - (element: HTMLElement, type: "error", useCapture?: boolean): _Event; - (element: HTMLElement, type: "focus", useCapture?: boolean): _Event; - (element: HTMLElement, type: "gotpointercapture", useCapture?: boolean): _Event; - (element: HTMLElement, type: "input", useCapture?: boolean): _Event; - (element: HTMLElement, type: "keydown", useCapture?: boolean): _Event; - (element: HTMLElement, type: "keypress", useCapture?: boolean): _Event; - (element: HTMLElement, type: "keyup", useCapture?: boolean): _Event; - (element: HTMLElement, type: "load", useCapture?: boolean): _Event; - (element: HTMLElement, type: "loadeddata", useCapture?: boolean): _Event; - (element: HTMLElement, type: "loadedmetadata", useCapture?: boolean): _Event; - (element: HTMLElement, type: "loadstart", useCapture?: boolean): _Event; - (element: HTMLElement, type: "lostpointercapture", useCapture?: boolean): _Event; - (element: HTMLElement, type: "mousedown", useCapture?: boolean): _Event; - (element: HTMLElement, type: "mouseenter", useCapture?: boolean): _Event; - (element: HTMLElement, type: "mouseleave", useCapture?: boolean): _Event; - (element: HTMLElement, type: "mousemove", useCapture?: boolean): _Event; - (element: HTMLElement, type: "mouseout", useCapture?: boolean): _Event; - (element: HTMLElement, type: "mouseover", useCapture?: boolean): _Event; - (element: HTMLElement, type: "mouseup", useCapture?: boolean): _Event; - (element: HTMLElement, type: "mousewheel", useCapture?: boolean): _Event; - (element: HTMLElement, type: "paste", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pause", useCapture?: boolean): _Event; - (element: HTMLElement, type: "play", useCapture?: boolean): _Event; - (element: HTMLElement, type: "playing", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pointercancel", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pointerdown", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pointerenter", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pointerleave", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pointermove", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pointerout", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pointerover", useCapture?: boolean): _Event; - (element: HTMLElement, type: "pointerup", useCapture?: boolean): _Event; - (element: HTMLElement, type: "progress", useCapture?: boolean): _Event; - (element: HTMLElement, type: "ratechange", useCapture?: boolean): _Event; - (element: HTMLElement, type: "reset", useCapture?: boolean): _Event; - (element: HTMLElement, type: "scroll", useCapture?: boolean): _Event; - (element: HTMLElement, type: "seeked", useCapture?: boolean): _Event; - (element: HTMLElement, type: "seeking", useCapture?: boolean): _Event; - (element: HTMLElement, type: "select", useCapture?: boolean): _Event; - (element: HTMLElement, type: "selectstart", useCapture?: boolean): _Event; - (element: HTMLElement, type: "stalled", useCapture?: boolean): _Event; - (element: HTMLElement, type: "submit", useCapture?: boolean): _Event; - (element: HTMLElement, type: "suspend", useCapture?: boolean): _Event; - (element: HTMLElement, type: "timeupdate", useCapture?: boolean): _Event; - (element: HTMLElement, type: "touchcancel", useCapture?: boolean): _Event; - (element: HTMLElement, type: "touchend", useCapture?: boolean): _Event; - (element: HTMLElement, type: "touchmove", useCapture?: boolean): _Event; - (element: HTMLElement, type: "touchstart", useCapture?: boolean): _Event; - (element: HTMLElement, type: "volumechange", useCapture?: boolean): _Event; - (element: HTMLElement, type: "waiting", useCapture?: boolean): _Event; - (element: HTMLElement, type: "webkitfullscreenchange", useCapture?: boolean): _Event; - (element: HTMLElement, type: "webkitfullscreenerror", useCapture?: boolean): _Event; - (element: HTMLElement, type: "wheel", useCapture?: boolean): _Event; - (element: HTMLElement, type: string, useCapture?: boolean): _Event; + (element: EventHandler, type: "MSContentZoom", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSGestureChange", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSGestureDoubleTap", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSGestureEnd", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSGestureHold", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSGestureStart", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSGestureTap", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSGotPointerCapture", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSInertiaStart", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSLostPointerCapture", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSManipulationStateChanged", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSPointerCancel", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSPointerDown", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSPointerEnter", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSPointerLeave", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSPointerMove", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSPointerOut", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSPointerOver", useCapture?: boolean): _Event; + (element: EventHandler, type: "MSPointerUp", useCapture?: boolean): _Event; + (element: EventHandler, type: "abort", useCapture?: boolean): _Event; + (element: EventHandler, type: "activate", useCapture?: boolean): _Event; + (element: EventHandler, type: "ariarequest", useCapture?: boolean): _Event; + (element: EventHandler, type: "beforeactivate", useCapture?: boolean): _Event; + (element: EventHandler, type: "beforecopy", useCapture?: boolean): _Event; + (element: EventHandler, type: "beforecut", useCapture?: boolean): _Event; + (element: EventHandler, type: "beforedeactivate", useCapture?: boolean): _Event; + (element: EventHandler, type: "beforepaste", useCapture?: boolean): _Event; + (element: EventHandler, type: "blur", useCapture?: boolean): _Event; + (element: EventHandler, type: "canplay", useCapture?: boolean): _Event; + (element: EventHandler, type: "canplaythrough", useCapture?: boolean): _Event; + (element: EventHandler, type: "change", useCapture?: boolean): _Event; + (element: EventHandler, type: "click", useCapture?: boolean): _Event; + (element: EventHandler, type: "command", useCapture?: boolean): _Event; + (element: EventHandler, type: "contextmenu", useCapture?: boolean): _Event; + (element: EventHandler, type: "copy", useCapture?: boolean): _Event; + (element: EventHandler, type: "cuechange", useCapture?: boolean): _Event; + (element: EventHandler, type: "cut", useCapture?: boolean): _Event; + (element: EventHandler, type: "dblclick", useCapture?: boolean): _Event; + (element: EventHandler, type: "deactivate", useCapture?: boolean): _Event; + (element: EventHandler, type: "drag", useCapture?: boolean): _Event; + (element: EventHandler, type: "dragend", useCapture?: boolean): _Event; + (element: EventHandler, type: "dragenter", useCapture?: boolean): _Event; + (element: EventHandler, type: "dragleave", useCapture?: boolean): _Event; + (element: EventHandler, type: "dragover", useCapture?: boolean): _Event; + (element: EventHandler, type: "dragstart", useCapture?: boolean): _Event; + (element: EventHandler, type: "drop", useCapture?: boolean): _Event; + (element: EventHandler, type: "durationchange", useCapture?: boolean): _Event; + (element: EventHandler, type: "emptied", useCapture?: boolean): _Event; + (element: EventHandler, type: "ended", useCapture?: boolean): _Event; + (element: EventHandler, type: "error", useCapture?: boolean): _Event; + (element: EventHandler, type: "focus", useCapture?: boolean): _Event; + (element: EventHandler, type: "gotpointercapture", useCapture?: boolean): _Event; + (element: EventHandler, type: "input", useCapture?: boolean): _Event; + (element: EventHandler, type: "keydown", useCapture?: boolean): _Event; + (element: EventHandler, type: "keypress", useCapture?: boolean): _Event; + (element: EventHandler, type: "keyup", useCapture?: boolean): _Event; + (element: EventHandler, type: "load", useCapture?: boolean): _Event; + (element: EventHandler, type: "loadeddata", useCapture?: boolean): _Event; + (element: EventHandler, type: "loadedmetadata", useCapture?: boolean): _Event; + (element: EventHandler, type: "loadstart", useCapture?: boolean): _Event; + (element: EventHandler, type: "lostpointercapture", useCapture?: boolean): _Event; + (element: EventHandler, type: "mousedown", useCapture?: boolean): _Event; + (element: EventHandler, type: "mouseenter", useCapture?: boolean): _Event; + (element: EventHandler, type: "mouseleave", useCapture?: boolean): _Event; + (element: EventHandler, type: "mousemove", useCapture?: boolean): _Event; + (element: EventHandler, type: "mouseout", useCapture?: boolean): _Event; + (element: EventHandler, type: "mouseover", useCapture?: boolean): _Event; + (element: EventHandler, type: "mouseup", useCapture?: boolean): _Event; + (element: EventHandler, type: "mousewheel", useCapture?: boolean): _Event; + (element: EventHandler, type: "paste", useCapture?: boolean): _Event; + (element: EventHandler, type: "pause", useCapture?: boolean): _Event; + (element: EventHandler, type: "play", useCapture?: boolean): _Event; + (element: EventHandler, type: "playing", useCapture?: boolean): _Event; + (element: EventHandler, type: "pointercancel", useCapture?: boolean): _Event; + (element: EventHandler, type: "pointerdown", useCapture?: boolean): _Event; + (element: EventHandler, type: "pointerenter", useCapture?: boolean): _Event; + (element: EventHandler, type: "pointerleave", useCapture?: boolean): _Event; + (element: EventHandler, type: "pointermove", useCapture?: boolean): _Event; + (element: EventHandler, type: "pointerout", useCapture?: boolean): _Event; + (element: EventHandler, type: "pointerover", useCapture?: boolean): _Event; + (element: EventHandler, type: "pointerup", useCapture?: boolean): _Event; + (element: EventHandler, type: "progress", useCapture?: boolean): _Event; + (element: EventHandler, type: "ratechange", useCapture?: boolean): _Event; + (element: EventHandler, type: "reset", useCapture?: boolean): _Event; + (element: EventHandler, type: "scroll", useCapture?: boolean): _Event; + (element: EventHandler, type: "seeked", useCapture?: boolean): _Event; + (element: EventHandler, type: "seeking", useCapture?: boolean): _Event; + (element: EventHandler, type: "select", useCapture?: boolean): _Event; + (element: EventHandler, type: "selectstart", useCapture?: boolean): _Event; + (element: EventHandler, type: "stalled", useCapture?: boolean): _Event; + (element: EventHandler, type: "submit", useCapture?: boolean): _Event; + (element: EventHandler, type: "suspend", useCapture?: boolean): _Event; + (element: EventHandler, type: "timeupdate", useCapture?: boolean): _Event; + (element: EventHandler, type: "touchcancel", useCapture?: boolean): _Event; + (element: EventHandler, type: "touchend", useCapture?: boolean): _Event; + (element: EventHandler, type: "touchmove", useCapture?: boolean): _Event; + (element: EventHandler, type: "touchstart", useCapture?: boolean): _Event; + (element: EventHandler, type: "volumechange", useCapture?: boolean): _Event; + (element: EventHandler, type: "waiting", useCapture?: boolean): _Event; + (element: EventHandler, type: "webkitfullscreenchange", useCapture?: boolean): _Event; + (element: EventHandler, type: "webkitfullscreenerror", useCapture?: boolean): _Event; + (element: EventHandler, type: "wheel", useCapture?: boolean): _Event; + (element: EventHandler, type: string, useCapture?: boolean): _Event; } -export const domEvent: IDomEvent = (element: HTMLElement, type: string, useCapture?) => { +export const domEvent: IDomEvent = (element: EventHandler, type: string, useCapture?) => { const fn = e => emitter.fire(e); const emitter = new Emitter({ onFirstListenerAdd: () => { diff --git a/src/vs/base/browser/ui/actionbar/actionbar.css b/src/vs/base/browser/ui/actionbar/actionbar.css index a5b43fe4546..67b6e689382 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.css +++ b/src/vs/base/browser/ui/actionbar/actionbar.css @@ -95,46 +95,6 @@ margin-left: 6px; } -.monaco-action-bar .action-item .progress-item .label { - padding: 0.7em; - background-color: #1382CE; - display: inline-block; - vertical-align: top; - cursor: pointer; -} - -.monaco-action-bar .action-item .progress-item .tag { - display: inline-block; - vertical-align: top; - padding: 0.7em 0; - color: white; - font-weight: bold; - text-align: center; - overflow: hidden; - width: 0; - transition: width 200ms; - -webkit-transition: width 200ms; - -o-transition: width 200ms; - -moz-transition: width 200ms; - -ms-transition: width 200ms; -} - -.monaco-action-bar .action-item .progress-item .tag.active { - width: 1.5em; -} - -.monaco-action-bar .action-item .progress-item .tag.progress { - background-color: gray; -} - -.monaco-action-bar .action-item .progress-item .tag.done { - background-color: green; -} - -.monaco-action-bar .progress-item .tag.error { - background-color: #C33; -} - /* Action Items */ .monaco-action-bar .action-item.select-container { overflow: hidden; /* somehow the dropdown overflows its container, we prevent it here to not push */ diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 339afe226aa..6f27ce26e02 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -310,60 +310,6 @@ export class ActionItem extends BaseActionItem { } } -export class ProgressItem extends BaseActionItem { - - public render(parent: HTMLElement): void { - - let container = document.createElement('div'); - $(container).addClass('progress-item'); - - let label = document.createElement('div'); - $(label).addClass('label'); - label.textContent = this.getAction().label; - label.title = this.getAction().label; - super.render(label); - - let progress = document.createElement('div'); - progress.textContent = '\u2026'; - $(progress).addClass('tag', 'progress'); - - let done = document.createElement('div'); - done.textContent = '\u2713'; - $(done).addClass('tag', 'done'); - - let error = document.createElement('div'); - error.textContent = '!'; - $(error).addClass('tag', 'error'); - - this.callOnDispose.push(this.addListener2(CommonEventType.BEFORE_RUN, () => { - $(progress).addClass('active'); - $(done).removeClass('active'); - $(error).removeClass('active'); - })); - - this.callOnDispose.push(this.addListener2(CommonEventType.RUN, (result) => { - $(progress).removeClass('active'); - if (result.error) { - $(done).removeClass('active'); - $(error).addClass('active'); - } else { - $(error).removeClass('active'); - $(done).addClass('active'); - } - })); - - container.appendChild(label); - container.appendChild(progress); - container.appendChild(done); - container.appendChild(error); - parent.appendChild(container); - } - - public dispose(): void { - super.dispose(); - } -} - export enum ActionsOrientation { HORIZONTAL = 1, VERTICAL = 2 diff --git a/src/vs/base/browser/ui/inputbox/inputBox.css b/src/vs/base/browser/ui/inputbox/inputBox.css index 13fe2cd1d0f..ac638af2d30 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.css +++ b/src/vs/base/browser/ui/inputbox/inputBox.css @@ -18,12 +18,6 @@ font-size: inherit; } -/*.monaco-inputbox { font-family: "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback"; } -.monaco-inputbox:lang(zh-Hans) { font-family: "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", "Noto Sans", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans", sans-serif; } -.monaco-inputbox:lang(zh-Hant) { font-family: "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", "Noto Sans", "Microsoft Jhenghei", "PingFang TC", "Source Han Sans TC", "Source Han Sans", "Source Han Sans TW", sans-serif; } -.monaco-inputbox:lang(ja) { font-family: "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", "Noto Sans", "Meiryo", "Hiragino Kaku Gothic Pro", "Source Han Sans J", "Source Han Sans JP", "Source Han Sans", "Sazanami Gothic", "IPA Gothic", sans-serif; } -.monaco-inputbox:lang(ko) { font-family: "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", "Noto Sans", "Malgun Gothic", "Nanum Gothic", "Dotom", "Apple SD Gothic Neo", "AppleGothic", "Source Han Sans K", "Source Han Sans JR", "Source Han Sans", "UnDotum", "FBaekmuk Gulim", sans-serif; }*/ - .monaco-inputbox > .wrapper > .input, .monaco-inputbox > .wrapper > .mirror { diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index 7da5370aec3..9c93f18e307 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -94,6 +94,10 @@ export class PagedList { return this.list.scrollTop; } + set scrollTop(scrollTop: number) { + this.list.scrollTop = scrollTop; + } + focusNext(n?: number, loop?: boolean): void { this.list.focusNext(n, loop); } @@ -110,6 +114,14 @@ export class PagedList { this.list.selectPrevious(n, loop); } + focusNextPage(): void { + this.list.focusNextPage(); + } + + focusPreviousPage(): void { + this.list.focusPreviousPage(); + } + getFocus(): number[] { return this.list.getFocus(); } @@ -121,4 +133,8 @@ export class PagedList { layout(height?: number): void { this.list.layout(height); } + + reveal(index: number, relativeTop?: number): void { + this.list.reveal(index, relativeTop); + } } \ 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 cba1e19027a..901ef728da6 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -7,7 +7,9 @@ import 'vs/css!./list'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { isNumber } from 'vs/base/common/types'; import * as DOM from 'vs/base/browser/dom'; -import Event, { Emitter, mapEvent, EventBufferer } from 'vs/base/common/event'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import Event, { Emitter, mapEvent, EventBufferer, filterEvent } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { IDelegate, IRenderer, IListMouseEvent, IFocusChangeEvent, ISelectionChangeEvent } from './list'; import { ListView, IListViewOptions } from './listView'; @@ -120,15 +122,23 @@ class FocusTrait extends Trait { class Controller implements IDisposable { - private toDispose: IDisposable[]; + private disposables: IDisposable[]; constructor( private list: List, private view: ListView ) { - this.toDispose = []; - this.toDispose.push(view.addListener('mousedown', e => this.onMouseDown(e))); - this.toDispose.push(view.addListener('click', e => this.onClick(e))); + this.disposables = []; + this.disposables.push(view.addListener('mousedown', e => this.onMouseDown(e))); + this.disposables.push(view.addListener('click', e => this.onClick(e))); + + const onRawKeyDown = domEvent(view.domNode, 'keydown'); + const onKeyDown = mapEvent(onRawKeyDown, e => new StandardKeyboardEvent(e)); + filterEvent(onKeyDown, e => e.keyCode === KeyCode.Enter)(this.onEnter, this, this.disposables); + filterEvent(onKeyDown, e => e.keyCode === KeyCode.UpArrow)(this.onUpArrow, this, this.disposables); + filterEvent(onKeyDown, e => e.keyCode === KeyCode.DownArrow)(this.onDownArrow, this, this.disposables); + filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageUp)(this.onPageUpArrow, this, this.disposables); + filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageDown)(this.onPageDownArrow, this, this.disposables); } private onMouseDown(e: IListMouseEvent) { @@ -144,8 +154,46 @@ class Controller implements IDisposable { this.list.setSelection(e.index); } + private onEnter(e: StandardKeyboardEvent): void { + e.preventDefault(); + e.stopPropagation(); + this.list.setSelection(...this.list.getFocus()); + } + + private onUpArrow(e: StandardKeyboardEvent): void { + e.preventDefault(); + e.stopPropagation(); + this.list.focusPrevious(); + this.list.reveal(this.list.getFocus()[0]); + this.view.domNode.focus(); + } + + private onDownArrow(e: StandardKeyboardEvent): void { + e.preventDefault(); + e.stopPropagation(); + this.list.focusNext(); + this.list.reveal(this.list.getFocus()[0]); + this.view.domNode.focus(); + } + + private onPageUpArrow(e: StandardKeyboardEvent): void { + e.preventDefault(); + e.stopPropagation(); + this.list.focusPreviousPage(); + this.list.reveal(this.list.getFocus()[0]); + this.view.domNode.focus(); + } + + private onPageDownArrow(e: StandardKeyboardEvent): void { + e.preventDefault(); + e.stopPropagation(); + this.list.focusNextPage(); + this.list.reveal(this.list.getFocus()[0]); + this.view.domNode.focus(); + } + dispose() { - this.toDispose = dispose(this.toDispose); + this.disposables = dispose(this.disposables); } } @@ -220,6 +268,10 @@ export class List implements IDisposable { return this.view.getScrollTop(); } + set scrollTop(scrollTop: number) { + this.view.setScrollTop(scrollTop); + } + layout(height?: number): void { this.view.layout(height); } diff --git a/src/vs/base/browser/ui/resourceviewer/resourceViewer.ts b/src/vs/base/browser/ui/resourceviewer/resourceViewer.ts index 571c6760386..d4340ec2c4b 100644 --- a/src/vs/base/browser/ui/resourceviewer/resourceViewer.ts +++ b/src/vs/base/browser/ui/resourceviewer/resourceViewer.ts @@ -63,20 +63,28 @@ const mapExtToMediaMimes = { '.movie': 'video/x-sgi-movie' }; +export interface IResourceDescriptor { + resource: URI; + name: string; + size: number; +} + /** * Helper to actually render the given resource into the provided container. Will adjust scrollbar (if provided) automatically based on loading * progress of the binary resource. */ export class ResourceViewer { - public static show(name: string, resource: URI, container: Builder, scrollbar: DomScrollableElement): void { + private static MAX_IMAGE_SIZE = 1024 * 1024; // showing images inline is memory intense, so we have a limit + + public static show(descriptor: IResourceDescriptor, container: Builder, scrollbar: DomScrollableElement): void { // Ensure CSS class $(container).setClass('monaco-resource-viewer'); // Lookup media mime if any let mime: string; - const ext = paths.extname(resource.toString()); + const ext = paths.extname(descriptor.resource.toString()); if (ext) { mime = mapExtToMediaMimes[ext.toLowerCase()]; } @@ -86,12 +94,12 @@ export class ResourceViewer { } // Show Image inline - if (mime.indexOf('image/') >= 0) { + if (mime.indexOf('image/') >= 0 && descriptor.size <= ResourceViewer.MAX_IMAGE_SIZE) { $(container) .empty() .addClass('image') .img({ - src: resource.toString() // disabled due to https://github.com/electron/electron/issues/6275 + '?' + Date.now() // We really want to avoid the browser from caching this resource, so we add a fake query param that is unique + src: descriptor.resource.toString() // disabled due to https://github.com/electron/electron/issues/6275 + '?' + Date.now() // We really want to avoid the browser from caching this resource, so we add a fake query param that is unique }).on(DOM.EventType.LOAD, (e, img) => { const imgElement = img.getHTMLElement(); if (imgElement.naturalWidth > imgElement.width || imgElement.naturalHeight > imgElement.height) { @@ -105,7 +113,7 @@ export class ResourceViewer { } // Update title when we know the image bounds - img.title(nls.localize('imgTitle', "{0} ({1}x{2})", paths.basename(resource.fsPath), imgElement.naturalWidth, imgElement.naturalHeight)); + img.title(nls.localize('imgTitle', "{0} ({1}x{2})", paths.basename(descriptor.resource.fsPath), imgElement.naturalWidth, imgElement.naturalHeight)); scrollbar.scanDomNode(); }); @@ -117,7 +125,7 @@ export class ResourceViewer { .empty() .element('object') .attr({ - data: resource.toString(), // disabled due to https://github.com/electron/electron/issues/6275 + '?' + Date.now(), // We really want to avoid the browser from caching this resource, so we add a fake query param that is unique + data: descriptor.resource.toString(), // disabled due to https://github.com/electron/electron/issues/6275 + '?' + Date.now(), // We really want to avoid the browser from caching this resource, so we add a fake query param that is unique width: '100%', height: '100%', type: mime @@ -130,7 +138,7 @@ export class ResourceViewer { .empty() .element('audio') .attr({ - src: resource.toString(), // disabled due to https://github.com/electron/electron/issues/6275 + '?' + Date.now(), // We really want to avoid the browser from caching this resource, so we add a fake query param that is unique + src: descriptor.resource.toString(), // disabled due to https://github.com/electron/electron/issues/6275 + '?' + Date.now(), // We really want to avoid the browser from caching this resource, so we add a fake query param that is unique text: nls.localize('missingAudioSupport', "Sorry but playback of audio files is not supported."), controls: 'controls' }).on(DOM.EventType.LOAD, () => { @@ -144,7 +152,7 @@ export class ResourceViewer { .empty() .element('video') .attr({ - src: resource.toString(), // disabled due to https://github.com/electron/electron/issues/6275 + '?' + Date.now(), // We really want to avoid the browser from caching this resource, so we add a fake query param that is unique + src: descriptor.resource.toString(), // disabled due to https://github.com/electron/electron/issues/6275 + '?' + Date.now(), // We really want to avoid the browser from caching this resource, so we add a fake query param that is unique text: nls.localize('missingVideoSupport', "Sorry but playback of video files is not supported."), controls: 'controls' }).on(DOM.EventType.LOAD, () => { @@ -157,7 +165,7 @@ export class ResourceViewer { $(container) .empty() .span({ - text: nls.localize('nativeBinaryError', "The file cannot be displayed in the editor because it is either binary, very large or uses an unsupported text encoding.") + text: nls.localize('nativeBinaryError', "The file will not be displayed in the editor because it is either binary, very large or uses an unsupported text encoding.") }); scrollbar.scanDomNode(); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index f25b9e263e0..dd3d7f747b1 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -240,12 +240,12 @@ export class ScrollableElement extends Widget { let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity; if (this._options.flipAxes) { - deltaY = e.deltaX; - deltaX = e.deltaY; + deltaY = deltaX; + deltaX = deltaY; } if (this._options.scrollYToX && !deltaX) { - deltaX = e.deltaY; + deltaX = deltaY; deltaY = 0; } diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index a8aa4198c5c..822a28f78ae 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -31,6 +31,12 @@ display: flex; } +/* Bold font style does not go well with CJK fonts */ +.monaco-split-view:lang(zh-Hans) > .split-view-view > .header, +.monaco-split-view:lang(zh-Hant) > .split-view-view > .header, +.monaco-split-view:lang(ja) > .split-view-view > .header, +.monaco-split-view:lang(ko) > .split-view-view > .header { font-weight: normal; } + .monaco-split-view > .split-view-view > .header.collapsible { cursor: pointer; } diff --git a/src/vs/base/browser/ui/toolbar/toolbar.css b/src/vs/base/browser/ui/toolbar/toolbar.css index 425eb455375..55f9069d035 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.css +++ b/src/vs/base/browser/ui/toolbar/toolbar.css @@ -29,20 +29,7 @@ background-image: url('ellipsis.svg'); } +.hc-black .monaco-toolbar .action-label.toolbar-toggle-more, .vs-dark .monaco-toolbar .action-label.toolbar-toggle-more { background-image: url('ellipsis-inverse.svg'); -} - -/* High Contrast Theming */ -.hc-black .monaco-toolbar .action-label.toolbar-toggle-more { - background: none; -} - -.hc-black .monaco-toolbar .action-label.toolbar-toggle-more:before { - content: url('ellipsis-inverse.svg'); - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; } \ No newline at end of file diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index f6b559fa460..d866111a822 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -199,8 +199,9 @@ export function debounceEvent(event: Event, merger: (last: O, event: I) output = merger(output, cur); clearTimeout(handle); handle = setTimeout(() => { - emitter.fire(output); + let _output = output; output = undefined; + emitter.fire(_output); }, delay); }); }, @@ -262,4 +263,4 @@ export class EventBufferer { this.buffers.pop(); buffer.forEach(flush => flush()); } -} \ No newline at end of file +} diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 9f90ff649de..e69a8db3128 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -256,19 +256,32 @@ export default class URI { return new URI().with(components); } + private static _schemePattern = /^\w[\w\d+.-]*$/; + private static _singleSlashStart = /^\//; + private static _doubleSlashStart = /^\/\//; + private static _validate(ret: URI): void { + // scheme, https://tools.ietf.org/html/rfc3986#section-3.1 + // ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + if (ret.scheme && !URI._schemePattern.test(ret.scheme)) { + throw new Error('[UriError]: Scheme contains illegal characters.'); + } - // validation // path, http://tools.ietf.org/html/rfc3986#section-3.3 // If a URI contains an authority component, then the path component // must either be empty or begin with a slash ("/") character. If a URI // does not contain an authority component, then the path cannot begin // with two slash characters ("//"). - if (ret.authority && ret.path && ret.path[0] !== '/') { - throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character'); - } - if (!ret.authority && ret.path.indexOf('//') === 0) { - throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")'); + if (ret.path) { + if (ret.authority) { + if (!URI._singleSlashStart.test(ret.path)) { + throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character'); + } + } else { + if (URI._doubleSlashStart.test(ret.path)) { + throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")'); + } + } } } diff --git a/src/vs/base/node/stdFork.ts b/src/vs/base/node/stdFork.ts index 4bb749129ff..4751a8fa83b 100644 --- a/src/vs/base/node/stdFork.ts +++ b/src/vs/base/node/stdFork.ts @@ -49,7 +49,7 @@ function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string newEnv['STDIN_PIPE_NAME'] = stdInPipeName; newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName; newEnv['STDERR_PIPE_NAME'] = stdErrPipeName; - newEnv['ELECTRON_RUN_AS_NODE'] = '1'; + newEnv['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = '1'; return newEnv; } diff --git a/src/vs/base/node/stdForkStart.js b/src/vs/base/node/stdForkStart.js index 92024acf6b8..0b1e7382fe5 100644 --- a/src/vs/base/node/stdForkStart.js +++ b/src/vs/base/node/stdForkStart.js @@ -33,7 +33,7 @@ var stdErrPipeName = process.env['STDERR_PIPE_NAME']; log('STDIN_PIPE_NAME: ' + stdInPipeName); log('STDOUT_PIPE_NAME: ' + stdOutPipeName); log('STDERR_PIPE_NAME: ' + stdErrPipeName); -log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']); +log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']); // stdout redirection to named pipe (function() { @@ -149,7 +149,7 @@ log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']); delete process.env['STDIN_PIPE_NAME']; delete process.env['STDOUT_PIPE_NAME']; delete process.env['STDERR_PIPE_NAME']; - delete process.env['ELECTRON_RUN_AS_NODE']; + delete process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']; require(program); diff --git a/src/vs/workbench/node/userSettings.ts b/src/vs/base/node/userSettings.ts similarity index 91% rename from src/vs/workbench/node/userSettings.ts rename to src/vs/base/node/userSettings.ts index 1ab54bb3bbb..58c4dd85a76 100644 --- a/src/vs/workbench/node/userSettings.ts +++ b/src/vs/base/node/userSettings.ts @@ -6,11 +6,10 @@ 'use strict'; -import fs = require('fs'); -import path = require('path'); - -import json = require('vs/base/common/json'); -import objects = require('vs/base/common/objects'); +import * as fs from 'fs'; +import * as path from 'path'; +import * as json from 'vs/base/common/json'; +import * as objects from 'vs/base/common/objects'; import {TPromise} from 'vs/base/common/winjs.base'; import Event, {Emitter} from 'vs/base/common/event'; @@ -24,7 +23,7 @@ export class UserSettings { private static CHANGE_BUFFER_DELAY = 300; - public globalSettings: ISettings; + globalSettings: ISettings; private timeoutHandle: number; private watcher: fs.FSWatcher; @@ -41,7 +40,7 @@ export class UserSettings { this.registerWatchers(); } - public static getValue(userDataPath: string, key: string, fallback?: any): TPromise { + static getValue(userDataPath: string, key: string, fallback?: any): TPromise { // TODO@joao cleanup! const appSettingsPath = path.join(userDataPath, 'User', 'settings.json'); @@ -66,11 +65,11 @@ export class UserSettings { }); } - public get onChange(): Event { + get onChange(): Event { return this._onChange.event; } - public getValue(key: string, fallback?: any): any { + getValue(key: string, fallback?: any): any { return UserSettings.doGetValue(this.globalSettings.settings, key, fallback); } @@ -116,7 +115,7 @@ export class UserSettings { }, UserSettings.CHANGE_BUFFER_DELAY); } - public loadSync(): boolean { + loadSync(): boolean { let loadedSettings = this.doLoadSync(); if (!objects.equals(loadedSettings, this.globalSettings)) { @@ -199,7 +198,7 @@ export class UserSettings { return []; } - public dispose(): void { + dispose(): void { if (this.watcher) { this.watcher.close(); this.watcher = null; diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index 9296f4fe1aa..4ccb63e4cef 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -620,8 +620,13 @@ export class QuickOpenWidget implements IModelProvider { // Indicate entries to tree this.tree.layout(); + let doAutoFocus = autoFocus && input && input.entries.some(e => this.isElementVisible(input, e)); + if (doAutoFocus && !autoFocus.autoFocusPrefixMatch) { + doAutoFocus = !this.tree.getFocus(); // if auto focus is not for prefix matches, we do not want to change what the user has focussed already + } + // Handle auto focus - if (input && input.entries.some(e => this.isElementVisible(input, e))) { + if (doAutoFocus) { this.autoFocus(input, autoFocus); } }, errors.onUnexpectedError); diff --git a/src/vs/base/parts/tree/browser/tree.css b/src/vs/base/parts/tree/browser/tree.css index 1f932ed2483..3f029712b7f 100644 --- a/src/vs/base/parts/tree/browser/tree.css +++ b/src/vs/base/parts/tree/browser/tree.css @@ -157,40 +157,40 @@ } /* Default style */ -.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused:not(.highlighted) { background-color: #DCEBFC; } -.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { background-color: #4FA7FF; color: white; } -.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused.selected:not(.highlighted) { background-color: #3399FF; color: white; } -.monaco-tree .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { background-color: #CCCEDB; } +.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused:not(.highlighted) { background-color: #DCEBFC; } +.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { background-color: #4FA7FF; color: white; } +.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused.selected:not(.highlighted) { background-color: #3399FF; color: white; } +.monaco-tree .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { background-color: #CCCEDB; } .monaco-tree .monaco-tree-rows > .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) { background-color: #F0F0F0; } .monaco-tree .monaco-tree-wrapper.drop-target, -.monaco-tree .monaco-tree-rows > .monaco-tree-row.drop-target { background-color: #DDECFF !important; color: inherit !important; } +.monaco-tree .monaco-tree-rows > .monaco-tree-row.drop-target { background-color: #DDECFF !important; color: inherit !important; } -.monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:before { border-color: transparent; border-left-color: #A6A6A6; } -.monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:after { border-color: transparent; border-left-color: #F6F6F6; } -.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected.has-children > .content:before { border-left-color: white; } -.monaco-tree .monaco-tree-rows > .monaco-tree-row.selected.has-children > .content:before { border-left-color: #646465; } -.monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children:hover:not(.selected):not(.focused) > .content:after { border-left-color: #f0f0f0; } -.monaco-tree .monaco-tree-rows > .monaco-tree-row.selected.has-children > .content:after { border-left-color: #CCCEDB; } -.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected.has-children > .content:after { border-left-color: #3399FF; } +.monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:before { border-color: transparent; border-left-color: #A6A6A6; } +.monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:after { border-color: transparent; border-left-color: #F6F6F6; } +.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected.has-children > .content:before { border-left-color: white; } +.monaco-tree .monaco-tree-rows > .monaco-tree-row.selected.has-children > .content:before { border-left-color: #646465; } +.monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children:hover:not(.selected):not(.focused) > .content:after { border-left-color: #f0f0f0; } +.monaco-tree .monaco-tree-rows > .monaco-tree-row.selected.has-children > .content:after { border-left-color: #CCCEDB; } +.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected.has-children > .content:after { border-left-color: #3399FF; } .monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:before { border-color: transparent; border-right-color: #646465; } -.monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:after { border-color: transparent; } +.monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:after { border-color: transparent; } .monaco-tree .monaco-tree-rows > .monaco-tree-row.selected.expanded > .content:before { border-left-color: transparent; } .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected.expanded > .content:before { border-right-color: white; border-left-color: transparent; } /* VS Dark */ -.vs-dark .monaco-tree.focused .monaco-tree-row.focused:not(.highlighted) { background-color: #073655; } -.vs-dark .monaco-tree.focused .monaco-tree-row.selected:not(.highlighted) { background-color: #0E639C; color: white; } +.vs-dark .monaco-tree.focused .monaco-tree-row.focused:not(.highlighted) { background-color: #073655; } +.vs-dark .monaco-tree.focused .monaco-tree-row.selected:not(.highlighted) { background-color: #0E639C; color: white; } .vs-dark .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused.selected:not(.highlighted) { background-color: #094771; color: white; } -.vs-dark .monaco-tree .monaco-tree-row.selected:not(.highlighted) { background-color: #3F3F46; } +.vs-dark .monaco-tree .monaco-tree-row.selected:not(.highlighted) { background-color: #3F3F46; } .vs-dark .monaco-tree .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) { background-color: #2A2D2E; } .vs-dark .monaco-tree-wrapper.drop-target, -.vs-dark .monaco-tree .monaco-tree-row.drop-target { background-color: #383B3D !important; color: inherit !important; } +.vs-dark .monaco-tree .monaco-tree-row.drop-target { background-color: #383B3D !important; color: inherit !important; } /* VS Dark twistie */ -.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:before { border-left-color: #D4D4D4; } -.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:after { border-left-color: #252526; } -.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:before { border-left-color: transparent; border-right-color: #D4D4D4; } +.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:before { border-left-color: #D4D4D4; } +.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:after { border-left-color: #252526; } +.vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:before { border-left-color: transparent; border-right-color: #D4D4D4; } .vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children:hover:not(.selected):not(.focused) > .content:after { border-left-color: #2A2D2E; } .vs-dark .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children.loading > .content:before { @@ -198,13 +198,13 @@ } /* High Contrast Theming */ -.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row { background: none !important; } +.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row { background: none !important; border: 1px solid transparent; } .hc-black .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused:not(.highlighted) { border: 1px dotted #f38518; } -.hc-black .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { border: 1px solid #f38518; } +.hc-black .monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { border: 1px solid #f38518; } .hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.selected:not(.highlighted) { border: 1px solid #f38518; } -.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) { border: 1px dashed #f38518; margin-top:-1px; margin-bottom:1px; margin-left:-1px; } +.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row:hover:not(.highlighted):not(.selected):not(.focused) { border: 1px dashed #f38518; } .hc-black .monaco-tree .monaco-tree-wrapper.drop-target, -.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.drop-target { background: none !important; border: 1px dashed #f38518; } +.hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.drop-target { background: none !important; border: 1px dashed #f38518; } .hc-black .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:before { border: none; diff --git a/src/vs/base/parts/tree/browser/tree.ts b/src/vs/base/parts/tree/browser/tree.ts index 9d71d02fb58..6f42e858163 100644 --- a/src/vs/base/parts/tree/browser/tree.ts +++ b/src/vs/base/parts/tree/browser/tree.ts @@ -126,7 +126,7 @@ export interface ITree extends Events.IEventEmitter { /** * Returns the relative top position of any given element, if visible. - * If not visible, returns -1. + * If not visible, returns a negative number or a number > 1. * Useful when calling `reveal(element, relativeTop)`. */ getRelativeTop(element: any): number; @@ -265,10 +265,15 @@ export interface ITree extends Events.IEventEmitter { focusPrevious(count?: number, eventPayload?:any): void; /** - * Focuses the currently selected element's parent. + * Focuses the currently focused element's parent. */ focusParent(eventPayload?: any): void; + /** + * Focuses the first child of the currently focused element. + */ + focusFirstChild(eventPayload?: any): void; + /** * Focuses the second element, in visible order. */ diff --git a/src/vs/base/parts/tree/browser/treeDefaults.ts b/src/vs/base/parts/tree/browser/treeDefaults.ts index 00fe16f9b96..012d54da931 100644 --- a/src/vs/base/parts/tree/browser/treeDefaults.ts +++ b/src/vs/base/parts/tree/browser/treeDefaults.ts @@ -339,7 +339,12 @@ export class DefaultController implements _.IController { tree.clearHighlight(payload); } else { var focus = tree.getFocus(); - tree.expand(focus).done(null, errors.onUnexpectedError); + tree.expand(focus).then(didExpand => { + if (focus && !didExpand) { + tree.focusFirstChild(payload); + return tree.reveal(tree.getFocus()); + } + }).done(null, errors.onUnexpectedError); } return true; } diff --git a/src/vs/base/parts/tree/browser/treeImpl.ts b/src/vs/base/parts/tree/browser/treeImpl.ts index 4ff2a308a7a..435c606eeb2 100644 --- a/src/vs/base/parts/tree/browser/treeImpl.ts +++ b/src/vs/base/parts/tree/browser/treeImpl.ts @@ -161,7 +161,7 @@ export class Tree extends Events.EventEmitter implements _.ITree { } public getRelativeTop(element: any): number { - let item= this.model.getItem(element); + let item = this.model.getItem(element); return this.view.getRelativeTop(item); } @@ -273,6 +273,10 @@ export class Tree extends Events.EventEmitter implements _.ITree { this.model.focusParent(eventPayload); } + public focusFirstChild(eventPayload?:any): void { + this.model.focusFirstChild(eventPayload); + } + public focusFirst(eventPayload?:any): void { this.model.focusFirst(eventPayload); } diff --git a/src/vs/base/parts/tree/browser/treeModel.ts b/src/vs/base/parts/tree/browser/treeModel.ts index 61a82465182..68823423a53 100644 --- a/src/vs/base/parts/tree/browser/treeModel.ts +++ b/src/vs/base/parts/tree/browser/treeModel.ts @@ -1197,6 +1197,17 @@ export class TreeModel extends Events.EventEmitter { } } + public focusFirstChild(eventPayload?: any): void { + const item = this.getItem(this.getFocus() || this.input); + const nav = this.getNavigator(item, false); + const next = nav.next(); + const parent = nav.parent(); + + if (parent === item) { + this.setFocus(next, eventPayload); + } + } + public focusFirst(eventPayload?: any): void { this.focusNth(0, eventPayload); } diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index a1ba2dde287..eec80162bf2 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -986,7 +986,7 @@ export class TreeView extends HeightMap { } public getRelativeTop(item: Model.Item): number { - if (item.isVisible()) { + if (item && item.isVisible()) { var viewItem = this.items[item.id]; if (viewItem) { return (viewItem.top - this.scrollTop) / (this.viewHeight - viewItem.height); diff --git a/src/vs/base/test/common/event.test.ts b/src/vs/base/test/common/event.test.ts index 24c23e3b85c..416005e8bc4 100644 --- a/src/vs/base/test/common/event.test.ts +++ b/src/vs/base/test/common/event.test.ts @@ -5,7 +5,7 @@ 'use strict'; import * as assert from 'assert'; -import Event, {Emitter, fromEventEmitter, EventBufferer} from 'vs/base/common/event'; +import Event, {Emitter, fromEventEmitter, debounceEvent, EventBufferer} from 'vs/base/common/event'; import {IDisposable} from 'vs/base/common/lifecycle'; import {EventEmitter} from 'vs/base/common/eventEmitter'; import Errors = require('vs/base/common/errors'); @@ -177,6 +177,37 @@ suite('Event',function(){ Errors.setUnexpectedErrorHandler(origErrorHandler); } }); + + test('Debounce Event', function (done: () => void) { + let doc = new Samples.Document3(); + + let onDocDidChange = debounceEvent(doc.onDidChange, (prev: string[], cur) => { + if (!prev) { + prev = [cur]; + } else if (prev.indexOf(cur) < 0) { + prev.push(cur); + } + return prev; + }, 10); + + let count = 0; + + onDocDidChange(keys => { + count++; + assert.ok(keys, 'was not expecting keys.'); + if (count === 1) { + doc.setText('4'); + assert.deepEqual(keys, ['1', '2', '3']); + } else if (count === 2){ + assert.deepEqual(keys, ['4']); + done(); + } + }); + + doc.setText('1'); + doc.setText('2'); + doc.setText('3'); + }); }); suite('EventBufferer', () => { diff --git a/src/vs/base/test/common/uri.test.ts b/src/vs/base/test/common/uri.test.ts index b7761f0744c..fd8cc4b511a 100644 --- a/src/vs/base/test/common/uri.test.ts +++ b/src/vs/base/test/common/uri.test.ts @@ -94,6 +94,14 @@ suite('URI', () => { assert.equal(URI.parse('scheme:/path').with({ authority: null }).toString(), 'scheme:/path'); }); + test('with, validation', () => { + let uri = URI.parse('foo:bar/path'); + assert.throws(() => uri.with({ scheme: 'fai:l' })); + assert.throws(() => uri.with({ scheme: 'fäil' })); + assert.throws(() => uri.with({ authority: 'fail' })); + assert.throws(() => uri.with({ path: '//fail' })); + }); + test('parse', () => { var value = URI.parse('http:/api/files/test.me?t=1234'); assert.equal(value.scheme, 'http'); @@ -195,6 +203,34 @@ suite('URI', () => { assert.equal(value.path, ''); assert.equal(value.query, ''); assert.equal(value.fragment, 'd'); + + value = URI.parse('f3ile:#d'); + assert.equal(value.scheme, 'f3ile'); + assert.equal(value.authority, ''); + assert.equal(value.path, ''); + assert.equal(value.query, ''); + assert.equal(value.fragment, 'd'); + + value = URI.parse('foo+bar:path'); + assert.equal(value.scheme, 'foo+bar'); + assert.equal(value.authority, ''); + assert.equal(value.path, 'path'); + assert.equal(value.query, ''); + assert.equal(value.fragment, ''); + + value = URI.parse('foo-bar:path'); + assert.equal(value.scheme, 'foo-bar'); + assert.equal(value.authority, ''); + assert.equal(value.path, 'path'); + assert.equal(value.query, ''); + assert.equal(value.fragment, ''); + + value = URI.parse('foo.bar:path'); + assert.equal(value.scheme, 'foo.bar'); + assert.equal(value.authority, ''); + assert.equal(value.path, 'path'); + assert.equal(value.query, ''); + assert.equal(value.fragment, ''); }); test('parse, disallow //path when no authority', () => { diff --git a/src/vs/code/electron-main/env.ts b/src/vs/code/electron-main/env.ts index 1c91df70de9..c6cfc269264 100644 --- a/src/vs/code/electron-main/env.ts +++ b/src/vs/code/electron-main/env.ts @@ -10,9 +10,11 @@ import * as fs from 'original-fs'; import * as path from 'path'; import * as os from 'os'; import { app } from 'electron'; +import { mkdirp } from 'vs/base/node/pfs'; import * as arrays from 'vs/base/common/arrays'; import * as strings from 'vs/base/common/strings'; import * as paths from 'vs/base/common/paths'; +import { TPromise } from 'vs/base/common/winjs.base'; import * as platform from 'vs/base/common/platform'; import URI from 'vs/base/common/uri'; import * as types from 'vs/base/common/types'; @@ -66,6 +68,8 @@ export interface IEnvironmentService { appKeybindingsPath: string; mainIPCHandle: string; sharedIPCHandle: string; + + createPaths(): TPromise; } function getNumericValue(value: string, defaultValue: number, fallback: number = void 0) { @@ -186,37 +190,29 @@ export class EnvService implements IEnvironmentService { this._isTestingFromCli = this.cliArgs.extensionTestsPath && !this.cliArgs.debugBrkExtensionHost; this._userHome = path.join(os.homedir(), product.dataFolderName); this._userExtensionsHome = this.cliArgs.extensionsHomePath || path.join(this._userHome, 'extensions'); - this._mainIPCHandle = this.getMainIPCHandle(); - this._sharedIPCHandle = this.getSharedIPCHandle(); + + const prefix = this.getIPCHandleBaseName(); + const suffix = process.platform === 'win32' ? '-sock' : '.sock'; + + this._mainIPCHandle = `${ prefix }-${ pkg.version }${ suffix }`; + this._sharedIPCHandle = `${ prefix }-${ pkg.version }-shared${ suffix }`; } - private getMainIPCHandle(): string { - return this.getIPCHandleName() + (process.platform === 'win32' ? '-sock' : '.sock'); - } - - private getSharedIPCHandle(): string { - return this.getIPCHandleName() + '-shared' + (process.platform === 'win32' ? '-sock' : '.sock'); - } - - private getIPCHandleName(): string { - let handleName = pkg.name; - - if (!this.isBuilt) { - handleName += '-dev'; - } + private getIPCHandleBaseName(): string { + let name = pkg.name; // Support to run VS Code multiple times as different user // by making the socket unique over the logged in user let userId = EnvService.getUniqueUserId(); if (userId) { - handleName += ('-' + userId); + name += `-${ userId }`; } if (process.platform === 'win32') { - return '\\\\.\\pipe\\' + handleName; + return `\\\\.\\pipe\\${ name }`; } - return path.join(os.tmpdir(), handleName); + return path.join(os.tmpdir(), name); } private static getUniqueUserId(): string { @@ -234,19 +230,22 @@ export class EnvService implements IEnvironmentService { // use sha256 to ensure the userid value can be used in filenames and are unique return crypto.createHash('sha256').update(username).digest('hex').substr(0, 6); } + + createPaths(): TPromise { + const promises = [this.appSettingsHome, this.userHome, this.userExtensionsHome] + .map(p => mkdirp(p)); + + return TPromise.join(promises) as TPromise; + } } function parsePathArguments(cwd: string, args: string[], gotoLineMode?: boolean): string[] { const result = args.map(arg => { - if (typeof arg !== 'string') { - return null; // TODO@Ben workaround for https://github.com/Microsoft/vscode/issues/7498 - } - - let pathCandidate = arg; + let pathCandidate = String(arg); let parsedPath: IParsedPath; if (gotoLineMode) { - parsedPath = parseLineAndColumnAware(arg); + parsedPath = parseLineAndColumnAware(pathCandidate); pathCandidate = parsedPath.path; } diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 25041c383e5..86b7c98fe1c 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -9,7 +9,6 @@ import * as nls from 'vs/nls'; import * as fs from 'original-fs'; import { app, ipcMain as ipc } from 'electron'; import { assign } from 'vs/base/common/objects'; -import { mkdirp } from 'vs/base/node/pfs'; import * as platform from 'vs/base/common/platform'; import { IProcessEnvironment, IEnvironmentService, EnvService } from 'vs/code/electron-main/env'; import { IWindowsService, WindowsManager } from 'vs/code/electron-main/windows'; @@ -31,7 +30,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { ILogService, MainLogService } from 'vs/code/electron-main/log'; import { IStorageService, StorageService } from 'vs/code/electron-main/storage'; import * as cp from 'child_process'; -import * as ansiregex from 'ansi-regex'; +import { generateUuid } from 'vs/base/common/uuid'; function quit(accessor: ServicesAccessor, error?: Error); function quit(accessor: ServicesAccessor, message?: string); @@ -255,17 +254,6 @@ function setupIPC(accessor: ServicesAccessor): TPromise { return setup(true); } -// TODO@Joao: what about in the cli process? -function createPaths(accessor: ServicesAccessor): TPromise { - const environmentService = accessor.get(IEnvironmentService); - - return TPromise.join([ - mkdirp(environmentService.appSettingsHome), - mkdirp(environmentService.userHome), - mkdirp(environmentService.userExtensionsHome) - ]) as any as TPromise; -} - // TODO: isolate const services = new ServiceCollection(); @@ -285,15 +273,17 @@ interface IEnv { function getUnixUserEnvironment(): TPromise { const promise = new TPromise((c, e) => { - const runAsNode = process.env['ELECTRON_RUN_AS_NODE']; + const runAsNode = process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']; const noAttach = process.env['ELECTRON_NO_ATTACH_CONSOLE']; + const mark = generateUuid().replace(/-/g, '').substr(0, 12); + const regex = new RegExp(mark + '(.*)' + mark); const env = assign({}, process.env, { - ELECTRON_RUN_AS_NODE: '1', + ATOM_SHELL_INTERNAL_RUN_AS_NODE: '1', ELECTRON_NO_ATTACH_CONSOLE: '1' }); - const command = `'${process.execPath}' -p 'JSON.stringify(process.env)'`; + const command = `'${process.execPath}' -p '"${ mark }" + JSON.stringify(process.env) + "${ mark }"'`; const child = cp.spawn(process.env.SHELL, ['-ilc', command], { detached: true, stdio: ['ignore', 'pipe', process.stderr], @@ -309,21 +299,17 @@ function getUnixUserEnvironment(): TPromise { return e(new Error('Failed to get environment')); } - const raw = Buffer - .concat(buffers) - .toString('utf8') - // remove regular ANSI escape sequences - .replace(ansiregex(), '') - // remove OSC ANSI escape sequences - .replace(/\u001b\].*?(\u0007|\u001b\\)/g, ''); + const raw = Buffer.concat(buffers).toString('utf8'); + const match = regex.exec(raw); + const rawStripped = match ? match[1] : '{}'; try { - const env = JSON.parse(raw); + const env = JSON.parse(rawStripped); if (runAsNode) { - env['ELECTRON_RUN_AS_NODE'] = runAsNode; + env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = runAsNode; } else { - delete env['ELECTRON_RUN_AS_NODE']; + delete env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']; } if (noAttach) { @@ -359,7 +345,7 @@ getUserEnvironment() // See also https://github.com/Microsoft/vscode/issues/4558 userEnv['VSCODE_NLS_CONFIG'] = process.env['VSCODE_NLS_CONFIG']; - return instantiationService.invokeFunction(createPaths) + return instantiationService.invokeFunction(a => a.get(IEnvironmentService).createPaths()) .then(() => instantiationService.invokeFunction(setupIPC)) .then(ipcServer => instantiationService.invokeFunction(main, ipcServer, userEnv)); }) diff --git a/src/vs/code/electron-main/menus.ts b/src/vs/code/electron-main/menus.ts index 5529236ea94..ada10d62cdc 100644 --- a/src/vs/code/electron-main/menus.ts +++ b/src/vs/code/electron-main/menus.ts @@ -757,10 +757,6 @@ export class VSCodeMenu { }, 0) })]; - if (this.updateService.lastCheckDate) { - result.push(new MenuItem({ label: nls.localize('miLastCheckedAt', "Last checked at {0}", this.updateService.lastCheckDate.toLocaleTimeString()), enabled: false })); - } - return result; } } diff --git a/src/vs/code/electron-main/settings.ts b/src/vs/code/electron-main/settings.ts index fbd4a7cb258..e97c26315aa 100644 --- a/src/vs/code/electron-main/settings.ts +++ b/src/vs/code/electron-main/settings.ts @@ -7,7 +7,7 @@ import { app } from 'electron'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { UserSettings, ISettings } from 'vs/workbench/node/userSettings'; +import { UserSettings, ISettings } from 'vs/base/node/userSettings'; import { IEnvironmentService } from 'vs/code/electron-main/env'; import Event from 'vs/base/common/event'; diff --git a/src/vs/code/electron-main/update-manager.ts b/src/vs/code/electron-main/update-manager.ts index d83fd0828c4..89b977293e2 100644 --- a/src/vs/code/electron-main/update-manager.ts +++ b/src/vs/code/electron-main/update-manager.ts @@ -199,9 +199,9 @@ export class UpdateManager extends EventEmitter implements IUpdateService { // Clear timer when checking for update this.on('checking-for-update', () => clearTimeout(timer)); - // If update not found, try again in 10 minutes + // If update not found, try again in 1 hour this.on('update-not-available', () => { - timer = setTimeout(() => this.checkForUpdates(), 10 * 60 * 1000); + timer = setTimeout(() => this.checkForUpdates(), 60 * 60 * 1000); }); } diff --git a/src/vs/code/node/argv.ts b/src/vs/code/node/argv.ts index a72b1835f98..3e0d5e2a263 100644 --- a/src/vs/code/node/argv.ts +++ b/src/vs/code/node/argv.ts @@ -83,6 +83,7 @@ export const optionsHelp: { [name: string]: string; } = { '-g, --goto': localize('goto', "Open the file at path at the line and column (add :line[:column] to path)."), '--locale ': localize('locale', "The locale to use (e.g. en-US or zh-TW)."), '-n, --new-window': localize('newWindow', "Force a new instance of Code."), + '-p, --performance': localize('performance', "Start with the 'Developer: Startup Performance' command enabled."), '-r, --reuse-window': localize('reuseWindow', "Force opening a file or folder in the last active window."), '--user-data-dir ': localize('userDataDir', "Specifies the directory that user data is kept in, useful when running as root."), '--verbose': localize('verbose', "Print verbose output (implies --wait)."), diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index ee5beb41a03..6dcfb032797 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -33,7 +33,7 @@ export function main(args: string[]): TPromise { 'VSCODE_CLI': '1', 'ELECTRON_NO_ATTACH_CONSOLE': '1' }); - delete env['ELECTRON_RUN_AS_NODE']; + delete env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']; let options = { detached: true, diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 4ea0eadc972..1399b2de7ec 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -134,44 +134,48 @@ export function main(argv: ParsedArgs): TPromise { const instantiationService: IInstantiationService = new InstantiationService(services); return instantiationService.invokeFunction(accessor => { - const services = new ServiceCollection(); - services.set(IEventService, new SyncDescriptor(EventService)); - services.set(IConfigurationService, new SyncDescriptor(NodeConfigurationService)); - services.set(IRequestService, new SyncDescriptor(NodeRequestService)); - services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); - services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); + const envService = accessor.get(IEnvironmentService); - const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt } = accessor.get(IEnvironmentService); + return envService.createPaths().then(() => { + const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt } = envService; - if (isBuilt && !extensionDevelopmentPath && product.enableTelemetry) { - const appenders: AppInsightsAppender[] = []; + const services = new ServiceCollection(); + services.set(IEventService, new SyncDescriptor(EventService)); + services.set(IConfigurationService, new SyncDescriptor(NodeConfigurationService)); + services.set(IRequestService, new SyncDescriptor(NodeRequestService)); + services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); + services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); - if (product.aiConfig && product.aiConfig.key) { - appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.key)); + if (isBuilt && !extensionDevelopmentPath && product.enableTelemetry) { + const appenders: AppInsightsAppender[] = []; + + if (product.aiConfig && product.aiConfig.key) { + appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.key)); + } + + if (product.aiConfig && product.aiConfig.asimovKey) { + appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey)); + } + + // It is important to dispose the AI adapter properly because + // only then they flush remaining data. + process.once('exit', () => appenders.forEach(a => a.dispose())); + + const config: ITelemetryServiceConfig = { + appender: combinedAppender(...appenders), + commonProperties: resolveCommonProperties(product.commit, pkg.version), + piiPaths: [appRoot, extensionsPath] + }; + + services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config)); + } else { + services.set(ITelemetryService, NullTelemetryService); } - if (product.aiConfig && product.aiConfig.asimovKey) { - appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey)); - } + const instantiationService2 = instantiationService.createChild(services); + const main = instantiationService2.createInstance(Main); - // It is important to dispose the AI adapter properly because - // only then they flush remaining data. - process.once('exit', () => appenders.forEach(a => a.dispose())); - - const config: ITelemetryServiceConfig = { - appender: combinedAppender(...appenders), - commonProperties: resolveCommonProperties(product.commit, pkg.version), - piiPaths: [appRoot, extensionsPath] - }; - - services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config)); - } else { - services.set(ITelemetryService, NullTelemetryService); - } - - const instantiationService2 = instantiationService.createChild(services); - const main = instantiationService2.createInstance(Main); - - return main.run(argv); + return main.run(argv); + }); }); } diff --git a/src/vs/editor/browser/standalone/standaloneCodeEditor.ts b/src/vs/editor/browser/standalone/standaloneCodeEditor.ts index 9aba38a080d..f826badcecd 100644 --- a/src/vs/editor/browser/standalone/standaloneCodeEditor.ts +++ b/src/vs/editor/browser/standalone/standaloneCodeEditor.ts @@ -79,7 +79,7 @@ export class StandaloneEditor extends CodeEditorWidget implements IStandaloneCod } options = options || {}; - super(domElement, options, instantiationService, codeEditorService, commandService, keybindingService, telemetryService); + super(domElement, options, instantiationService, codeEditorService, commandService, keybindingService.createScoped(domElement), telemetryService); if (keybindingService instanceof StandaloneKeybindingService) { this._standaloneKeybindingService = keybindingService; @@ -184,7 +184,7 @@ export class StandaloneDiffEditor extends DiffEditorWidget implements IStandalon (keybindingService).setInstantiationService(instantiationService); } - super(domElement, options, editorWorkerService, instantiationService); + super(domElement, options, editorWorkerService, keybindingService, instantiationService); if (keybindingService instanceof StandaloneKeybindingService) { this._standaloneKeybindingService = keybindingService; diff --git a/src/vs/editor/browser/standalone/standaloneLanguages.ts b/src/vs/editor/browser/standalone/standaloneLanguages.ts index 68e33c16b2c..6c6476f4a88 100644 --- a/src/vs/editor/browser/standalone/standaloneLanguages.ts +++ b/src/vs/editor/browser/standalone/standaloneLanguages.ts @@ -399,6 +399,12 @@ class SuggestAdapter { const ran = model.getWordUntilPosition(position); return toThenable(this._provider.provideCompletionItems(model, position, token)).then(value => { + let defaultSuggestions: modes.ISuggestResult = { + suggestions: [], + currentWord: ran ? ran.word : '', + }; + let allSuggestions: modes.ISuggestResult[] = [defaultSuggestions]; + let list: CompletionList; if (Array.isArray(value)) { list = { @@ -407,6 +413,7 @@ class SuggestAdapter { }; } else if (typeof value === 'object' && Array.isArray(value.items)) { list = value; + defaultSuggestions.incomplete = list.isIncomplete; } else if (!value) { // undefined and null are valid results return; @@ -415,12 +422,6 @@ class SuggestAdapter { console.warn('INVALID result from completion provider. expected CompletionItem-array or CompletionList but got:', value); } - let defaultSuggestions: modes.ISuggestResult = { - suggestions: [], - currentWord: ran ? ran.word : '', - }; - let allSuggestions: modes.ISuggestResult[] = [defaultSuggestions]; - for (let i = 0; i < list.items.length; i++) { const item = list.items[i]; const suggestion = SuggestAdapter.from(item); diff --git a/src/vs/editor/browser/standalone/standaloneServices.ts b/src/vs/editor/browser/standalone/standaloneServices.ts index 04321cd42e5..4a763ede06e 100644 --- a/src/vs/editor/browser/standalone/standaloneServices.ts +++ b/src/vs/editor/browser/standalone/standaloneServices.ts @@ -149,6 +149,7 @@ export interface IStaticServices { editorWorkerService: IEditorWorkerService; eventService: IEventService; storageService: IStorageService; + commandService: ICommandService; instantiationService: IInstantiationService; } @@ -266,6 +267,7 @@ export function getOrCreateStaticServices(services?: IEditorOverrideServices): I staticServices = { configurationService: configurationService, extensionService: extensionService, + commandService: commandService, compatWorkerService: compatWorkerService, modeService: modeService, markerService: markerService, diff --git a/src/vs/editor/browser/view/viewLayer.ts b/src/vs/editor/browser/view/viewLayer.ts index 77c27e39503..fd13c4ed928 100644 --- a/src/vs/editor/browser/view/viewLayer.ts +++ b/src/vs/editor/browser/view/viewLayer.ts @@ -29,10 +29,10 @@ export interface IVisibleLineData { layoutLine(lineNumber: number, deltaTop:number): void; } -interface IRendererContext { +interface IRendererContext { domNode: HTMLElement; rendLineNumberStart: number; - lines: IVisibleLineData[]; + lines: T[]; linesLength: number; getInlineDecorationsForLineInViewport(lineNumber:number): InlineDecoration[]; viewportTop: number; @@ -41,14 +41,222 @@ interface IRendererContext { scrollDomNodeIsAbove: boolean; } -export abstract class ViewLayer extends ViewPart { +export interface ILine { + onContentChanged(): void; + onLinesInsertedAbove(): void; + onLinesDeletedAbove(): void; + onLineChangedAbove(): void; + onTokensChanged(): void; +} + +export class RenderedLinesCollection { + private _lines: T[]; + private _rendLineNumberStart:number; + private _createLine:()=>T; + + constructor(createLine:()=>T) { + this._lines = []; + this._rendLineNumberStart = 1; + this._createLine = createLine; + } + + _set(rendLineNumberStart:number, lines:T[]): void { + this._lines = lines; + this._rendLineNumberStart = rendLineNumberStart; + } + + _get(): { rendLineNumberStart:number; lines:T[]; } { + return { + rendLineNumberStart: this._rendLineNumberStart, + lines: this._lines + }; + } + + /** + * @returns Inclusive line number that is inside this collection + */ + public getStartLineNumber(): number { + return this._rendLineNumberStart; + } + + /** + * @returns Inclusive line number that is inside this collection + */ + public getEndLineNumber(): number { + return this._rendLineNumberStart + this._lines.length - 1; + } + + public getCount(): number { + return this._lines.length; + } + + public getLine(lineNumber:number): T { + let lineIndex = lineNumber - this._rendLineNumberStart; + if (lineIndex < 0 || lineIndex >= this._lines.length) { + throw new Error('Illegal value for lineNumber: ' + lineNumber); + } + return this._lines[lineIndex]; + } + + /** + * @returns Lines that were removed from this collection + */ + public onModelLinesDeleted(deleteFromLineNumber:number, deleteToLineNumber:number): T[] { + if (this.getCount() === 0) { + // no lines + return null; + } + + let startLineNumber = this.getStartLineNumber(); + let endLineNumber = this.getEndLineNumber(); + + // Record what needs to be deleted, notify lines that survive after deletion + let deleteStartIndex = 0; + let deleteCount = 0; + for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) { + let lineIndex = lineNumber - this._rendLineNumberStart; + + if (deleteFromLineNumber <= lineNumber && lineNumber <= deleteToLineNumber) { + // this is a line to be deleted + if (deleteCount === 0) { + // this is the first line to be deleted + deleteStartIndex = lineIndex; + deleteCount = 1; + } else { + deleteCount++; + } + } else if (lineNumber > deleteToLineNumber) { + // this is a line after the deletion + this._lines[lineIndex].onLinesDeletedAbove(); + } + } + + // Adjust this._rendLineNumberStart for lines deleted above + if (deleteFromLineNumber < startLineNumber) { + // Something was deleted above + let deleteAboveCount = 0; + + if (deleteToLineNumber < startLineNumber) { + // the entire deleted lines are above + deleteAboveCount = deleteToLineNumber - deleteFromLineNumber + 1; + } else { + deleteAboveCount = startLineNumber - deleteFromLineNumber; + } + + this._rendLineNumberStart -= deleteAboveCount; + } + + let deleted = this._lines.splice(deleteStartIndex, deleteCount); + return deleted; + } + + public onModelLineChanged(changedLineNumber:number): boolean { + if (this.getCount() === 0) { + // no lines + return false; + } + + let startLineNumber = this.getStartLineNumber(); + let endLineNumber = this.getEndLineNumber(); + + // Notify lines after the change + let notifiedSomeone = false; + for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) { + let lineIndex = lineNumber - this._rendLineNumberStart; + + if (lineNumber === changedLineNumber) { + this._lines[lineIndex].onContentChanged(); + notifiedSomeone = true; + } else if (lineNumber > changedLineNumber) { + // this is a line after the changed one + this._lines[lineIndex].onLineChangedAbove(); + notifiedSomeone = true; + } + } + + return notifiedSomeone; + } + + public onModelLinesInserted(insertFromLineNumber:number, insertToLineNumber:number): T[] { + if (this.getCount() === 0) { + // no lines + return null; + } + + let insertCnt = insertToLineNumber - insertFromLineNumber + 1; + let startLineNumber = this.getStartLineNumber(); + let endLineNumber = this.getEndLineNumber(); + + // Notify lines that survive after insertion + for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) { + let lineIndex = lineNumber - this._rendLineNumberStart; + + if (insertFromLineNumber <= lineNumber) { + this._lines[lineIndex].onLinesInsertedAbove(); + } + } + + if (insertFromLineNumber <= startLineNumber) { + // inserting above the viewport + this._rendLineNumberStart += insertCnt; + return null; + } + + if (insertFromLineNumber > endLineNumber) { + // inserting below the viewport + return null; + } + + if (insertCnt + insertFromLineNumber > endLineNumber) { + // insert inside the viewport in such a way that all remaining lines are pushed outside + let deleted = this._lines.splice(insertFromLineNumber - this._rendLineNumberStart, endLineNumber - insertFromLineNumber + 1); + return deleted; + } + + // insert inside the viewport, push out some lines, but not all remaining lines + let newLines: T[] = []; + for (let i = 0; i < insertCnt; i++) { + newLines[i] = this._createLine(); + } + let insertIndex = insertFromLineNumber - this._rendLineNumberStart; + let beforeLines = this._lines.slice(0, insertIndex); + let afterLines = this._lines.slice(insertIndex, this._lines.length - insertCnt); + let deletedLines = this._lines.slice(this._lines.length - insertCnt, this._lines.length); + + this._lines = beforeLines.concat(newLines).concat(afterLines); + + return deletedLines; + } + + public onModelTokensChanged(changedFromLineNumber:number, changedToLineNumber:number): boolean { + if (this.getCount() === 0) { + // no lines + return false; + } + + let startLineNumber = this.getStartLineNumber(); + let endLineNumber = this.getEndLineNumber(); + + // Notify lines after the change + let notifiedSomeone = false; + for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) { + let lineIndex = lineNumber - this._rendLineNumberStart; + + if (changedFromLineNumber <= lineNumber && lineNumber <= changedToLineNumber) { + this._lines[lineIndex].onTokensChanged(); + notifiedSomeone = true; + } + } + + return notifiedSomeone; + } +} + +export abstract class ViewLayer extends ViewPart { protected domNode: FastDomNode; - - protected _lines:IVisibleLineData[]; - protected _rendLineNumberStart:number; - - private _renderer: ViewLayerRenderer; + protected _linesCollection: RenderedLinesCollection; + private _renderer: ViewLayerRenderer; private _scrollDomNode: HTMLElement; private _scrollDomNodeIsAbove: boolean; @@ -57,13 +265,12 @@ export abstract class ViewLayer extends ViewPart { this.domNode = this._createDomNode(); - this._lines = []; - this._rendLineNumberStart = 1; + this._linesCollection = new RenderedLinesCollection(() => this._createLine()); this._scrollDomNode = null; this._scrollDomNodeIsAbove = false; - this._renderer = new ViewLayerRenderer( + this._renderer = new ViewLayerRenderer( () => this._createLine(), () => this._extraDomNodeHTML() ); @@ -71,7 +278,7 @@ export abstract class ViewLayer extends ViewPart { public dispose(): void { super.dispose(); - this._lines = null; + this._linesCollection = null; } protected _extraDomNodeHTML(): string { @@ -81,8 +288,11 @@ export abstract class ViewLayer extends ViewPart { // ---- begin view event handlers public onConfigurationChanged(e:editorCommon.IConfigurationChangedEvent): boolean { - for (var i = 0; i < this._lines.length; i++) { - this._lines[i].onConfigurationChanged(e); + let startLineNumber = this._linesCollection.getStartLineNumber(); + let endLineNumber = this._linesCollection.getEndLineNumber(); + for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) { + let line = this._linesCollection.getLine(lineNumber); + line.onConfigurationChanged(e); } return true; } @@ -100,158 +310,61 @@ export abstract class ViewLayer extends ViewPart { } public onModelFlushed(): boolean { - this._lines = []; - this._rendLineNumberStart = 1; + this._linesCollection = new RenderedLinesCollection(() => this._createLine()); this._scrollDomNode = null; // No need to clear the dom node because a full .innerHTML will occur in ViewLayerRenderer._render return true; } public onModelLinesDeleted(e:editorCommon.IViewLinesDeletedEvent): boolean { - var from = Math.max(e.fromLineNumber - this._rendLineNumberStart, 0); - var to = Math.min(e.toLineNumber - this._rendLineNumberStart, this._lines.length - 1); - var i:number; - - // Adjust this._rendLineNumberStart - if (e.fromLineNumber < this._rendLineNumberStart) { - // Deleting lines starting above the viewport - - if (e.toLineNumber < this._rendLineNumberStart) { - // All deleted lines are above the viewport - this._rendLineNumberStart -= (e.toLineNumber - e.fromLineNumber + 1); - } else { - // Some deleted lines are inside the viewport - this._rendLineNumberStart = e.fromLineNumber; - } - } - - // Remove lines if they fall in the viewport - if (from <= to) { + let deleted = this._linesCollection.onModelLinesDeleted(e.fromLineNumber, e.toLineNumber); + if (deleted) { // Remove from DOM - for (i = from; i <= to; i++) { - var lineDomNode = this._lines[i].getDomNode(); + for (let i = 0, len = deleted.length; i < len; i++) { + let lineDomNode = deleted[i].getDomNode(); if (lineDomNode) { this.domNode.domNode.removeChild(lineDomNode); } } - // Remove from array - this._lines.splice(from, to - from + 1); - } - - // Mark the rest of the visible lines as possibly invalid - for (i = from; i < this._lines.length; i++) { - this._lines[i].onLinesDeletedAbove(); } return true; } public onModelLineChanged(e:editorCommon.IViewLineChangedEvent): boolean { - var lineIndex = e.lineNumber - this._rendLineNumberStart, - shouldRender = false; - - if (lineIndex >= 0 && lineIndex < this._lines.length) { - this._lines[lineIndex].onContentChanged(); - shouldRender = true; - } - - // Mark the rest of the visible lines as possibly invalid - for (var i = Math.max(lineIndex, 0); i < this._lines.length; i++) { - this._lines[i].onLineChangedAbove(); - shouldRender = true; - } - - return shouldRender; + return this._linesCollection.onModelLineChanged(e.lineNumber); } public onModelLinesInserted(e:editorCommon.IViewLinesInsertedEvent): boolean { - var i:number; - - if (e.fromLineNumber <= this._rendLineNumberStart) { - // a. We are inserting lines above the viewport - this._rendLineNumberStart += (e.toLineNumber - e.fromLineNumber + 1); - - // Mark the visible lines as possibly invalid - for (i = 0; i < this._lines.length; i++) { - this._lines[i].onLinesInsertedAbove(); - } - - return true; - } - - if (e.fromLineNumber >= this._rendLineNumberStart + this._lines.length) { - // b. We are inserting lines below the viewport - return false; - } - - // c. We are inserting lines in the viewport - - var insertFrom = Math.min(e.fromLineNumber - this._rendLineNumberStart, this._lines.length - 1); - var insertTo = Math.min(e.toLineNumber - this._rendLineNumberStart, this._lines.length - 1); - if (insertFrom <= insertTo) { - // Insert lines that fall inside the viewport - for (i = insertFrom; i <= insertTo; i++) { - var line:IVisibleLineData = this._createLine(); - this._lines.splice(i, 0, line); - } - - // We need to remove lines that are pushed outside the viewport by this insertion, - // due to the Math.min above on `insertTo`. Otherwise, it is possible for the next line - // after the insertion to be marked `maybeInvalid` when it should be definitely `invalid`. - var insertCount = insertTo - insertFrom + 1; - for (i = 0; i < insertCount; i++) { - // Remove from array - var lastLine = this._lines.pop(); - // Remove from DOM - var lineDomNode = lastLine.getDomNode(); + let deleted = this._linesCollection.onModelLinesInserted(e.fromLineNumber, e.toLineNumber); + if (deleted) { + // Remove from DOM + for (let i = 0, len = deleted.length; i < len; i++) { + let lineDomNode = deleted[i].getDomNode(); if (lineDomNode) { this.domNode.domNode.removeChild(lineDomNode); } } } - // Mark the rest of the lines as possibly invalid - for (i = insertTo; i < this._lines.length; i++) { - this._lines[i].onLinesInsertedAbove(); - } - return true; } public onModelTokensChanged(e:editorCommon.IViewTokensChangedEvent): boolean { - if (this._lines.length === 0) { - return false; - } - - var changedFromIndex = e.fromLineNumber - this._rendLineNumberStart; - var changedToIndex = e.toLineNumber - this._rendLineNumberStart; - - if (changedToIndex < 0 || changedFromIndex >= this._lines.length) { - return false; - } - - var fromIndex = Math.min(Math.max(changedFromIndex, 0), this._lines.length - 1); - var toIndex = Math.min(Math.max(changedToIndex, 0), this._lines.length - 1); - - var somethingMayHaveChanged = false; - - for (var i = fromIndex; i <= toIndex; i++) { - somethingMayHaveChanged = true; - this._lines[i].onTokensChanged(); - } - - return somethingMayHaveChanged; + return this._linesCollection.onModelTokensChanged(e.fromLineNumber, e.toLineNumber); } // ---- end view event handlers public _renderLines(linesViewportData:ViewLinesViewportData): void { - var ctx: IRendererContext = { + let inp = this._linesCollection._get(); + + let ctx: IRendererContext = { domNode: this.domNode.domNode, - rendLineNumberStart: this._rendLineNumberStart, - lines: this._lines, - linesLength: this._lines.length, + rendLineNumberStart: inp.rendLineNumberStart, + lines: inp.lines, + linesLength: inp.lines.length, getInlineDecorationsForLineInViewport: (lineNumber:number) => linesViewportData.getInlineDecorationsForLineInViewport(lineNumber), viewportTop: linesViewportData.viewportTop, viewportHeight: linesViewportData.viewportHeight, @@ -260,10 +373,9 @@ export abstract class ViewLayer extends ViewPart { }; // Decide if this render will do a single update (single large .innerHTML) or many updates (inserting/removing dom nodes) - var resCtx = this._renderer.renderWithManyUpdates(ctx, linesViewportData.startLineNumber, linesViewportData.endLineNumber, linesViewportData.relativeVerticalOffset); + let resCtx = this._renderer.renderWithManyUpdates(ctx, linesViewportData.startLineNumber, linesViewportData.endLineNumber, linesViewportData.relativeVerticalOffset); - this._rendLineNumberStart = resCtx.rendLineNumberStart; - this._lines = resCtx.lines; + this._linesCollection._set(resCtx.rendLineNumberStart, resCtx.lines); this._scrollDomNode = resCtx.scrollDomNode; this._scrollDomNodeIsAbove = resCtx.scrollDomNodeIsAbove; } @@ -277,28 +389,26 @@ export abstract class ViewLayer extends ViewPart { return domNode; } - public _createLine(): IVisibleLineData { - throw new Error('Implement me!'); - } + protected abstract _createLine(): T; } -class ViewLayerRenderer { +class ViewLayerRenderer { - private _createLine: () => IVisibleLineData; + private _createLine: () => T; private _extraDomNodeHTML: () => string; - constructor(createLine: () => IVisibleLineData, extraDomNodeHTML: () => string) { + constructor(createLine: () => T, extraDomNodeHTML: () => string) { this._createLine = createLine; this._extraDomNodeHTML = extraDomNodeHTML; } - public renderWithManyUpdates(ctx: IRendererContext, startLineNumber: number, stopLineNumber: number, deltaTop:number[]): IRendererContext { + public renderWithManyUpdates(ctx: IRendererContext, startLineNumber: number, stopLineNumber: number, deltaTop:number[]): IRendererContext { return this._render(ctx, startLineNumber, stopLineNumber, deltaTop); } - private _render(inContext: IRendererContext, startLineNumber: number, stopLineNumber: number, deltaTop:number[]): IRendererContext { + private _render(inContext: IRendererContext, startLineNumber: number, stopLineNumber: number, deltaTop:number[]): IRendererContext { - var ctx: IRendererContext = { + var ctx: IRendererContext = { domNode: inContext.domNode, rendLineNumberStart: inContext.rendLineNumberStart, lines: inContext.lines.slice(0), @@ -406,7 +516,7 @@ class ViewLayerRenderer { return ctx; } - private _renderUntouchedLines(ctx: IRendererContext, startIndex: number, endIndex: number, deltaTop:number[], deltaLN:number): void { + private _renderUntouchedLines(ctx: IRendererContext, startIndex: number, endIndex: number, deltaTop:number[], deltaLN:number): void { var i: number, lineNumber: number; @@ -419,9 +529,9 @@ class ViewLayerRenderer { } } - private _insertLinesBefore(ctx: IRendererContext, fromLineNumber: number, toLineNumber: number, deltaTop:number[], deltaLN:number): void { - var newLines:IVisibleLineData[] = [], - line:IVisibleLineData, + private _insertLinesBefore(ctx: IRendererContext, fromLineNumber: number, toLineNumber: number, deltaTop:number[], deltaLN:number): void { + var newLines:T[] = [], + line:T, lineNumber: number; for (lineNumber = fromLineNumber; lineNumber <= toLineNumber; lineNumber++) { @@ -439,7 +549,7 @@ class ViewLayerRenderer { return 0; } - private _removeIfNotScrollDomNode(ctx: IRendererContext, domNode: HTMLElement, isAbove: boolean) { + private _removeIfNotScrollDomNode(ctx: IRendererContext, domNode: HTMLElement, isAbove: boolean) { var time = this._getScrollDomNodeTime(domNode); if (!time) { ctx.domNode.removeChild(domNode); @@ -465,7 +575,7 @@ class ViewLayerRenderer { ctx.scrollDomNodeIsAbove = isAbove; } - private _removeLinesBefore(ctx: IRendererContext, removeCount: number): void { + private _removeLinesBefore(ctx: IRendererContext, removeCount: number): void { var i: number; for (i = 0; i < removeCount; i++) { @@ -477,9 +587,9 @@ class ViewLayerRenderer { ctx.lines.splice(0, removeCount); } - private _insertLinesAfter(ctx: IRendererContext, fromLineNumber: number, toLineNumber: number, deltaTop:number[], deltaLN:number): void { - var newLines:IVisibleLineData[] = [], - line:IVisibleLineData, + private _insertLinesAfter(ctx: IRendererContext, fromLineNumber: number, toLineNumber: number, deltaTop:number[], deltaLN:number): void { + var newLines:T[] = [], + line:T, lineNumber: number; for (lineNumber = fromLineNumber; lineNumber <= toLineNumber; lineNumber++) { @@ -489,7 +599,7 @@ class ViewLayerRenderer { ctx.lines = ctx.lines.concat(newLines); } - private _removeLinesAfter(ctx: IRendererContext, removeCount: number): void { + private _removeLinesAfter(ctx: IRendererContext, removeCount: number): void { var i: number, removeIndex = ctx.linesLength - removeCount; @@ -502,7 +612,7 @@ class ViewLayerRenderer { ctx.lines.splice(removeIndex, removeCount); } - private static _resolveInlineDecorations(ctx: IRendererContext): InlineDecoration[][] { + private static _resolveInlineDecorations(ctx: IRendererContext): InlineDecoration[][] { let result: InlineDecoration[][] = []; for (let i = 0, len = ctx.linesLength; i < len; i++) { let lineNumber = i + ctx.rendLineNumberStart; @@ -511,7 +621,7 @@ class ViewLayerRenderer { return result; } - private _finishRenderingNewLines(ctx: IRendererContext, domNodeIsEmpty:boolean, newLinesHTML: string[], wasNew: boolean[]): void { + private _finishRenderingNewLines(ctx: IRendererContext, domNodeIsEmpty:boolean, newLinesHTML: string[], wasNew: boolean[]): void { var lastChild = ctx.domNode.lastChild; if (domNodeIsEmpty || !lastChild) { ctx.domNode.innerHTML = this._extraDomNodeHTML() + newLinesHTML.join(''); @@ -529,7 +639,7 @@ class ViewLayerRenderer { } } - private _finishRenderingInvalidLines(ctx: IRendererContext, invalidLinesHTML: string[], wasInvalid: boolean[]): void { + private _finishRenderingInvalidLines(ctx: IRendererContext, invalidLinesHTML: string[], wasInvalid: boolean[]): void { var hugeDomNode = document.createElement('div'); hugeDomNode.innerHTML = invalidLinesHTML.join(''); @@ -547,7 +657,7 @@ class ViewLayerRenderer { } } - private _finishRendering(ctx: IRendererContext, domNodeIsEmpty:boolean, deltaTop:number[]): void { + private _finishRendering(ctx: IRendererContext, domNodeIsEmpty:boolean, deltaTop:number[]): void { let inlineDecorations = ViewLayerRenderer._resolveInlineDecorations(ctx); diff --git a/src/vs/editor/browser/view/viewOverlays.ts b/src/vs/editor/browser/view/viewOverlays.ts index 97773fd1e77..7f85650c06d 100644 --- a/src/vs/editor/browser/view/viewOverlays.ts +++ b/src/vs/editor/browser/view/viewOverlays.ts @@ -15,7 +15,7 @@ import {IRenderingContext, IRestrictedRenderingContext} from 'vs/editor/common/v import {ILayoutProvider} from 'vs/editor/browser/viewLayout/layoutProvider'; import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel'; -export class ViewOverlays extends ViewLayer { +export class ViewOverlays extends ViewLayer { private _dynamicOverlays:DynamicViewOverlay[]; private _isFocused:boolean; @@ -74,7 +74,7 @@ export class ViewOverlays extends ViewLayer { // ----- end event handlers - _createLine(): IVisibleLineData { + _createLine(): ViewOverlayLine { var r = new ViewOverlayLine(this._context, this._dynamicOverlays); return r; } @@ -104,7 +104,7 @@ export class ViewOverlays extends ViewLayer { } } -class ViewOverlayLine implements IVisibleLineData { +export class ViewOverlayLine implements IVisibleLineData { private _context:ViewContext; private _dynamicOverlays:DynamicViewOverlay[]; diff --git a/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts b/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts index e6ebfa2963c..0bfd408e74e 100644 --- a/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts +++ b/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts @@ -27,12 +27,12 @@ export class DecorationToRender { export abstract class DedupOverlay extends DynamicViewOverlay { - protected _render(visibleStartLineNumber:number, visibleEndLineNumber:number, decorations:DecorationToRender[]): string[] { + protected _render(visibleStartLineNumber:number, visibleEndLineNumber:number, decorations:DecorationToRender[]): string[][] { - let output: string[] = []; + let output: string[][] = []; for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) { let lineIndex = lineNumber - visibleStartLineNumber; - output[lineIndex] = ''; + output[lineIndex] = []; } if (decorations.length === 0) { @@ -66,7 +66,7 @@ export abstract class DedupOverlay extends DynamicViewOverlay { } for (let i = startLineIndex; i <= prevEndLineIndex; i++) { - output[i] += ' ' + prevClassName; + output[i].push(prevClassName); } } @@ -189,8 +189,8 @@ export class GlyphMarginOverlay extends DedupOverlay { output[lineIndex] = ''; } else { output[lineIndex] = ( - '
{ /** * Width to extends a line to render the line feed at the end of the line */ @@ -57,7 +57,6 @@ export class ViewLines extends ViewLayer { private _layoutProvider:ILayoutProvider; - _lines:ViewLine[]; private _textRangeRestingSpot:HTMLElement; // --- config @@ -146,9 +145,11 @@ export class ViewLines extends ViewLayer { } public onModelDecorationsChanged(e:editorCommon.IViewDecorationsChangedEvent): boolean { - var shouldRender = super.onModelDecorationsChanged(e); - for (var i = 0; i < this._lines.length; i++) { - this._lines[i].onModelDecorationsChanged(); + let shouldRender = super.onModelDecorationsChanged(e); + let rendStartLineNumber = this._linesCollection.getStartLineNumber(); + let rendEndLineNumber = this._linesCollection.getEndLineNumber(); + for (let lineNumber = rendStartLineNumber; lineNumber <= rendEndLineNumber; lineNumber++) { + this._linesCollection.getLine(lineNumber).onModelDecorationsChanged(); } return shouldRender || true; } @@ -186,7 +187,7 @@ export class ViewLines extends ViewLayer { // ----------- HELPERS FOR OTHERS public getPositionFromDOMInfo(spanNode:HTMLElement, offset:number): editorCommon.IPosition { - var lineNumber = this._getLineNumberFromDOMInfo(spanNode); + let lineNumber = this._getLineNumberFromDOMInfo(spanNode); if (lineNumber === -1) { // Couldn't find span node @@ -206,14 +207,15 @@ export class ViewLines extends ViewLayer { }; } - var lineIndex = lineNumber - this._rendLineNumberStart; - if (lineIndex < 0 || lineIndex >= this._lines.length) { + let rendStartLineNumber = this._linesCollection.getStartLineNumber(); + let rendEndLineNumber = this._linesCollection.getEndLineNumber(); + if (lineNumber < rendStartLineNumber || lineNumber > rendEndLineNumber) { // Couldn't find line return null; } - var column = this._lines[lineIndex].getColumnOfNodeOffset(lineNumber, spanNode, offset); - var minColumn = this._context.model.getLineMinColumn(lineNumber); + let column = this._linesCollection.getLine(lineNumber).getColumnOfNodeOffset(lineNumber, spanNode, offset); + let minColumn = this._context.model.getLineMinColumn(lineNumber); if (column < minColumn) { column = minColumn; } @@ -234,12 +236,14 @@ export class ViewLines extends ViewLayer { } public getLineWidth(lineNumber: number): number { - var lineIndex = lineNumber - this._rendLineNumberStart; - if (lineIndex < 0 || lineIndex >= this._lines.length) { + let rendStartLineNumber = this._linesCollection.getStartLineNumber(); + let rendEndLineNumber = this._linesCollection.getEndLineNumber(); + if (lineNumber < rendStartLineNumber || lineNumber > rendEndLineNumber) { + // Couldn't find line return -1; } - return this._lines[lineIndex].getWidth(); + return this._linesCollection.getLine(lineNumber).getWidth(); } public linesVisibleRangesForRange(range:editorCommon.IRange, includeNewLines:boolean): LineVisibleRanges[] { @@ -263,16 +267,17 @@ export class ViewLines extends ViewLayer { nextLineModelLineNumber = this._context.model.convertViewPositionToModelPosition(range.startLineNumber, 1).lineNumber; } + let rendStartLineNumber = this._linesCollection.getStartLineNumber(); + let rendEndLineNumber = this._linesCollection.getEndLineNumber(); for (let lineNumber = range.startLineNumber; lineNumber <= range.endLineNumber; lineNumber++) { - let lineIndex = lineNumber - this._rendLineNumberStart; - if (lineIndex < 0 || lineIndex >= this._lines.length) { + if (lineNumber < rendStartLineNumber || lineNumber > rendEndLineNumber) { continue; } let startColumn = lineNumber === range.startLineNumber ? range.startColumn : 1; let endColumn = lineNumber === range.endLineNumber ? range.endColumn : this._context.model.getLineMaxColumn(lineNumber); - let visibleRangesForLine = this._lines[lineIndex].getVisibleRangesForRange(startColumn, endColumn, clientRectDeltaLeft, this._textRangeRestingSpot); + let visibleRangesForLine = this._linesCollection.getLine(lineNumber).getVisibleRangesForRange(startColumn, endColumn, clientRectDeltaLeft, this._textRangeRestingSpot); if (!visibleRangesForLine || visibleRangesForLine.length === 0) { continue; @@ -314,16 +319,17 @@ export class ViewLines extends ViewLayer { let clientRectDeltaLeft = this.domNode.domNode.getBoundingClientRect().left; let bigNumbersDelta = this._lastRenderedData.getBigNumbersDelta(); + let rendStartLineNumber = this._linesCollection.getStartLineNumber(); + let rendEndLineNumber = this._linesCollection.getEndLineNumber(); for (let lineNumber = range.startLineNumber; lineNumber <= range.endLineNumber; lineNumber++) { - let lineIndex = lineNumber - this._rendLineNumberStart; - if (lineIndex < 0 || lineIndex >= this._lines.length) { + if (lineNumber < rendStartLineNumber || lineNumber > rendEndLineNumber) { continue; } let startColumn = lineNumber === range.startLineNumber ? range.startColumn : 1; let endColumn = lineNumber === range.endLineNumber ? range.endColumn : this._context.model.getLineMaxColumn(lineNumber); - let visibleRangesForLine = this._lines[lineIndex].getVisibleRangesForRange(startColumn, endColumn, clientRectDeltaLeft, this._textRangeRestingSpot); + let visibleRangesForLine = this._linesCollection.getLine(lineNumber).getVisibleRangesForRange(startColumn, endColumn, clientRectDeltaLeft, this._textRangeRestingSpot); if (!visibleRangesForLine || visibleRangesForLine.length === 0) { continue; @@ -344,18 +350,17 @@ export class ViewLines extends ViewLayer { // --- implementation - _createLine(): IVisibleLineData { + _createLine(): ViewLine { return createLine(this._context); } private _updateLineWidths(): void { - var i:number, - localMaxLineWidth = 1, - widthInPx:number; + let rendStartLineNumber = this._linesCollection.getStartLineNumber(); + let rendEndLineNumber = this._linesCollection.getEndLineNumber(); - // Read line widths - for (i = 0; i < this._lines.length; i++) { - widthInPx = this._lines[i].getWidth(); + let localMaxLineWidth = 1; + for (let lineNumber = rendStartLineNumber; lineNumber <= rendEndLineNumber; lineNumber++) { + let widthInPx = this._linesCollection.getLine(lineNumber).getWidth(); localMaxLineWidth = Math.max(localMaxLineWidth, widthInPx); } diff --git a/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts b/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts index af7280003be..307648df7f7 100644 --- a/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts +++ b/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts @@ -112,16 +112,11 @@ export class LinesDecorationsOverlay extends DedupOverlay { for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) { let lineIndex = lineNumber - visibleStartLineNumber; let classNames = toRender[lineIndex]; - - if (classNames.length === 0) { - output[lineIndex] = ''; - } else { - output[lineIndex] = ( - '
this._onOriginalEditorEvents(events))); this._toDispose.push(this.addEmitter2(this.originalEditor)); @@ -755,11 +763,15 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif this._onViewZonesChanged(); } if (type === editorCommon.EventType.ConfigurationChanged) { + let e = data; let isViewportWrapping = this.modifiedEditor.getConfiguration().wrappingInfo.isViewportWrapping; if (isViewportWrapping) { // oh no, you didn't! this.modifiedEditor.updateOptions({ wrappingColumn: -1 }); } + if (e.fontInfo && this.modifiedEditor.getModel()) { + this._onViewZonesChanged(); + } } } this._recomputeIfNecessary(events); diff --git a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts index c1bc8345d24..de80b7f38c3 100644 --- a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts +++ b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts @@ -29,7 +29,7 @@ export class EmbeddedCodeEditorWidget extends CodeEditorWidget { @IKeybindingService keybindingService: IKeybindingService, @ITelemetryService telemetryService: ITelemetryService ) { - super(domElement, parentEditor.getRawConfiguration(), instantiationService, codeEditorService, commandService, keybindingService, telemetryService); + super(domElement, parentEditor.getRawConfiguration(), instantiationService, codeEditorService, commandService, keybindingService.createScoped(domElement), telemetryService); this._parentEditor = parentEditor; this._overwriteOptions = options; diff --git a/src/vs/editor/common/commonCodeEditor.ts b/src/vs/editor/common/commonCodeEditor.ts index b99a57f8472..0a1001c35f2 100644 --- a/src/vs/editor/common/commonCodeEditor.ts +++ b/src/vs/editor/common/commonCodeEditor.ts @@ -31,6 +31,7 @@ import {CharacterHardWrappingLineMapperFactory} from 'vs/editor/common/viewModel import {SplitLinesCollection} from 'vs/editor/common/viewModel/splitLinesCollection'; import {ViewModel} from 'vs/editor/common/viewModel/viewModelImpl'; import {hash} from 'vs/base/common/hash'; +import {EditorModeContext} from 'vs/editor/common/modes/editorModeContext'; var EDITOR_ID = 0; @@ -142,7 +143,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom this._lifetimeDispose = []; this._commandService = commandService; - this._keybindingService = keybindingService.createScoped(domElement); + this._keybindingService = keybindingService; this._editorIdContextKey = this._keybindingService.createKey('editorId', this.getId()); this._editorFocusContextKey = this._keybindingService.createKey(editorCommon.KEYBINDING_CONTEXT_EDITOR_FOCUS, undefined); this._editorTabMovesFocusKey = this._keybindingService.createKey(editorCommon.KEYBINDING_CONTEXT_EDITOR_TAB_MOVES_FOCUS, false); @@ -150,6 +151,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom this._hasMultipleSelectionsKey = this._keybindingService.createKey(editorCommon.KEYBINDING_CONTEXT_EDITOR_HAS_MULTIPLE_SELECTIONS, false); this._hasNonEmptySelectionKey = this._keybindingService.createKey(editorCommon.KEYBINDING_CONTEXT_EDITOR_HAS_NON_EMPTY_SELECTION, false); this._langIdKey = this._keybindingService.createKey(editorCommon.KEYBINDING_CONTEXT_EDITOR_LANGUAGE_ID, undefined); + this._lifetimeDispose.push(new EditorModeContext(this, this._keybindingService)); this._decorationTypeKeysToIds = {}; this._decorationTypeSubtypes = {}; diff --git a/src/vs/editor/common/editorAction.ts b/src/vs/editor/common/editorAction.ts index ae96914023e..5aebc0a6f9d 100644 --- a/src/vs/editor/common/editorAction.ts +++ b/src/vs/editor/common/editorAction.ts @@ -17,7 +17,6 @@ export class EditorAction extends Action implements IEditorContribution { public editor:ICommonCodeEditor; - private _shouldShowInContextMenu:boolean; private _supportsReadonly:boolean; private _descriptor:IEditorActionDescriptorData; private _enablementState:IEnablementState; @@ -29,8 +28,6 @@ export class EditorAction extends Action implements IEditorContribution { this.label = descriptor.label || ''; this._enablementState = createActionEnablement(editor, condition, this); - this._shouldShowInContextMenu = !!(condition & Behaviour.ShowInContextMenu); - this._supportsReadonly = !(condition & Behaviour.Writeable); } @@ -43,17 +40,6 @@ export class EditorAction extends Action implements IEditorContribution { super.dispose(); } - /** - * A helper to be able to group and sort actions when they are presented visually. - */ - public getGroupId(): string { - return this.id; - } - - public shouldShowInContextMenu(): boolean { - return this._shouldShowInContextMenu; - } - public getDescriptor(): IEditorActionDescriptorData { return this._descriptor; } @@ -125,11 +111,9 @@ export class HandlerEditorAction extends EditorAction { export class DynamicEditorAction extends EditorAction { - private static _transformBehaviour(behaviour:IActionEnablement, contextMenuGroupId: string): Behaviour { + private static _transformBehaviour(behaviour:IActionEnablement): Behaviour { var r = 0; - if (contextMenuGroupId) { - r |= Behaviour.ShowInContextMenu; - } else if (behaviour.textFocus) { + if (behaviour.textFocus) { // Allowed to set text focus only if not appearing in the context menu r |= Behaviour.TextFocus; } @@ -149,7 +133,6 @@ export class DynamicEditorAction extends EditorAction { return r; } - private _contextMenuGroupId: string; private _run: (editor:ICommonCodeEditor)=>void; private _tokensAtPosition:string[]; private _wordAtPosition:boolean; @@ -159,19 +142,14 @@ export class DynamicEditorAction extends EditorAction { super({ id: descriptor.id, label: descriptor.label - }, editor, DynamicEditorAction._transformBehaviour(enablement, descriptor.contextMenuGroupId)); + }, editor, DynamicEditorAction._transformBehaviour(enablement)); - this._contextMenuGroupId = descriptor.contextMenuGroupId; this._run = descriptor.run; this._tokensAtPosition = enablement.tokensAtPosition; this._wordAtPosition = enablement.wordAtPosition; } - public getGroupId(): string { - return this._contextMenuGroupId; - } - public run(): TPromise { return TPromise.as(this._run(this.editor)); } diff --git a/src/vs/editor/common/editorActionEnablement.ts b/src/vs/editor/common/editorActionEnablement.ts index 1149504194d..a5f52dec0ca 100644 --- a/src/vs/editor/common/editorActionEnablement.ts +++ b/src/vs/editor/common/editorActionEnablement.ts @@ -13,7 +13,6 @@ export enum Behaviour { Writeable = 1 << 2, UpdateOnModelChange = 1 << 3, UpdateOnConfigurationChange = 1 << 4, - ShowInContextMenu = 1 << 5, UpdateOnCursorPositionChange = 1 << 6 } diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index caea66f73ba..43b638a6b7d 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -3056,6 +3056,56 @@ export const KEYBINDING_CONTEXT_EDITOR_LANGUAGE_ID = 'editorLangId'; */ export const SHOW_ACCESSIBILITY_HELP_ACTION_ID = 'editor.action.showAccessibilityHelp'; +/** + * @internal + */ +export namespace ModeContextKeys { + /** + * @internal + */ + export const hasCompletionItemProvider = 'editorHasCompletionItemProvider'; + /** + * @internal + */ + export const hasCodeActionsProvider = 'editorHasCodeActionsProvider'; + /** + * @internal + */ + export const hasCodeLensProvider = 'editorHasCodeLensProvider'; + /** + * @internal + */ + export const hasDefinitionProvider = 'editorHasDefinitionProvider'; + /** + * @internal + */ + export const hasHoverProvider = 'editorHasHoverProvider'; + /** + * @internal + */ + export const hasDocumentHighlightProvider = 'editorHasDocumentHighlightProvider'; + /** + * @internal + */ + export const hasDocumentSymbolProvider = 'editorHasDocumentSymbolProvider'; + /** + * @internal + */ + export const hasReferenceProvider = 'editorHasReferenceProvider'; + /** + * @internal + */ + export const hasRenameProvider = 'editorHasRenameProvider'; + /** + * @internal + */ + export const hasFormattingProvider = 'editorHasFormattingProvider'; + /** + * @internal + */ + export const hasSignatureHelpProvider = 'editorHasSignatureHelpProvider'; +} + export class BareFontInfo { _bareFontInfoBrand: void; @@ -3368,17 +3418,7 @@ export interface IActionDescriptor { * A set of enablement conditions. */ enablement?: IActionEnablement; - /** - * Control if the action should show up in the context menu and where. - * Built-in groups: - * 1_goto/* => e.g. 1_goto/1_peekDefinition - * 2_change/* => e.g. 2_change/2_format - * 3_edit/* => e.g. 3_edit/1_copy - * 4_tools/* => e.g. 4_tools/1_commands - * You can also create your own group. - * Defaults to null (don't show in context menu). - */ - contextMenuGroupId?: string; + /** * Method that will be executed when the action is triggered. * @param editor The editor instance is passed in as a convinience diff --git a/src/vs/editor/common/editorCommonExtensions.ts b/src/vs/editor/common/editorCommonExtensions.ts index f6edaa3878b..fc2b4779e14 100644 --- a/src/vs/editor/common/editorCommonExtensions.ts +++ b/src/vs/editor/common/editorCommonExtensions.ts @@ -18,6 +18,7 @@ import {findFocusedEditor, getActiveEditor, withCodeEditorFromCommandHandler} fr import {Position} from 'vs/editor/common/core/position'; import * as editorCommon from 'vs/editor/common/editorCommon'; import {IModelService} from 'vs/editor/common/services/modelService'; +import {MenuId, MenuRegistry} from 'vs/platform/actions/common/actions'; // --- Keybinding extensions to make it more concise to express keybindings conditions export enum ContextKey { @@ -33,17 +34,27 @@ export interface IEditorActionKeybindingOptions extends IKeybindings { export interface IEditorCommandKeybindingOptions extends IKeybindings { context: ContextKey; } +export interface IEditorCommandMenuOptions { + kbExpr: KbExpr; + menu?: MenuId; + group?: string; + order?: number; +} // --- Editor Actions export class EditorActionDescriptor { - public ctor:editorCommon.IEditorActionContributionCtor; - public id:string; - public label:string; - public alias:string; - public kbOpts:IEditorActionKeybindingOptions; + public ctor: editorCommon.IEditorActionContributionCtor; + public id: string; + public label: string; + public alias: string; + public kbOpts: IEditorActionKeybindingOptions; + public menuOpts: IEditorCommandMenuOptions; - constructor(ctor:editorCommon.IEditorActionContributionCtor, id:string, label:string, kbOpts: IEditorActionKeybindingOptions = defaultEditorActionKeybindingOptions, alias?:string) { + constructor(ctor: editorCommon.IEditorActionContributionCtor, id: string, label: string, + kbOpts: IEditorActionKeybindingOptions = defaultEditorActionKeybindingOptions, + alias?: string + ) { this.ctor = ctor; this.id = id; this.label = label; @@ -192,6 +203,19 @@ class EditorContributionRegistry { when = desc.kbOpts.kbExpr; } + if (desc.menuOpts) { + let {menu, kbExpr, group, order} = desc.menuOpts; + MenuRegistry.appendMenuItem(menu || MenuId.EditorContext, { + command: { + id: desc.id, + title: desc.label + }, + when: kbExpr, + group, + order + }); + } + let commandDesc: ICommandDescriptor = { id: desc.id, handler: handler, diff --git a/src/vs/editor/common/model/modelLine.ts b/src/vs/editor/common/model/modelLine.ts index 525f477a816..b1aa3b132cc 100644 --- a/src/vs/editor/common/model/modelLine.ts +++ b/src/vs/editor/common/model/modelLine.ts @@ -145,7 +145,7 @@ export class ModelLine { private _state:IState; private _modeTransitions: ModeTransition[]; - private _lineTokens: LineTokens; + private _lineTokens: number[]; private _markers:ILineMarker[]; constructor(lineNumber:number, text:string, tabSize:number) { @@ -189,13 +189,13 @@ export class ModelLine { this._modeTransitions = toModeTransitions(topLevelMode, modeTransitions); } - private _setLineTokensFromDeflated(map:TokensInflatorMap, tokens:number[]): void { - this._lineTokens = toLineTokensFromDeflated(map, tokens, this._text.length); + private _setLineTokensFromDeflated(tokens:number[]): void { + this._lineTokens = toLineTokensFromDeflated(tokens, this._text.length); } - public getTokens(): ILineTokens { + public getTokens(map:TokensInflatorMap): ILineTokens { if (this._lineTokens) { - return this._lineTokens; + return new LineTokens(map, this._lineTokens); } if (this._text.length === 0) { return EmptyLineTokens.INSTANCE; @@ -211,9 +211,7 @@ export class ModelLine { return NO_OP_TOKENS_ADJUSTER; } - var lineTokens = this._lineTokens; - - let tokens = lineTokens.getBinaryEncodedTokens(); + let tokens = this._lineTokens; let tokensLength = tokens.length; let tokensIndex = 0; let currentTokenStartIndex = 0; @@ -277,10 +275,9 @@ export class ModelLine { this._setPlusOneIndentLevel(computePlusOneIndentLevel(text, tabSize)); } - if (this._lineTokens) { - let map = this._lineTokens.getBinaryEncodedTokensMap(), - tokens = this._lineTokens.getBinaryEncodedTokens(), - lineTextLength = this._text.length; + let tokens = this._lineTokens; + if (tokens) { + let lineTextLength = this._text.length; // Remove overflowing tokens while (tokens.length > 0) { @@ -293,7 +290,7 @@ export class ModelLine { tokens.pop(); } - this._setLineTokensFromDeflated(map, tokens); + this._setLineTokensFromDeflated(tokens); } } @@ -521,10 +518,9 @@ export class ModelLine { var thisTextLength = this._text.length; this._setText(this._text + other._text, tabSize); - let otherLineTokens = other._lineTokens; - if (otherLineTokens) { + let otherTokens = other._lineTokens; + if (otherTokens) { // Other has real tokens - let otherTokens = otherLineTokens.getBinaryEncodedTokens(); // Adjust other tokens if (thisTextLength > 0) { @@ -544,10 +540,10 @@ export class ModelLine { let myLineTokens = this._lineTokens; if (myLineTokens) { // I have real tokens - this._setLineTokensFromDeflated(myLineTokens.getBinaryEncodedTokensMap(), myLineTokens.getBinaryEncodedTokens().concat(otherTokens)); + this._setLineTokensFromDeflated(myLineTokens.concat(otherTokens)); } else { // I don't have real tokens - this._setLineTokensFromDeflated(otherLineTokens.getBinaryEncodedTokensMap(), otherTokens); + this._setLineTokensFromDeflated(otherTokens); } } @@ -695,7 +691,7 @@ export class ModelLine { } } -function toLineTokensFromInflated(map:TokensInflatorMap, tokens:LineToken[], textLength:number): LineTokens { +function toLineTokensFromInflated(map:TokensInflatorMap, tokens:LineToken[], textLength:number): number[] { if (textLength === 0) { return null; } @@ -708,11 +704,10 @@ function toLineTokensFromInflated(map:TokensInflatorMap, tokens:LineToken[], tex } } - let deflated = TokensBinaryEncoding.deflateArr(map, tokens); - return new LineTokens(map, deflated); + return TokensBinaryEncoding.deflateArr(map, tokens); } -function toLineTokensFromDeflated(map:TokensInflatorMap, tokens:number[], textLength:number): LineTokens { +function toLineTokensFromDeflated(tokens:number[], textLength:number): number[] { if (textLength === 0) { return null; } @@ -724,7 +719,7 @@ function toLineTokensFromDeflated(map:TokensInflatorMap, tokens:number[], textLe return null; } } - return new LineTokens(map, tokens); + return tokens; } export class LineTokens implements ILineTokens { diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 95f71783102..284a46c9020 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -509,7 +509,10 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo return 1 + Math.floor(rng.indent / this._options.tabSize); } if (rng.endLineNumber + 1 === lineNumber) { - return Math.ceil(rng.indent / this._options.tabSize); + if (i === 0 || indentRanges[i - 1].endLineNumber + 1 !== lineNumber) { + // For endLineNumber matches, we need to find the outermost indent range + return Math.ceil(rng.indent / this._options.tabSize); + } } } @@ -996,6 +999,10 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo break; } bestResult = result; + if (m.index + m[0].length === text.length) { + // Reached the end of the line + break; + } } return bestResult; } @@ -1008,8 +1015,8 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo m = searchRegex.exec(text); if (m) { var range = new Range(lineNumber, m.index + 1 + deltaOffset, lineNumber, m.index + 1 + m[0].length + deltaOffset); - // Exit early if the regex matches the same range if (range.equalsRange(result[result.length - 1])) { + // Exit early if the regex matches the same range return counter; } result.push(range); @@ -1017,6 +1024,10 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo if (counter >= limitResultCount) { return counter; } + if (m.index + m[0].length === text.length) { + // Reached the end of the line + return counter; + } } } while(m); return counter; diff --git a/src/vs/editor/common/model/textModelWithTokens.ts b/src/vs/editor/common/model/textModelWithTokens.ts index a6d1a816896..7fcc0447432 100644 --- a/src/vs/editor/common/model/textModelWithTokens.ts +++ b/src/vs/editor/common/model/textModelWithTokens.ts @@ -131,10 +131,10 @@ class LineContext implements ILineContext { private _text:string; private _lineTokens:editorCommon.ILineTokens; - constructor (topLevelMode:IMode, line:ModelLine) { + constructor (topLevelMode:IMode, line:ModelLine, map:TokensInflatorMap) { this.modeTransitions = line.getModeTransitions(topLevelMode); this._text = line.text; - this._lineTokens = line.getTokens(); + this._lineTokens = line.getTokens(map); } public getLineContent(): string { @@ -397,7 +397,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke if (!inaccurateTokensAcceptable) { this._updateTokensUntilLine(lineNumber, true); } - return this._lines[lineNumber - 1].getTokens(); + return this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); } public getLineContext(lineNumber:number): ILineContext { @@ -407,12 +407,12 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke this._updateTokensUntilLine(lineNumber, true); - return new LineContext(this._mode, this._lines[lineNumber - 1]); + return new LineContext(this._mode, this._lines[lineNumber - 1], this._tokensInflatorMap); } _getInternalTokens(lineNumber:number): editorCommon.ILineTokens { this._updateTokensUntilLine(lineNumber, true); - return this._lines[lineNumber - 1].getTokens(); + return this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); } public getMode(): IMode { @@ -791,7 +791,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke let lineNumber = position.lineNumber; let lineText = this._lines[lineNumber - 1].text; - let lineTokens = this._lines[lineNumber - 1].getTokens(); + let lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); let currentTokenIndex = lineTokens.findIndexOfOffset(position.column - 1); let currentTokenStart = lineTokens.getTokenStartIndex(currentTokenIndex); @@ -899,7 +899,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke let count = -1; for (let lineNumber = position.lineNumber; lineNumber >= 1; lineNumber--) { - let lineTokens = this._lines[lineNumber - 1].getTokens(); + let lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); let lineText = this._lines[lineNumber - 1].text; let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this._mode); let currentModeIndex = modeTransitions.length - 1; @@ -966,7 +966,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke let count = 1; for (let lineNumber = position.lineNumber, lineCount = this.getLineCount(); lineNumber <= lineCount; lineNumber++) { - let lineTokens = this._lines[lineNumber - 1].getTokens(); + let lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); let lineText = this._lines[lineNumber - 1].text; let modeTransitions = this._lines[lineNumber - 1].getModeTransitions(this._mode); let currentModeIndex = 0; @@ -1030,7 +1030,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke let reversedBracketRegex = /[\(\)\[\]\{\}]/; // TODO@Alex: use mode's brackets for (let lineNumber = position.lineNumber; lineNumber >= 1; lineNumber--) { - let lineTokens = this._lines[lineNumber - 1].getTokens(); + let lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); let lineText = this._lines[lineNumber - 1].text; let tokensLength = lineTokens.getTokenCount() - 1; @@ -1064,7 +1064,7 @@ export class TextModelWithTokens extends TextModel implements editorCommon.IToke let bracketRegex = /[\(\)\[\]\{\}]/; // TODO@Alex: use mode's brackets for (let lineNumber = position.lineNumber, lineCount = this.getLineCount(); lineNumber <= lineCount; lineNumber++) { - let lineTokens = this._lines[lineNumber - 1].getTokens(); + let lineTokens = this._lines[lineNumber - 1].getTokens(this._tokensInflatorMap); let lineText = this._lines[lineNumber - 1].text; let startTokenIndex = 0; diff --git a/src/vs/editor/common/modes/editorModeContext.ts b/src/vs/editor/common/modes/editorModeContext.ts new file mode 100644 index 00000000000..88821bb05bd --- /dev/null +++ b/src/vs/editor/common/modes/editorModeContext.ts @@ -0,0 +1,104 @@ +/*--------------------------------------------------------------------------------------------- + * 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 {IDisposable, dispose} from 'vs/base/common/lifecycle'; +import {IKeybindingContextKey, IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; +import * as modes from 'vs/editor/common/modes'; +import {ICommonCodeEditor, ModeContextKeys} from 'vs/editor/common/editorCommon'; + +export class EditorModeContext { + + private _disposables: IDisposable[] = []; + private _editor: ICommonCodeEditor; + + private _hasCompletionItemProvider: IKeybindingContextKey; + private _hasCodeActionsProvider: IKeybindingContextKey; + private _hasCodeLensProvider: IKeybindingContextKey; + private _hasDefinitionProvider: IKeybindingContextKey; + private _hasHoverProvider: IKeybindingContextKey; + private _hasDocumentHighlightProvider: IKeybindingContextKey; + private _hasDocumentSymbolProvider: IKeybindingContextKey; + private _hasReferenceProvider: IKeybindingContextKey; + private _hasRenameProvider: IKeybindingContextKey; + private _hasFormattingProvider: IKeybindingContextKey; + private _hasSignatureHelpProvider: IKeybindingContextKey; + + constructor( + editor: ICommonCodeEditor, + keybindingService: IKeybindingService + ) { + this._editor = editor; + + this._hasCompletionItemProvider = keybindingService.createKey(ModeContextKeys.hasCompletionItemProvider, undefined); + this._hasCodeActionsProvider = keybindingService.createKey(ModeContextKeys.hasCodeActionsProvider, undefined); + this._hasCodeLensProvider = keybindingService.createKey(ModeContextKeys.hasCodeLensProvider, undefined); + this._hasDefinitionProvider = keybindingService.createKey(ModeContextKeys.hasDefinitionProvider, undefined); + this._hasHoverProvider = keybindingService.createKey(ModeContextKeys.hasHoverProvider, undefined); + this._hasDocumentHighlightProvider = keybindingService.createKey(ModeContextKeys.hasDocumentHighlightProvider, undefined); + this._hasDocumentSymbolProvider = keybindingService.createKey(ModeContextKeys.hasDocumentSymbolProvider, undefined); + this._hasReferenceProvider = keybindingService.createKey(ModeContextKeys.hasReferenceProvider, undefined); + this._hasRenameProvider = keybindingService.createKey(ModeContextKeys.hasRenameProvider, undefined); + this._hasFormattingProvider = keybindingService.createKey(ModeContextKeys.hasFormattingProvider, undefined); + this._hasSignatureHelpProvider = keybindingService.createKey(ModeContextKeys.hasSignatureHelpProvider, undefined); + + // update when model/mode changes + this._disposables.push(editor.onDidChangeModel(() => this._update())); + this._disposables.push(editor.onDidChangeModelMode(() => this._update())); + + // update when registries change + modes.SuggestRegistry.onDidChange(this._update, this, this._disposables); + modes.CodeActionProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.CodeLensProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.DefinitionProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.HoverProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.DocumentHighlightProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.DocumentSymbolProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.ReferenceProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.RenameProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.DocumentFormattingEditProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.DocumentRangeFormattingEditProviderRegistry.onDidChange(this._update, this, this._disposables); + modes.SignatureHelpProviderRegistry.onDidChange(this._update, this, this._disposables); + + this._update(); + } + + dispose() { + this._disposables = dispose(this._disposables); + } + + reset() { + this._hasCompletionItemProvider.reset(); + this._hasCodeActionsProvider.reset(); + this._hasCodeLensProvider.reset(); + this._hasDefinitionProvider.reset(); + this._hasHoverProvider.reset(); + this._hasDocumentHighlightProvider.reset(); + this._hasDocumentSymbolProvider.reset(); + this._hasReferenceProvider.reset(); + this._hasRenameProvider.reset(); + this._hasFormattingProvider.reset(); + this._hasSignatureHelpProvider.reset(); + } + + private _update() { + const model = this._editor.getModel(); + if (!model) { + this.reset(); + return; + } + this._hasCompletionItemProvider.set(modes.SuggestRegistry.has(model)); + this._hasCodeActionsProvider.set(modes.CodeActionProviderRegistry.has(model)); + this._hasCodeLensProvider.set(modes.CodeLensProviderRegistry.has(model)); + this._hasDefinitionProvider.set(modes.DefinitionProviderRegistry.has(model)); + this._hasHoverProvider.set(modes.HoverProviderRegistry.has(model)); + this._hasDocumentHighlightProvider.set(modes.DocumentHighlightProviderRegistry.has(model)); + this._hasDocumentSymbolProvider.set(modes.DocumentSymbolProviderRegistry.has(model)); + this._hasReferenceProvider.set(modes.ReferenceProviderRegistry.has(model)); + this._hasRenameProvider.set(modes.RenameProviderRegistry.has(model)); + this._hasSignatureHelpProvider.set(modes.SignatureHelpProviderRegistry.has(model)); + this._hasFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.has(model) || modes.DocumentRangeFormattingEditProviderRegistry.has(model)); + } +} diff --git a/src/vs/editor/common/modes/languageSelector.ts b/src/vs/editor/common/modes/languageSelector.ts index 9b43883a43a..86a1f148df2 100644 --- a/src/vs/editor/common/modes/languageSelector.ts +++ b/src/vs/editor/common/modes/languageSelector.ts @@ -37,15 +37,19 @@ export function score(selector: LanguageSelector, uri: URI, language: string): n return 0; } } else if (selector) { - let filter = selector; - let value = 0; + // all must match but only highest score counts + const filter = selector; + + let valueLanguage = 0; + let valueScheme = 0; + let valuePattern = 0; // language id if (filter.language) { if (filter.language === language) { - value += 10; + valueLanguage = 10; } else if (filter.language === '*') { - value += 5; + valueLanguage = 5; } else { return 0; } @@ -54,7 +58,7 @@ export function score(selector: LanguageSelector, uri: URI, language: string): n // scheme if (filter.scheme) { if (filter.scheme === uri.scheme) { - value += 10; + valueScheme = 10; } else { return 0; } @@ -63,14 +67,14 @@ export function score(selector: LanguageSelector, uri: URI, language: string): n // match fsPath with pattern if (filter.pattern) { if (filter.pattern === uri.fsPath) { - value += 10; + valuePattern = 10; } else if (matchGlobPattern(filter.pattern, uri.fsPath)) { - value += 5; + valuePattern = 5; } else { return 0; } } - return value; + return Math.max(valueLanguage, valueScheme, valuePattern); } } diff --git a/src/vs/editor/common/modes/linkComputer.ts b/src/vs/editor/common/modes/linkComputer.ts index cea04057a49..983b465f969 100644 --- a/src/vs/editor/common/modes/linkComputer.ts +++ b/src/vs/editor/common/modes/linkComputer.ts @@ -11,19 +11,23 @@ export interface ILinkComputerTarget { getLineContent(lineNumber:number): string; } -// State machine for http:// or https:// -var STATE_MAP:{[ch:string]:number}[] = [], START_STATE = 1, END_STATE = 9, ACCEPT_STATE = 10; -STATE_MAP[1] = { 'h': 2, 'H': 2, 'f': 11, 'F': 11 }; +// State machine for http:// or https:// or file:// +const STATE_MAP:{[ch:string]:number}[] = []; +const START_STATE = 1; +const END_STATE = 12; +const ACCEPT_STATE = 13; + +STATE_MAP[1] = { 'h': 2, 'H': 2, 'f': 6, 'F': 6 }; STATE_MAP[2] = { 't': 3, 'T': 3 }; STATE_MAP[3] = { 't': 4, 'T': 4 }; STATE_MAP[4] = { 'p': 5, 'P': 5 }; -STATE_MAP[5] = { 's': 6, 'S': 6, ':': 7 }; -STATE_MAP[6] = { ':': 7 }; -STATE_MAP[7] = { '/': 8 }; -STATE_MAP[8] = { '/': 9 }; -STATE_MAP[11] = { 'i': 12, 'I': 12 }; -STATE_MAP[12] = { 'l': 13, 'L': 13 }; -STATE_MAP[13] = { 'e': 6, 'E': 6 }; +STATE_MAP[5] = { 's': 9, 'S': 9, ':': 10 }; +STATE_MAP[6] = { 'i': 7, 'I': 7 }; +STATE_MAP[7] = { 'l': 8, 'L': 8 }; +STATE_MAP[8] = { 'e': 9, 'E': 9 }; +STATE_MAP[9] = { ':': 10 }; +STATE_MAP[10] = { '/': 11 }; +STATE_MAP[11] = { '/': END_STATE }; enum CharacterClass { None = 0, @@ -31,12 +35,12 @@ enum CharacterClass { CannotEndIn = 2 } -let _openParens = '('.charCodeAt(0); -let _closeParens = ')'.charCodeAt(0); -let _openSquareBracket = '['.charCodeAt(0); -let _closeSquareBracket = ']'.charCodeAt(0); -let _openCurlyBracket = '{'.charCodeAt(0); -let _closeCurlyBracket = '}'.charCodeAt(0); +const _openParens = '('.charCodeAt(0); +const _closeParens = ')'.charCodeAt(0); +const _openSquareBracket = '['.charCodeAt(0); +const _closeSquareBracket = ']'.charCodeAt(0); +const _openCurlyBracket = '{'.charCodeAt(0); +const _closeCurlyBracket = '}'.charCodeAt(0); class CharacterClassifier { @@ -51,8 +55,8 @@ class CharacterClassifier { private _map: CharacterClass[]; constructor() { - var FORCE_TERMINATION_CHARACTERS = ' \t<>\'\"、。。、,.:;?!@#$%&*‘“〈《「『【〔([{「」}])〕】』」》〉”’`~…'; - var CANNOT_END_WITH_CHARACTERS = '.,;'; + const FORCE_TERMINATION_CHARACTERS = ' \t<>\'\"、。。、,.:;?!@#$%&*‘“〈《「『【〔([{「」}])〕】』」》〉”’`~…'; + const CANNOT_END_WITH_CHARACTERS = '.,;'; this._asciiMap = []; for (let i = 0; i < 256; i++) { @@ -91,60 +95,53 @@ class CharacterClassifier { } } +const characterClassifier = new CharacterClassifier(); + class LinkComputer { - private static _characterClassifier = new CharacterClassifier(); - private static _createLink(line:string, lineNumber:number, linkBeginIndex:number, linkEndIndex:number):ILink { + // Do not allow to end link in certain characters... + let lastIncludedCharIndex = linkEndIndex - 1; + do { + const chCode = line.charCodeAt(lastIncludedCharIndex); + const chClass = characterClassifier.classify(chCode); + if (chClass !== CharacterClass.CannotEndIn) { + break; + } + lastIncludedCharIndex--; + } while (lastIncludedCharIndex > linkBeginIndex); + return { range: { startLineNumber: lineNumber, startColumn: linkBeginIndex + 1, endLineNumber: lineNumber, - endColumn: linkEndIndex + 1 + endColumn: lastIncludedCharIndex + 2 }, - url: line.substring(linkBeginIndex, linkEndIndex) + url: line.substring(linkBeginIndex, lastIncludedCharIndex + 1) }; } public static computeLinks(model:ILinkComputerTarget):ILink[] { + let result:ILink[] = []; + for (let i = 1, lineCount = model.getLineCount(); i <= lineCount; i++) { + const line = model.getLineContent(i); + const len = line.length; - var i:number, - lineCount:number, - result:ILink[] = []; - - var line:string, - j:number, - lastIncludedCharIndex:number, - len:number, - linkBeginIndex:number, - state:number, - ch:string, - chCode:number, - chClass:CharacterClass, - resetStateMachine:boolean, - hasOpenParens:boolean, - hasOpenSquareBracket:boolean, - hasOpenCurlyBracket:boolean, - characterClassifier = LinkComputer._characterClassifier; - - for (i = 1, lineCount = model.getLineCount(); i <= lineCount; i++) { - line = model.getLineContent(i); - j = 0; - len = line.length; - linkBeginIndex = 0; - state = START_STATE; - hasOpenParens = false; - hasOpenSquareBracket = false; - hasOpenCurlyBracket = false; + let j = 0; + let linkBeginIndex = 0; + let state = START_STATE; + let hasOpenParens = false; + let hasOpenSquareBracket = false; + let hasOpenCurlyBracket = false; while (j < len) { - ch = line.charAt(j); - chCode = line.charCodeAt(j); - resetStateMachine = false; + + let resetStateMachine = false; if (state === ACCEPT_STATE) { - + const chCode = line.charCodeAt(j); + let chClass:CharacterClass; switch (chCode) { case _openParens: hasOpenParens = true; @@ -173,23 +170,12 @@ class LinkComputer { // Check if character terminates link if (chClass === CharacterClass.ForceTermination) { - - // Do not allow to end link in certain characters... - lastIncludedCharIndex = j - 1; - do { - chCode = line.charCodeAt(lastIncludedCharIndex); - chClass = characterClassifier.classify(chCode); - if (chClass !== CharacterClass.CannotEndIn) { - break; - } - lastIncludedCharIndex--; - } while (lastIncludedCharIndex > linkBeginIndex); - - result.push(LinkComputer._createLink(line, i, linkBeginIndex, lastIncludedCharIndex + 1)); + result.push(LinkComputer._createLink(line, i, linkBeginIndex, j)); resetStateMachine = true; } } else if (state === END_STATE) { - chClass = characterClassifier.classify(chCode); + const chCode = line.charCodeAt(j); + const chClass = characterClassifier.classify(chCode); // Check if character terminates link if (chClass === CharacterClass.ForceTermination) { @@ -198,6 +184,7 @@ class LinkComputer { state = ACCEPT_STATE; } } else { + const ch = line.charAt(j); if (STATE_MAP[state].hasOwnProperty(ch)) { state = STATE_MAP[state][ch]; } else { diff --git a/src/vs/editor/common/modes/supports.ts b/src/vs/editor/common/modes/supports.ts index 2cb7d13a51a..f5af8a5910b 100644 --- a/src/vs/editor/common/modes/supports.ts +++ b/src/vs/editor/common/modes/supports.ts @@ -164,7 +164,6 @@ export class SnippetsRegistry { let currentFullWord = SnippetsRegistry.getNonWhitespacePrefix(model, position).toLowerCase(); let result : modes.ISuggestResult = { currentWord: currentWord, - incomplete: currentWord.length === 0, suggestions: [] }; @@ -193,6 +192,7 @@ export class SnippetsRegistry { } else if (currentFullWord.length > currentWord.length && strings.startsWith(label, currentFullWord)) { p = objects.clone(p); p.overwriteBefore = currentFullWord.length; + p.filterText = label; } else { return; } diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index 0afa95dc30e..c36c704bf4c 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -121,7 +121,7 @@ class ModelMarkerHandler { let className: string; let color: string; let darkColor: string; - let htmlMessage: MarkedString[] = null; + let hoverMessage: MarkedString[] = null; switch (marker.severity) { case Severity.Ignore: @@ -142,21 +142,21 @@ class ModelMarkerHandler { } if (typeof marker.message === 'string') { - htmlMessage = [ textToMarkedString(marker.message) ]; + hoverMessage = [ textToMarkedString(marker.message) ]; } else if (Array.isArray(marker.message)) { - htmlMessage = marker.message; + hoverMessage = marker.message; } else if (marker.message) { - htmlMessage = [ marker.message ]; + hoverMessage = [ marker.message ]; } - if (htmlMessage && marker.source) { - htmlMessage.unshift(`[${marker.source}] `); + if (hoverMessage && marker.source) { + hoverMessage.unshift(`[${marker.source}] `); } return { stickiness: editorCommon.TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges, className, - hoverMessage: htmlMessage, + hoverMessage, overviewRuler: { color, darkColor, diff --git a/src/vs/editor/contrib/clipboard/browser/clipboard.ts b/src/vs/editor/contrib/clipboard/browser/clipboard.ts index f39022f7839..98869bd9bf5 100644 --- a/src/vs/editor/contrib/clipboard/browser/clipboard.ts +++ b/src/vs/editor/contrib/clipboard/browser/clipboard.ts @@ -18,8 +18,7 @@ import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import * as editorCommon from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; -import {MenuRegistry} from 'vs/platform/actions/browser/menuService'; -import {MenuId} from 'vs/platform/actions/common/actions'; +import {MenuId, MenuRegistry} from 'vs/platform/actions/common/actions'; class ClipboardWritingAction extends EditorAction { @@ -67,10 +66,6 @@ class ExecCommandCutAction extends ClipboardWritingAction { super(descriptor, editor, Behaviour.Writeable | Behaviour.WidgetFocus | Behaviour.UpdateOnCursorPositionChange); } - public getGroupId(): string { - return '3_edit/1_cut'; - } - public getEnablementState(): boolean { return super.getEnablementState() && editorCursorIsInEditableRange(this.editor); } @@ -88,10 +83,6 @@ class ExecCommandCopyAction extends ClipboardWritingAction { super(descriptor, editor, Behaviour.WidgetFocus); } - public getGroupId(): string { - return '3_edit/2_copy'; - } - public run(): TPromise { this.editor.focus(); document.execCommand('copy'); @@ -105,10 +96,6 @@ class ExecCommandPasteAction extends EditorAction { super(descriptor, editor, Behaviour.Writeable | Behaviour.WidgetFocus | Behaviour.UpdateOnCursorPositionChange); } - public getGroupId(): string { - return '3_edit/3_paste'; - } - public getEnablementState(): boolean { return editorCursorIsInEditableRange(this.editor); } @@ -143,14 +130,13 @@ function registerClipboardAction(desc: IClipboardCommand, alias: string, weight: kbExpr: KbExpr.has(editorCommon.KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS) }, alias)); - MenuRegistry.addCommand({ - id: desc.id, - title: desc.label - }); - MenuRegistry.appendMenuItem(MenuId.EditorContext, { - command: MenuRegistry.getCommand(desc.id), - group: `cutcopypaste@${weight}`, + command: { + id: desc.id, + title: desc.label + }, + group: `cutcopypaste`, + order: weight, when: desc.kbExpr }); } diff --git a/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts b/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts index 4a35593db35..f5c1f2e5173 100644 --- a/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts +++ b/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts @@ -28,6 +28,19 @@ interface IPosition { y: number; } +interface OldContextMenuAction extends IAction { + getGroupId(): string; + shouldShowInContextMenu(): boolean; + isSupported(): boolean; +} + +namespace OldContextMenuAction { + export function is(thing: any): thing is OldContextMenuAction { + return typeof (thing).getGroupId === 'function' + && typeof (thing).shouldShowInContextMenu === 'function'; + } +} + class ContextMenuController implements IEditorContribution { public static ID = 'editor.contrib.contextmenu'; @@ -130,18 +143,22 @@ class ContextMenuController implements IEditorContribution { return []; } - const contributedActions = this._editor.getActions().filter(action => { - if (action instanceof EditorAction) { + const actions: IAction[] = []; + fillInActions(this._contextMenu, actions); + + const oldContextMenuActions = this._editor.getActions().filter(action => { + if (OldContextMenuAction.is(action)) { return action.shouldShowInContextMenu() && action.isSupported(); } }); + if (oldContextMenuActions.length > 0) { + actions.push(new Separator(), ...ContextMenuController._prepareActions(oldContextMenuActions)); + } - const actions = ContextMenuController._prepareActions(contributedActions); - fillInActions(this._contextMenu, actions); return actions; } - private static _prepareActions(actions: EditorAction[]): IAction[] { + private static _prepareActions(actions: OldContextMenuAction[]): IAction[] { const data = actions.map(action => { const groupId = action.getGroupId(); diff --git a/src/vs/editor/contrib/find/browser/findWidget.ts b/src/vs/editor/contrib/find/browser/findWidget.ts index 7c16dbc3d69..6f565b0f162 100644 --- a/src/vs/editor/contrib/find/browser/findWidget.ts +++ b/src/vs/editor/contrib/find/browser/findWidget.ts @@ -545,7 +545,7 @@ export class FindWidget extends Widget implements IOverlayWidget { label: NLS_TOGGLE_REPLACE_MODE_BTN_LABEL, className: 'toggle left', onTrigger: () => { - this._state.change({ isReplaceRevealed: !this._isReplaceVisible }, true); + this._state.change({ isReplaceRevealed: !this._isReplaceVisible }, false); }, onKeyDown: (e) => {} })); diff --git a/src/vs/editor/contrib/find/common/findController.ts b/src/vs/editor/contrib/find/common/findController.ts index f70e27597ce..2f3ef174527 100644 --- a/src/vs/editor/contrib/find/common/findController.ts +++ b/src/vs/editor/contrib/find/common/findController.ts @@ -8,7 +8,7 @@ import * as nls from 'vs/nls'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import {Disposable} from 'vs/base/common/lifecycle'; import {TPromise} from 'vs/base/common/winjs.base'; -import {IKeybindingContextKey, IKeybindingService, IKeybindings} from 'vs/platform/keybinding/common/keybinding'; +import {IKeybindingContextKey, IKeybindingService, IKeybindings, KbExpr} from 'vs/platform/keybinding/common/keybinding'; import {Range} from 'vs/editor/common/core/range'; import {Selection} from 'vs/editor/common/core/selection'; import {EditorAction} from 'vs/editor/common/editorAction'; @@ -544,16 +544,9 @@ export class SelectHighlightsAction extends EditorAction { constructor(descriptor:editorCommon.IEditorActionDescriptorData, editor:editorCommon.ICommonCodeEditor) { let behaviour = Behaviour.WidgetFocus | Behaviour.Writeable; - if (descriptor.id === SelectHighlightsAction.COMPAT_ID) { - behaviour |= Behaviour.ShowInContextMenu; - } super(descriptor, editor, behaviour); } - public getGroupId(): string { - return '2_change/1_changeAll'; - } - public run(): TPromise { let r = multiCursorFind(this.editor, true); if (!r) { @@ -742,10 +735,21 @@ CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(SelectHighl primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_L }, 'Select All Occurences of Find Match')); // register SelectHighlightsAction again to replace the now removed Change All action -CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(SelectHighlightsAction, SelectHighlightsAction.COMPAT_ID, nls.localize('changeAll.label', "Change All Occurrences"), { - context: ContextKey.EditorTextFocus, - primary: KeyMod.CtrlCmd | KeyCode.F2 -}, 'Change All Occurrences')); +CommonEditorRegistry.registerEditorAction({ + ctor: SelectHighlightsAction, + id: SelectHighlightsAction.COMPAT_ID, + label: nls.localize('changeAll.label', "Change All Occurrences"), + alias: 'Change All Occurrences', + kbOpts: { + context: ContextKey.EditorTextFocus, + primary: KeyMod.CtrlCmd | KeyCode.F2 + }, + menuOpts: { + group: 'modification', + order: 2, + kbExpr: KbExpr.not(editorCommon.KEYBINDING_CONTEXT_EDITOR_READONLY) + } +}); // register actions CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(StartFindAction, FIND_IDS.StartFindAction, nls.localize('startFindAction',"Find"), { diff --git a/src/vs/editor/contrib/find/common/findModel.ts b/src/vs/editor/contrib/find/common/findModel.ts index 78fc3423b5c..1363276ddb1 100644 --- a/src/vs/editor/contrib/find/common/findModel.ts +++ b/src/vs/editor/contrib/find/common/findModel.ts @@ -7,6 +7,7 @@ import {RunOnceScheduler} from 'vs/base/common/async'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; +import {ReplacePattern} from 'vs/platform/search/common/replace'; import {ReplaceCommand} from 'vs/editor/common/commands/replaceCommand'; import {Position} from 'vs/editor/common/core/position'; import {Range} from 'vs/editor/common/core/range'; @@ -290,13 +291,8 @@ export class FindModelBoundToEditorModel { } private getReplaceString(matchedString:string): string { - if (!this._state.isRegex) { - return this._state.replaceString; - } - let regexp = strings.createRegExp(this._state.searchString, this._state.isRegex, this._state.matchCase, this._state.wholeWord, true); - // Parse the replace string to support that \t or \n mean the right thing - let parsedReplaceString = parseReplaceString(this._state.replaceString); - return matchedString.replace(regexp, parsedReplaceString); + let replacePattern= new ReplacePattern(this._state.replaceString, {pattern: this._state.searchString, isRegExp: this._state.isRegex, isCaseSensitive: this._state.matchCase, isWordMatch: this._state.wholeWord}); + return replacePattern.getReplaceString(matchedString); } private _rangeIsMatch(range:Range): boolean { @@ -378,95 +374,4 @@ export class FindModelBoundToEditorModel { this._ignoreModelContentChanged = false; } } -} - -const BACKSLASH_CHAR_CODE = '\\'.charCodeAt(0); -const DOLLAR_CHAR_CODE = '$'.charCodeAt(0); -const ZERO_CHAR_CODE = '0'.charCodeAt(0); -const n_CHAR_CODE = 'n'.charCodeAt(0); -const t_CHAR_CODE = 't'.charCodeAt(0); - -/** - * \n => LF - * \t => TAB - * \\ => \ - * $0 => $& (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter) - * everything else stays untouched - */ -export function parseReplaceString(input:string): string { - if (!input || input.length === 0) { - return input; - } - - let substrFrom = 0, result = ''; - for (let i = 0, len = input.length; i < len; i++) { - let chCode = input.charCodeAt(i); - - if (chCode === BACKSLASH_CHAR_CODE) { - - // move to next char - i++; - - if (i >= len) { - // string ends with a \ - break; - } - - let nextChCode = input.charCodeAt(i); - let replaceWithCharacter: string = null; - - switch (nextChCode) { - case BACKSLASH_CHAR_CODE: - // \\ => \ - replaceWithCharacter = '\\'; - break; - case n_CHAR_CODE: - // \n => LF - replaceWithCharacter = '\n'; - break; - case t_CHAR_CODE: - // \t => TAB - replaceWithCharacter = '\t'; - break; - } - - if (replaceWithCharacter) { - result += input.substring(substrFrom, i - 1) + replaceWithCharacter; - substrFrom = i + 1; - } - } - - if (chCode === DOLLAR_CHAR_CODE) { - - // move to next char - i++; - - if (i >= len) { - // string ends with a $ - break; - } - - let nextChCode = input.charCodeAt(i); - let replaceWithCharacter: string = null; - - switch (nextChCode) { - case ZERO_CHAR_CODE: - // $0 => $& - replaceWithCharacter = '$&'; - break; - } - - if (replaceWithCharacter) { - result += input.substring(substrFrom, i - 1) + replaceWithCharacter; - substrFrom = i + 1; - } - } - } - - if (substrFrom === 0) { - // no replacement occured - return input; - } - - return result + input.substring(substrFrom); -} +} \ No newline at end of file diff --git a/src/vs/editor/contrib/find/test/common/findModel.test.ts b/src/vs/editor/contrib/find/test/common/findModel.test.ts index 04684b16cf4..54274a9c02d 100644 --- a/src/vs/editor/contrib/find/test/common/findModel.test.ts +++ b/src/vs/editor/contrib/find/test/common/findModel.test.ts @@ -10,66 +10,12 @@ import {Position} from 'vs/editor/common/core/position'; import {Selection} from 'vs/editor/common/core/selection'; import {Range} from 'vs/editor/common/core/range'; import {Handler, ICommonCodeEditor, IRange} from 'vs/editor/common/editorCommon'; -import {FindModelBoundToEditorModel, parseReplaceString} from 'vs/editor/contrib/find/common/findModel'; +import {FindModelBoundToEditorModel} from 'vs/editor/contrib/find/common/findModel'; import {FindReplaceState} from 'vs/editor/contrib/find/common/findState'; import {withMockCodeEditor} from 'vs/editor/test/common/mocks/mockCodeEditor'; suite('FindModel', () => { - test('parseFindWidgetString', () => { - let testParse = (input:string, expected:string) => { - let actual = parseReplaceString(input); - assert.equal(actual, expected); - - let actual2 = parseReplaceString('hello' + input + 'hi'); - assert.equal(actual2, 'hello' + expected + 'hi'); - }; - - // no backslash => no treatment - testParse('hello', 'hello'); - - // \t => TAB - testParse('\\thello', '\thello'); - - // \n => LF - testParse('\\nhello', '\nhello'); - - // \\t => \t - testParse('\\\\thello', '\\thello'); - - // \\\t => \TAB - testParse('\\\\\\thello', '\\\thello'); - - // \\\\t => \\t - testParse('\\\\\\\\thello', '\\\\thello'); - - // \ at the end => no treatment - testParse('hello\\', 'hello\\'); - - // \ with unknown char => no treatment - testParse('hello\\x', 'hello\\x'); - - // \ with back reference => no treatment - testParse('hello\\0', 'hello\\0'); - - - - // $1 => no treatment - testParse('hello$1', 'hello$1'); - // $2 => no treatment - testParse('hello$2', 'hello$2'); - // $12 => no treatment - testParse('hello$12', 'hello$12'); - // $$ => no treatment - testParse('hello$$', 'hello$$'); - // $$0 => no treatment - testParse('hello$$0', 'hello$$0'); - - // $0 => $& - testParse('hello$0', 'hello$&'); - testParse('hello$02', 'hello$&2'); - }); - function findTest(testName:string, callback:(editor:ICommonCodeEditor, cursor:Cursor)=>void): void { test(testName, () => { withMockCodeEditor([ @@ -963,6 +909,35 @@ suite('FindModel', () => { findState.dispose(); }); + findTest('find .*', (editor, cursor) => { + let findState = new FindReplaceState(); + findState.change({ searchString: '.*', isRegex: true }, false); + let findModel = new FindModelBoundToEditorModel(editor, findState); + + assertFindState( + editor, + [1, 1, 1, 1], + null, + [ + [ 1, 1, 1, 18], + [ 2, 1, 2, 18], + [ 3, 1, 3, 20], + [ 4, 1, 4, 1], + [ 5, 1, 5, 13], + [ 6, 1, 6, 43], + [ 7, 1, 7, 41], + [ 8, 1, 8, 41], + [ 9, 1, 9, 40], + [10, 1, 10, 2], + [11, 1, 11, 17], + [12, 1, 12, 1], + ] + ); + + findModel.dispose(); + findState.dispose(); + }); + findTest('find next ^.*$', (editor, cursor) => { let findState = new FindReplaceState(); findState.change({ searchString: '^.*$', isRegex: true }, false); diff --git a/src/vs/editor/contrib/folding/browser/folding.css b/src/vs/editor/contrib/folding/browser/folding.css index bd952d663a2..14c6c882bd1 100644 --- a/src/vs/editor/contrib/folding/browser/folding.css +++ b/src/vs/editor/contrib/folding/browser/folding.css @@ -6,40 +6,31 @@ .monaco-editor .margin-view-overlays .folding { margin-left: 5px; cursor: pointer; -} - -.monaco-editor .margin-view-overlays .folding::after { background-repeat: no-repeat; background-origin: border-box; background-position: 3px center; background-size: 15px; - position: absolute; - top: 0; - left:0; - right: 0; - bottom: 0; - content: ""; opacity: 0; transition: opacity 0.5s; } -.monaco-editor .margin-view-overlays:hover .folding::after { +.monaco-editor .margin-view-overlays:hover .folding { background-image: url('arrow-expand.svg'); opacity: 1; } -.monaco-editor .margin-view-overlays .folding.collapsed::after { +.monaco-editor .margin-view-overlays .folding.collapsed { background-image: url('arrow-collapse.svg'); opacity: 1; } -.monaco-editor.hc-black .margin-view-overlays:hover .folding::after, -.monaco-editor.vs-dark .margin-view-overlays:hover .folding::after { +.monaco-editor.hc-black .margin-view-overlays:hover .folding, +.monaco-editor.vs-dark .margin-view-overlays:hover .folding { background-image: url('arrow-expand-dark.svg'); } -.monaco-editor.hc-black .margin-view-overlays .folding.collapsed::after, -.monaco-editor.vs-dark .margin-view-overlays .folding.collapsed::after { +.monaco-editor.hc-black .margin-view-overlays .folding.collapsed, +.monaco-editor.vs-dark .margin-view-overlays .folding.collapsed { background-image: url('arrow-collapse-dark.svg'); } diff --git a/src/vs/editor/contrib/format/common/formatActions.ts b/src/vs/editor/contrib/format/common/formatActions.ts index 0e1f41e84e7..f52b64312ed 100644 --- a/src/vs/editor/contrib/format/common/formatActions.ts +++ b/src/vs/editor/contrib/format/common/formatActions.ts @@ -12,7 +12,8 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; +import {KbExpr} from 'vs/platform/keybinding/common/keybinding'; +import {CommonEditorRegistry, ContextKey} from 'vs/editor/common/editorCommonExtensions'; import {DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry} from 'vs/editor/common/modes'; import {getOnTypeFormattingEdits, getDocumentFormattingEdits, getDocumentRangeFormattingEdits} from '../common/format'; import {EditOperationsCommand} from './formatCommand'; @@ -140,7 +141,7 @@ export class FormatAction extends EditorAction { private _disposables: IDisposable[]; constructor(descriptor:editorCommon.IEditorActionDescriptorData, editor:editorCommon.ICommonCodeEditor) { - super(descriptor, editor, Behaviour.WidgetFocus | Behaviour.Writeable | Behaviour.UpdateOnModelChange | Behaviour.ShowInContextMenu); + super(descriptor, editor, Behaviour.WidgetFocus | Behaviour.Writeable | Behaviour.UpdateOnModelChange); this._disposables = [ DocumentFormattingEditProviderRegistry.onDidChange(() => this.resetEnablementState()), DocumentRangeFormattingEditProviderRegistry.onDidChange(() => this.resetEnablementState()) @@ -151,11 +152,6 @@ export class FormatAction extends EditorAction { super.dispose(); this._disposables = dispose(this._disposables); } - - public getGroupId(): string { - return '2_change/2_format'; - } - public isSupported(): boolean { return ( ( @@ -224,9 +220,20 @@ export class FormatAction extends EditorAction { } // register action -CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(FormatAction, FormatAction.ID, nls.localize('formatAction.label', "Format Code"), { - context: ContextKey.EditorTextFocus, - primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_F, - linux: { primary:KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I } -}, 'Format Code')); +CommonEditorRegistry.registerEditorAction({ + ctor: FormatAction, + id: FormatAction.ID, + label: nls.localize('formatAction.label', "Format Code"), + alias: 'Format Code', + kbOpts: { + context: ContextKey.EditorTextFocus, + primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_F, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I } + }, + menuOpts: { + group: 'modification', + order: 10, + kbExpr: KbExpr.has(editorCommon.ModeContextKeys.hasFormattingProvider) + } +}); CommonEditorRegistry.registerEditorContribution(FormatOnType); \ No newline at end of file diff --git a/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts b/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts index 3aa3e4b1825..342d41294a1 100644 --- a/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts +++ b/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts @@ -7,6 +7,7 @@ import 'vs/css!./goToDeclaration'; import * as nls from 'vs/nls'; +import {KbExpr} from 'vs/platform/keybinding/common/keybinding'; import {Throttler} from 'vs/base/common/async'; import {onUnexpectedError} from 'vs/base/common/errors'; import {MarkedString, textToMarkedString} from 'vs/base/common/htmlContent'; @@ -38,7 +39,7 @@ import {optional} from 'vs/platform/instantiation/common/instantiation'; export class DefinitionActionConfig { constructor( - public condition = Behaviour.WidgetFocus | Behaviour.ShowInContextMenu | Behaviour.UpdateOnCursorPositionChange, + public condition = Behaviour.WidgetFocus | Behaviour.UpdateOnCursorPositionChange, public openToSide = false, public openInPeek = false, public filterCurrent = true @@ -59,10 +60,6 @@ export class DefinitionAction extends EditorAction { super(descriptor, editor, _configuration.condition); } - public getGroupId(): string { - return '1_goto/2_visitDefinition'; - } - public isSupported(): boolean { return DefinitionProviderRegistry.has(this.editor.getModel()) && super.isSupported(); } @@ -135,7 +132,13 @@ export class DefinitionAction extends EditorAction { private _openReference(reference: Location, sideBySide: boolean): TPromise{ let {uri, range} = reference; - return this._editorService.openEditor({ resource:uri, options: { selection: range } }, sideBySide).then(editor => { + return this._editorService.openEditor({ + resource: uri, + options: { + selection: range, + revealIfOpened: !sideBySide + } + }, sideBySide).then(editor => { return editor.getControl(); }); } @@ -371,23 +374,23 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC return; } - let htmlMessage: MarkedString = void 0;; + let hoverMessage: MarkedString = void 0; if (text && text.trim().length > 0) { if (isCode) { - htmlMessage = { + hoverMessage = { language: model.getMode().getId(), value: text }; } else { - htmlMessage = textToMarkedString(text); + hoverMessage = textToMarkedString(text); } } - let newDecorations = { + let newDecorations : editorCommon.IModelDeltaDecoration = { range: range, options: { inlineClassName: 'goto-definition-link', - htmlMessage: [htmlMessage] + hoverMessage } }; @@ -483,23 +486,43 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC } // register actions -CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(PeekDefinitionAction, PeekDefinitionAction.ID, nls.localize('actions.previewDecl.label', "Peek Definition"), { - context: ContextKey.EditorTextFocus, - primary: KeyMod.Alt | KeyCode.F12, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.F10 }, -}, 'Peek Definition')); -let goToDeclarationKb: number; -if (platform.isWeb) { - goToDeclarationKb = KeyMod.CtrlCmd | KeyCode.F12; -} else { - goToDeclarationKb = KeyCode.F12; -} +CommonEditorRegistry.registerEditorAction({ + id: PeekDefinitionAction.ID, + ctor: PeekDefinitionAction, + label: nls.localize('actions.previewDecl.label', "Peek Definition"), + alias: 'Peek Definition', + kbOpts: { + context: ContextKey.EditorTextFocus, + primary: KeyMod.Alt | KeyCode.F12, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.F10 } + }, + menuOpts: { + group: 'navigation', + order: 2, + kbExpr: KbExpr.has(editorCommon.ModeContextKeys.hasDefinitionProvider) + } +}); -CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(GoToDefinitionAction, GoToDefinitionAction.ID, nls.localize('actions.goToDecl.label', "Go to Definition"), { - context: ContextKey.EditorTextFocus, - primary: goToDeclarationKb -}, 'Go to Definition')); +const goToDeclarationKb = platform.isWeb + ? KeyMod.CtrlCmd | KeyCode.F12 + : KeyCode.F12; + +CommonEditorRegistry.registerEditorAction({ + ctor: GoToDefinitionAction, + id: GoToDefinitionAction.ID, + label: nls.localize('actions.goToDecl.label', "Go to Definition"), + alias: 'Go to Definition', + kbOpts: { + context: ContextKey.EditorTextFocus, + primary: goToDeclarationKb + }, + menuOpts: { + group: 'navigation', + order: 1, + kbExpr: KbExpr.has(editorCommon.ModeContextKeys.hasDefinitionProvider) + } +}); CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(OpenDefinitionToSideAction, OpenDefinitionToSideAction.ID, nls.localize('actions.goToDeclToSide.label', "Open Definition to the Side"), { context: ContextKey.EditorTextFocus, diff --git a/src/vs/editor/contrib/quickOpen/browser/quickCommand.contribution.ts b/src/vs/editor/contrib/quickOpen/browser/quickCommand.contribution.ts index d225ed6dccd..487ead42852 100644 --- a/src/vs/editor/contrib/quickOpen/browser/quickCommand.contribution.ts +++ b/src/vs/editor/contrib/quickOpen/browser/quickCommand.contribution.ts @@ -7,11 +7,22 @@ import * as nls from 'vs/nls'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import * as browser from 'vs/base/browser/browser'; -import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; +import {KbExpr} from 'vs/platform/keybinding/common/keybinding'; +import {KEYBINDING_CONTEXT_EDITOR_FOCUS} from 'vs/editor/common/editorCommon'; +import {CommonEditorRegistry, ContextKey} from 'vs/editor/common/editorCommonExtensions'; import {QuickCommandAction} from './quickCommand'; // Contribute "Quick Command" to context menu -CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(QuickCommandAction, QuickCommandAction.ID, nls.localize('label', "Command Palette"), { - context: ContextKey.EditorFocus, - primary: (browser.isIE11orEarlier ? KeyMod.Alt | KeyCode.F1 : KeyCode.F1) -}, 'Command Palette')); \ No newline at end of file +CommonEditorRegistry.registerEditorAction({ + ctor: QuickCommandAction, + id: QuickCommandAction.ID, + label: nls.localize('label', "Command Palette"), + alias: 'Command Palette', + kbOpts: { + context: ContextKey.EditorFocus, + primary: (browser.isIE11orEarlier ? KeyMod.Alt | KeyCode.F1 : KeyCode.F1) + }, + menuOpts: { + kbExpr: KbExpr.has(KEYBINDING_CONTEXT_EDITOR_FOCUS) + } +}); \ No newline at end of file diff --git a/src/vs/editor/contrib/quickOpen/browser/quickCommand.ts b/src/vs/editor/contrib/quickOpen/browser/quickCommand.ts index 9f28752dd04..565bdc2fb75 100644 --- a/src/vs/editor/contrib/quickOpen/browser/quickCommand.ts +++ b/src/vs/editor/contrib/quickOpen/browser/quickCommand.ts @@ -14,7 +14,6 @@ import {IContext, IHighlight, QuickOpenEntryGroup, QuickOpenModel} from 'vs/base import {IAutoFocus, Mode} from 'vs/base/parts/quickopen/common/quickOpen'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; import {EditorAction} from 'vs/editor/common/editorAction'; -import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import {ICommonCodeEditor, IEditor, IEditorActionDescriptorData} from 'vs/editor/common/editorCommon'; import {BaseEditorQuickOpenAction} from './editorQuickOpen'; @@ -77,7 +76,7 @@ export class QuickCommandAction extends BaseEditorQuickOpenAction { private _keybindingService: IKeybindingService; constructor(descriptor: IEditorActionDescriptorData, editor: ICommonCodeEditor, @IKeybindingService keybindingService: IKeybindingService) { - super(descriptor, editor, nls.localize('QuickCommandAction.label', "Command Palette"), Behaviour.WidgetFocus | Behaviour.ShowInContextMenu); + super(descriptor, editor, nls.localize('QuickCommandAction.label', "Command Palette")); this._keybindingService = keybindingService; } @@ -85,10 +84,6 @@ export class QuickCommandAction extends BaseEditorQuickOpenAction { return new QuickOpenModel(this._editorActionsToEntries(this.editor.getActions(), value)); } - public getGroupId(): string { - return '4_tools/1_commands'; - } - _sort(elementA: QuickOpenEntryGroup, elementB: QuickOpenEntryGroup): number { let elementAName = elementA.getLabel().toLowerCase(); let elementBName = elementB.getLabel().toLowerCase(); diff --git a/src/vs/editor/contrib/quickOpen/browser/quickOutline.contribution.ts b/src/vs/editor/contrib/quickOpen/browser/quickOutline.contribution.ts index e7c8f88be83..066dc53f23a 100644 --- a/src/vs/editor/contrib/quickOpen/browser/quickOutline.contribution.ts +++ b/src/vs/editor/contrib/quickOpen/browser/quickOutline.contribution.ts @@ -6,11 +6,24 @@ import * as nls from 'vs/nls'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; -import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; +import {KbExpr} from 'vs/platform/keybinding/common/keybinding'; +import {ModeContextKeys} from 'vs/editor/common/editorCommon'; +import {CommonEditorRegistry, ContextKey} from 'vs/editor/common/editorCommonExtensions'; import {QuickOutlineAction} from './quickOutline'; // Contribute "Quick Outline" to context menu -CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(QuickOutlineAction, QuickOutlineAction.ID, nls.localize('label', "Go to Symbol..."), { - context: ContextKey.EditorFocus, - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_O -}, 'Go to Symbol...')); +CommonEditorRegistry.registerEditorAction({ + ctor: QuickOutlineAction, + id: QuickOutlineAction.ID, + label: nls.localize('label', "Go to Symbol..."), + alias: 'Go to Symbol...', + kbOpts: { + context: ContextKey.EditorFocus, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_O + }, + menuOpts: { + group: 'navigation', + order: 3, + kbExpr: KbExpr.and(KbExpr.has(ModeContextKeys.hasDocumentSymbolProvider)) + } +}); diff --git a/src/vs/editor/contrib/quickOpen/browser/quickOutline.ts b/src/vs/editor/contrib/quickOpen/browser/quickOutline.ts index 2882708006c..4569e44efd5 100644 --- a/src/vs/editor/contrib/quickOpen/browser/quickOutline.ts +++ b/src/vs/editor/contrib/quickOpen/browser/quickOutline.ts @@ -14,7 +14,6 @@ import * as strings from 'vs/base/common/strings'; import {TPromise} from 'vs/base/common/winjs.base'; import {IContext, IHighlight, QuickOpenEntryGroup, QuickOpenModel} from 'vs/base/parts/quickopen/browser/quickOpenModel'; import {IAutoFocus, Mode} from 'vs/base/parts/quickopen/common/quickOpen'; -import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import {ICommonCodeEditor, IEditorActionDescriptorData, IRange} from 'vs/editor/common/editorCommon'; import {SymbolInformation, SymbolKind, DocumentSymbolProviderRegistry} from 'vs/editor/common/modes'; import {BaseEditorQuickOpenAction, IDecorator} from './editorQuickOpen'; @@ -114,15 +113,10 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction { private cachedResult: SymbolInformation[]; constructor(descriptor: IEditorActionDescriptorData, editor: ICommonCodeEditor) { - super(descriptor, editor, nls.localize('QuickOutlineAction.label', "Go to Symbol..."), Behaviour.WidgetFocus | Behaviour.ShowInContextMenu); + super(descriptor, editor, nls.localize('QuickOutlineAction.label', "Go to Symbol...")); } - - public getGroupId(): string { - return '1_goto/5_visitSymbol'; - } - public isSupported(): boolean { - return (DocumentSymbolProviderRegistry.has(this.editor.getModel()) && super.isSupported()); + return DocumentSymbolProviderRegistry.has(this.editor.getModel()) && super.isSupported(); } public run(): TPromise { diff --git a/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.ts b/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.ts index abd60da00a0..a897ed56625 100644 --- a/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.ts +++ b/src/vs/editor/contrib/referenceSearch/browser/referenceSearch.ts @@ -18,7 +18,7 @@ import {Range} from 'vs/editor/common/core/range'; import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; +import {CommonEditorRegistry, ContextKey} from 'vs/editor/common/editorCommonExtensions'; import {Location, ReferenceProviderRegistry} from 'vs/editor/common/modes'; import {IPeekViewService, getOuterEditor} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget'; import {provideReferences} from '../common/referenceSearch'; @@ -47,7 +47,7 @@ export class ReferenceAction extends EditorAction { @IKeybindingService keybindingService: IKeybindingService, @optional(IPeekViewService) peekViewService: IPeekViewService ) { - super(descriptor, editor, Behaviour.WidgetFocus | Behaviour.ShowInContextMenu | Behaviour.UpdateOnCursorPositionChange); + super(descriptor, editor, Behaviour.WidgetFocus | Behaviour.UpdateOnCursorPositionChange); this.label = nls.localize('references.action.label', "Find All References"); @@ -57,10 +57,6 @@ export class ReferenceAction extends EditorAction { } } - public getGroupId(): string { - return '1_goto/4_references'; - } - public isSupported():boolean { return ReferenceProviderRegistry.has(this.editor.getModel()) && super.isSupported(); } @@ -130,10 +126,21 @@ let showReferencesCommand: ICommandHandler = (accessor:ServicesAccessor, resourc // register action -CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(ReferenceAction, ReferenceAction.ID, nls.localize('references.action.name', "Find All References"), { - context: ContextKey.EditorTextFocus, - primary: KeyMod.Shift | KeyCode.F12 -}, 'Find All References')); +CommonEditorRegistry.registerEditorAction({ + ctor: ReferenceAction, + id: ReferenceAction.ID, + label: nls.localize('references.action.name', "Find All References"), + alias: 'Find All References', + kbOpts: { + context: ContextKey.EditorTextFocus, + primary: KeyMod.Shift | KeyCode.F12 + }, + menuOpts: { + kbExpr: KbExpr.has(editorCommon.ModeContextKeys.hasReferenceProvider), + group: 'navigation' + } +}); + KeybindingsRegistry.registerCommandDesc({ id: 'editor.action.findReferences', handler: findReferencesCommand, @@ -141,6 +148,7 @@ KeybindingsRegistry.registerCommandDesc({ when: null, primary: undefined }); + KeybindingsRegistry.registerCommandDesc({ id: 'editor.action.showReferences', handler: showReferencesCommand, diff --git a/src/vs/editor/contrib/rename/browser/rename.ts b/src/vs/editor/contrib/rename/browser/rename.ts index 5546c632e06..4c07c1c29ee 100644 --- a/src/vs/editor/contrib/rename/browser/rename.ts +++ b/src/vs/editor/contrib/rename/browser/rename.ts @@ -12,14 +12,16 @@ import Severity from 'vs/base/common/severity'; import {TPromise} from 'vs/base/common/winjs.base'; import {IEditorService} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; -import {IKeybindingContextKey, IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; +import {IKeybindingContextKey, IKeybindingService, KbExpr} from 'vs/platform/keybinding/common/keybinding'; import {IMessageService} from 'vs/platform/message/common/message'; +import {IProgressService} from 'vs/platform/progress/common/progress'; import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import {IEditorActionDescriptorData, IRange} from 'vs/editor/common/editorCommon'; -import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; -import {RenameProviderRegistry} from 'vs/editor/common/modes'; +import {CommonEditorRegistry, ContextKey} from 'vs/editor/common/editorCommonExtensions'; +import {KEYBINDING_CONTEXT_EDITOR_READONLY, ModeContextKeys} from 'vs/editor/common/editorCommon'; import {BulkEdit, createBulkEdit} from 'vs/editor/common/services/bulkEdit'; +import {RenameProviderRegistry} from 'vs/editor/common/modes'; import {ICodeEditor} from 'vs/editor/browser/editorBrowser'; import {rename} from '../common/rename'; import RenameInputField from './renameInputField'; @@ -34,28 +36,22 @@ export class RenameAction extends EditorAction { public static ID: string = 'editor.action.rename'; - private _messageService: IMessageService; - private _eventService: IEventService; - private _editorService: IEditorService; private _renameInputField: RenameInputField; private _renameInputVisible: IKeybindingContextKey; constructor(descriptor: IEditorActionDescriptorData, editor: ICodeEditor, - @IMessageService messageService: IMessageService, @IKeybindingService keybindingService: IKeybindingService, - @IEventService eventService: IEventService, @IEditorService editorService: IEditorService) { - super(descriptor, editor, Behaviour.WidgetFocus | Behaviour.Writeable | Behaviour.ShowInContextMenu | Behaviour.UpdateOnCursorPositionChange); + @IMessageService private _messageService: IMessageService, + @IEventService private _eventService: IEventService, + @IEditorService private _editorService: IEditorService, + @IProgressService private _progressService: IProgressService, + @IKeybindingService keybindingService: IKeybindingService + ) { + super(descriptor, editor, Behaviour.WidgetFocus | Behaviour.Writeable); - this._messageService = messageService; - this._eventService = eventService; - this._editorService = editorService; this._renameInputField = new RenameInputField(editor); this._renameInputVisible = keybindingService.createKey(CONTEXT_RENAME_INPUT_VISIBLE, false); } - public getGroupId(): string { - return '2_change/1_rename2'; - } - public isSupported(): boolean { return RenameProviderRegistry.has(this.editor.getModel()) && !this.editor.getModel().hasEditableRange() && super.isSupported(); } @@ -93,10 +89,11 @@ export class RenameAction extends EditorAction { this._renameInputVisible.set(true); return this._renameInputField.getInput(wordRange, word.word, selectionStart, selectionEnd).then(newName => { this._renameInputVisible.reset(); - return this._prepareRename(newName).then(edit => { + this.editor.focus(); + + const renameOperation = this._prepareRename(newName).then(edit => { return edit.finish().then(selection => { - this.editor.focus(); if (selection) { this.editor.setSelection(selection); } @@ -106,9 +103,14 @@ export class RenameAction extends EditorAction { if (typeof err === 'string') { this._messageService.show(Severity.Info, err); } else { + this._messageService.show(Severity.Error, nls.localize('rename.failed', "Sorry, rename failed to execute.")); return TPromise.wrapError(err); } }); + + this._progressService.showWhile(renameOperation, 250); + return renameOperation; + }, err => { this._renameInputVisible.reset(); this.editor.focus(); @@ -145,10 +147,21 @@ export class RenameAction extends EditorAction { const weight = CommonEditorRegistry.commandWeight(99); -CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(RenameAction, RenameAction.ID, nls.localize('rename.label', "Rename Symbol"), { - context: ContextKey.EditorTextFocus, - primary: KeyCode.F2 -}, 'Rename Symbol')); +CommonEditorRegistry.registerEditorAction({ + ctor: RenameAction, + id: RenameAction.ID, + label: nls.localize('rename.label', "Rename Symbol"), + alias: 'Rename Symbol', + kbOpts: { + context: ContextKey.EditorTextFocus, + primary: KeyCode.F2 + }, + menuOpts: { + group: 'modification', + order: 1, + kbExpr: KbExpr.and(KbExpr.has(ModeContextKeys.hasRenameProvider), KbExpr.not(KEYBINDING_CONTEXT_EDITOR_READONLY)) + } +}); CommonEditorRegistry.registerEditorCommand('acceptRenameInput', weight, { primary: KeyCode.Enter }, false, CONTEXT_RENAME_INPUT_VISIBLE, (ctx, editor, args) => { const action = editor.getAction(RenameAction.ID); diff --git a/src/vs/editor/contrib/rename/browser/renameInputField.css b/src/vs/editor/contrib/rename/browser/renameInputField.css index d138aee0de9..3c674d7d366 100644 --- a/src/vs/editor/contrib/rename/browser/renameInputField.css +++ b/src/vs/editor/contrib/rename/browser/renameInputField.css @@ -15,7 +15,6 @@ .monaco-editor .rename-box .rename-input { border: 1px solid #39F; - font-size: 13px; padding: 4px; } diff --git a/src/vs/editor/contrib/rename/browser/renameInputField.ts b/src/vs/editor/contrib/rename/browser/renameInputField.ts index 61bd78d4f87..8b7b03f0d82 100644 --- a/src/vs/editor/contrib/rename/browser/renameInputField.ts +++ b/src/vs/editor/contrib/rename/browser/renameInputField.ts @@ -21,6 +21,7 @@ export default class RenameInputField implements IContentWidget, IDisposable { private _domNode: HTMLElement; private _inputField: HTMLInputElement; private _visible: boolean; + private _disposables: IDisposable[] = []; // Editor.IContentWidget.allowEditorOverflow public allowEditorOverflow: boolean = true; @@ -28,9 +29,16 @@ export default class RenameInputField implements IContentWidget, IDisposable { constructor(editor: ICodeEditor) { this._editor = editor; this._editor.addContentWidget(this); + + this._disposables.push(editor.onDidChangeConfiguration(e => { + if (e.fontInfo) { + this.updateFont(); + } + })); } public dispose(): void { + this._disposables = dispose(this._disposables); this._editor.removeContentWidget(this); } @@ -48,10 +56,22 @@ export default class RenameInputField implements IContentWidget, IDisposable { this._domNode.style.height = `${this._editor.getConfiguration().lineHeight}px`; this._domNode.className = 'monaco-editor rename-box'; this._domNode.appendChild(this._inputField); + + this.updateFont(); } return this._domNode; } + private updateFont(): void { + if (!this._inputField) { + return; + } + + const fontInfo = this._editor.getConfiguration().fontInfo; + this._inputField.style.fontFamily = fontInfo.fontFamily; + this._inputField.style.fontSize = `${ fontInfo.fontSize }px`; + } + public getPosition(): IContentWidgetPosition { return this._visible ? { position: this._position, preference: [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] } diff --git a/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts b/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts index 5027d748740..b685bc6eb83 100644 --- a/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts +++ b/src/vs/editor/contrib/smartSelect/test/common/tokenSelectionSupport.test.ts @@ -5,11 +5,12 @@ 'use strict'; import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import URI from 'vs/base/common/uri'; import {Range} from 'vs/editor/common/core/range'; import {IMode, IndentAction} from 'vs/editor/common/modes'; import {TokenSelectionSupport} from 'vs/editor/contrib/smartSelect/common/tokenSelectionSupport'; -import {createMockModelService} from 'vs/editor/test/common/servicesTestUtils'; +import {createMockModelService} from 'vs/test/utils/servicesTestUtils'; import {MockTokenizingMode} from 'vs/editor/test/common/mocks/mockMode'; import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry'; @@ -59,10 +60,15 @@ class MockJSMode extends MockTokenizingMode { suite('TokenSelectionSupport', () => { - let modelService = createMockModelService(); - let tokenSelectionSupport = new TokenSelectionSupport(modelService); + let modelService; + let tokenSelectionSupport; let _mode: IMode = new MockJSMode(); + setup(() => { + modelService= createMockModelService(new TestInstantiationService()); + tokenSelectionSupport = new TokenSelectionSupport(modelService); + }); + function assertGetRangesToPosition(text:string[], lineNumber:number, column:number, ranges:Range[]): void { let uri = URI.file('test.js'); modelService.createModel(text.join('\n'), _mode, uri); diff --git a/src/vs/editor/contrib/suggest/browser/suggestModel.ts b/src/vs/editor/contrib/suggest/browser/suggestModel.ts index 41d17b80f66..d7f8e90e1e3 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestModel.ts @@ -9,7 +9,7 @@ import Event, { Emitter } from 'vs/base/common/event'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {startsWith} from 'vs/base/common/strings'; import {TPromise} from 'vs/base/common/winjs.base'; -import {ICommonCodeEditor, ICursorSelectionChangedEvent, CursorChangeReason} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, ICursorSelectionChangedEvent, CursorChangeReason, IModel, IPosition} from 'vs/editor/common/editorCommon'; import {ISuggestSupport, ISuggestion, SuggestRegistry} from 'vs/editor/common/modes'; import {CodeSnippet} from 'vs/editor/contrib/snippet/common/snippet'; import {ISuggestResult2, provideCompletionItems} from '../common/suggest'; @@ -52,9 +52,7 @@ class Context { wordBefore: string; wordAfter: string; - constructor(editor: ICommonCodeEditor, private auto: boolean) { - const model = editor.getModel(); - const position = editor.getPosition(); + constructor(model: IModel, position: IPosition, private auto: boolean) { const lineContent = model.getLineContent(position.lineNumber); const wordUnderCursor = model.getWordAtPosition(position); @@ -262,7 +260,13 @@ export class SuggestModel implements IDisposable { return; } - const ctx = new Context(this.editor, false); + const model = this.editor.getModel(); + + if (!model) { + return; + } + + const ctx = new Context(model, this.editor.getPosition(), false); if (isInactive) { // trigger was not called or it was canceled @@ -298,6 +302,11 @@ export class SuggestModel implements IDisposable { trigger(auto: boolean, triggerCharacter?: string, retrigger: boolean = false, groups?: ISuggestSupport[][]): void { const model = this.editor.getModel(); + + if (!model) { + return; + } + const characterTriggered = !!triggerCharacter; groups = groups || SuggestRegistry.orderedGroups(model); @@ -305,7 +314,7 @@ export class SuggestModel implements IDisposable { return; } - const ctx = new Context(this.editor, auto); + const ctx = new Context(model, this.editor.getPosition(), auto); if (!ctx.isInEditableRange) { return; @@ -331,7 +340,13 @@ export class SuggestModel implements IDisposable { this.raw = all; this.incomplete = all.some(result => result.incomplete); - this.onNewContext(new Context(this.editor, auto)); + const model = this.editor.getModel(); + + if (!model) { + return; + } + + this.onNewContext(new Context(model, this.editor.getPosition(), auto)); }).then(null, onUnexpectedError); } diff --git a/src/vs/editor/test/browser/view/viewLayer.test.ts b/src/vs/editor/test/browser/view/viewLayer.test.ts new file mode 100644 index 00000000000..a778393d0c8 --- /dev/null +++ b/src/vs/editor/test/browser/view/viewLayer.test.ts @@ -0,0 +1,762 @@ +/*--------------------------------------------------------------------------------------------- + * 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 {RenderedLinesCollection, ILine} from 'vs/editor/browser/view/viewLayer'; + +class TestLine implements ILine { + + _pinged = false; + constructor(public id:string) { + } + + onContentChanged(): void { + this._pinged = true; + } + onLinesInsertedAbove(): void { + this._pinged = true; + } + onLinesDeletedAbove(): void { + this._pinged = true; + } + onLineChangedAbove(): void { + this._pinged = true; + } + onTokensChanged(): void { + this._pinged = true; + } +} + +interface ILinesCollectionState { + startLineNumber: number; + lines: string[]; + pinged: boolean[]; +} + +function assertState(col:RenderedLinesCollection, state:ILinesCollectionState): void { + let actualState:ILinesCollectionState = { + startLineNumber: col.getStartLineNumber(), + lines: [], + pinged: [] + }; + for (let lineNumber = col.getStartLineNumber(); lineNumber <= col.getEndLineNumber(); lineNumber++) { + actualState.lines.push(col.getLine(lineNumber).id); + actualState.pinged.push(col.getLine(lineNumber)._pinged); + } + assert.deepEqual(actualState, state); +} + +suite('RenderedLinesCollection onModelLinesDeleted', () => { + + function testOnModelLinesDeleted(deleteFromLineNumber:number, deleteToLineNumber:number, expectedDeleted:string[], expectedState:ILinesCollectionState): void { + let col = new RenderedLinesCollection(() => new TestLine('new')); + col._set(6, [ + new TestLine('old6'), + new TestLine('old7'), + new TestLine('old8'), + new TestLine('old9') + ]); + let actualDeleted1 = col.onModelLinesDeleted(deleteFromLineNumber, deleteToLineNumber); + let actualDeleted = []; + if (actualDeleted1) { + actualDeleted = actualDeleted1.map(line => line.id); + } + assert.deepEqual(actualDeleted, expectedDeleted); + assertState(col, expectedState); + } + + test('A1', () => { + testOnModelLinesDeleted(3, 3, [], { + startLineNumber: 5, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A2', () => { + testOnModelLinesDeleted(3, 4, [], { + startLineNumber: 4, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A3', () => { + testOnModelLinesDeleted(3, 5, [], { + startLineNumber: 3, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A4', () => { + testOnModelLinesDeleted(3, 6, ['old6'], { + startLineNumber: 3, + lines: ['old7', 'old8', 'old9'], + pinged: [true, true, true] + }); + }); + + test('A5', () => { + testOnModelLinesDeleted(3, 7, ['old6', 'old7'], { + startLineNumber: 3, + lines: ['old8', 'old9'], + pinged: [true, true] + }); + }); + + test('A6', () => { + testOnModelLinesDeleted(3, 8, ['old6', 'old7', 'old8'], { + startLineNumber: 3, + lines: ['old9'], + pinged: [true] + }); + }); + + test('A7', () => { + testOnModelLinesDeleted(3, 9, ['old6', 'old7', 'old8', 'old9'], { + startLineNumber: 3, + lines: [], + pinged: [] + }); + }); + + test('A8', () => { + testOnModelLinesDeleted(3, 10, ['old6', 'old7', 'old8', 'old9'], { + startLineNumber: 3, + lines: [], + pinged: [] + }); + }); + + + test('B1', () => { + testOnModelLinesDeleted(5, 5, [], { + startLineNumber: 5, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('B2', () => { + testOnModelLinesDeleted(5, 6, ['old6'], { + startLineNumber: 5, + lines: ['old7', 'old8', 'old9'], + pinged: [true, true, true] + }); + }); + + test('B3', () => { + testOnModelLinesDeleted(5, 7, ['old6', 'old7'], { + startLineNumber: 5, + lines: ['old8', 'old9'], + pinged: [true, true] + }); + }); + + test('B4', () => { + testOnModelLinesDeleted(5, 8, ['old6', 'old7', 'old8'], { + startLineNumber: 5, + lines: ['old9'], + pinged: [true] + }); + }); + + test('B5', () => { + testOnModelLinesDeleted(5, 9, ['old6', 'old7', 'old8', 'old9'], { + startLineNumber: 5, + lines: [], + pinged: [] + }); + }); + + test('B6', () => { + testOnModelLinesDeleted(5, 10, ['old6', 'old7', 'old8', 'old9'], { + startLineNumber: 5, + lines: [], + pinged: [] + }); + }); + + + test('C1', () => { + testOnModelLinesDeleted(6, 6, ['old6'], { + startLineNumber: 6, + lines: ['old7', 'old8', 'old9'], + pinged: [true, true, true] + }); + }); + + test('C2', () => { + testOnModelLinesDeleted(6, 7, ['old6', 'old7'], { + startLineNumber: 6, + lines: ['old8', 'old9'], + pinged: [true, true] + }); + }); + + test('C3', () => { + testOnModelLinesDeleted(6, 8, ['old6', 'old7', 'old8'], { + startLineNumber: 6, + lines: ['old9'], + pinged: [true] + }); + }); + + test('C4', () => { + testOnModelLinesDeleted(6, 9, ['old6', 'old7', 'old8', 'old9'], { + startLineNumber: 6, + lines: [], + pinged: [] + }); + }); + + test('C5', () => { + testOnModelLinesDeleted(6, 10, ['old6', 'old7', 'old8', 'old9'], { + startLineNumber: 6, + lines: [], + pinged: [] + }); + }); + + + test('D1', () => { + testOnModelLinesDeleted(7, 7, ['old7'], { + startLineNumber: 6, + lines: ['old6', 'old8', 'old9'], + pinged: [false, true, true] + }); + }); + + test('D2', () => { + testOnModelLinesDeleted(7, 8, ['old7', 'old8'], { + startLineNumber: 6, + lines: ['old6', 'old9'], + pinged: [false, true] + }); + }); + + test('D3', () => { + testOnModelLinesDeleted(7, 9, ['old7', 'old8', 'old9'], { + startLineNumber: 6, + lines: ['old6'], + pinged: [false] + }); + }); + + test('D4', () => { + testOnModelLinesDeleted(7, 10, ['old7', 'old8', 'old9'], { + startLineNumber: 6, + lines: ['old6'], + pinged: [false] + }); + }); + + + test('E1', () => { + testOnModelLinesDeleted(8, 8, ['old8'], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old9'], + pinged: [false, false, true] + }); + }); + + test('E2', () => { + testOnModelLinesDeleted(8, 9, ['old8', 'old9'], { + startLineNumber: 6, + lines: ['old6', 'old7'], + pinged: [false, false] + }); + }); + + test('E3', () => { + testOnModelLinesDeleted(8, 10, ['old8', 'old9'], { + startLineNumber: 6, + lines: ['old6', 'old7'], + pinged: [false, false] + }); + }); + + + test('F1', () => { + testOnModelLinesDeleted(9, 9, ['old9'], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8'], + pinged: [false, false, false] + }); + }); + + test('F2', () => { + testOnModelLinesDeleted(9, 10, ['old9'], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8'], + pinged: [false, false, false] + }); + }); + + + test('G1', () => { + testOnModelLinesDeleted(10, 10, [], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + + test('G2', () => { + testOnModelLinesDeleted(10, 11, [], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + + + test('H1', () => { + testOnModelLinesDeleted(11, 13, [], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); +}); + +suite('RenderedLinesCollection onModelLineChanged', () => { + + function testOnModelLineChanged(changedLineNumber:number, expectedPinged:boolean, expectedState:ILinesCollectionState): void { + let col = new RenderedLinesCollection(() => new TestLine('new')); + col._set(6, [ + new TestLine('old6'), + new TestLine('old7'), + new TestLine('old8'), + new TestLine('old9') + ]); + let actualPinged = col.onModelLineChanged(changedLineNumber); + assert.deepEqual(actualPinged, expectedPinged); + assertState(col, expectedState); + } + + test('3', () => { + testOnModelLineChanged(3, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + test('4', () => { + testOnModelLineChanged(4, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + test('5', () => { + testOnModelLineChanged(5, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + test('6', () => { + testOnModelLineChanged(6, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + test('7', () => { + testOnModelLineChanged(7, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, true, true, true] + }); + }); + test('8', () => { + testOnModelLineChanged(8, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, true, true] + }); + }); + test('9', () => { + testOnModelLineChanged(9, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, true] + }); + }); + test('10', () => { + testOnModelLineChanged(10, false, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + test('11', () => { + testOnModelLineChanged(11, false, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + +}); + +suite('RenderedLinesCollection onModelLinesInserted', () => { + + function testOnModelLinesInserted(insertFromLineNumber:number, insertToLineNumber:number, expectedDeleted:string[], expectedState:ILinesCollectionState): void { + let col = new RenderedLinesCollection(() => new TestLine('new')); + col._set(6, [ + new TestLine('old6'), + new TestLine('old7'), + new TestLine('old8'), + new TestLine('old9') + ]); + let actualDeleted1 = col.onModelLinesInserted(insertFromLineNumber, insertToLineNumber); + let actualDeleted = []; + if (actualDeleted1) { + actualDeleted = actualDeleted1.map(line => line.id); + } + assert.deepEqual(actualDeleted, expectedDeleted); + assertState(col, expectedState); + } + + test('A1', () => { + testOnModelLinesInserted(3, 3, [], { + startLineNumber: 7, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A2', () => { + testOnModelLinesInserted(3, 4, [], { + startLineNumber: 8, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A3', () => { + testOnModelLinesInserted(3, 5, [], { + startLineNumber: 9, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A4', () => { + testOnModelLinesInserted(3, 6, [], { + startLineNumber: 10, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A5', () => { + testOnModelLinesInserted(3, 7, [], { + startLineNumber: 11, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A6', () => { + testOnModelLinesInserted(3, 8, [], { + startLineNumber: 12, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A7', () => { + testOnModelLinesInserted(3, 9, [], { + startLineNumber: 13, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('A8', () => { + testOnModelLinesInserted(3, 10, [], { + startLineNumber: 14, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + + test('B1', () => { + testOnModelLinesInserted(5, 5, [], { + startLineNumber: 7, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('B2', () => { + testOnModelLinesInserted(5, 6, [], { + startLineNumber: 8, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('B3', () => { + testOnModelLinesInserted(5, 7, [], { + startLineNumber: 9, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('B4', () => { + testOnModelLinesInserted(5, 8, [], { + startLineNumber: 10, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('B5', () => { + testOnModelLinesInserted(5, 9, [], { + startLineNumber: 11, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('B6', () => { + testOnModelLinesInserted(5, 10, [], { + startLineNumber: 12, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + + test('C1', () => { + testOnModelLinesInserted(6, 6, [], { + startLineNumber: 7, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('C2', () => { + testOnModelLinesInserted(6, 7, [], { + startLineNumber: 8, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('C3', () => { + testOnModelLinesInserted(6, 8, [], { + startLineNumber: 9, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('C4', () => { + testOnModelLinesInserted(6, 9, [], { + startLineNumber: 10, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + test('C5', () => { + testOnModelLinesInserted(6, 10, [], { + startLineNumber: 11, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + + + test('D1', () => { + testOnModelLinesInserted(7, 7, ['old9'], { + startLineNumber: 6, + lines: ['old6', 'new', 'old7', 'old8'], + pinged: [false, false, true, true] + }); + }); + + test('D2', () => { + testOnModelLinesInserted(7, 8, ['old8', 'old9'], { + startLineNumber: 6, + lines: ['old6', 'new', 'new', 'old7'], + pinged: [false, false, false, true] + }); + }); + + test('D3', () => { + testOnModelLinesInserted(7, 9, ['old7', 'old8', 'old9'], { + startLineNumber: 6, + lines: ['old6'], + pinged: [false] + }); + }); + + test('D4', () => { + testOnModelLinesInserted(7, 10, ['old7', 'old8', 'old9'], { + startLineNumber: 6, + lines: ['old6'], + pinged: [false] + }); + }); + + + test('E1', () => { + testOnModelLinesInserted(8, 8, ['old9'], { + startLineNumber: 6, + lines: ['old6', 'old7', 'new', 'old8'], + pinged: [false, false, false, true] + }); + }); + + test('E2', () => { + testOnModelLinesInserted(8, 9, ['old8', 'old9'], { + startLineNumber: 6, + lines: ['old6', 'old7'], + pinged: [false, false] + }); + }); + + test('E3', () => { + testOnModelLinesInserted(8, 10, ['old8', 'old9'], { + startLineNumber: 6, + lines: ['old6', 'old7'], + pinged: [false, false] + }); + }); + + + test('F1', () => { + testOnModelLinesInserted(9, 9, ['old9'], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8'], + pinged: [false, false, false] + }); + }); + + test('F2', () => { + testOnModelLinesInserted(9, 10, ['old9'], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8'], + pinged: [false, false, false] + }); + }); + + + test('G1', () => { + testOnModelLinesInserted(10, 10, [], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + + test('G2', () => { + testOnModelLinesInserted(10, 11, [], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + + + test('H1', () => { + testOnModelLinesInserted(11, 13, [], { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); +}); + + +suite('RenderedLinesCollection onModelTokensChanged', () => { + + function testOnModelTokensChanged(changedFromLineNumber:number, changedToLineNumber:number, expectedPinged:boolean, expectedState:ILinesCollectionState): void { + let col = new RenderedLinesCollection(() => new TestLine('new')); + col._set(6, [ + new TestLine('old6'), + new TestLine('old7'), + new TestLine('old8'), + new TestLine('old9') + ]); + let actualPinged = col.onModelTokensChanged(changedFromLineNumber, changedToLineNumber); + assert.deepEqual(actualPinged, expectedPinged); + assertState(col, expectedState); + } + + test('A', () => { + testOnModelTokensChanged(3, 3, false, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + test('B', () => { + testOnModelTokensChanged(3, 5, false, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + test('C', () => { + testOnModelTokensChanged(3, 6, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, false, false, false] + }); + }); + test('D', () => { + testOnModelTokensChanged(6, 6, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, false, false, false] + }); + }); + test('E', () => { + testOnModelTokensChanged(5, 10, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [true, true, true, true] + }); + }); + test('F', () => { + testOnModelTokensChanged(8, 9, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, true, true] + }); + }); + test('G', () => { + testOnModelTokensChanged(8, 11, true, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, true, true] + }); + }); + test('H', () => { + testOnModelTokensChanged(10, 10, false, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); + test('I', () => { + testOnModelTokensChanged(10, 11, false, { + startLineNumber: 6, + lines: ['old6', 'old7', 'old8', 'old9'], + pinged: [false, false, false, false] + }); + }); +}); diff --git a/src/vs/editor/test/common/model/model.line.test.ts b/src/vs/editor/test/common/model/model.line.test.ts index 6249c056fdc..fd0e2ffac7f 100644 --- a/src/vs/editor/test/common/model/model.line.test.ts +++ b/src/vs/editor/test/common/model/model.line.test.ts @@ -264,25 +264,26 @@ suite('Editor Model - modelLine.append text', () => { suite('Editor Model - modelLine.applyEdits text & tokens', () => { function testLineEditTokens(initialText:string, initialTokens: LineToken[], edits:ILineEdit[], expectedText:string, expectedTokens: LineToken[]): void { - var line = new ModelLine(1, initialText, NO_TAB_SIZE); - line.setTokens(new TokensInflatorMap(), initialTokens, null, []); + let line = new ModelLine(1, initialText, NO_TAB_SIZE); + let map = new TokensInflatorMap(); + line.setTokens(map, initialTokens, null, []); line.applyEdits({}, edits, NO_TAB_SIZE); assert.equal(line.text, expectedText); - assertLineTokens(line.getTokens(), expectedTokens); + assertLineTokens(line.getTokens(map), expectedTokens); } test('insertion on empty line', () => { - var line = new ModelLine(1, 'some text', NO_TAB_SIZE); - var map = new TokensInflatorMap(); + let line = new ModelLine(1, 'some text', NO_TAB_SIZE); + let map = new TokensInflatorMap(); line.setTokens(map, [new LineToken(0, 'bar')], null, []); line.applyEdits({}, [{startColumn:1, endColumn:10, text:'', forceMoveMarkers: false}], NO_TAB_SIZE); line.setTokens(map, [], null, []); line.applyEdits({}, [{startColumn:1, endColumn:1, text:'a', forceMoveMarkers: false}], NO_TAB_SIZE); - assertLineTokens(line.getTokens(), [{ + assertLineTokens(line.getTokens(map), [{ startIndex: 0, type:'' }]); @@ -838,14 +839,15 @@ suite('Editor Model - modelLine.applyEdits text & tokens', () => { suite('Editor Model - modelLine.split text & tokens', () => { function testLineSplitTokens(initialText:string, initialTokens: LineToken[], splitColumn:number, expectedText1:string, expectedText2:string, expectedTokens: LineToken[]): void { - var line = new ModelLine(1, initialText, NO_TAB_SIZE); - line.setTokens(new TokensInflatorMap(), initialTokens, null, []); + let line = new ModelLine(1, initialText, NO_TAB_SIZE); + let map = new TokensInflatorMap(); + line.setTokens(map, initialTokens, null, []); - var other = line.split({}, splitColumn, false, NO_TAB_SIZE); + let other = line.split({}, splitColumn, false, NO_TAB_SIZE); assert.equal(line.text, expectedText1); assert.equal(other.text, expectedText2); - assertLineTokens(line.getTokens(), expectedTokens); + assertLineTokens(line.getTokens(map), expectedTokens); } test('split at the beginning', () => { @@ -920,18 +922,18 @@ suite('Editor Model - modelLine.split text & tokens', () => { suite('Editor Model - modelLine.append text & tokens', () => { function testLineAppendTokens(aText:string, aTokens: LineToken[], bText:string, bTokens:LineToken[], expectedText:string, expectedTokens:IToken[]): void { - var inflator = new TokensInflatorMap(); + let inflator = new TokensInflatorMap(); - var a = new ModelLine(1, aText, NO_TAB_SIZE); + let a = new ModelLine(1, aText, NO_TAB_SIZE); a.setTokens(inflator, aTokens, null, []); - var b = new ModelLine(2, bText, NO_TAB_SIZE); + let b = new ModelLine(2, bText, NO_TAB_SIZE); b.setTokens(inflator, bTokens, null, []); a.append({}, b, NO_TAB_SIZE); assert.equal(a.text, expectedText); - assertLineTokens(a.getTokens(), expectedTokens); + assertLineTokens(a.getTokens(inflator), expectedTokens); } test('append empty 1', () => { @@ -1060,19 +1062,19 @@ suite('Editor Model - modelLine.applyEdits text & markers', () => { } function testLineEditMarkers(initialText:string, initialMarkers: LineMarker[], edits:ILineEdit[], expectedText:string, expectedChangedMarkers:number[], _expectedMarkers: LineMarker[]): void { - var line = new ModelLine(1, initialText, NO_TAB_SIZE); + let line = new ModelLine(1, initialText, NO_TAB_SIZE); line.addMarkers(initialMarkers); - var changedMarkers = Object.create(null); + let changedMarkers = Object.create(null); line.applyEdits(changedMarkers, edits, NO_TAB_SIZE); assert.equal(line.text, expectedText, 'text'); - var actualMarkers = line.getMarkers().map(toLightWeightMarker); - var expectedMarkers = _expectedMarkers.map(toLightWeightMarker); + let actualMarkers = line.getMarkers().map(toLightWeightMarker); + let expectedMarkers = _expectedMarkers.map(toLightWeightMarker); assert.deepEqual(actualMarkers, expectedMarkers, 'markers'); - var actualChangedMarkers = Object.keys(changedMarkers); + let actualChangedMarkers = Object.keys(changedMarkers); actualChangedMarkers.sort().map(Object.prototype.toString); assert.deepEqual(actualChangedMarkers, expectedChangedMarkers, 'changed markers'); } @@ -1876,24 +1878,24 @@ suite('Editor Model - modelLine.split text & markers', () => { } function testLineSplitMarkers(initialText:string, initialMarkers: LineMarker[], splitColumn:number, forceMoveMarkers:boolean, expectedText1:string, expectedText2:string, expectedChangedMarkers:number[], _expectedMarkers1: LineMarker[], _expectedMarkers2: LineMarker[]): void { - var line = new ModelLine(1, initialText, NO_TAB_SIZE); + let line = new ModelLine(1, initialText, NO_TAB_SIZE); line.addMarkers(initialMarkers); - var changedMarkers = Object.create(null); - var otherLine = line.split(changedMarkers, splitColumn, forceMoveMarkers, NO_TAB_SIZE); + let changedMarkers = Object.create(null); + let otherLine = line.split(changedMarkers, splitColumn, forceMoveMarkers, NO_TAB_SIZE); assert.equal(line.text, expectedText1, 'text'); assert.equal(otherLine.text, expectedText2, 'text'); - var actualMarkers1 = line.getMarkers().map(toLightWeightMarker); - var expectedMarkers1 = _expectedMarkers1.map(toLightWeightMarker); + let actualMarkers1 = line.getMarkers().map(toLightWeightMarker); + let expectedMarkers1 = _expectedMarkers1.map(toLightWeightMarker); assert.deepEqual(actualMarkers1, expectedMarkers1, 'markers'); - var actualMarkers2 = otherLine.getMarkers().map(toLightWeightMarker); - var expectedMarkers2 = _expectedMarkers2.map(toLightWeightMarker); + let actualMarkers2 = otherLine.getMarkers().map(toLightWeightMarker); + let expectedMarkers2 = _expectedMarkers2.map(toLightWeightMarker); assert.deepEqual(actualMarkers2, expectedMarkers2, 'markers'); - var actualChangedMarkers = Object.keys(changedMarkers); + let actualChangedMarkers = Object.keys(changedMarkers); actualChangedMarkers.sort().map(Object.prototype.toString); assert.deepEqual(actualChangedMarkers, expectedChangedMarkers, 'changed markers'); } @@ -2144,22 +2146,22 @@ suite('Editor Model - modelLine.append text & markers', () => { } function testLinePrependMarkers(aText:string, aMarkers: LineMarker[], bText:string, bMarkers: LineMarker[], expectedText:string, expectedChangedMarkers:number[], _expectedMarkers: LineMarker[]): void { - var a = new ModelLine(1, aText, NO_TAB_SIZE); + let a = new ModelLine(1, aText, NO_TAB_SIZE); a.addMarkers(aMarkers); - var b = new ModelLine(1, bText, NO_TAB_SIZE); + let b = new ModelLine(1, bText, NO_TAB_SIZE); b.addMarkers(bMarkers); - var changedMarkers = Object.create(null); + let changedMarkers = Object.create(null); a.append(changedMarkers, b, NO_TAB_SIZE); assert.equal(a.text, expectedText, 'text'); - var actualMarkers = a.getMarkers().map(toLightWeightMarker); - var expectedMarkers = _expectedMarkers.map(toLightWeightMarker); + let actualMarkers = a.getMarkers().map(toLightWeightMarker); + let expectedMarkers = _expectedMarkers.map(toLightWeightMarker); assert.deepEqual(actualMarkers, expectedMarkers, 'markers'); - var actualChangedMarkers = Object.keys(changedMarkers); + let actualChangedMarkers = Object.keys(changedMarkers); actualChangedMarkers.sort().map(Object.prototype.toString); assert.deepEqual(actualChangedMarkers, expectedChangedMarkers, 'changed markers'); } diff --git a/src/vs/editor/test/common/model/model.test.ts b/src/vs/editor/test/common/model/model.test.ts index 16e7a7eafd4..8246f33a038 100644 --- a/src/vs/editor/test/common/model/model.test.ts +++ b/src/vs/editor/test/common/model/model.test.ts @@ -528,22 +528,26 @@ suite('Editor Model - Find', () => { let actualRanges = model.findMatches(searchString, false, isRegex, matchCase, wholeWord); let actual = actualRanges.map(toArrRange); - assert.deepEqual(actual, expected); + assert.deepEqual(actual, expected, 'findMatches OK'); // test `findNextMatch` - let match = model.findNextMatch(searchString, new Position(1, 1), isRegex, matchCase, wholeWord); - assert.deepEqual(toArrRange(match), expected[0]); + let startPos = new Position(1, 1); + let match = model.findNextMatch(searchString, startPos, isRegex, matchCase, wholeWord); + assert.deepEqual(toArrRange(match), expected[0], `findNextMatch ${startPos}`); for (let i = 0; i < expected.length; i++) { - match = model.findNextMatch(searchString, new Position(expected[i][0], expected[i][1]), isRegex, matchCase, wholeWord); - assert.deepEqual(toArrRange(match), expected[i]); + startPos = new Position(expected[i][0], expected[i][1]); + match = model.findNextMatch(searchString, startPos, isRegex, matchCase, wholeWord); + assert.deepEqual(toArrRange(match), expected[i], `findNextMatch ${startPos}`); } // test `findPrevMatch` - match = model.findPreviousMatch(searchString, new Position(model.getLineCount(), model.getLineMaxColumn(model.getLineCount())), isRegex, matchCase, wholeWord); - assert.deepEqual(toArrRange(match), expected[expected.length-1]); + startPos = new Position(model.getLineCount(), model.getLineMaxColumn(model.getLineCount())); + match = model.findPreviousMatch(searchString, startPos, isRegex, matchCase, wholeWord); + assert.deepEqual(toArrRange(match), expected[expected.length-1], `findPrevMatch ${startPos}`); for (let i = 0; i < expected.length; i++) { - match = model.findPreviousMatch(searchString, new Position(expected[i][2], expected[i][3]), isRegex, matchCase, wholeWord); - assert.deepEqual(toArrRange(match), expected[i]); + startPos = new Position(expected[i][2], expected[i][3]); + match = model.findPreviousMatch(searchString, startPos, isRegex, matchCase, wholeWord); + assert.deepEqual(toArrRange(match), expected[i], `findPrevMatch ${startPos}`); } model.dispose(); @@ -623,6 +627,20 @@ suite('Editor Model - Find', () => { ); }); + test('/.*/ find', () => { + assertFindMatches( + regularText.join('\n'), + '.*', true, false, false, + [ + [1, 1, 1, 74], + [2, 1, 2, 69], + [3, 1, 3, 54], + [4, 1, 4, 65], + [5, 1, 5, 31] + ] + ); + }); + test('/^$/ find', () => { assertFindMatches( [ diff --git a/src/vs/editor/test/common/model/textModel.test.ts b/src/vs/editor/test/common/model/textModel.test.ts index 0e28102bad0..7ee2e6ea4bb 100644 --- a/src/vs/editor/test/common/model/textModel.test.ts +++ b/src/vs/editor/test/common/model/textModel.test.ts @@ -599,7 +599,7 @@ suite('TextModel.getLineIndentGuide', () => { [1, ' A'], [1, ' A'], [2, ' A'], - [1, 'A'], + [0, 'A'], ]); }); @@ -697,4 +697,15 @@ suite('TextModel.getLineIndentGuide', () => { [1, '\tindent1'], ]); }); + + test('issue #8952 - Indentation guide lines going through text on .yml file', () => { + assertIndentGuides([ + [0, 'properties:'], + [1, ' emailAddress:'], + [2, ' - bla'], + [2, ' - length:'], + [3, ' max: 255'], + [0, 'getters:'], + ]); + }); }); diff --git a/src/vs/editor/test/common/modes/languageSelector.test.ts b/src/vs/editor/test/common/modes/languageSelector.test.ts index cef7d65f288..9d05591c75e 100644 --- a/src/vs/editor/test/common/modes/languageSelector.test.ts +++ b/src/vs/editor/test/common/modes/languageSelector.test.ts @@ -31,7 +31,7 @@ suite('LanguageSelector', function() { test('score, filter', function() { assert.equal(score('farboo', model.uri, model.language), 10); assert.equal(score({ language: 'farboo'}, model.uri, model.language), 10); - assert.equal(score({ language: 'farboo', scheme: 'file' }, model.uri, model.language), 20); + assert.equal(score({ language: 'farboo', scheme: 'file' }, model.uri, model.language), 10); assert.equal(score({ language: 'farboo', scheme: 'http' }, model.uri, model.language), 0); assert.equal(score({ pattern: '**/*.fb' }, model.uri, model.language), 5); @@ -42,9 +42,9 @@ suite('LanguageSelector', function() { let match = { language: 'farboo', scheme: 'file' }; let fail = { language: 'farboo', scheme: 'http' }; - assert.equal(score(match, model.uri, model.language), 20); + assert.equal(score(match, model.uri, model.language), 10); assert.equal(score(fail, model.uri, model.language), 0); - assert.equal(score([match, fail], model.uri, model.language), 20); + assert.equal(score([match, fail], model.uri, model.language), 10); assert.equal(score(['farboo', '*'], model.uri, model.language), 10); assert.equal(score(['*', 'farboo'], model.uri, model.language), 10); }); diff --git a/src/vs/editor/test/common/modes/linkComputer.test.ts b/src/vs/editor/test/common/modes/linkComputer.test.ts index 853cef3df96..35c6d0e6943 100644 --- a/src/vs/editor/test/common/modes/linkComputer.test.ts +++ b/src/vs/editor/test/common/modes/linkComputer.test.ts @@ -181,7 +181,9 @@ suite('Editor Modes - Link Computer', () => { 'x = "file://shäres/foo.bar";', ' file://shäres/foo.bar ' ); - - // foo bar (see http://www.w3schools.com/tags/att_iframe_sandbox.asp) + assertLink( + 'Some text, then http://www.bing.com.', + ' http://www.bing.com ' + ); }); }); diff --git a/src/vs/editor/test/common/modes/modesRegistry.test.ts b/src/vs/editor/test/common/modes/modesRegistry.test.ts index 6c036b7f52b..e18da231204 100644 --- a/src/vs/editor/test/common/modes/modesRegistry.test.ts +++ b/src/vs/editor/test/common/modes/modesRegistry.test.ts @@ -5,12 +5,22 @@ 'use strict'; import 'vs/languages/html/common/html.contribution'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import * as assert from 'assert'; -import {createMockModeService} from 'vs/editor/test/common/servicesTestUtils'; +import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl'; +import {IExtensionService} from 'vs/platform/extensions/common/extensions'; suite('Editor Modes - Modes Registry', () => { + + let instantiationService: TestInstantiationService; + + setup(() => { + instantiationService= new TestInstantiationService(); + instantiationService.stub(IExtensionService); + }); + test('Bug 12104: [f12] createModel not successfully handling mime type list?', () => { - let modeService = createMockModeService(); + let modeService = instantiationService.createInstance(ModeServiceImpl); assert.equal(modeService.getModeId('text/html,text/plain'), 'html'); }); }); diff --git a/src/vs/editor/test/common/servicesTestUtils.ts b/src/vs/editor/test/common/servicesTestUtils.ts deleted file mode 100644 index abb17d18014..00000000000 --- a/src/vs/editor/test/common/servicesTestUtils.ts +++ /dev/null @@ -1,83 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 {TPromise} from 'vs/base/common/winjs.base'; -import {ConfigurationService, IContent, IStat} from 'vs/platform/configuration/common/configurationService'; -import {EventService} from 'vs/platform/event/common/eventService'; -import {IExtensionService} from 'vs/platform/extensions/common/extensions'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; -import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService'; -import {IModeService} from 'vs/editor/common/services/modeService'; -import {ModeServiceImpl} from 'vs/editor/common/services/modeServiceImpl'; -import {IModelService} from 'vs/editor/common/services/modelService'; -import {ModelServiceImpl} from 'vs/editor/common/services/modelServiceImpl'; -import {MockExtensionService} from 'vs/editor/test/common/mocks/mockExtensionService'; - -class MockModeService extends ModeServiceImpl {} - -class MockModelService extends ModelServiceImpl { } - -export function createMockModeService(): IModeService { - let services = new ServiceCollection(); - let inst = new InstantiationService(services); - - var extensionService = new MockExtensionService(); - services.set(IExtensionService, extensionService); - - var modeService = new MockModeService(inst, extensionService); - services.set(IModeService, modeService); - - return modeService; -} - -export function createMockModelService(): IModelService { - let contextService = new BaseWorkspaceContextService({ - resource: URI.from({ scheme: 'inmemory', authority: 'model', path: '/' }), - id: null, - name: null, - uid: null, - mtime: null - }, {}); - - let eventService = new EventService(); - - let configurationService = new MockConfigurationService(contextService, eventService); - - return new MockModelService(null, configurationService, null); -} - -export class MockConfigurationService extends ConfigurationService { - - protected resolveContents(resources: URI[]): TPromise { - return TPromise.as(resources.map((resource) => { - return { - resource: resource, - value: '' - }; - })); - } - - protected resolveContent(resource: URI): TPromise { - return TPromise.as({ - resource: resource, - value: '' - }); - } - - protected resolveStat(resource: URI): TPromise { - return TPromise.as({ - resource: resource, - isDirectory: false - }); - } - - setUserConfiguration(key: any, value: any) : Thenable { - return TPromise.as(null); - } - -} diff --git a/src/vs/languages/handlebars/common/handlebars.ts b/src/vs/languages/handlebars/common/handlebars.ts index 1f492e16a9b..d076da2395c 100644 --- a/src/vs/languages/handlebars/common/handlebars.ts +++ b/src/vs/languages/handlebars/common/handlebars.ts @@ -26,19 +26,19 @@ export enum States { export class HandlebarsState extends htmlMode.State { constructor(mode:modes.IMode, - public kind:htmlMode.States, + kind:htmlMode.States, public handlebarsKind:States, - public lastTagName:string, - public lastAttributeName:string, - public embeddedContentType:string, - public attributeValueQuote:string, - public attributeValue:string) { + lastTagName:string, + lastAttributeName:string, + embeddedContentType:string, + attributeValueQuote:string, + attributeValueLength:number) { - super(mode, kind, lastTagName, lastAttributeName, embeddedContentType, attributeValueQuote, attributeValue); + super(mode, kind, lastTagName, lastAttributeName, embeddedContentType, attributeValueQuote, attributeValueLength); } public makeClone(): HandlebarsState { - return new HandlebarsState(this.getMode(), this.kind, this.handlebarsKind, this.lastTagName, this.lastAttributeName, this.embeddedContentType, this.attributeValueQuote, this.attributeValue); + return new HandlebarsState(this.getMode(), this.kind, this.handlebarsKind, this.lastTagName, this.lastAttributeName, this.embeddedContentType, this.attributeValueQuote, this.attributeValueLength); } public equals(other:modes.IState):boolean { @@ -186,13 +186,13 @@ export class HandlebarsMode extends htmlMode.HTMLMode { } public getInitialState() : modes.IState { - return new HandlebarsState(this, htmlMode.States.Content, States.HTML, '', '', '', '', ''); + return new HandlebarsState(this, htmlMode.States.Content, States.HTML, '', '', '', '', 0); } public getLeavingNestedModeData(line:string, state:modes.IState):ILeavingNestedModeData { var leavingNestedModeData = super.getLeavingNestedModeData(line, state); if (leavingNestedModeData) { - leavingNestedModeData.stateAfterNestedMode = new HandlebarsState(this, htmlMode.States.Content, States.HTML, '', '', '', '', ''); + leavingNestedModeData.stateAfterNestedMode = new HandlebarsState(this, htmlMode.States.Content, States.HTML, '', '', '', '', 0); } return leavingNestedModeData; } diff --git a/src/vs/languages/html/common/html.ts b/src/vs/languages/html/common/html.ts index e02bcbb8922..99781411389 100644 --- a/src/vs/languages/html/common/html.ts +++ b/src/vs/languages/html/common/html.ts @@ -47,16 +47,16 @@ export class State extends AbstractState { public lastAttributeName:string; public embeddedContentType:string; public attributeValueQuote:string; - public attributeValue:string; + public attributeValueLength:number; - constructor(mode:modes.IMode, kind:States, lastTagName:string, lastAttributeName:string, embeddedContentType:string, attributeValueQuote:string, attributeValue:string) { + constructor(mode:modes.IMode, kind:States, lastTagName:string, lastAttributeName:string, embeddedContentType:string, attributeValueQuote:string, attributeValueLength:number) { super(mode); this.kind = kind; this.lastTagName = lastTagName; this.lastAttributeName = lastAttributeName; this.embeddedContentType = embeddedContentType; this.attributeValueQuote = attributeValueQuote; - this.attributeValue = attributeValue; + this.attributeValueLength = attributeValueLength; } static escapeTagName(s:string):string { @@ -64,7 +64,7 @@ export class State extends AbstractState { } public makeClone():State { - return new State(this.getMode(), this.kind, this.lastTagName, this.lastAttributeName, this.embeddedContentType, this.attributeValueQuote, this.attributeValue); + return new State(this.getMode(), this.kind, this.lastTagName, this.lastAttributeName, this.embeddedContentType, this.attributeValueQuote, this.attributeValueLength); } public equals(other:modes.IState):boolean { @@ -76,7 +76,7 @@ export class State extends AbstractState { this.lastAttributeName === other.lastAttributeName && this.embeddedContentType === other.embeddedContentType && this.attributeValueQuote === other.attributeValueQuote && - this.attributeValue === other.attributeValue + this.attributeValueLength === other.attributeValueLength ); } return false; @@ -223,24 +223,24 @@ export class State extends AbstractState { // We are in a attribute value if (this.attributeValueQuote === '"' || this.attributeValueQuote === '\'') { - if (this.attributeValue === this.attributeValueQuote && ('script' === this.lastTagName || 'style' === this.lastTagName) && 'type' === this.lastAttributeName) { - this.attributeValue = stream.advanceUntilString(this.attributeValueQuote, true); - if (this.attributeValue.length > 0) { - this.embeddedContentType = this.unquote(this.attributeValue); + if (this.attributeValueLength === 1 && ('script' === this.lastTagName || 'style' === this.lastTagName) && 'type' === this.lastAttributeName) { + let attributeValue = stream.advanceUntilString(this.attributeValueQuote, true); + if (attributeValue.length > 0) { + this.embeddedContentType = this.unquote(attributeValue); this.kind = States.WithinTag; - this.attributeValue = ''; + this.attributeValueLength = 0; this.attributeValueQuote = ''; return { type: htmlTokenTypes.ATTRIB_VALUE }; } } else { if (stream.advanceIfCharCode2(this.attributeValueQuote.charCodeAt(0))) { this.kind = States.WithinTag; - this.attributeValue = ''; + this.attributeValueLength = 0; this.attributeValueQuote = ''; this.lastAttributeName = null; } else { - var part = stream.next(); - this.attributeValue += part; + stream.next(); + this.attributeValueLength++; } return { type: htmlTokenTypes.ATTRIB_VALUE }; } @@ -254,7 +254,7 @@ export class State extends AbstractState { var ch = stream.peek(); if (ch === '\'' || ch === '"') { this.attributeValueQuote = ch; - this.attributeValue = ch; + this.attributeValueLength = 1; stream.next2(); return { type: htmlTokenTypes.ATTRIB_VALUE }; } else { @@ -396,7 +396,7 @@ export class HTMLMode extends CompatMode implem // TokenizationSupport public getInitialState():modes.IState { - return new State(this, States.Content, '', '', '', '', ''); + return new State(this, States.Content, '', '', '', '', 0); } public enterNestedMode(state:modes.IState):boolean { @@ -443,7 +443,7 @@ export class HTMLMode extends CompatMode implem return { nestedModeBuffer: line.substring(0, match.index), bufferAfterNestedMode: line.substring(match.index), - stateAfterNestedMode: new State(this, States.Content, '', '', '', '', '') + stateAfterNestedMode: new State(this, States.Content, '', '', '', '', 0) }; } return null; diff --git a/src/vs/languages/razor/common/razor.ts b/src/vs/languages/razor/common/razor.ts index f76931d5c9d..d73a46b8259 100644 --- a/src/vs/languages/razor/common/razor.ts +++ b/src/vs/languages/razor/common/razor.ts @@ -22,12 +22,12 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; class RAZORState extends htmlMode.State { - constructor(mode:modes.IMode, kind:htmlMode.States, lastTagName:string, lastAttributeName:string, embeddedContentType:string, attributeValueQuote:string, attributeValue:string) { - super(mode, kind, lastTagName, lastAttributeName, embeddedContentType, attributeValueQuote, attributeValue); + constructor(mode:modes.IMode, kind:htmlMode.States, lastTagName:string, lastAttributeName:string, embeddedContentType:string, attributeValueQuote:string, attributeValueLength:number) { + super(mode, kind, lastTagName, lastAttributeName, embeddedContentType, attributeValueQuote, attributeValueLength); } public makeClone():RAZORState { - return new RAZORState(this.getMode(), this.kind, this.lastTagName, this.lastAttributeName, this.embeddedContentType, this.attributeValueQuote, this.attributeValue); + return new RAZORState(this.getMode(), this.kind, this.lastTagName, this.lastAttributeName, this.embeddedContentType, this.attributeValueQuote, this.attributeValueLength); } public equals(other:modes.IState):boolean { @@ -138,13 +138,13 @@ export class RAZORMode extends htmlMode.HTMLMode { } public getInitialState(): modes.IState { - return new RAZORState(this, htmlMode.States.Content, '', '', '', '', ''); + return new RAZORState(this, htmlMode.States.Content, '', '', '', '', 0); } public getLeavingNestedModeData(line:string, state:modes.IState): ILeavingNestedModeData { var leavingNestedModeData = super.getLeavingNestedModeData(line, state); if (leavingNestedModeData) { - leavingNestedModeData.stateAfterNestedMode = new RAZORState(this, htmlMode.States.Content, '', '', '', '', ''); + leavingNestedModeData.stateAfterNestedMode = new RAZORState(this, htmlMode.States.Content, '', '', '', '', 0); } return leavingNestedModeData; } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 63d3a17915d..ae89ed9f851 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2796,17 +2796,6 @@ declare module monaco.editor { * A set of enablement conditions. */ enablement?: IActionEnablement; - /** - * Control if the action should show up in the context menu and where. - * Built-in groups: - * 1_goto/* => e.g. 1_goto/1_peekDefinition - * 2_change/* => e.g. 2_change/2_format - * 3_edit/* => e.g. 3_edit/1_copy - * 4_tools/* => e.g. 4_tools/1_commands - * You can also create your own group. - * Defaults to null (don't show in context menu). - */ - contextMenuGroupId?: string; /** * Method that will be executed when the action is triggered. * @param editor The editor instance is passed in as a convinience diff --git a/src/vs/platform/actions/browser/menuService.ts b/src/vs/platform/actions/browser/menuService.ts index d473249eb8e..02886c47469 100644 --- a/src/vs/platform/actions/browser/menuService.ts +++ b/src/vs/platform/actions/browser/menuService.ts @@ -11,49 +11,11 @@ import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {IAction} from 'vs/base/common/actions'; import {values} from 'vs/base/common/collections'; import {KbExpr, IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; -import {MenuId, ICommandAction, MenuItemAction, IMenu, IMenuItem, IMenuService} from 'vs/platform/actions/common/actions'; +import {MenuId, MenuRegistry, ICommandAction, MenuItemAction, IMenu, IMenuItem, IMenuService} from 'vs/platform/actions/common/actions'; import {IExtensionService} from 'vs/platform/extensions/common/extensions'; import {ICommandService} from 'vs/platform/commands/common/commands'; import {ResourceContextKey} from 'vs/platform/actions/common/resourceContextKey'; - -export interface IMenuRegistry { - addCommand(userCommand: ICommandAction): boolean; - getCommand(id: string): ICommandAction; - appendMenuItem(menu: MenuId, item: IMenuItem): void; -} - -const _registry = new class { - - commands: { [id: string]: ICommandAction } = Object.create(null); - - menuItems: { [loc: number]: IMenuItem[] } = Object.create(null); - - addCommand(command: ICommandAction): boolean { - const old = this.commands[command.id]; - this.commands[command.id] = command; - return old !== void 0; - } - - getCommand(id: string): ICommandAction { - return this.commands[id]; - } - - appendMenuItem(loc: MenuId, items: IMenuItem): void { - let array = this.menuItems[loc]; - if (!array) { - this.menuItems[loc] = [items]; - } else { - array.push(items); - } - } - getMenuItems(loc: MenuId): IMenuItem[] { - return this.menuItems[loc] || []; - } -}; - -export const MenuRegistry: IMenuRegistry = _registry; - export class MenuService implements IMenuService { _serviceBrand: any; @@ -70,7 +32,7 @@ export class MenuService implements IMenuService { } getCommandActions(): ICommandAction[] { - return values(_registry.commands); + return values(MenuRegistry.commands); } } @@ -90,7 +52,7 @@ class Menu implements IMenu { ) { this._extensionService.onReady().then(_ => { - const menuItems = _registry.getMenuItems(id); + const menuItems = MenuRegistry.getMenuItems(id); const keysFilter: { [key: string]: boolean } = Object.create(null); let group: MenuItemGroup; @@ -98,7 +60,7 @@ class Menu implements IMenu { for (let item of menuItems) { // group by groupId - const groupName = Menu._group(item.group); + const groupName = item.group; if (!group || group[0] !== groupName) { group = [groupName, []]; this._menuGroups.push(group); @@ -143,7 +105,7 @@ class Menu implements IMenu { activeActions.push(action); } } - if (actions.length > 0) { + if (activeActions.length > 0) { result.push([id, activeActions]); } } @@ -159,27 +121,41 @@ class Menu implements IMenu { } private static _compareMenuItems(a: IMenuItem, b: IMenuItem): number { - if (a.group === b.group) { - return a.command.title.localeCompare(b.command.title); - } else if (!a.group) { + + let aGroup = a.group; + let bGroup = b.group; + + // Falsy groups come last + if (!aGroup && bGroup) { return 1; - } else if (!b.group) { + } else if (aGroup && !bGroup) { return -1; - } else { - return Menu._compareGroupId(a.group, b.group); } - } - private static _compareGroupId(a: string, b: string): number { - const a_order = Number(a.substr(a.lastIndexOf('@') + 1)) || 0; - const b_order = Number(b.substr(b.lastIndexOf('@') + 1)) || 0; - if (a_order !== b_order) { - return a_order < b_order ? -1 : 1; + // 'navigation' group comes first + if (aGroup === 'navigation') { + return -1; + } else if (bGroup === 'navigation') { + return 1; } - return a.localeCompare(b); - } - private static _group(a: string): string { - return a && (a.substr(0, a.lastIndexOf('@')) || a); + // lexical sort for groups + if (aGroup < bGroup) { + return -1; + } else if(aGroup > bGroup) { + return 1; + } + + // sort on priority - default is 0 + let aPrio = a.order || 0; + let bPrio = b.order || 0; + if (aPrio < bPrio) { + return -1; + } else if (aPrio > bPrio) { + return 1; + } + + // sort on titles + return a.command.title.localeCompare(b.command.title); } } \ No newline at end of file diff --git a/src/vs/platform/actions/browser/menusExtensionPoint.ts b/src/vs/platform/actions/browser/menusExtensionPoint.ts index 7c7b7abc052..6057a293b49 100644 --- a/src/vs/platform/actions/browser/menusExtensionPoint.ts +++ b/src/vs/platform/actions/browser/menusExtensionPoint.ts @@ -11,9 +11,8 @@ import {IdGenerator} from 'vs/base/common/idGenerator'; import {IJSONSchema} from 'vs/base/common/jsonSchema'; import {forEach} from 'vs/base/common/collections'; import {IExtensionPointUser, IExtensionMessageCollector, ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegistry'; -import {MenuRegistry} from './menuService'; import {KbExpr} from 'vs/platform/keybinding/common/keybinding'; -import {MenuId} from 'vs/platform/actions/common/actions'; +import {MenuId, MenuRegistry} from 'vs/platform/actions/common/actions'; namespace schema { @@ -278,10 +277,23 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyM collector.info(localize('nosupport.altCommand', "Sorry, but currently only the 'navigation' group of the 'editor/title' menu supports alt-commands")); } + let group: string; + let order: number; + if (item.group) { + const idx = item.group.lastIndexOf('@'); + if (idx > 0) { + group = item.group.substr(0, idx); + order = Number(item.group.substr(idx + 1)) || undefined; + } else { + group = item.group; + } + } + MenuRegistry.appendMenuItem(menu, { command, alt, - group: item.group || undefined, + group, + order, when: KbExpr.deserialize(item.when) }); } diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index c56e7bdfe06..896bf564211 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -31,7 +31,8 @@ export interface IMenuItem { command: ICommandAction; alt?: ICommandAction; when?: KbExpr; - group?: string; + group?: 'navigation' | string; + order?: number; } export enum MenuId { @@ -51,6 +52,45 @@ export interface IMenuService { getCommandActions(): ICommandAction[]; } +export interface IMenuRegistry { + commands: { [id: string]: ICommandAction }; + addCommand(userCommand: ICommandAction): boolean; + getCommand(id: string): ICommandAction; + appendMenuItem(menu: MenuId, item: IMenuItem): void; + getMenuItems(loc: MenuId): IMenuItem[]; +} + +export const MenuRegistry: IMenuRegistry = new class { + + commands: { [id: string]: ICommandAction } = Object.create(null); + + menuItems: { [loc: number]: IMenuItem[] } = Object.create(null); + + addCommand(command: ICommandAction): boolean { + const old = this.commands[command.id]; + this.commands[command.id] = command; + return old !== void 0; + } + + getCommand(id: string): ICommandAction { + return this.commands[id]; + } + + appendMenuItem(loc: MenuId, items: IMenuItem): void { + let array = this.menuItems[loc]; + if (!array) { + this.menuItems[loc] = [items]; + } else { + array.push(items); + } + } + + getMenuItems(loc: MenuId): IMenuItem[] { + return this.menuItems[loc] || []; + } +}; + + export class MenuItemAction extends Actions.Action { private static _getMenuItemId(item: IMenuItem): string { diff --git a/src/vs/platform/actions/test/common/actions.test.ts b/src/vs/platform/actions/test/common/actions.test.ts index ac46922480a..3940812cfb3 100644 --- a/src/vs/platform/actions/test/common/actions.test.ts +++ b/src/vs/platform/actions/test/common/actions.test.ts @@ -6,11 +6,10 @@ import assert = require('assert'); import WinJS = require('vs/base/common/winjs.base'); +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {DeferredAction} from 'vs/platform/actions/common/actions'; import Actions = require('vs/base/common/actions'); import EventEmitter = require('vs/base/common/eventEmitter'); -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; import {AsyncDescriptor} from 'vs/platform/instantiation/common/descriptors'; import {IEventService} from 'vs/platform/event/common/event'; @@ -36,10 +35,11 @@ class TestEventService extends EventEmitter.EventEmitter { } suite('Platform actions', () => { + test('DeferredAction', (done) => { - let services = new ServiceCollection([IEventService, {}]); - let instantiationService = new InstantiationService(services); + let instantiationService: TestInstantiationService= new TestInstantiationService(); + instantiationService.stub(IEventService); let action = new DeferredAction( instantiationService, diff --git a/src/vs/platform/commands/common/commandService.ts b/src/vs/platform/commands/common/commandService.ts index d8cf7ea4df7..b6f0f43df9a 100644 --- a/src/vs/platform/commands/common/commandService.ts +++ b/src/vs/platform/commands/common/commandService.ts @@ -37,14 +37,4 @@ export class CommandService implements ICommandService { } }); } - - isKnownCommand(commandId: string): boolean { - const command = CommandsRegistry.getCommand(commandId); - - if (!command) { - return false; - } - - return true; - } } diff --git a/src/vs/platform/commands/common/commands.ts b/src/vs/platform/commands/common/commands.ts index 4e91a8a59a7..018ef9bb688 100644 --- a/src/vs/platform/commands/common/commands.ts +++ b/src/vs/platform/commands/common/commands.ts @@ -14,7 +14,6 @@ export interface ICommandService { _serviceBrand: any; executeCommand(commandId: string, ...args: any[]): TPromise; executeCommand(commandId: string, ...args: any[]): TPromise; - isKnownCommand(commandId: string): boolean; } export interface ICommandsMap { @@ -100,8 +99,5 @@ export const NullCommandService: ICommandService = { _serviceBrand: undefined, executeCommand() { return TPromise.as(undefined); - }, - isKnownCommand() { - return false; } }; \ No newline at end of file diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 8855776d914..b0f02a8a3f7 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { TPromise } from 'vs/base/common/winjs.base'; export const IEnvironmentService = createDecorator('environmentService'); @@ -11,8 +12,11 @@ export interface IEnvironmentService { _serviceBrand: any; appRoot: string; + userHome: string; userDataPath: string; extensionsPath: string; extensionDevelopmentPath: string; isBuilt: boolean; + + createPaths(): TPromise; } diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index f0c7100c607..d61457ec57f 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -9,8 +9,10 @@ import product from 'vs/platform/product'; import pkg from 'vs/platform/package'; import * as os from 'os'; import * as path from 'path'; +import { mkdirp } from 'vs/base/node/pfs'; import { parseArgs } from 'vs/code/node/argv'; import URI from 'vs/base/common/uri'; +import { TPromise } from 'vs/base/common/winjs.base'; export class EnvironmentService implements IEnvironmentService { @@ -19,6 +21,9 @@ export class EnvironmentService implements IEnvironmentService { private _appRoot: string; get appRoot(): string { return this._appRoot; } + private _userHome: string; + get userHome(): string { return this._userHome; } + private _userDataPath: string; get userDataPath(): string { return this._userDataPath; } @@ -36,10 +41,17 @@ export class EnvironmentService implements IEnvironmentService { this._appRoot = path.dirname(URI.parse(require.toUrl('')).fsPath); this._userDataPath = paths.getUserDataPath(process.platform, pkg.name, process.argv); - const userHome = path.join(os.homedir(), product.dataFolderName); - this._extensionsPath = argv.extensionHomePath || path.join(userHome, 'extensions'); + this._userHome = path.join(os.homedir(), product.dataFolderName); + this._extensionsPath = argv.extensionHomePath || path.join(this._userHome, 'extensions'); this._extensionsPath = path.normalize(this._extensionsPath); this._extensionDevelopmentPath = argv.extensionDevelopmentPath; } + + createPaths(): TPromise { + const promises = [this.userHome, this.extensionsPath] + .map(p => mkdirp(p)); + + return TPromise.join(promises) as TPromise; + } } \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 62bf1e0dad7..0cc83941f44 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -21,7 +21,7 @@ import { getProxyAgent } from 'vs/base/node/proxy'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Limiter } from 'vs/base/common/async'; import Event, { Emitter } from 'vs/base/common/event'; -import { UserSettings } from 'vs/workbench/node/userSettings'; +import { UserSettings } from 'vs/base/node/userSettings'; import * as semver from 'semver'; import { groupBy, values } from 'vs/base/common/collections'; import { isValidExtensionVersion } from 'vs/platform/extensions/node/extensionValidator'; diff --git a/src/vs/platform/search/common/replace.ts b/src/vs/platform/search/common/replace.ts new file mode 100644 index 00000000000..3ca69b60ef8 --- /dev/null +++ b/src/vs/platform/search/common/replace.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * 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 {IPatternInfo} from 'vs/platform/search/common/search'; + +const BACKSLASH_CHAR_CODE = '\\'.charCodeAt(0); +const DOLLAR_CHAR_CODE = '$'.charCodeAt(0); +const ZERO_CHAR_CODE = '0'.charCodeAt(0); +const ONE_CHAR_CODE = '1'.charCodeAt(0); +const NINE_CHAR_CODE = '9'.charCodeAt(0); +const BACK_TICK_CHAR_CODE = '`'.charCodeAt(0); +const SINGLE_QUOTE_CHAR_CODE = '`'.charCodeAt(0); +const n_CHAR_CODE = 'n'.charCodeAt(0); +const t_CHAR_CODE = 't'.charCodeAt(0); + +export class ReplacePattern { + + private _replacePattern: string; + private _searchRegExp: RegExp; + private _hasParameters: boolean= false; + + constructor(private replaceString: string, private searchPatternInfo: IPatternInfo) { + this._replacePattern= replaceString; + if (searchPatternInfo.isRegExp) { + this._searchRegExp= strings.createRegExp(searchPatternInfo.pattern, searchPatternInfo.isRegExp, searchPatternInfo.isCaseSensitive, searchPatternInfo.isWordMatch, true); + this.parseReplaceString(replaceString); + } + } + + public get hasParameters(): boolean { + return this._hasParameters; + } + + public get pattern(): string { + return this._replacePattern; + } + + public getReplaceString(matchedString: string): string { + if (this.hasParameters) { + return matchedString.replace(this._searchRegExp, this.pattern); + } + return this.pattern; + } + + /** + * \n => LF + * \t => TAB + * \\ => \ + * $0 => $& (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter) + * everything else stays untouched + */ + private parseReplaceString(replaceString: string): void { + if (!replaceString || replaceString.length === 0) { + return; + } + + let substrFrom = 0, result = ''; + for (let i = 0, len = replaceString.length; i < len; i++) { + let chCode = replaceString.charCodeAt(i); + + if (chCode === BACKSLASH_CHAR_CODE) { + + // move to next char + i++; + + if (i >= len) { + // string ends with a \ + break; + } + + let nextChCode = replaceString.charCodeAt(i); + let replaceWithCharacter: string = null; + + switch (nextChCode) { + case BACKSLASH_CHAR_CODE: + // \\ => \ + replaceWithCharacter = '\\'; + break; + case n_CHAR_CODE: + // \n => LF + replaceWithCharacter = '\n'; + break; + case t_CHAR_CODE: + // \t => TAB + replaceWithCharacter = '\t'; + break; + } + + if (replaceWithCharacter) { + result += replaceString.substring(substrFrom, i - 1) + replaceWithCharacter; + substrFrom = i + 1; + } + } + + if (chCode === DOLLAR_CHAR_CODE) { + + // move to next char + i++; + + if (i >= len) { + // string ends with a $ + break; + } + + let nextChCode = replaceString.charCodeAt(i); + let replaceWithCharacter: string = null; + + switch (nextChCode) { + case ZERO_CHAR_CODE: + // $0 => $& + replaceWithCharacter = '$&'; + this._hasParameters = true; + break; + case BACK_TICK_CHAR_CODE: + case SINGLE_QUOTE_CHAR_CODE: + this._hasParameters = true; + break; + default: + // check if it is a valid string parameter $n (0 <= n <= 99). $0 is already handled by now. + if (!this.between(nextChCode, ONE_CHAR_CODE, NINE_CHAR_CODE)) { + break; + } + if (i === replaceString.length - 1) { + this._hasParameters = true; + break; + } + let charCode= replaceString.charCodeAt(++i); + if (!this.between(charCode, ZERO_CHAR_CODE, NINE_CHAR_CODE)) { + this._hasParameters = true; + --i; + break; + } + if (i === replaceString.length - 1) { + this._hasParameters = true; + break; + } + charCode= replaceString.charCodeAt(++i); + if (!this.between(charCode, ZERO_CHAR_CODE, NINE_CHAR_CODE)) { + this._hasParameters = true; + --i; + break; + } + break; + } + + if (replaceWithCharacter) { + result += replaceString.substring(substrFrom, i - 1) + replaceWithCharacter; + substrFrom = i + 1; + } + } + } + + if (substrFrom === 0) { + // no replacement occured + return; + } + + this._replacePattern= result + replaceString.substring(substrFrom); + } + + private between(value: number, from: number, to: number): boolean { + return from <= value && value <= to; + } +} + diff --git a/src/vs/platform/search/test/common/replace.test.ts b/src/vs/platform/search/test/common/replace.test.ts new file mode 100644 index 00000000000..e2b574e91e3 --- /dev/null +++ b/src/vs/platform/search/test/common/replace.test.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 assert from 'assert'; +import { ReplacePattern } from 'vs/platform/search/common/replace'; + +suite('Replace Pattern test', () => { + + test('parse replace string', () => { + let testParse = (input:string, expected:string, expectedHasParameters:boolean) => { + let actual = new ReplacePattern(input, {pattern: 'somepattern', isRegExp: true}); + assert.equal(expected, actual.pattern); + assert.equal(expectedHasParameters, actual.hasParameters); + + actual= new ReplacePattern('hello' + input + 'hi', {pattern: 'sonepattern', isRegExp: true}); + assert.equal('hello' + expected + 'hi', actual.pattern); + assert.equal(expectedHasParameters, actual.hasParameters); + }; + + // no backslash => no treatment + testParse('hello', 'hello', false); + + // \t => TAB + testParse('\\thello', '\thello', false); + + // \n => LF + testParse('\\nhello', '\nhello', false); + + // \\t => \t + testParse('\\\\thello', '\\thello', false); + + // \\\t => \TAB + testParse('\\\\\\thello', '\\\thello', false); + + // \\\\t => \\t + testParse('\\\\\\\\thello', '\\\\thello', false); + + // \ at the end => no treatment + testParse('hello\\', 'hello\\', false); + + // \ with unknown char => no treatment + testParse('hello\\x', 'hello\\x', false); + + // \ with back reference => no treatment + testParse('hello\\0', 'hello\\0', false); + + + + // $1 => no treatment + testParse('hello$1', 'hello$1', true); + // $2 => no treatment + testParse('hello$2', 'hello$2', true); + // $12 => no treatment + testParse('hello$12', 'hello$12', true); + // $99 => no treatment + testParse('hello$99', 'hello$99', true); + // $99a => no treatment + testParse('hello$99a', 'hello$99a', true); + // $100 => no treatment + testParse('hello$100', 'hello$100', false); + // $100a => no treatment + testParse('hello$100a', 'hello$100a', false); + // $10a0 => no treatment + testParse('hello$10a0', 'hello$10a0', true); + // $$ => no treatment + testParse('hello$$', 'hello$$', false); + // $$0 => no treatment + testParse('hello$$0', 'hello$$0', false); + + // $0 => $& + testParse('hello$0', 'hello$&', true); + testParse('hello$02', 'hello$&2', true); + }); + + test('get replace string for a matched string', () => { + let testObject= new ReplacePattern('hello', {pattern: 'bla', isRegExp: true}); + let actual= testObject.getReplaceString('bla'); + assert.equal('hello', actual); + + testObject= new ReplacePattern('hello', {pattern: 'bla', isRegExp: false}); + actual= testObject.getReplaceString('bla'); + assert.equal('hello', actual); + + testObject= new ReplacePattern('hello', {pattern: '(bla)', isRegExp: true}); + actual= testObject.getReplaceString('bla'); + assert.equal('hello', actual); + + testObject= new ReplacePattern('hello$0', {pattern: '(bla)', isRegExp: true}); + actual= testObject.getReplaceString('bla'); + assert.equal('hellobla', actual); + + testObject= new ReplacePattern('import * as $1 from \'$2\';', {pattern: 'let\\s+(\\w+)\\s*=\\s*require\\s*\\(\\s*[\'\"]([\\w\.\\-/]+)\\s*[\'\"]\\s*\\)\\s*', isRegExp: true}); + actual= testObject.getReplaceString('let fs = require(\'fs\')'); + assert.equal('import * as fs from \'fs\';', actual); + + actual= testObject.getReplaceString('let something = require(\'fs\')'); + assert.equal('import * as something from \'fs\';', actual); + + actual= testObject.getReplaceString('let require(\'fs\')'); + assert.equal('let require(\'fs\')', actual); + + testObject= new ReplacePattern('import * as $1 from \'$1\';', {pattern: 'let\\s+(\\w+)\\s*=\\s*require\\s*\\(\\s*[\'\"]([\\w\.\\-/]+)\\s*[\'\"]\\s*\\)\\s*', isRegExp: true}); + actual= testObject.getReplaceString('let something = require(\'fs\')'); + assert.equal('import * as something from \'something\';', actual); + + testObject= new ReplacePattern('import * as $2 from \'$1\';', {pattern: 'let\\s+(\\w+)\\s*=\\s*require\\s*\\(\\s*[\'\"]([\\w\.\\-/]+)\\s*[\'\"]\\s*\\)\\s*', isRegExp: true}); + actual= testObject.getReplaceString('let something = require(\'fs\')'); + assert.equal('import * as fs from \'something\';', actual); + + testObject= new ReplacePattern('import * as $0 from \'$0\';', {pattern: 'let\\s+(\\w+)\\s*=\\s*require\\s*\\(\\s*[\'\"]([\\w\.\\-/]+)\\s*[\'\"]\\s*\\)\\s*', isRegExp: true}); + actual= testObject.getReplaceString('let something = require(\'fs\');'); + assert.equal('import * as let something = require(\'fs\') from \'let something = require(\'fs\')\';;', actual); + + testObject= new ReplacePattern('import * as $1 from \'$2\';', {pattern: 'let\\s+(\\w+)\\s*=\\s*require\\s*\\(\\s*[\'\"]([\\w\.\\-/]+)\\s*[\'\"]\\s*\\)\\s*', isRegExp: false}); + actual= testObject.getReplaceString('let fs = require(\'fs\');'); + assert.equal('import * as $1 from \'$2\';', actual); + + testObject= new ReplacePattern('cat$1', {pattern: 'for(.*)', isRegExp: true}); + actual= testObject.getReplaceString('for ()'); + assert.equal('cat ()', actual); + + // Not maching cases + testObject= new ReplacePattern('hello', {pattern: 'bla', isRegExp: true}); + actual= testObject.getReplaceString('foo'); + assert.equal('hello', actual); + + testObject= new ReplacePattern('hello', {pattern: 'bla', isRegExp: false}); + actual= testObject.getReplaceString('foo'); + assert.equal('hello', actual); + }); +}); \ No newline at end of file diff --git a/src/vs/platform/telemetry/test/node/commonProperties.test.ts b/src/vs/platform/telemetry/test/node/commonProperties.test.ts index 9e02b7d0d19..c014a8d9b81 100644 --- a/src/vs/platform/telemetry/test/node/commonProperties.test.ts +++ b/src/vs/platform/telemetry/test/node/commonProperties.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import {TPromise} from 'vs/base/common/winjs.base'; import {resolveWorkbenchCommonProperties} from 'vs/platform/telemetry/node/workbenchCommonProperties'; -import {TestStorageService, TestContextService} from 'vs/workbench/test/common/servicesTestUtils'; +import {TestStorageService, TestContextService} from 'vs/test/utils/servicesTestUtils'; suite('Telemetry - common properties', function () { diff --git a/src/vs/platform/telemetry/test/node/sinon.d.ts b/src/vs/platform/telemetry/test/node/sinon.d.ts deleted file mode 100644 index ebe5282512d..00000000000 --- a/src/vs/platform/telemetry/test/node/sinon.d.ts +++ /dev/null @@ -1,375 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -// Type definitions for Sinon 1.5 -// Project: http://sinonjs.org/ -// Definitions by: William Sears -// DefinitelyTyped: https://github.com/borisyankov/DefinitelyTyped -// Minor change to export interfaces - -declare module Sinon { - export interface SinonSpyCallApi { - // Properties - thisValue: any; - args: any[]; - exception: any; - returnValue: any; - - // Methods - calledOn(obj: any): boolean; - calledWith(...args: any[]): boolean; - calledWithExactly(...args: any[]): boolean; - calledWithMatch(...args: SinonMatcher[]): boolean; - notCalledWith(...args: any[]): boolean; - notCalledWithMatch(...args: SinonMatcher[]): boolean; - returned(value: any): boolean; - threw(): boolean; - threw(type: string): boolean; - threw(obj: any): boolean; - callArg(pos: number): void; - callArgOn(pos: number, obj: any, ...args: any[]): void; - callArgWith(pos: number, ...args: any[]): void; - callArgOnWith(pos: number, obj: any, ...args: any[]): void; - yield(...args: any[]): void; - yieldOn(obj: any, ...args: any[]): void; - yieldTo(property: string, ...args: any[]): void; - yieldToOn(property: string, obj: any, ...args: any[]): void; - } - - export interface SinonSpyCall extends SinonSpyCallApi { - calledBefore(call: SinonSpyCall): boolean; - calledAfter(call: SinonSpyCall): boolean; - calledWithNew(call: SinonSpyCall): boolean; - } - - export interface SinonSpy extends SinonSpyCallApi { - // Properties - callCount: number; - called: boolean; - notCalled: boolean; - calledOnce: boolean; - calledTwice: boolean; - calledThrice: boolean; - firstCall: SinonSpyCall; - secondCall: SinonSpyCall; - thirdCall: SinonSpyCall; - lastCall: SinonSpyCall; - thisValues: any[]; - args: any[][]; - exceptions: any[]; - returnValues: any[]; - - // Methods - (...args: any[]): any; - calledBefore(anotherSpy: SinonSpy): boolean; - calledAfter(anotherSpy: SinonSpy): boolean; - calledWithNew(spy: SinonSpy): boolean; - withArgs(...args: any[]): void; - alwaysCalledOn(obj: any); - alwaysCalledWith(...args: any[]); - alwaysCalledWithExactly(...args: any[]); - alwaysCalledWithMatch(...args: SinonMatcher[]); - neverCalledWith(...args: any[]); - neverCalledWithMatch(...args: SinonMatcher[]); - alwaysThrew(): boolean; - alwaysThrew(type: string); - alwaysThrew(obj: any); - alwaysReturned(): boolean; - invokeCallback(...args: any[]): void; - getCall(n: number): SinonSpyCall; - reset(): void; - printf(format: string, ...args: any[]); - restore(): void; - } - - export interface SinonSpyStatic { - (): SinonSpy; - (func: any): SinonSpy; - (obj: any, method: string): SinonSpy; - } - - export var spy: SinonSpyStatic; - - export interface SinonStub extends SinonSpy { - resetBehavior(): void; - returns(obj: any): SinonStub; - returnsArg(index: number): SinonStub; - throws(type?: string): SinonStub; - throws(obj: any): SinonStub; - callsArg(index: number): SinonStub; - callsArgOn(index: number, context: any): SinonStub; - callsArgWith(index: number, ...args: any[]): SinonStub; - callsArgOnWith(index: number, context: any, ...args: any[]): SinonStub; - callsArgAsync(index: number): SinonStub; - callsArgOnAsync(index: number, context: any): SinonStub; - callsArgWithAsync(index: number, ...args: any[]): SinonStub; - callsArgOnWithAsync(index: number, context: any, ...args: any[]): SinonStub; - yields(...args: any[]): SinonStub; - yieldsOn(context: any, ...args: any[]): SinonStub; - yieldsTo(property: string, ...args: any[]): SinonStub; - yieldsToOn(property: string, context: any, ...args: any[]): SinonStub; - yieldsAsync(...args: any[]): SinonStub; - yieldsOnAsync(context: any, ...args: any[]): SinonStub; - yieldsToAsync(property: string, ...args: any[]): SinonStub; - yieldsToOnAsync(property: string, context: any, ...args: any[]): SinonStub; - } - - export interface SinonStubStatic { - (): SinonStub; - (obj: any): SinonStub; - (obj: any, method: string): SinonStub; - (obj: any, method: string, func: any): SinonStub; - } - - export var stub: SinonStubStatic; - - export interface SinonExpectation { - atLeast(n: number): SinonExpectation; - atMost(n: number): SinonExpectation; - never(): SinonExpectation; - once(): SinonExpectation; - twice(): SinonExpectation; - thrice(): SinonExpectation; - exactly(n: number): SinonExpectation; - withArgs(...args: any[]): SinonExpectation; - withExactArgs(...args: any[]): SinonExpectation; - on(obj: any): SinonExpectation; - verify(): SinonExpectation; - restore(): void; - } - - export interface SinonExpectationStatic { - create(methodName?: string): SinonExpectation; - } - - export interface SinonMock { - expects(method: string): SinonExpectationStatic; - restore(): void; - verify(): void; - } - - export interface SinonMockStatic { - (): SinonExpectation; - (obj: any): SinonMock; - } - - export var expectation: SinonExpectationStatic; - export var mock: SinonMockStatic; - - export interface SinonFakeTimers { - now: number; - create(now: number): SinonFakeTimers; - setTimeout(callback: (...args: any[]) => void , timeout: number, ...args: any[]): number; - clearTimeout(id: number): void; - setInterval(callback: (...args: any[]) => void , timeout: number, ...args: any[]): number; - clearInterval(id: number): void; - tick(ms: number): number; - reset(): void; - Date(): Date; - Date(year: number): Date; - Date(year: number, month: number): Date; - Date(year: number, month: number, day: number): Date; - Date(year: number, month: number, day: number, hour: number): Date; - Date(year: number, month: number, day: number, hour: number, minute: number): Date; - Date(year: number, month: number, day: number, hour: number, minute: number, second: number): Date; - Date(year: number, month: number, day: number, hour: number, minute: number, second: number, ms: number): Date; - restore(): void; - } - - export interface SinonFakeTimersStatic { - (): SinonFakeTimers; - (...timers: string[]): SinonFakeTimers; - (now: number, ...timers: string[]): SinonFakeTimers; - } - - export var useFakeTimers: SinonFakeTimersStatic; - export var clock: SinonFakeTimers; - - export interface SinonFakeXMLHttpRequest { - // Properties - onCreate: (xhr: SinonFakeXMLHttpRequest) => void; - url: string; - method: string; - requestHeaders: any; - requestBody: string; - status: number; - statusText: string; - async: boolean; - username: string; - password: string; - responseXML: Document; - getResponseHeader(header: string): string; - getAllResponseHeaders(): any; - - // Methods - restore(): void; - useFilters: boolean; - addFilter(filter: (method, url, async, username, password) => boolean): void; - setResponseHeaders(headers: any): void; - setResponseBody(body: string): void; - respond(status: number, headers: any, body: string): void; - autoRespond(ms: number): void; - } - - export interface SinonFakeXMLHttpRequestStatic { - (): SinonFakeXMLHttpRequest; - } - - export var useFakeXMLHttpRequest: SinonFakeXMLHttpRequestStatic; - export var FakeXMLHttpRequest: SinonFakeXMLHttpRequest; - - export interface SinonFakeServer { - // Properties - autoRespond: boolean; - autoRespondAfter: number; - fakeHTTPMethods: boolean; - getHTTPMethod: (request: SinonFakeXMLHttpRequest) => string; - - // Methods - respondWith(body: string): void; - respondWith(response: any[]): void; - respondWith(fn: (SinonFakeXMLHttpRequest) => void ): void; - respondWith(url: string, body: string): void; - respondWith(url: string, response: any[]): void; - respondWith(url: string, fn: (SinonFakeXMLHttpRequest) => void ): void; - respondWith(method: string, url: string, body: string): void; - respondWith(method: string, url: string, response: any[]): void; - respondWith(method: string, url: string, fn: (SinonFakeXMLHttpRequest) => void ): void; - respondWith(url: RegExp, body: string): void; - respondWith(url: RegExp, response: any[]): void; - respondWith(url: RegExp, fn: (SinonFakeXMLHttpRequest) => void ): void; - respondWith(method: string, url: RegExp, body: string): void; - respondWith(method: string, url: RegExp, response: any[]): void; - respondWith(method: string, url: RegExp, fn: (SinonFakeXMLHttpRequest) => void ): void; - respond(): void; - restore(): void; - } - - export interface SinonFakeServerStatic { - create(): SinonFakeServer; - } - - export var fakeServer: SinonFakeServerStatic; - export var fakeServerWithClock: SinonFakeServerStatic; - - export interface SinonExposeOptions { - prefix?: string; - includeFail?: boolean; - } - - export interface SinonAssert { - // Properties - failException: string; - fail: (message?: string) => void; // Overridable - pass: (assertion: any) => void; // Overridable - - // Methods - notCalled(spy: SinonSpy): void; - called(spy: SinonSpy): void; - calledOnce(spy: SinonSpy): void; - calledTwice(spy: SinonSpy): void; - calledThrice(spy: SinonSpy): void; - callCount(spy: SinonSpy, count: number): void; - callOrder(...spies: SinonSpy[]): void; - calledOn(spy: SinonSpy, obj: any): void; - alwaysCalledOn(spy: SinonSpy, obj: any): void; - calledWith(spy: SinonSpy, ...args: any[]): void; - alwaysCalledWith(spy: SinonSpy, ...args: any[]): void; - neverCalledWith(spy: SinonSpy, ...args: any[]): void; - calledWithExactly(spy: SinonSpy, ...args: any[]): void; - alwaysCalledWithExactly(spy: SinonSpy, ...args: any[]): void; - calledWithMatch(spy: SinonSpy, ...args: SinonMatcher[]): void; - alwaysCalledWithMatch(spy: SinonSpy, ...args: SinonMatcher[]): void; - neverCalledWithMatch(spy: SinonSpy, ...args: SinonMatcher[]): void; - threw(spy: SinonSpy): void; - threw(spy: SinonSpy, exception: string): void; - threw(spy: SinonSpy, exception: any): void; - alwaysThrew(spy: SinonSpy): void; - alwaysThrew(spy: SinonSpy, exception: string): void; - alwaysThrew(spy: SinonSpy, exception: any): void; - expose(obj: any, options?: SinonExposeOptions): void; - } - - export var assert: SinonAssert; - - export interface SinonMatcher { - and(expr: SinonMatch): SinonMatcher; - or(expr: SinonMatch): SinonMatcher; - } - - export interface SinonMatch { - (value: number): SinonMatcher; - (value: string): SinonMatcher; - (expr: RegExp): SinonMatcher; - (obj: any): SinonMatcher; - (callback: (value: any) => boolean): SinonMatcher; - any: SinonMatcher; - defined: SinonMatcher; - truthy: SinonMatcher; - falsy: SinonMatcher; - boolean: SinonMatcher; - number: SinonMatcher; - string: SinonMatcher; - object: SinonMatcher; - func: SinonMatcher; - array: SinonMatcher; - regexp: SinonMatcher; - date: SinonMatcher; - same(obj: any): SinonMatcher; - typeOf(type: string): SinonMatcher; - instanceOf(type: any): SinonMatcher; - has(property: string, expect?: any): SinonMatcher; - hasOwn(property: string, expect?: any): SinonMatcher; - } - - export var match: SinonMatch; - - export interface SinonSandboxConfig { - injectInto?: any; - properties?: string[]; - useFakeTimers?: any; - useFakeServer?: any; - } - - export interface SinonSandbox { - clock: SinonFakeTimers; - requests: SinonFakeXMLHttpRequest; - server: SinonFakeServer; - spy(): SinonSpy; - stub(): SinonStub; - mock(): SinonMock; - useFakeTimers: SinonFakeTimers; - useFakeXMLHttpRequest: SinonFakeXMLHttpRequest; - restore(): void; - } - - export interface SinonSandboxStatic { - create(): SinonSandbox; - create(config: SinonSandboxConfig): SinonSandbox; - } - - export var sandbox: SinonSandboxStatic; - - export interface SinonTestConfig { - injectIntoThis?: boolean; - injectInto?: any; - properties?: string[]; - useFakeTimers?: boolean; - useFakeServer?: boolean; - } - - export interface SinonTestWrapper extends SinonSandbox { - (...args: any[]): any; - } - - export function format (obj: any): string; - export function log (message: string): void; - export var config: SinonTestConfig; - export function test(fn: (...args: any[]) => any): SinonTestWrapper; - export function testCase(tests: any): any; -} - -declare module 'sinon' { - export = Sinon; -} \ No newline at end of file diff --git a/src/vs/test/lib/sinon.d.ts b/src/vs/test/lib/sinon.d.ts new file mode 100644 index 00000000000..0ca6c3840a0 --- /dev/null +++ b/src/vs/test/lib/sinon.d.ts @@ -0,0 +1,448 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// Type definitions for Sinon 1.16.0 +// Project: http://sinonjs.org/ +// Definitions by: William Sears +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module '~sinon/lib/sinon' { + module Sinon { + export interface SinonSpyCallApi { + // Properties + thisValue: any; + args: any[]; + exception: any; + returnValue: any; + + // Methods + calledOn(obj: any): boolean; + calledWith(...args: any[]): boolean; + calledWithExactly(...args: any[]): boolean; + calledWithMatch(...args: any[]): boolean; + notCalledWith(...args: any[]): boolean; + notCalledWithMatch(...args: any[]): boolean; + returned(value: any): boolean; + threw(): boolean; + threw(type: string): boolean; + threw(obj: any): boolean; + callArg(pos: number): void; + callArgOn(pos: number, obj: any, ...args: any[]): void; + callArgWith(pos: number, ...args: any[]): void; + callArgOnWith(pos: number, obj: any, ...args: any[]): void; + yield(...args: any[]): void; + yieldOn(obj: any, ...args: any[]): void; + yieldTo(property: string, ...args: any[]): void; + yieldToOn(property: string, obj: any, ...args: any[]): void; + } + + export interface SinonSpyCall extends SinonSpyCallApi { + calledBefore(call: SinonSpyCall): boolean; + calledAfter(call: SinonSpyCall): boolean; + calledWithNew(call: SinonSpyCall): boolean; + } + + export interface SinonSpy extends SinonSpyCallApi { + // Properties + callCount: number; + called: boolean; + notCalled: boolean; + calledOnce: boolean; + calledTwice: boolean; + calledThrice: boolean; + firstCall: SinonSpyCall; + secondCall: SinonSpyCall; + thirdCall: SinonSpyCall; + lastCall: SinonSpyCall; + thisValues: any[]; + args: any[][]; + exceptions: any[]; + returnValues: any[]; + + // Methods + (...args: any[]): any; + calledBefore(anotherSpy: SinonSpy): boolean; + calledAfter(anotherSpy: SinonSpy): boolean; + calledWithNew(spy: SinonSpy): boolean; + withArgs(...args: any[]): SinonSpy; + alwaysCalledOn(obj: any): boolean; + alwaysCalledWith(...args: any[]): boolean; + alwaysCalledWithExactly(...args: any[]): boolean; + alwaysCalledWithMatch(...args: any[]): boolean; + neverCalledWith(...args: any[]): boolean; + neverCalledWithMatch(...args: any[]): boolean; + alwaysThrew(): boolean; + alwaysThrew(type: string): boolean; + alwaysThrew(obj: any): boolean; + alwaysReturned(): boolean; + invokeCallback(...args: any[]): void; + getCall(n: number): SinonSpyCall; + getCalls(): SinonSpyCall[]; + reset(): void; + printf(format: string, ...args: any[]): string; + restore(): void; + } + + export interface SinonSpyStatic { + (): SinonSpy; + (func: any): SinonSpy; + (obj: any, method: string): SinonSpy; + } + + export interface SinonStatic { + spy: SinonSpyStatic; + } + + export interface SinonStub extends SinonSpy { + resetBehavior(): void; + returns(obj: any): SinonStub; + returnsArg(index: number): SinonStub; + returnsThis(): SinonStub; + throws(type?: string): SinonStub; + throws(obj: any): SinonStub; + callsArg(index: number): SinonStub; + callsArgOn(index: number, context: any): SinonStub; + callsArgWith(index: number, ...args: any[]): SinonStub; + callsArgOnWith(index: number, context: any, ...args: any[]): SinonStub; + callsArgAsync(index: number): SinonStub; + callsArgOnAsync(index: number, context: any): SinonStub; + callsArgWithAsync(index: number, ...args: any[]): SinonStub; + callsArgOnWithAsync(index: number, context: any, ...args: any[]): SinonStub; + onCall(n: number): SinonStub; + onFirstCall(): SinonStub; + onSecondCall(): SinonStub; + onThirdCall(): SinonStub; + yields(...args: any[]): SinonStub; + yieldsOn(context: any, ...args: any[]): SinonStub; + yieldsTo(property: string, ...args: any[]): SinonStub; + yieldsToOn(property: string, context: any, ...args: any[]): SinonStub; + yieldsAsync(...args: any[]): SinonStub; + yieldsOnAsync(context: any, ...args: any[]): SinonStub; + yieldsToAsync(property: string, ...args: any[]): SinonStub; + yieldsToOnAsync(property: string, context: any, ...args: any[]): SinonStub; + withArgs(...args: any[]): SinonStub; + } + + export interface SinonStubStatic { + (): SinonStub; + (obj: any): SinonStub; + (obj: any, method: string): SinonStub; + (obj: any, method: string, func: any): SinonStub; + } + + export interface SinonStatic { + stub: SinonStubStatic; + } + + export interface SinonExpectation extends SinonStub { + atLeast(n: number): SinonExpectation; + atMost(n: number): SinonExpectation; + never(): SinonExpectation; + once(): SinonExpectation; + twice(): SinonExpectation; + thrice(): SinonExpectation; + exactly(n: number): SinonExpectation; + withArgs(...args: any[]): SinonExpectation; + withExactArgs(...args: any[]): SinonExpectation; + on(obj: any): SinonExpectation; + verify(): SinonExpectation; + restore(): void; + } + + export interface SinonExpectationStatic { + create(methodName?: string): SinonExpectation; + } + + export interface SinonMock { + expects(method: string): SinonExpectation; + restore(): void; + verify(): void; + } + + export interface SinonMockStatic { + (): SinonExpectation; + (obj: any): SinonMock; + } + + export interface SinonStatic { + expectation: SinonExpectationStatic; + mock: SinonMockStatic; + } + + export interface SinonFakeTimers { + now: number; + create(now: number): SinonFakeTimers; + setTimeout(callback: (...args: any[]) => void, timeout: number, ...args: any[]): number; + clearTimeout(id: number): void; + setInterval(callback: (...args: any[]) => void, timeout: number, ...args: any[]): number; + clearInterval(id: number): void; + tick(ms: number): number; + reset(): void; + Date(): Date; + Date(year: number): Date; + Date(year: number, month: number): Date; + Date(year: number, month: number, day: number): Date; + Date(year: number, month: number, day: number, hour: number): Date; + Date(year: number, month: number, day: number, hour: number, minute: number): Date; + Date(year: number, month: number, day: number, hour: number, minute: number, second: number): Date; + Date(year: number, month: number, day: number, hour: number, minute: number, second: number, ms: number): Date; + restore(): void; + + /** + * Simulate the user changing the system clock while your program is running. It changes the 'now' timestamp + * without affecting timers, intervals or immediates. + * @param now The new 'now' in unix milliseconds + */ + setSystemTime(now: number): void; + /** + * Simulate the user changing the system clock while your program is running. It changes the 'now' timestamp + * without affecting timers, intervals or immediates. + * @param now The new 'now' as a JavaScript Date + */ + setSystemTime(date: Date): void; + } + + export interface SinonFakeTimersStatic { + (): SinonFakeTimers; + (...timers: string[]): SinonFakeTimers; + (now: number, ...timers: string[]): SinonFakeTimers; + } + + export interface SinonStatic { + useFakeTimers: SinonFakeTimersStatic; + clock: SinonFakeTimers; + } + + export interface SinonFakeUploadProgress { + eventListeners: { + progress: any[]; + load: any[]; + abort: any[]; + error: any[]; + }; + + addEventListener(event: string, listener: (e: Event) => any): void; + removeEventListener(event: string, listener: (e: Event) => any): void; + dispatchEvent(event: Event): void; + } + + export interface SinonFakeXMLHttpRequest { + // Properties + onCreate: (xhr: SinonFakeXMLHttpRequest) => void; + url: string; + method: string; + requestHeaders: any; + requestBody: string; + status: number; + statusText: string; + async: boolean; + username: string; + password: string; + withCredentials: boolean; + upload: SinonFakeUploadProgress; + responseXML: Document; + getResponseHeader(header: string): string; + getAllResponseHeaders(): any; + + // Methods + restore(): void; + useFilters: boolean; + addFilter(filter: (method: string, url: string, async: boolean, username: string, password: string) => boolean): void; + setResponseHeaders(headers: any): void; + setResponseBody(body: string): void; + respond(status: number, headers: any, body: string): void; + autoRespond(ms: number): void; + } + + export interface SinonFakeXMLHttpRequestStatic { + (): SinonFakeXMLHttpRequest; + } + + export interface SinonStatic { + useFakeXMLHttpRequest: SinonFakeXMLHttpRequestStatic; + FakeXMLHttpRequest: SinonFakeXMLHttpRequest; + } + + export interface SinonFakeServer { + // Properties + autoRespond: boolean; + autoRespondAfter: number; + fakeHTTPMethods: boolean; + getHTTPMethod: (request: SinonFakeXMLHttpRequest) => string; + requests: SinonFakeXMLHttpRequest[]; + respondImmediately: boolean; + + // Methods + respondWith(body: string): void; + respondWith(response: any[]): void; + respondWith(fn: (xhr: SinonFakeXMLHttpRequest) => void): void; + respondWith(url: string, body: string): void; + respondWith(url: string, response: any[]): void; + respondWith(url: string, fn: (xhr: SinonFakeXMLHttpRequest) => void): void; + respondWith(method: string, url: string, body: string): void; + respondWith(method: string, url: string, response: any[]): void; + respondWith(method: string, url: string, fn: (xhr: SinonFakeXMLHttpRequest) => void): void; + respondWith(url: RegExp, body: string): void; + respondWith(url: RegExp, response: any[]): void; + respondWith(url: RegExp, fn: (xhr: SinonFakeXMLHttpRequest) => void): void; + respondWith(method: string, url: RegExp, body: string): void; + respondWith(method: string, url: RegExp, response: any[]): void; + respondWith(method: string, url: RegExp, fn: (xhr: SinonFakeXMLHttpRequest) => void): void; + respond(): void; + restore(): void; + } + + export interface SinonFakeServerStatic { + create(): SinonFakeServer; + } + + export interface SinonStatic { + fakeServer: SinonFakeServerStatic; + fakeServerWithClock: SinonFakeServerStatic; + } + + export interface SinonExposeOptions { + prefix?: string; + includeFail?: boolean; + } + + export interface SinonAssert { + // Properties + failException: string; + fail: (message?: string) => void; // Overridable + pass: (assertion: any) => void; // Overridable + + // Methods + notCalled(spy: SinonSpy): void; + called(spy: SinonSpy): void; + calledOnce(spy: SinonSpy): void; + calledTwice(spy: SinonSpy): void; + calledThrice(spy: SinonSpy): void; + callCount(spy: SinonSpy, count: number): void; + callOrder(...spies: SinonSpy[]): void; + calledOn(spy: SinonSpy, obj: any): void; + alwaysCalledOn(spy: SinonSpy, obj: any): void; + calledWith(spy: SinonSpy, ...args: any[]): void; + alwaysCalledWith(spy: SinonSpy, ...args: any[]): void; + neverCalledWith(spy: SinonSpy, ...args: any[]): void; + calledWithExactly(spy: SinonSpy, ...args: any[]): void; + alwaysCalledWithExactly(spy: SinonSpy, ...args: any[]): void; + calledWithMatch(spy: SinonSpy, ...args: any[]): void; + alwaysCalledWithMatch(spy: SinonSpy, ...args: any[]): void; + neverCalledWithMatch(spy: SinonSpy, ...args: any[]): void; + threw(spy: SinonSpy): void; + threw(spy: SinonSpy, exception: string): void; + threw(spy: SinonSpy, exception: any): void; + alwaysThrew(spy: SinonSpy): void; + alwaysThrew(spy: SinonSpy, exception: string): void; + alwaysThrew(spy: SinonSpy, exception: any): void; + expose(obj: any, options?: SinonExposeOptions): void; + } + + export interface SinonStatic { + assert: SinonAssert; + } + + export interface SinonMatcher { + and(expr: SinonMatcher): SinonMatcher; + or(expr: SinonMatcher): SinonMatcher; + } + + export interface SinonMatch { + (value: number): SinonMatcher; + (value: string): SinonMatcher; + (expr: RegExp): SinonMatcher; + (obj: any): SinonMatcher; + (callback: (value: any) => boolean): SinonMatcher; + any: SinonMatcher; + defined: SinonMatcher; + truthy: SinonMatcher; + falsy: SinonMatcher; + bool: SinonMatcher; + number: SinonMatcher; + string: SinonMatcher; + object: SinonMatcher; + func: SinonMatcher; + array: SinonMatcher; + regexp: SinonMatcher; + date: SinonMatcher; + same(obj: any): SinonMatcher; + typeOf(type: string): SinonMatcher; + instanceOf(type: any): SinonMatcher; + has(property: string, expect?: any): SinonMatcher; + hasOwn(property: string, expect?: any): SinonMatcher; + } + + export interface SinonStatic { + match: SinonMatch; + } + + export interface SinonSandboxConfig { + injectInto?: any; + properties?: string[]; + useFakeTimers?: any; + useFakeServer?: any; + } + + export interface SinonSandbox { + clock: SinonFakeTimers; + requests: SinonFakeXMLHttpRequest; + server: SinonFakeServer; + spy: SinonSpyStatic; + stub: SinonStubStatic; + mock: SinonMockStatic; + useFakeTimers: SinonFakeTimersStatic; + useFakeXMLHttpRequest: SinonFakeXMLHttpRequestStatic; + useFakeServer(): SinonFakeServer; + restore(): void; + } + + export interface SinonSandboxStatic { + create(): SinonSandbox; + create(config: SinonSandboxConfig): SinonSandbox; + } + + export interface SinonStatic { + sandbox: SinonSandboxStatic; + } + + export interface SinonTestConfig { + injectIntoThis?: boolean; + injectInto?: any; + properties?: string[]; + useFakeTimers?: boolean; + useFakeServer?: boolean; + } + + export interface SinonTestWrapper extends SinonSandbox { + (...args: any[]): any; + } + + export interface SinonStatic { + config: SinonTestConfig; + test(fn: (...args: any[]) => any): SinonTestWrapper; + testCase(tests: any): any; + } + + // Utility overridables + export interface SinonStatic { + createStubInstance(constructor: any): SinonStub; + format(obj: any): string; + log(message: string): void; + restore(object: any): void; + } + } + + var Sinon: Sinon.SinonStatic; + + export = Sinon; +} +declare module 'sinon/lib/sinon' { + import main = require('~sinon/lib/sinon'); + export = main; +} +declare module 'sinon' { + import main = require('~sinon/lib/sinon'); + export = main; +} \ No newline at end of file diff --git a/src/vs/test/utils/instantiationTestUtils.ts b/src/vs/test/utils/instantiationTestUtils.ts new file mode 100644 index 00000000000..84c12e4bd24 --- /dev/null +++ b/src/vs/test/utils/instantiationTestUtils.ts @@ -0,0 +1,142 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. +*--------------------------------------------------------------------------------------------*/ + +import * as sinon from 'sinon'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { SimpleMap } from 'vs/base/common/map'; +import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; + +// Known services +import {IEventService} from 'vs/platform/event/common/event'; +import {EventService} from 'vs/platform/event/common/eventService'; +import { ITelemetryService, NullTelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { ISearchService } from 'vs/platform/search/common/search'; +import { SearchService } from 'vs/workbench/services/search/node/searchService'; +import { IHistoryService } from 'vs/workbench/services/history/common/history'; +import { HistoryService } from 'vs/workbench/services/history/browser/history'; +import { IModeService } from 'vs/editor/common/services/modeService'; +import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl'; +import { IExtensionService } from 'vs/platform/extensions/common/extensions'; +import { SimpleExtensionService } from 'vs/editor/browser/standalone/simpleServices'; +import { MarkerService } from 'vs/platform/markers/common/markerService'; +import { IMarkerService } from 'vs/platform/markers/common/markers'; +import { IReplaceService } from 'vs/workbench/parts/search/common/replace'; +import { ReplaceService } from 'vs/workbench/parts/search/browser/replaceService'; + +interface IServiceMock { + id: ServiceIdentifier; + service: any; +} + +export class TestInstantiationService extends InstantiationService { + + private _servciesMap: SimpleMap, any>; + + constructor(private _serviceCollection: ServiceCollection = new ServiceCollection()) { + super(_serviceCollection); + + this._servciesMap= new SimpleMap, any>(); + this._servciesMap.set(ITelemetryService, NullTelemetryService); + this._servciesMap.set(IEventService, EventService); + this._servciesMap.set(ISearchService, SearchService); + this._servciesMap.set(IHistoryService, HistoryService); + this._servciesMap.set(IModeService, ModeServiceImpl); + this._servciesMap.set(IExtensionService, SimpleExtensionService); + this._servciesMap.set(IMarkerService, MarkerService); + this._servciesMap.set(IReplaceService, ReplaceService); + } + + public mock(service:ServiceIdentifier): T | sinon.SinonMock { + return this._create(service, {mock: true}); + } + + public stub(service?:ServiceIdentifier, ctor?: any): T + public stub(service?:ServiceIdentifier, obj?: any): T + public stub(service?:ServiceIdentifier, ctor?: any, fnProperty?: string, value?: any): sinon.SinonStub + public stub(service?:ServiceIdentifier, obj?: any, fnProperty?: string, value?: any): sinon.SinonStub + public stub(service?:ServiceIdentifier, fnProperty?: string, value?: any): sinon.SinonStub + public stub(serviceIdentifier?: ServiceIdentifier, arg2?: any, arg3?: string, arg4?: any): sinon.SinonStub { + let service= typeof arg2 !== 'string' ? arg2 : void 0; + let serviceMock: IServiceMock= {id: serviceIdentifier, service: service}; + let fnProperty= typeof arg2 === 'string' ? arg2 : arg3; + let value= typeof arg2 === 'string' ? arg3 : arg4; + + let stubObject= this._create(serviceMock, {stub: true}); + if (fnProperty) { + if (stubObject[fnProperty].hasOwnProperty('restore')) { + stubObject[fnProperty].restore(); + } + if (typeof value === 'function') { + stubObject[fnProperty] = value; + } else { + let stub = value ? sinon.stub().returns(value) : sinon.stub(); + stubObject[fnProperty] = stub; + return stub; + } + } + return stubObject; + } + + public stubPromise(service?:ServiceIdentifier, fnProperty?: string, value?: any): T | sinon.SinonStub + public stubPromise(service?:ServiceIdentifier, ctor?: any, fnProperty?: string, value?: any): sinon.SinonStub + public stubPromise(service?:ServiceIdentifier, obj?: any, fnProperty?: string, value?: any): sinon.SinonStub + public stubPromise(arg1?:any, arg2?: any, arg3?: any, arg4?: any): sinon.SinonStub { + arg3= typeof arg2 === 'string' ? TPromise.as(arg3) : arg3; + arg4= typeof arg2 !== 'string' && typeof arg3 === 'string' ? TPromise.as(arg4) : arg4; + return this.stub(arg1, arg2, arg3, arg4); + } + + public spy(service:ServiceIdentifier, fnProperty: string): sinon.SinonSpy { + let spy= sinon.spy(); + this.stub(service, fnProperty, spy); + return spy; + } + + private _create(serviceMock: IServiceMock, options: SinonOptions): any + private _create(ctor: any, options: SinonOptions): any + private _create(arg1: any, options: SinonOptions): any { + if (this.isServiceMock(arg1)) { + let service= this._getOrCreateService(arg1, options); + this._serviceCollection.set(arg1.id, service); + return service; + } + return options.mock ? sinon.mock(arg1) : this._createStub(arg1); + } + + private _getOrCreateService(serviceMock: IServiceMock, opts: SinonOptions): any { + let service:any = this._serviceCollection.get(serviceMock.id); + if (service) { + if (opts.mock && service['sinonOptions'] && !!service['sinonOptions'].mock) { + return service; + } + if (opts.stub && service['sinonOptions'] && !!service['sinonOptions'].stub) { + return service; + } + } + return this._createService(serviceMock, opts); + } + + private _createService(serviceMock: IServiceMock, opts: SinonOptions): any { + serviceMock.service= serviceMock.service ? serviceMock.service : this._servciesMap.get(serviceMock.id); + let service= opts.mock ? sinon.mock(serviceMock.service) : this._createStub(serviceMock.service); + service['sinonOptions']= opts; + return service; + } + + private _createStub(arg: any): any { + return typeof arg === 'object' ? arg : sinon.createStubInstance(arg); + } + + private isServiceMock(arg1: any): boolean { + return typeof arg1 === 'object' && arg1.hasOwnProperty('id'); + } +} + +interface SinonOptions { + mock?: boolean; + stub?: boolean; +} \ No newline at end of file diff --git a/src/vs/test/utils/promiseTestUtils.ts b/src/vs/test/utils/promiseTestUtils.ts new file mode 100644 index 00000000000..4096e44e0fc --- /dev/null +++ b/src/vs/test/utils/promiseTestUtils.ts @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. +*--------------------------------------------------------------------------------------------*/ + +import { TPromise, PPromise, TValueCallback, TProgressCallback } from 'vs/base/common/winjs.base'; +import errors = require('vs/base/common/errors'); + +export class DeferredTPromise extends TPromise { + + constructor(init:(complete: TValueCallback, error:(err:any)=>void)=>void) { + super((c, e) => setTimeout(() => init(c, e))); + } + +} + +export class DeferredPPromise extends PPromise { + + private completeCallback:TValueCallback; + private errorCallback:(err:any)=>void; + private progressCallback:TProgressCallback

; + + constructor(init:(complete: TValueCallback, error:(err:any)=>void, progress: TProgressCallback

)=>void = (c, e, p) => {}, oncancel?: any) { + super((c, e, p) => {this.completeCallback= c; this.errorCallback= e; this.progressCallback= p;}, oncancel ? oncancel : () => this.oncancel); + } + + private oncancel(): void { + this.errorCallback(errors.canceled()); + } + + public complete(c: C) { + this.completeCallback(c); + } + + public progress(p: P) { + this.progressCallback(p); + } + + public error(e: any) { + this.errorCallback(e); + } +} \ No newline at end of file diff --git a/src/vs/workbench/test/common/servicesTestUtils.ts b/src/vs/test/utils/servicesTestUtils.ts similarity index 94% rename from src/vs/workbench/test/common/servicesTestUtils.ts rename to src/vs/test/utils/servicesTestUtils.ts index 202c8e25fdb..d26b70bd5db 100644 --- a/src/vs/workbench/test/common/servicesTestUtils.ts +++ b/src/vs/test/utils/servicesTestUtils.ts @@ -6,6 +6,7 @@ 'use strict'; import {Promise, TPromise} from 'vs/base/common/winjs.base'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import EventEmitter = require('vs/base/common/eventEmitter'); import Paths = require('vs/base/common/paths'); import URI from 'vs/base/common/uri'; @@ -17,6 +18,7 @@ import Types = require('vs/base/common/types'); import Severity from 'vs/base/common/severity'; import http = require('vs/base/common/http'); import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; +import {IContent, IStat} from 'vs/platform/configuration/common/configurationService'; import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage'; import WorkbenchEditorService = require('vs/workbench/services/editor/common/editorService'); import QuickOpenService = require('vs/workbench/services/quickopen/common/quickOpenService'); @@ -29,7 +31,6 @@ import {IMessageService, IConfirmation} from 'vs/platform/message/common/message import {BaseRequestService} from 'vs/platform/request/common/baseRequestService'; import {IWorkspace, IConfiguration} from 'vs/platform/workspace/common/workspace'; import {ILifecycleService, ShutdownEvent} from 'vs/platform/lifecycle/common/lifecycle'; -import {IHistoryService} from 'vs/workbench/services/history/common/history'; import {EditorStacksModel} from 'vs/workbench/common/editor/editorStacksModel'; import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; @@ -38,6 +39,7 @@ import {TextFileService} from 'vs/workbench/parts/files/common/textFileServices' import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IFileService, IResolveContentOptions} from 'vs/platform/files/common/files'; import {IModelService} from 'vs/editor/common/services/modelService'; +import {ModelServiceImpl} from 'vs/editor/common/services/modelServiceImpl'; import {IRawTextContent} from 'vs/workbench/parts/files/common/files'; import {RawText} from 'vs/editor/common/model/textModel'; @@ -53,34 +55,6 @@ export const TestConfiguration: IConfiguration = { env: Object.create(null) }; -export class TestHistoryService implements IHistoryService { - public _serviceBrand: any; - - public forward(): void { - - } - - public back(): void { - - } - - public clear(): void { - - } - - public remove(input: IEditorInput): void { - - } - - public popLastClosedEditor(): IEditorInput { - return null; - } - - public getHistory(): IEditorInput[] { - return []; - } -} - export class TestContextService implements WorkspaceContextService.IWorkspaceContextService { public _serviceBrand: any; @@ -620,6 +594,29 @@ export class TestConfigurationService extends EventEmitter.EventEmitter implemen private configuration = Object.create(null); + protected resolveContents(resources: URI[]): TPromise { + return TPromise.as(resources.map((resource) => { + return { + resource: resource, + value: '' + }; + })); + } + + protected resolveContent(resource: URI): TPromise { + return TPromise.as({ + resource: resource, + value: '' + }); + } + + protected resolveStat(resource: URI): TPromise { + return TPromise.as({ + resource: resource, + isDirectory: false + }); + } + public loadConfiguration(section?: string): TPromise { return TPromise.as(this.getConfiguration()); } @@ -632,15 +629,14 @@ export class TestConfigurationService extends EventEmitter.EventEmitter implemen return false; } - public onDidUpdateConfiguration() { - return { dispose() { } }; - } - public setUserConfiguration(key: any, value: any): Thenable { this.configuration[key] = value; - return TPromise.as(null); } + + public onDidUpdateConfiguration() { + return { dispose() { } }; + } } export class TestLifecycleService implements ILifecycleService { @@ -664,4 +660,9 @@ export class TestLifecycleService implements ILifecycleService { public get onShutdown(): Event { return this._onShutdown.event; } +} + +export function createMockModelService(instantiationService: TestInstantiationService): IModelService { + instantiationService.stub(IConfigurationService, new TestConfigurationService()); + return instantiationService.createInstance(ModelServiceImpl); } \ No newline at end of file diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 84bc601ed67..96f58bb3a07 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -3543,12 +3543,12 @@ declare namespace vscode { * (2.1) When both are equal score is `10`, * (2.2) When the selector is `*` score is `5`, * (2.3) Else score is `0`. - * (3) When selector is a [filter](#DocumentFilter) every property must score higher `0`. Iff the score is the sum of the following: + * (3) When selector is a [filter](#DocumentFilter) return the maximum individual score given that each score is `>0`. * (3.1) When [language](#DocumentFilter.language) is set apply rules from #2, when `0` the total score is `0`. - * (3.2) When [scheme](#Document.scheme) is set and equals the [uri](#TextDocument.uri)-scheme add `10` to the score, else the total score is `0`. + * (3.2) When [scheme](#Document.scheme) is set and equals the [uri](#TextDocument.uri)-scheme score with `10`, else the total score is `0`. * (3.3) When [pattern](#Document.pattern) is set - * (3.3.1) pattern eqauls the [uri](#TextDocument.uri)-fsPath add `10` to the score, - * (3.3.1) if the pattern matches as glob-pattern add `5` to the score, + * (3.3.1) pattern equals the [uri](#TextDocument.uri)-fsPath score with `10`, + * (3.3.1) if the pattern matches as glob-pattern score with `5`, * (3.3.1) the total score is `0` * ``` * diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index bef2fd60dc2..fe870ef47ff 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -38,7 +38,7 @@ import {CancellationTokenSource} from 'vs/base/common/cancellation'; import vscode = require('vscode'); import * as paths from 'vs/base/common/paths'; import {ITelemetryService, ITelemetryInfo} from 'vs/platform/telemetry/common/telemetry'; -import {MainContext, ExtHostContext, InstanceCollection} from './extHostProtocol'; +import {MainContext, ExtHostContext, InstanceCollection} from './extHost.protocol'; /** * This class implements the API described in vscode.d.ts, diff --git a/src/vs/workbench/api/node/extHost.contribution.ts b/src/vs/workbench/api/node/extHost.contribution.ts index 205b45c3994..406944d016f 100644 --- a/src/vs/workbench/api/node/extHost.contribution.ts +++ b/src/vs/workbench/api/node/extHost.contribution.ts @@ -10,7 +10,7 @@ import {Registry} from 'vs/platform/platform'; import {IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions} from 'vs/workbench/common/contributions'; import {IInstantiationService, IConstructorSignature0} from 'vs/platform/instantiation/common/instantiation'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; -import {MainContext, InstanceCollection} from './extHostProtocol'; +import {MainContext, InstanceCollection} from './extHost.protocol'; import {IExtensionService} from 'vs/platform/extensions/common/extensions'; // --- addressable @@ -60,7 +60,6 @@ export class ExtHostContribution implements IWorkbenchContribution { // Addressable instances const col = new InstanceCollection(); col.define(MainContext.MainThreadCommands).set(create(MainThreadCommands)); - col.define(MainContext.MainThreadConfiguration).set(create(MainThreadConfiguration)); col.define(MainContext.MainThreadDiagnostics).set(create(MainThreadDiagnostics)); col.define(MainContext.MainThreadDocuments).set(create(MainThreadDocuments)); col.define(MainContext.MainThreadEditors).set(create(MainThreadEditors)); @@ -81,6 +80,7 @@ export class ExtHostContribution implements IWorkbenchContribution { // Other interested parties create(MainProcessTextMateSyntax); + create(MainThreadConfiguration); create(MainProcessTextMateSnippet); create(JSONValidationExtensionPoint); create(LanguageConfigurationFileHandler); diff --git a/src/vs/workbench/api/node/extHostProtocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts similarity index 82% rename from src/vs/workbench/api/node/extHostProtocol.ts rename to src/vs/workbench/api/node/extHost.protocol.ts index b55b4c879b6..dcd24828edf 100644 --- a/src/vs/workbench/api/node/extHostProtocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -29,7 +29,7 @@ import {IResourceEdit} from 'vs/editor/common/services/bulkEdit'; import {IPickOpenEntry, IPickOptions} from 'vs/workbench/services/quickopen/common/quickOpenService'; import {ITypeBearing} from 'vs/workbench/parts/search/common/search'; -import {TextEditorRevealType, ITextEditorConfigurationUpdate, IResolvedTextEditorConfiguration} from './mainThreadEditorsTracker'; +import {TextEditorRevealType, ITextEditorConfigurationUpdate, IResolvedTextEditorConfiguration, ISelectionChangeEvent} from './mainThreadEditorsTracker'; import {EndOfLine} from './extHostTypes'; export interface InstanceSetter { @@ -81,33 +81,30 @@ export abstract class MainThreadCommandsShape { $getCommands(): Thenable { throw ni(); } } -export abstract class MainThreadConfigurationShape { -} - export abstract class MainThreadDiagnosticsShape { $changeMany(owner: string, entries: [URI, IMarkerData[]][]): TPromise { throw ni(); } $clear(owner: string): TPromise { throw ni(); } } export abstract class MainThreadDocumentsShape { - _tryOpenDocument(uri: URI): TPromise { throw ni(); } + $tryOpenDocument(uri: URI): TPromise { throw ni(); } $registerTextContentProvider(handle:number, scheme: string): void { throw ni(); } $onVirtualDocumentChange(uri: URI, value: string): void { throw ni(); } $unregisterTextContentProvider(handle: number): void { throw ni(); } - _trySaveDocument(uri: URI): TPromise { throw ni(); } + $trySaveDocument(uri: URI): TPromise { throw ni(); } } export abstract class MainThreadEditorsShape { - _tryShowTextDocument(resource: URI, position: EditorPosition, preserveFocus: boolean): TPromise { throw ni(); } - _registerTextEditorDecorationType(key: string, options: editorCommon.IDecorationRenderOptions): void { throw ni(); } - _removeTextEditorDecorationType(key: string): void { throw ni(); } - _tryShowEditor(id: string, position: EditorPosition): TPromise { throw ni(); } - _tryHideEditor(id: string): TPromise { throw ni(); } - _trySetOptions(id: string, options: ITextEditorConfigurationUpdate): TPromise { throw ni(); } - _trySetDecorations(id: string, key: string, ranges: editorCommon.IDecorationOptions[]): TPromise { throw ni(); } - _tryRevealRange(id: string, range: editorCommon.IRange, revealType: TextEditorRevealType): TPromise { throw ni(); } - _trySetSelections(id: string, selections: editorCommon.ISelection[]): TPromise { throw ni(); } - _tryApplyEdits(id: string, modelVersionId: number, edits: editorCommon.ISingleEditOperation[], setEndOfLine:EndOfLine): TPromise { throw ni(); } + $tryShowTextDocument(resource: URI, position: EditorPosition, preserveFocus: boolean): TPromise { throw ni(); } + $registerTextEditorDecorationType(key: string, options: editorCommon.IDecorationRenderOptions): void { throw ni(); } + $removeTextEditorDecorationType(key: string): void { throw ni(); } + $tryShowEditor(id: string, position: EditorPosition): TPromise { throw ni(); } + $tryHideEditor(id: string): TPromise { throw ni(); } + $trySetOptions(id: string, options: ITextEditorConfigurationUpdate): TPromise { throw ni(); } + $trySetDecorations(id: string, key: string, ranges: editorCommon.IDecorationOptions[]): TPromise { throw ni(); } + $tryRevealRange(id: string, range: editorCommon.IRange, revealType: TextEditorRevealType): TPromise { throw ni(); } + $trySetSelections(id: string, selections: editorCommon.ISelection[]): TPromise { throw ni(); } + $tryApplyEdits(id: string, modelVersionId: number, edits: editorCommon.ISingleEditOperation[], setEndOfLine:EndOfLine): TPromise { throw ni(); } } export abstract class MainThreadErrorsShape { @@ -134,7 +131,7 @@ export abstract class MainThreadLanguageFeaturesShape { } export abstract class MainThreadLanguagesShape { - _getLanguages(): TPromise { throw ni(); } + $getLanguages(): TPromise { throw ni(); } } export abstract class MainThreadMessageServiceShape { @@ -142,10 +139,10 @@ export abstract class MainThreadMessageServiceShape { } export abstract class MainThreadOutputServiceShape { - append(channelId: string, label: string, value: string): TPromise { throw ni(); } - clear(channelId: string, label: string): TPromise { throw ni(); } - reveal(channelId: string, label: string, preserveFocus: boolean): TPromise { throw ni(); } - close(channelId: string): TPromise { throw ni(); } + $append(channelId: string, label: string, value: string): TPromise { throw ni(); } + $clear(channelId: string, label: string): TPromise { throw ni(); } + $reveal(channelId: string, label: string, preserveFocus: boolean): TPromise { throw ni(); } + $close(channelId: string): TPromise { throw ni(); } } export interface MyQuickPickItems extends IPickOpenEntry { @@ -159,13 +156,13 @@ export abstract class MainThreadQuickOpenShape { } export abstract class MainThreadStatusBarShape { - setEntry(id: number, text: string, tooltip: string, command: string, color: string, alignment: MainThreadStatusBarAlignment, priority: number): void { throw ni(); } - dispose(id: number) { throw ni(); } + $setEntry(id: number, text: string, tooltip: string, command: string, color: string, alignment: MainThreadStatusBarAlignment, priority: number): void { throw ni(); } + $dispose(id: number) { throw ni(); } } export abstract class MainThreadStorageShape { - getValue(shared: boolean, key: string): TPromise { throw ni(); } - setValue(shared: boolean, key: string, value: any): TPromise { throw ni(); } + $getValue(shared: boolean, key: string): TPromise { throw ni(); } + $setValue(shared: boolean, key: string, value: any): TPromise { throw ni(); } } export abstract class MainThreadTelemetryShape { @@ -181,10 +178,10 @@ export abstract class MainThreadWorkspaceShape { } export abstract class MainProcessExtensionServiceShape { - public $onExtensionHostReady(extensionDescriptions: IExtensionDescription[], messages: IMessage[]): TPromise { throw ni(); } - public $localShowMessage(severity: Severity, msg: string): void { throw ni(); } - public $onExtensionActivated(extensionId: string): void { throw ni(); } - public $onExtensionActivationFailed(extensionId: string): void { throw ni(); } + $onExtensionHostReady(extensionDescriptions: IExtensionDescription[], messages: IMessage[]): TPromise { throw ni(); } + $localShowMessage(severity: Severity, msg: string): void { throw ni(); } + $onExtensionActivated(extensionId: string): void { throw ni(); } + $onExtensionActivationFailed(extensionId: string): void { throw ni(); } } // -- extension host @@ -211,13 +208,13 @@ export interface IModelAddedData { } export abstract class ExtHostDocumentsShape { $provideTextDocumentContent(handle: number, uri: URI): TPromise { throw ni(); } - _acceptModelAdd(initData: IModelAddedData): void { throw ni(); } - _acceptModelModeChanged(strURL: string, oldModeId: string, newModeId: string): void { throw ni(); } - _acceptModelSaved(strURL: string): void { throw ni(); } - _acceptModelDirty(strURL: string): void { throw ni(); } - _acceptModelReverted(strURL: string): void { throw ni(); } - _acceptModelRemoved(strURL: string): void { throw ni(); } - _acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[]): void { throw ni(); } + $acceptModelAdd(initData: IModelAddedData): void { throw ni(); } + $acceptModelModeChanged(strURL: string, oldModeId: string, newModeId: string): void { throw ni(); } + $acceptModelSaved(strURL: string): void { throw ni(); } + $acceptModelDirty(strURL: string): void { throw ni(); } + $acceptModelReverted(strURL: string): void { throw ni(); } + $acceptModelRemoved(strURL: string): void { throw ni(); } + $acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[]): void { throw ni(); } } export interface ITextEditorAddData { @@ -231,12 +228,12 @@ export interface ITextEditorPositionData { [id: string]: EditorPosition; } export abstract class ExtHostEditorsShape { - _acceptTextEditorAdd(data: ITextEditorAddData): void { throw ni(); } - _acceptOptionsChanged(id: string, opts: IResolvedTextEditorConfiguration): void { throw ni(); } - _acceptSelectionsChanged(id: string, _selections: editorCommon.ISelection[]): void { throw ni(); } - _acceptActiveEditorAndVisibleEditors(id: string, visibleIds: string[]): void { throw ni(); } - _acceptEditorPositionData(data: ITextEditorPositionData): void { throw ni(); } - _acceptTextEditorRemove(id: string): void { throw ni(); } + $acceptTextEditorAdd(data: ITextEditorAddData): void { throw ni(); } + $acceptOptionsChanged(id: string, opts: IResolvedTextEditorConfiguration): void { throw ni(); } + $acceptSelectionsChanged(id: string, event: ISelectionChangeEvent): void { throw ni(); } + $acceptActiveEditorAndVisibleEditors(id: string, visibleIds: string[]): void { throw ni(); } + $acceptEditorPositionData(data: ITextEditorPositionData): void { throw ni(); } + $acceptTextEditorRemove(id: string): void { throw ni(); } } export abstract class ExtHostExtensionServiceShape { @@ -250,7 +247,7 @@ export interface FileSystemEvents { deleted: URI[]; } export abstract class ExtHostFileSystemEventServiceShape { - _onFileEvent(events: FileSystemEvents) { throw ni(); } + $onFileEvent(events: FileSystemEvents) { throw ni(); } } export abstract class ExtHostLanguageFeaturesShape { @@ -281,7 +278,6 @@ export abstract class ExtHostQuickOpenShape { export const MainContext = { MainThreadCommands: createMainId('MainThreadCommands', MainThreadCommandsShape), - MainThreadConfiguration: createMainId('MainThreadConfiguration', MainThreadConfigurationShape), MainThreadDiagnostics: createMainId('MainThreadDiagnostics', MainThreadDiagnosticsShape), MainThreadDocuments: createMainId('MainThreadDocuments', MainThreadDocumentsShape), MainThreadEditors: createMainId('MainThreadEditors', MainThreadEditorsShape), diff --git a/src/vs/workbench/api/node/extHostCommands.ts b/src/vs/workbench/api/node/extHostCommands.ts index d3480cde4dc..a0622faf796 100644 --- a/src/vs/workbench/api/node/extHostCommands.ts +++ b/src/vs/workbench/api/node/extHostCommands.ts @@ -12,7 +12,7 @@ import {ExtHostEditors} from 'vs/workbench/api/node/extHostEditors'; import * as extHostTypes from 'vs/workbench/api/node/extHostTypes'; import * as extHostTypeConverter from 'vs/workbench/api/node/extHostTypeConverters'; import {cloneAndChange} from 'vs/base/common/objects'; -import {MainContext, MainThreadCommandsShape} from './extHostProtocol'; +import {MainContext, MainThreadCommandsShape, ExtHostCommandsShape} from './extHost.protocol'; interface CommandHandler { callback: Function; @@ -20,7 +20,7 @@ interface CommandHandler { description: ICommandHandlerDescription; } -export class ExtHostCommands { +export class ExtHostCommands extends ExtHostCommandsShape { private _commands: { [n: string]: CommandHandler } = Object.create(null); private _proxy: MainThreadCommandsShape; @@ -30,6 +30,7 @@ export class ExtHostCommands { threadService: IThreadService, extHostEditors:ExtHostEditors ) { + super(); this._extHostEditors = extHostEditors; this._proxy = threadService.get(MainContext.MainThreadCommands); } diff --git a/src/vs/workbench/api/node/extHostConfiguration.ts b/src/vs/workbench/api/node/extHostConfiguration.ts index 2f79028fc41..b37ec21751b 100644 --- a/src/vs/workbench/api/node/extHostConfiguration.ts +++ b/src/vs/workbench/api/node/extHostConfiguration.ts @@ -8,14 +8,16 @@ import {clone} from 'vs/base/common/objects'; import {illegalState} from 'vs/base/common/errors'; import Event, {Emitter} from 'vs/base/common/event'; import {WorkspaceConfiguration} from 'vscode'; +import {ExtHostConfigurationShape} from './extHost.protocol'; -export class ExtHostConfiguration { +export class ExtHostConfiguration extends ExtHostConfigurationShape { private _config: any; private _hasConfig: boolean; private _onDidChangeConfiguration: Emitter; constructor() { + super(); this._onDidChangeConfiguration = new Emitter(); } diff --git a/src/vs/workbench/api/node/extHostDiagnostics.ts b/src/vs/workbench/api/node/extHostDiagnostics.ts index a4a90f8d2e6..dab90f9e538 100644 --- a/src/vs/workbench/api/node/extHostDiagnostics.ts +++ b/src/vs/workbench/api/node/extHostDiagnostics.ts @@ -9,7 +9,7 @@ import {IMarkerData} from 'vs/platform/markers/common/markers'; import URI from 'vs/base/common/uri'; import Severity from 'vs/base/common/severity'; import * as vscode from 'vscode'; -import {MainContext, MainThreadDiagnosticsShape} from './extHostProtocol'; +import {MainContext, MainThreadDiagnosticsShape, ExtHostDiagnosticsShape} from './extHost.protocol'; export class DiagnosticCollection implements vscode.DiagnosticCollection { @@ -175,7 +175,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { } } -export class ExtHostDiagnostics { +export class ExtHostDiagnostics extends ExtHostDiagnosticsShape { private static _idPool: number = 0; @@ -183,6 +183,7 @@ export class ExtHostDiagnostics { private _collections: DiagnosticCollection[]; constructor(threadService: IThreadService) { + super(); this._proxy = threadService.get(MainContext.MainThreadDiagnostics); this._collections = []; } diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index f817314a299..36784a021a9 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -17,7 +17,7 @@ import {TPromise} from 'vs/base/common/winjs.base'; import * as vscode from 'vscode'; import {asWinJsPromise} from 'vs/base/common/async'; import {getWordAtText, ensureValidWordDefinition} from 'vs/editor/common/model/wordHelper'; -import {MainContext, MainThreadDocumentsShape, IModelAddedData} from './extHostProtocol'; +import {MainContext, MainThreadDocumentsShape, ExtHostDocumentsShape, IModelAddedData} from './extHost.protocol'; const _modeId2WordDefinition: { [modeId: string]: RegExp; @@ -31,7 +31,7 @@ function getWordDefinitionFor(modeId: string): RegExp { return _modeId2WordDefinition[modeId]; } -export class ExtHostDocuments { +export class ExtHostDocuments extends ExtHostDocumentsShape { private static _handlePool: number = 0; @@ -54,6 +54,7 @@ export class ExtHostDocuments { private _proxy: MainThreadDocumentsShape; constructor(threadService: IThreadService) { + super(); this._proxy = threadService.get(MainContext.MainThreadDocuments); this._onDidAddDocumentEventEmitter = new Emitter(); @@ -100,7 +101,7 @@ export class ExtHostDocuments { let promise = this._documentLoader[uri.toString()]; if (!promise) { - promise = this._proxy._tryOpenDocument(uri).then(() => { + promise = this._proxy.$tryOpenDocument(uri).then(() => { delete this._documentLoader[uri.toString()]; return this._documentData[uri.toString()]; }, err => { @@ -152,7 +153,7 @@ export class ExtHostDocuments { return asWinJsPromise(token => provider.provideTextDocumentContent(uri, token)); } - public _acceptModelAdd(initData: IModelAddedData): void { + public $acceptModelAdd(initData: IModelAddedData): void { let data = new ExtHostDocumentData(this._proxy, initData.url, initData.value.lines, initData.value.EOL, initData.modeId, initData.versionId, initData.isDirty); let key = data.document.uri.toString(); if (this._documentData[key]) { @@ -162,7 +163,7 @@ export class ExtHostDocuments { this._onDidAddDocumentEventEmitter.fire(data.document); } - public _acceptModelModeChanged(strURL: string, oldModeId: string, newModeId: string): void { + public $acceptModelModeChanged(strURL: string, oldModeId: string, newModeId: string): void { let data = this._documentData[strURL]; // Treat a mode change as a remove + add @@ -172,23 +173,23 @@ export class ExtHostDocuments { this._onDidAddDocumentEventEmitter.fire(data.document); } - public _acceptModelSaved(strURL: string): void { + public $acceptModelSaved(strURL: string): void { let data = this._documentData[strURL]; data._acceptIsDirty(false); this._onDidSaveDocumentEventEmitter.fire(data.document); } - public _acceptModelDirty(strURL: string): void { + public $acceptModelDirty(strURL: string): void { let document = this._documentData[strURL]; document._acceptIsDirty(true); } - public _acceptModelReverted(strURL: string): void { + public $acceptModelReverted(strURL: string): void { let document = this._documentData[strURL]; document._acceptIsDirty(false); } - public _acceptModelRemoved(strURL: string): void { + public $acceptModelRemoved(strURL: string): void { if (!this._documentData[strURL]) { throw new Error('Document `' + strURL + '` does not exist.'); } @@ -198,7 +199,7 @@ export class ExtHostDocuments { data.dispose(); } - public _acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[]): void { + public $acceptModelChanged(strURL: string, events: editorCommon.IModelContentChangedEvent2[]): void { let data = this._documentData[strURL]; data.onEvents(events); this._onDidChangeDocumentEventEmitter.fire({ @@ -252,7 +253,7 @@ export class ExtHostDocumentData extends MirrorModel2 { get languageId() { return data._languageId; }, get version() { return data._versionId; }, get isDirty() { return data._isDirty; }, - save() { return data._proxy._trySaveDocument(data._uri); }, + save() { return data._proxy.$trySaveDocument(data._uri); }, getText(range?) { return range ? data._getTextInRange(range) : data.getText(); }, get lineCount() { return data._lines.length; }, lineAt(lineOrPos) { return data.lineAt(lineOrPos); }, diff --git a/src/vs/workbench/api/node/extHostEditors.ts b/src/vs/workbench/api/node/extHostEditors.ts index bb8df791782..f15a38174b8 100644 --- a/src/vs/workbench/api/node/extHostEditors.ts +++ b/src/vs/workbench/api/node/extHostEditors.ts @@ -12,13 +12,13 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import {ExtHostDocuments, ExtHostDocumentData} from 'vs/workbench/api/node/extHostDocuments'; import {Selection, Range, Position, EditorOptions, EndOfLine, TextEditorRevealType} from './extHostTypes'; -import {ISingleEditOperation, ISelection} from 'vs/editor/common/editorCommon'; -import {IResolvedTextEditorConfiguration} from 'vs/workbench/api/node/mainThreadEditorsTracker'; +import {ISingleEditOperation} from 'vs/editor/common/editorCommon'; +import {IResolvedTextEditorConfiguration, ISelectionChangeEvent} from 'vs/workbench/api/node/mainThreadEditorsTracker'; import * as TypeConverters from './extHostTypeConverters'; import {TextDocument, TextEditorSelectionChangeEvent, TextEditorOptionsChangeEvent, TextEditorOptions, TextEditorViewColumnChangeEvent, ViewColumn} from 'vscode'; -import {MainContext, MainThreadEditorsShape, ITextEditorAddData, ITextEditorPositionData} from './extHostProtocol'; +import {MainContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextEditorAddData, ITextEditorPositionData} from './extHost.protocol'; -export class ExtHostEditors { +export class ExtHostEditors extends ExtHostEditorsShape { public onDidChangeTextEditorSelection: Event; private _onDidChangeTextEditorSelection: Emitter; @@ -40,6 +40,7 @@ export class ExtHostEditors { threadService: IThreadService, extHostDocuments: ExtHostDocuments ) { + super(); this._onDidChangeTextEditorSelection = new Emitter(); this.onDidChangeTextEditorSelection = this._onDidChangeTextEditorSelection.event; @@ -70,7 +71,7 @@ export class ExtHostEditors { } showTextDocument(document: TextDocument, column: ViewColumn, preserveFocus: boolean): TPromise { - return this._proxy._tryShowTextDocument( document.uri, TypeConverters.fromViewColumn(column), preserveFocus).then(id => { + return this._proxy.$tryShowTextDocument( document.uri, TypeConverters.fromViewColumn(column), preserveFocus).then(id => { let editor = this._editors[id]; if (editor) { return editor; @@ -86,13 +87,13 @@ export class ExtHostEditors { // --- called from main thread - _acceptTextEditorAdd(data: ITextEditorAddData): void { + $acceptTextEditorAdd(data: ITextEditorAddData): void { let document = this._extHostDocuments.getDocumentData(data.document); let newEditor = new ExtHostTextEditor(this._proxy, data.id, document, data.selections.map(TypeConverters.toSelection), data.options, TypeConverters.toViewColumn(data.editorPosition)); this._editors[data.id] = newEditor; } - _acceptOptionsChanged(id: string, opts: IResolvedTextEditorConfiguration): void { + $acceptOptionsChanged(id: string, opts: IResolvedTextEditorConfiguration): void { let editor = this._editors[id]; editor._acceptOptions(opts); this._onDidChangeTextEditorOptions.fire({ @@ -101,8 +102,8 @@ export class ExtHostEditors { }); } - _acceptSelectionsChanged(id: string, _selections: ISelection[]): void { - let selections = _selections.map(TypeConverters.toSelection); + $acceptSelectionsChanged(id: string, event: ISelectionChangeEvent): void { + let selections = event.selections.map(TypeConverters.toSelection); let editor = this._editors[id]; editor._acceptSelections(selections); this._onDidChangeTextEditorSelection.fire({ @@ -111,7 +112,7 @@ export class ExtHostEditors { }); } - _acceptActiveEditorAndVisibleEditors(id: string, visibleIds: string[]): void { + $acceptActiveEditorAndVisibleEditors(id: string, visibleIds: string[]): void { this._visibleEditorIds = visibleIds; if (this._activeEditorId === id) { @@ -122,7 +123,7 @@ export class ExtHostEditors { this._onDidChangeActiveTextEditor.fire(this.getActiveTextEditor()); } - _acceptEditorPositionData(data: ITextEditorPositionData): void { + $acceptEditorPositionData(data: ITextEditorPositionData): void { for (let id in data) { let textEditor = this._editors[id]; let viewColumn = TypeConverters.toViewColumn(data[id]); @@ -133,15 +134,15 @@ export class ExtHostEditors { } } - _acceptTextEditorRemove(id: string): void { + $acceptTextEditorRemove(id: string): void { // make sure the removed editor is not visible let newVisibleEditors = this._visibleEditorIds.filter(visibleEditorId => visibleEditorId !== id); if (this._activeEditorId === id) { // removing the current active editor - this._acceptActiveEditorAndVisibleEditors(undefined, newVisibleEditors); + this.$acceptActiveEditorAndVisibleEditors(undefined, newVisibleEditors); } else { - this._acceptActiveEditorAndVisibleEditors(this._activeEditorId, newVisibleEditors); + this.$acceptActiveEditorAndVisibleEditors(this._activeEditorId, newVisibleEditors); } let editor = this._editors[id]; @@ -160,11 +161,11 @@ class TextEditorDecorationType implements vscode.TextEditorDecorationType { constructor(proxy: MainThreadEditorsShape, options: vscode.DecorationRenderOptions) { this.key = TextEditorDecorationType._Keys.nextId(); this._proxy = proxy; - this._proxy._registerTextEditorDecorationType(this.key, options); + this._proxy.$registerTextEditorDecorationType(this.key, options); } public dispose(): void { - this._proxy._removeTextEditorDecorationType(this.key); + this._proxy.$removeTextEditorDecorationType(this.key); } } @@ -292,11 +293,11 @@ class ExtHostTextEditor implements vscode.TextEditor { } @deprecated('TextEditor.show') show(column: vscode.ViewColumn) { - this._proxy._tryShowEditor(this._id, TypeConverters.fromViewColumn(column)); + this._proxy.$tryShowEditor(this._id, TypeConverters.fromViewColumn(column)); } @deprecated('TextEditor.hide') hide() { - this._proxy._tryHideEditor(this._id); + this._proxy.$tryHideEditor(this._id); } // ---- the document @@ -318,7 +319,7 @@ class ExtHostTextEditor implements vscode.TextEditor { set options(value: TextEditorOptions) { this._options = value; this._runOnProxy(() => { - return this._proxy._trySetOptions(this._id, this._options); + return this._proxy.$trySetOptions(this._id, this._options); }, true); } @@ -368,7 +369,7 @@ class ExtHostTextEditor implements vscode.TextEditor { setDecorations(decorationType: vscode.TextEditorDecorationType, ranges: Range[] | vscode.DecorationOptions[]): void { this._runOnProxy( - () => this._proxy._trySetDecorations( + () => this._proxy.$trySetDecorations( this._id, decorationType.key, TypeConverters.fromRangeOrRangeWithMessage(ranges) @@ -379,7 +380,7 @@ class ExtHostTextEditor implements vscode.TextEditor { revealRange(range: Range, revealType: vscode.TextEditorRevealType): void { this._runOnProxy( - () => this._proxy._tryRevealRange( + () => this._proxy.$tryRevealRange( this._id, TypeConverters.fromRange(range), revealType || TextEditorRevealType.Default @@ -390,7 +391,7 @@ class ExtHostTextEditor implements vscode.TextEditor { private _trySetSelection(silent: boolean): TPromise { let selection = this._selections.map(TypeConverters.fromSelection); - return this._runOnProxy(() => this._proxy._trySetSelections(this._id, selection), silent); + return this._runOnProxy(() => this._proxy.$trySetSelections(this._id, selection), silent); } _acceptSelections(selections: Selection[]): void { @@ -417,7 +418,7 @@ class ExtHostTextEditor implements vscode.TextEditor { }; }); - return this._proxy._tryApplyEdits(this._id, editData.documentVersionId, edits, editData.setEndOfLine); + return this._proxy.$tryApplyEdits(this._id, editData.documentVersionId, edits, editData.setEndOfLine); } // ---- util diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index d6572b128dd..137317c3415 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -15,7 +15,7 @@ import {ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegist import {ExtHostStorage} from 'vs/workbench/api/node/extHostStorage'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; -import {MainContext, MainProcessExtensionServiceShape} from './extHostProtocol'; +import {MainContext, MainProcessExtensionServiceShape} from './extHost.protocol'; const hasOwnProperty = Object.hasOwnProperty; diff --git a/src/vs/workbench/api/node/extHostFileSystemEventService.ts b/src/vs/workbench/api/node/extHostFileSystemEventService.ts index 50e99dc057b..ac3e60a7247 100644 --- a/src/vs/workbench/api/node/extHostFileSystemEventService.ts +++ b/src/vs/workbench/api/node/extHostFileSystemEventService.ts @@ -8,7 +8,7 @@ import Event, {Emitter} from 'vs/base/common/event'; import {Disposable} from './extHostTypes'; import {match} from 'vs/base/common/glob'; import {Uri, FileSystemWatcher as _FileSystemWatcher} from 'vscode'; -import {FileSystemEvents} from './extHostProtocol'; +import {FileSystemEvents, ExtHostFileSystemEventServiceShape} from './extHost.protocol'; export class FileSystemWatcher implements _FileSystemWatcher { @@ -87,18 +87,19 @@ export class FileSystemWatcher implements _FileSystemWatcher { } } -export class ExtHostFileSystemEventService { +export class ExtHostFileSystemEventService extends ExtHostFileSystemEventServiceShape { private _emitter = new Emitter(); constructor() { + super(); } public createFileSystemWatcher(globPattern: string, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): _FileSystemWatcher { return new FileSystemWatcher(this._emitter.event, globPattern, ignoreCreateEvents, ignoreChangeEvents, ignoreDeleteEvents); } - _onFileEvent(events: FileSystemEvents) { + $onFileEvent(events: FileSystemEvents) { this._emitter.fire(events); } } diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index ea7968bc36f..efbfe5d059b 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -18,7 +18,7 @@ import {ExtHostCommands} from 'vs/workbench/api/node/extHostCommands'; import {ExtHostDiagnostics} from 'vs/workbench/api/node/extHostDiagnostics'; import {INavigateTypesSupport, ITypeBearing} from 'vs/workbench/parts/search/common/search'; import {asWinJsPromise, ShallowCancelThenPromise} from 'vs/base/common/async'; -import {MainContext, MainThreadLanguageFeaturesShape} from './extHostProtocol'; +import {MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape} from './extHost.protocol'; import {regExpLeadsToEndlessLoop} from 'vs/base/common/strings'; // --- adapter @@ -593,7 +593,7 @@ type Adapter = OutlineAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapt | RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter | SuggestAdapter | SignatureHelpAdapter; -export class ExtHostLanguageFeatures { +export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape { private static _handlePool: number = 0; @@ -609,6 +609,7 @@ export class ExtHostLanguageFeatures { commands: ExtHostCommands, diagnostics: ExtHostDiagnostics ) { + super(); this._proxy = threadService.get(MainContext.MainThreadLanguageFeatures); this._documents = documents; this._commands = commands; diff --git a/src/vs/workbench/api/node/extHostLanguages.ts b/src/vs/workbench/api/node/extHostLanguages.ts index 30dc4af61cc..a64ecfb8199 100644 --- a/src/vs/workbench/api/node/extHostLanguages.ts +++ b/src/vs/workbench/api/node/extHostLanguages.ts @@ -6,7 +6,7 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; -import {MainContext, MainThreadLanguagesShape} from './extHostProtocol'; +import {MainContext, MainThreadLanguagesShape} from './extHost.protocol'; export class ExtHostLanguages { @@ -19,7 +19,7 @@ export class ExtHostLanguages { } getLanguages(): TPromise { - return this._proxy._getLanguages(); + return this._proxy.$getLanguages(); } } diff --git a/src/vs/workbench/api/node/extHostMessageService.ts b/src/vs/workbench/api/node/extHostMessageService.ts index 8e5cc36715a..49789406046 100644 --- a/src/vs/workbench/api/node/extHostMessageService.ts +++ b/src/vs/workbench/api/node/extHostMessageService.ts @@ -7,7 +7,7 @@ import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import Severity from 'vs/base/common/severity'; import vscode = require('vscode'); -import {MainContext, MainThreadMessageServiceShape} from './extHostProtocol'; +import {MainContext, MainThreadMessageServiceShape} from './extHost.protocol'; export class ExtHostMessageService { diff --git a/src/vs/workbench/api/node/extHostOutputService.ts b/src/vs/workbench/api/node/extHostOutputService.ts index ecb32d6960b..068787f179b 100644 --- a/src/vs/workbench/api/node/extHostOutputService.ts +++ b/src/vs/workbench/api/node/extHostOutputService.ts @@ -5,7 +5,7 @@ 'use strict'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; -import {MainContext, MainThreadOutputServiceShape} from './extHostProtocol'; +import {MainContext, MainThreadOutputServiceShape} from './extHost.protocol'; export class ExtHostOutputChannel implements vscode.OutputChannel { @@ -28,14 +28,14 @@ export class ExtHostOutputChannel implements vscode.OutputChannel { dispose(): void { if (!this._disposed) { - this._proxy.clear(this._id, this._name).then(() => { + this._proxy.$clear(this._id, this._name).then(() => { this._disposed = true; }); } } append(value: string): void { - this._proxy.append(this._id, this._name, value); + this._proxy.$append(this._id, this._name, value); } appendLine(value: string): void { @@ -43,7 +43,7 @@ export class ExtHostOutputChannel implements vscode.OutputChannel { } clear(): void { - this._proxy.clear(this._id, this._name); + this._proxy.$clear(this._id, this._name); } show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void { @@ -51,11 +51,11 @@ export class ExtHostOutputChannel implements vscode.OutputChannel { preserveFocus = columnOrPreserveFocus; } - this._proxy.reveal(this._id, this._name, preserveFocus); + this._proxy.$reveal(this._id, this._name, preserveFocus); } hide(): void { - this._proxy.close(this._id); + this._proxy.$close(this._id); } } diff --git a/src/vs/workbench/api/node/extHostQuickOpen.ts b/src/vs/workbench/api/node/extHostQuickOpen.ts index 5bed2fc6e5f..59ec73bbb81 100644 --- a/src/vs/workbench/api/node/extHostQuickOpen.ts +++ b/src/vs/workbench/api/node/extHostQuickOpen.ts @@ -7,17 +7,18 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import {QuickPickOptions, QuickPickItem, InputBoxOptions} from 'vscode'; -import {MainContext, MainThreadQuickOpenShape, MyQuickPickItems} from './extHostProtocol'; +import {MainContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, MyQuickPickItems} from './extHost.protocol'; export type Item = string | QuickPickItem; -export class ExtHostQuickOpen { +export class ExtHostQuickOpen extends ExtHostQuickOpenShape { private _proxy: MainThreadQuickOpenShape; private _onDidSelectItem: (handle: number) => void; private _validateInput: (input: string) => string; constructor(threadService: IThreadService) { + super(); this._proxy = threadService.get(MainContext.MainThreadQuickOpen); } diff --git a/src/vs/workbench/api/node/extHostStatusBar.ts b/src/vs/workbench/api/node/extHostStatusBar.ts index ea3e8740d0c..e10ab046e13 100644 --- a/src/vs/workbench/api/node/extHostStatusBar.ts +++ b/src/vs/workbench/api/node/extHostStatusBar.ts @@ -8,7 +8,7 @@ import {IThreadService} from 'vs/workbench/services/thread/common/threadService' import {StatusbarAlignment as MainThreadStatusBarAlignment} from 'vs/platform/statusbar/common/statusbar'; import {StatusBarAlignment as ExtHostStatusBarAlignment, Disposable} from './extHostTypes'; import {StatusBarItem, StatusBarAlignment} from 'vscode'; -import {MainContext, MainThreadStatusBarShape} from './extHostProtocol'; +import {MainContext, MainThreadStatusBarShape} from './extHost.protocol'; export class ExtHostStatusBarEntry implements StatusBarItem { private static ID_GEN = 0; @@ -89,7 +89,7 @@ export class ExtHostStatusBarEntry implements StatusBarItem { public hide(): void { this._visible = false; - this._proxy.dispose(this.id); + this._proxy.$dispose(this.id); } private update(): void { @@ -106,7 +106,7 @@ export class ExtHostStatusBarEntry implements StatusBarItem { this._timeoutHandle = null; // Set to status bar - this._proxy.setEntry(this.id, this.text, this.tooltip, this.command, this.color, + this._proxy.$setEntry(this.id, this.text, this.tooltip, this.command, this.color, this._alignment === ExtHostStatusBarAlignment.Left ? MainThreadStatusBarAlignment.LEFT : MainThreadStatusBarAlignment.RIGHT, this._priority); }, 0); diff --git a/src/vs/workbench/api/node/extHostStorage.ts b/src/vs/workbench/api/node/extHostStorage.ts index 8b171c47df9..4740b3523cd 100644 --- a/src/vs/workbench/api/node/extHostStorage.ts +++ b/src/vs/workbench/api/node/extHostStorage.ts @@ -6,7 +6,7 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; -import {MainContext, MainThreadStorageShape} from './extHostProtocol'; +import {MainContext, MainThreadStorageShape} from './extHost.protocol'; export class ExtHostStorage { @@ -17,10 +17,10 @@ export class ExtHostStorage { } getValue(shared: boolean, key: string, defaultValue?: T): TPromise { - return this._proxy.getValue(shared, key).then(value => value || defaultValue); + return this._proxy.$getValue(shared, key).then(value => value || defaultValue); } setValue(shared: boolean, key: string, value: any): TPromise { - return this._proxy.setValue(shared, key, value); + return this._proxy.$setValue(shared, key, value); } } \ No newline at end of file diff --git a/src/vs/workbench/api/node/extHostTelemetry.ts b/src/vs/workbench/api/node/extHostTelemetry.ts index 2594a9029c9..ef35ca0ef33 100644 --- a/src/vs/workbench/api/node/extHostTelemetry.ts +++ b/src/vs/workbench/api/node/extHostTelemetry.ts @@ -8,7 +8,7 @@ import {notImplemented} from 'vs/base/common/errors'; import {TPromise} from 'vs/base/common/winjs.base'; import {ITelemetryService, ITelemetryInfo} from 'vs/platform/telemetry/common/telemetry'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; -import {MainContext, MainThreadTelemetryShape} from './extHostProtocol'; +import {MainContext, MainThreadTelemetryShape} from './extHost.protocol'; export class RemoteTelemetryService implements ITelemetryService { diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index fb32d9bc839..d2aba3b575b 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -10,7 +10,7 @@ import {IResourceEdit} from 'vs/editor/common/services/bulkEdit'; import {TPromise} from 'vs/base/common/winjs.base'; import {fromRange} from 'vs/workbench/api/node/extHostTypeConverters'; import {Uri, CancellationToken} from 'vscode'; -import {MainContext, MainThreadWorkspaceShape} from './extHostProtocol'; +import {MainContext, MainThreadWorkspaceShape} from './extHost.protocol'; export class ExtHostWorkspace { diff --git a/src/vs/workbench/api/node/mainThreadCommands.ts b/src/vs/workbench/api/node/mainThreadCommands.ts index ed61077b8cf..54dd71eec48 100644 --- a/src/vs/workbench/api/node/mainThreadCommands.ts +++ b/src/vs/workbench/api/node/mainThreadCommands.ts @@ -7,9 +7,9 @@ import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import {ICommandService, CommandsRegistry, ICommandHandlerDescription} from 'vs/platform/commands/common/commands'; import {TPromise} from 'vs/base/common/winjs.base'; -import {ExtHostContext, ExtHostCommandsShape} from './extHostProtocol'; +import {ExtHostContext, MainThreadCommandsShape, ExtHostCommandsShape} from './extHost.protocol'; -export class MainThreadCommands { +export class MainThreadCommands extends MainThreadCommandsShape { private _proxy: ExtHostCommandsShape; @@ -17,6 +17,7 @@ export class MainThreadCommands { @IThreadService private _threadService: IThreadService, @ICommandService private _commandService: ICommandService ) { + super(); this._proxy = this._threadService.get(ExtHostContext.ExtHostCommands); } diff --git a/src/vs/workbench/api/node/mainThreadConfiguration.ts b/src/vs/workbench/api/node/mainThreadConfiguration.ts index 4c06bf9f960..b624e91fa22 100644 --- a/src/vs/workbench/api/node/mainThreadConfiguration.ts +++ b/src/vs/workbench/api/node/mainThreadConfiguration.ts @@ -7,7 +7,7 @@ import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; -import {ExtHostContext, ExtHostConfigurationShape} from './extHostProtocol'; +import {ExtHostContext, ExtHostConfigurationShape} from './extHost.protocol'; export class MainThreadConfiguration { @@ -19,7 +19,6 @@ export class MainThreadConfiguration { @IConfigurationService configurationService: IConfigurationService, @IThreadService threadService: IThreadService ) { - this._configurationService = configurationService; this._proxy = threadService.get(ExtHostContext.ExtHostConfiguration); diff --git a/src/vs/workbench/api/node/mainThreadDiagnostics.ts b/src/vs/workbench/api/node/mainThreadDiagnostics.ts index beb0a0f2b24..b625d7909a3 100644 --- a/src/vs/workbench/api/node/mainThreadDiagnostics.ts +++ b/src/vs/workbench/api/node/mainThreadDiagnostics.ts @@ -7,12 +7,14 @@ import {IMarkerService, IMarkerData} from 'vs/platform/markers/common/markers'; import URI from 'vs/base/common/uri'; import {TPromise} from 'vs/base/common/winjs.base'; +import {MainThreadDiagnosticsShape} from './extHost.protocol'; -export class MainThreadDiagnostics { +export class MainThreadDiagnostics extends MainThreadDiagnosticsShape { private _markerService: IMarkerService; constructor(@IMarkerService markerService: IMarkerService) { + super(); this._markerService = markerService; } diff --git a/src/vs/workbench/api/node/mainThreadDocuments.ts b/src/vs/workbench/api/node/mainThreadDocuments.ts index 8b48d048a18..5289778d638 100644 --- a/src/vs/workbench/api/node/mainThreadDocuments.ts +++ b/src/vs/workbench/api/node/mainThreadDocuments.ts @@ -19,9 +19,9 @@ import {IFileService} from 'vs/platform/files/common/files'; import {IModeService} from 'vs/editor/common/services/modeService'; import {IUntitledEditorService} from 'vs/workbench/services/untitled/common/untitledEditorService'; import {ResourceEditorInput} from 'vs/workbench/common/editor/resourceEditorInput'; -import {ExtHostContext, ExtHostDocumentsShape} from './extHostProtocol'; +import {ExtHostContext, MainThreadDocumentsShape, ExtHostDocumentsShape} from './extHost.protocol'; -export class MainThreadDocuments { +export class MainThreadDocuments extends MainThreadDocumentsShape { private _modelService: IModelService; private _modeService: IModeService; private _textFileService: ITextFileService; @@ -45,6 +45,7 @@ export class MainThreadDocuments { @IFileService fileService: IFileService, @IUntitledEditorService untitledEditorService: IUntitledEditorService ) { + super(); this._modelService = modelService; this._modeService = modeService; this._textFileService = textFileService; @@ -61,17 +62,17 @@ export class MainThreadDocuments { this._toDispose.push(eventService.addListener2(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => { if (this._shouldHandleFileEvent(e)) { - this._proxy._acceptModelSaved(e.resource.toString()); + this._proxy.$acceptModelSaved(e.resource.toString()); } })); this._toDispose.push(eventService.addListener2(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => { if (this._shouldHandleFileEvent(e)) { - this._proxy._acceptModelReverted(e.resource.toString()); + this._proxy.$acceptModelReverted(e.resource.toString()); } })); this._toDispose.push(eventService.addListener2(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => { if (this._shouldHandleFileEvent(e)) { - this._proxy._acceptModelDirty(e.resource.toString()); + this._proxy.$acceptModelDirty(e.resource.toString()); } })); @@ -105,7 +106,7 @@ export class MainThreadDocuments { let modelUrl = model.uri; this._modelIsSynced[modelUrl.toString()] = true; this._modelToDisposeMap[modelUrl.toString()] = model.addBulkListener((events) => this._onModelEvents(modelUrl, events)); - this._proxy._acceptModelAdd({ + this._proxy.$acceptModelAdd({ url: model.uri, versionId: model.getVersionId(), value: model.toRawText(), @@ -120,7 +121,7 @@ export class MainThreadDocuments { if (!this._modelIsSynced[modelUrl.toString()]) { return; } - this._proxy._acceptModelModeChanged(model.uri.toString(), oldModeId, model.getMode().getId()); + this._proxy.$acceptModelModeChanged(model.uri.toString(), oldModeId, model.getMode().getId()); } private _onModelRemoved(model: editorCommon.IModel): void { @@ -131,7 +132,7 @@ export class MainThreadDocuments { delete this._modelIsSynced[modelUrl.toString()]; this._modelToDisposeMap[modelUrl.toString()].dispose(); delete this._modelToDisposeMap[modelUrl.toString()]; - this._proxy._acceptModelRemoved(modelUrl.toString()); + this._proxy.$acceptModelRemoved(modelUrl.toString()); } private _onModelEvents(modelUrl: URI, events: EmitterEvent[]): void { @@ -145,17 +146,17 @@ export class MainThreadDocuments { } } if (changedEvents.length > 0) { - this._proxy._acceptModelChanged(modelUrl.toString(), changedEvents); + this._proxy.$acceptModelChanged(modelUrl.toString(), changedEvents); } } // --- from extension host process - _trySaveDocument(uri: URI): TPromise { + $trySaveDocument(uri: URI): TPromise { return this._textFileService.save(uri); } - _tryOpenDocument(uri: URI): TPromise { + $tryOpenDocument(uri: URI): TPromise { if (!uri.scheme || !(uri.fsPath || uri.authority)) { return TPromise.wrapError(`Invalid uri. Scheme and authority or path must be set.`); @@ -201,7 +202,7 @@ export class MainThreadDocuments { if (!this._modelIsSynced[uri.toString()]) { throw new Error(`expected URI ${uri.toString()} to have come to LIFE`); } - return this._proxy._acceptModelDirty(uri.toString()); // mark as dirty + return this._proxy.$acceptModelDirty(uri.toString()); // mark as dirty }).then(() => { return true; }); diff --git a/src/vs/workbench/api/node/mainThreadEditors.ts b/src/vs/workbench/api/node/mainThreadEditors.ts index a7b1fc61831..ec374bddceb 100644 --- a/src/vs/workbench/api/node/mainThreadEditors.ts +++ b/src/vs/workbench/api/node/mainThreadEditors.ts @@ -20,9 +20,9 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IEventService} from 'vs/platform/event/common/event'; import {equals as arrayEquals} from 'vs/base/common/arrays'; import {equals as objectEquals} from 'vs/base/common/objects'; -import {ExtHostContext, ExtHostEditorsShape, ITextEditorPositionData} from './extHostProtocol'; +import {ExtHostContext, MainThreadEditorsShape, ExtHostEditorsShape, ITextEditorPositionData} from './extHost.protocol'; -export class MainThreadEditors { +export class MainThreadEditors extends MainThreadEditorsShape { private _proxy: ExtHostEditorsShape; private _workbenchEditorService: IWorkbenchEditorService; @@ -44,6 +44,7 @@ export class MainThreadEditors { @IEventService eventService: IEventService, @IModelService modelService: IModelService ) { + super(); this._proxy = threadService.get(ExtHostContext.ExtHostEditors); this._workbenchEditorService = workbenchEditorService; this._telemetryService = telemetryService; @@ -78,12 +79,12 @@ export class MainThreadEditors { let id = textEditor.getId(); let toDispose: IDisposable[] = []; toDispose.push(textEditor.onConfigurationChanged((opts) => { - this._proxy._acceptOptionsChanged(id, opts); + this._proxy.$acceptOptionsChanged(id, opts); })); - toDispose.push(textEditor.onSelectionChanged((selection) => { - this._proxy._acceptSelectionsChanged(id, selection); + toDispose.push(textEditor.onSelectionChanged((event) => { + this._proxy.$acceptSelectionsChanged(id, event); })); - this._proxy._acceptTextEditorAdd({ + this._proxy.$acceptTextEditorAdd({ id: id, document: textEditor.getModel().uri, options: textEditor.getConfiguration(), @@ -100,7 +101,7 @@ export class MainThreadEditors { dispose(this._textEditorsListenersMap[id]); delete this._textEditorsListenersMap[id]; delete this._textEditorsMap[id]; - this._proxy._acceptTextEditorRemove(id); + this._proxy.$acceptTextEditorRemove(id); } private _updateActiveAndVisibleTextEditors(): void { @@ -111,14 +112,14 @@ export class MainThreadEditors { if (activeEditor !== this._activeTextEditor || !arrayEquals(this._visibleEditors, visibleEditors, (a, b) => a === b)) { this._activeTextEditor = activeEditor; this._visibleEditors = visibleEditors; - this._proxy._acceptActiveEditorAndVisibleEditors(this._activeTextEditor, this._visibleEditors); + this._proxy.$acceptActiveEditorAndVisibleEditors(this._activeTextEditor, this._visibleEditors); } // editor columns let editorPositionData = this._getTextEditorPositionData(); if (!objectEquals(this._editorPositionData, editorPositionData)) { this._editorPositionData = editorPositionData; - this._proxy._acceptEditorPositionData(this._editorPositionData); + this._proxy.$acceptEditorPositionData(this._editorPositionData); } } @@ -177,7 +178,7 @@ export class MainThreadEditors { // --- from extension host process - _tryShowTextDocument(resource: URI, position: EditorPosition, preserveFocus: boolean): TPromise { + $tryShowTextDocument(resource: URI, position: EditorPosition, preserveFocus: boolean): TPromise { const input = { resource, @@ -221,7 +222,7 @@ export class MainThreadEditors { }); } - _tryShowEditor(id: string, position: EditorPosition): TPromise { + $tryShowEditor(id: string, position: EditorPosition): TPromise { // check how often this is used this._telemetryService.publicLog('api.deprecated', { function: 'TextEditor.show' }); @@ -235,7 +236,7 @@ export class MainThreadEditors { } } - _tryHideEditor(id: string): TPromise { + $tryHideEditor(id: string): TPromise { // check how often this is used this._telemetryService.publicLog('api.deprecated', { function: 'TextEditor.hide' }); @@ -250,7 +251,7 @@ export class MainThreadEditors { } } - _trySetSelections(id: string, selections: ISelection[]): TPromise { + $trySetSelections(id: string, selections: ISelection[]): TPromise { if (!this._textEditorsMap[id]) { return TPromise.wrapError('TextEditor disposed'); } @@ -258,7 +259,7 @@ export class MainThreadEditors { return TPromise.as(null); } - _trySetDecorations(id: string, key: string, ranges: IDecorationOptions[]): TPromise { + $trySetDecorations(id: string, key: string, ranges: IDecorationOptions[]): TPromise { if (!this._textEditorsMap[id]) { return TPromise.wrapError('TextEditor disposed'); } @@ -266,14 +267,14 @@ export class MainThreadEditors { return TPromise.as(null); } - _tryRevealRange(id: string, range: IRange, revealType: TextEditorRevealType): TPromise { + $tryRevealRange(id: string, range: IRange, revealType: TextEditorRevealType): TPromise { if (!this._textEditorsMap[id]) { return TPromise.wrapError('TextEditor disposed'); } this._textEditorsMap[id].revealRange(range, revealType); } - _trySetOptions(id: string, options: ITextEditorConfigurationUpdate): TPromise { + $trySetOptions(id: string, options: ITextEditorConfigurationUpdate): TPromise { if (!this._textEditorsMap[id]) { return TPromise.wrapError('TextEditor disposed'); } @@ -281,18 +282,18 @@ export class MainThreadEditors { return TPromise.as(null); } - _tryApplyEdits(id: string, modelVersionId: number, edits: ISingleEditOperation[], setEndOfLine:EndOfLine): TPromise { + $tryApplyEdits(id: string, modelVersionId: number, edits: ISingleEditOperation[], setEndOfLine:EndOfLine): TPromise { if (!this._textEditorsMap[id]) { return TPromise.wrapError('TextEditor disposed'); } return TPromise.as(this._textEditorsMap[id].applyEdits(modelVersionId, edits, setEndOfLine)); } - _registerTextEditorDecorationType(key: string, options: IDecorationRenderOptions): void { + $registerTextEditorDecorationType(key: string, options: IDecorationRenderOptions): void { this._editorTracker.registerTextEditorDecorationType(key, options); } - _removeTextEditorDecorationType(key: string): void { + $removeTextEditorDecorationType(key: string): void { this._editorTracker.removeTextEditorDecorationType(key); } } diff --git a/src/vs/workbench/api/node/mainThreadEditorsTracker.ts b/src/vs/workbench/api/node/mainThreadEditorsTracker.ts index f4f79b8dcc7..e89a71a3592 100644 --- a/src/vs/workbench/api/node/mainThreadEditorsTracker.ts +++ b/src/vs/workbench/api/node/mainThreadEditorsTracker.ts @@ -40,6 +40,11 @@ function configurationsEqual(a:IResolvedTextEditorConfiguration, b:IResolvedText ); } +export interface ISelectionChangeEvent { + selections: Selection[]; + source?: string; +} + export interface IFocusTracker { onGainedFocus(): void; onLostFocus(): void; @@ -68,7 +73,7 @@ export class MainThreadTextEditor { private _lastSelection: Selection[]; private _configuration: IResolvedTextEditorConfiguration; - private _onSelectionChanged: Emitter; + private _onSelectionChanged: Emitter; private _onConfigurationChanged: Emitter; constructor( @@ -85,7 +90,7 @@ export class MainThreadTextEditor { this._modelService = modelService; this._codeEditorListeners = []; - this._onSelectionChanged = new Emitter(); + this._onSelectionChanged = new Emitter(); this._onConfigurationChanged = new Emitter(); this._lastSelection = [ new Selection(1,1,1,1) ]; @@ -132,9 +137,12 @@ export class MainThreadTextEditor { this.setCodeEditor(null); })); - let forwardSelection = () => { + let forwardSelection = (event?: EditorCommon.ICursorSelectionChangedEvent) => { this._lastSelection = this._codeEditor.getSelections(); - this._onSelectionChanged.fire(this._lastSelection); + this._onSelectionChanged.fire({ + selections: this._lastSelection, + source: event && event.source + }); }; this._codeEditorListeners.push(this._codeEditor.onDidChangeCursorSelection(forwardSelection)); if (!Selection.selectionsArrEqual(this._lastSelection, this._codeEditor.getSelections())) { @@ -157,7 +165,7 @@ export class MainThreadTextEditor { return !!this._codeEditor; } - public get onSelectionChanged(): Event { + public get onSelectionChanged(): Event { return this._onSelectionChanged.event; } diff --git a/src/vs/workbench/api/node/mainThreadErrors.ts b/src/vs/workbench/api/node/mainThreadErrors.ts index 33d32470601..34491ea9562 100644 --- a/src/vs/workbench/api/node/mainThreadErrors.ts +++ b/src/vs/workbench/api/node/mainThreadErrors.ts @@ -5,8 +5,9 @@ 'use strict'; import * as errors from 'vs/base/common/errors'; +import {MainThreadErrorsShape} from './extHost.protocol'; -export class MainThreadErrors { +export class MainThreadErrors extends MainThreadErrorsShape { public onUnexpectedExtHostError(err: any): void { errors.onUnexpectedError(err); diff --git a/src/vs/workbench/api/node/mainThreadExtensionService.ts b/src/vs/workbench/api/node/mainThreadExtensionService.ts index f1f00b2f183..4a19404288c 100644 --- a/src/vs/workbench/api/node/mainThreadExtensionService.ts +++ b/src/vs/workbench/api/node/mainThreadExtensionService.ts @@ -12,7 +12,7 @@ import {ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegist import {IMessageService} from 'vs/platform/message/common/message'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; -import {ExtHostContext, ExtHostExtensionServiceShape} from './extHostProtocol'; +import {ExtHostContext, ExtHostExtensionServiceShape} from './extHost.protocol'; /** * Represents a failed extension in the ext host. diff --git a/src/vs/workbench/api/node/mainThreadFileSystemEventService.ts b/src/vs/workbench/api/node/mainThreadFileSystemEventService.ts index de2c118eef3..535dcb14d58 100644 --- a/src/vs/workbench/api/node/mainThreadFileSystemEventService.ts +++ b/src/vs/workbench/api/node/mainThreadFileSystemEventService.ts @@ -8,7 +8,7 @@ import {FileChangesEvent, FileChangeType} from 'vs/platform/files/common/files'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import {IEventService} from 'vs/platform/event/common/event'; import {RunOnceScheduler} from 'vs/base/common/async'; -import {ExtHostContext, ExtHostFileSystemEventServiceShape, FileSystemEvents} from './extHostProtocol'; +import {ExtHostContext, ExtHostFileSystemEventServiceShape, FileSystemEvents} from './extHost.protocol'; export class MainThreadFileSystemEventService { @@ -22,7 +22,7 @@ export class MainThreadFileSystemEventService { }; const scheduler = new RunOnceScheduler(() => { - proxy._onFileEvent(events); + proxy.$onFileEvent(events); events.created.length = 0; events.changed.length = 0; events.deleted.length = 0; diff --git a/src/vs/workbench/api/node/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/node/mainThreadLanguageFeatures.ts index 1afe4059d94..355c0ed889d 100644 --- a/src/vs/workbench/api/node/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/node/mainThreadLanguageFeatures.ts @@ -15,15 +15,16 @@ import {wireCancellationToken} from 'vs/base/common/async'; import {CancellationToken} from 'vs/base/common/cancellation'; import {Position as EditorPosition} from 'vs/editor/common/core/position'; import {Range as EditorRange} from 'vs/editor/common/core/range'; -import {ExtHostContext, ExtHostLanguageFeaturesShape} from './extHostProtocol'; +import {ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape} from './extHost.protocol'; import {LanguageConfigurationRegistry, LanguageConfiguration} from 'vs/editor/common/modes/languageConfigurationRegistry'; -export class MainThreadLanguageFeatures { +export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape { private _proxy: ExtHostLanguageFeaturesShape; private _registrations: { [handle: number]: IDisposable; } = Object.create(null); constructor( @IThreadService threadService: IThreadService) { + super(); this._proxy = threadService.get(ExtHostContext.ExtHostLanguageFeatures); } diff --git a/src/vs/workbench/api/node/mainThreadLanguages.ts b/src/vs/workbench/api/node/mainThreadLanguages.ts index 7f5df0fbd6b..3abbc3e7b75 100644 --- a/src/vs/workbench/api/node/mainThreadLanguages.ts +++ b/src/vs/workbench/api/node/mainThreadLanguages.ts @@ -6,18 +6,20 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {IModeService} from 'vs/editor/common/services/modeService'; +import {MainThreadLanguagesShape} from './extHost.protocol'; -export class MainThreadLanguages { +export class MainThreadLanguages extends MainThreadLanguagesShape { private _modeService: IModeService; constructor( @IModeService modeService: IModeService ) { + super(); this._modeService = modeService; } - _getLanguages(): TPromise { + $getLanguages(): TPromise { return TPromise.as(this._modeService.getRegisteredModes()); } } diff --git a/src/vs/workbench/api/node/mainThreadMessageService.ts b/src/vs/workbench/api/node/mainThreadMessageService.ts index fbb006ea93f..f00ee755f90 100644 --- a/src/vs/workbench/api/node/mainThreadMessageService.ts +++ b/src/vs/workbench/api/node/mainThreadMessageService.ts @@ -9,12 +9,14 @@ import {IMessageService} from 'vs/platform/message/common/message'; import Severity from 'vs/base/common/severity'; import {Action} from 'vs/base/common/actions'; import {TPromise as Promise} from 'vs/base/common/winjs.base'; +import {MainThreadMessageServiceShape} from './extHost.protocol'; -export class MainThreadMessageService { +export class MainThreadMessageService extends MainThreadMessageServiceShape { private _messageService: IMessageService; constructor(@IMessageService messageService:IMessageService) { + super(); this._messageService = messageService; } diff --git a/src/vs/workbench/api/node/mainThreadOutputService.ts b/src/vs/workbench/api/node/mainThreadOutputService.ts index acf65d094ef..5ee37e826d4 100644 --- a/src/vs/workbench/api/node/mainThreadOutputService.ts +++ b/src/vs/workbench/api/node/mainThreadOutputService.ts @@ -9,8 +9,9 @@ import {Registry} from 'vs/platform/platform'; import {IOutputService, IOutputChannel, OUTPUT_PANEL_ID, Extensions, IOutputChannelRegistry} from 'vs/workbench/parts/output/common/output'; import {IPartService} from 'vs/workbench/services/part/common/partService'; import {IPanelService} from 'vs/workbench/services/panel/common/panelService'; +import {MainThreadOutputServiceShape} from './extHost.protocol'; -export class MainThreadOutputService { +export class MainThreadOutputService extends MainThreadOutputServiceShape { private _outputService: IOutputService; private _partService: IPartService; @@ -20,22 +21,23 @@ export class MainThreadOutputService { @IPartService partService: IPartService, @IPanelService panelService: IPanelService ) { + super(); this._outputService = outputService; this._partService = partService; this._panelService = panelService; } - public append(channelId: string, label: string, value: string): TPromise { + public $append(channelId: string, label: string, value: string): TPromise { this._getChannel(channelId, label).append(value); return undefined; } - public clear(channelId: string, label: string): TPromise { + public $clear(channelId: string, label: string): TPromise { this._getChannel(channelId, label).clear(); return undefined; } - public reveal(channelId: string, label: string, preserveFocus: boolean): TPromise { + public $reveal(channelId: string, label: string, preserveFocus: boolean): TPromise { this._getChannel(channelId, label).show(preserveFocus); return undefined; } @@ -48,7 +50,7 @@ export class MainThreadOutputService { return this._outputService.getChannel(channelId); } - public close(channelId: string): TPromise { + public $close(channelId: string): TPromise { const panel = this._panelService.getActivePanel(); if (panel && panel.getId() === OUTPUT_PANEL_ID && channelId === this._outputService.getActiveChannel().id ) { this._partService.setPanelHidden(true); diff --git a/src/vs/workbench/api/node/mainThreadQuickOpen.ts b/src/vs/workbench/api/node/mainThreadQuickOpen.ts index 5b76c54b218..12a883b2527 100644 --- a/src/vs/workbench/api/node/mainThreadQuickOpen.ts +++ b/src/vs/workbench/api/node/mainThreadQuickOpen.ts @@ -8,9 +8,9 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import {IQuickOpenService, IPickOptions, IInputOptions} from 'vs/workbench/services/quickopen/common/quickOpenService'; import {InputBoxOptions} from 'vscode'; -import {ExtHostContext, ExtHostQuickOpenShape, MyQuickPickItems} from './extHostProtocol'; +import {ExtHostContext, MainThreadQuickOpenShape, ExtHostQuickOpenShape, MyQuickPickItems} from './extHost.protocol'; -export class MainThreadQuickOpen { +export class MainThreadQuickOpen extends MainThreadQuickOpenShape { private _proxy: ExtHostQuickOpenShape; private _quickOpenService: IQuickOpenService; @@ -19,7 +19,11 @@ export class MainThreadQuickOpen { private _contents: TPromise; private _token: number = 0; - constructor( @IThreadService threadService: IThreadService, @IQuickOpenService quickOpenService: IQuickOpenService) { + constructor( + @IThreadService threadService: IThreadService, + @IQuickOpenService quickOpenService: IQuickOpenService + ) { + super(); this._proxy = threadService.get(ExtHostContext.ExtHostQuickOpen); this._quickOpenService = quickOpenService; } diff --git a/src/vs/workbench/api/node/mainThreadStatusBar.ts b/src/vs/workbench/api/node/mainThreadStatusBar.ts index 1de60997c89..811bdbc76b5 100644 --- a/src/vs/workbench/api/node/mainThreadStatusBar.ts +++ b/src/vs/workbench/api/node/mainThreadStatusBar.ts @@ -6,27 +6,29 @@ import {IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment} from 'vs/platform/statusbar/common/statusbar'; import {IDisposable} from 'vs/base/common/lifecycle'; +import {MainThreadStatusBarShape} from './extHost.protocol'; -export class MainThreadStatusBar { +export class MainThreadStatusBar extends MainThreadStatusBarShape { private mapIdToDisposable: { [id: number]: IDisposable }; constructor( @IStatusbarService private statusbarService: IStatusbarService ) { + super(); this.mapIdToDisposable = Object.create(null); } - setEntry(id: number, text: string, tooltip: string, command: string, color: string, alignment: MainThreadStatusBarAlignment, priority: number): void { + $setEntry(id: number, text: string, tooltip: string, command: string, color: string, alignment: MainThreadStatusBarAlignment, priority: number): void { // Dispose any old - this.dispose(id); + this.$dispose(id); // Add new let disposeable = this.statusbarService.addEntry({ text, tooltip, command, color }, alignment, priority); this.mapIdToDisposable[id] = disposeable; } - dispose(id: number) { + $dispose(id: number) { let disposeable = this.mapIdToDisposable[id]; if (disposeable) { disposeable.dispose(); diff --git a/src/vs/workbench/api/node/mainThreadStorage.ts b/src/vs/workbench/api/node/mainThreadStorage.ts index 52bf5ab3c36..6cbc3c63203 100644 --- a/src/vs/workbench/api/node/mainThreadStorage.ts +++ b/src/vs/workbench/api/node/mainThreadStorage.ts @@ -6,16 +6,18 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage'; +import {MainThreadStorageShape} from './extHost.protocol'; -export class MainThreadStorage { +export class MainThreadStorage extends MainThreadStorageShape { private _storageService: IStorageService; constructor( @IStorageService storageService: IStorageService) { + super(); this._storageService = storageService; } - getValue(shared: boolean, key: string): TPromise { + $getValue(shared: boolean, key: string): TPromise { let jsonValue = this._storageService.get(key, shared ? StorageScope.GLOBAL : StorageScope.WORKSPACE); if (!jsonValue) { return TPromise.as(undefined); @@ -29,7 +31,7 @@ export class MainThreadStorage { } } - setValue(shared: boolean, key: string, value: any): TPromise { + $setValue(shared: boolean, key: string, value: any): TPromise { let jsonValue: any; try { jsonValue = JSON.stringify(value); diff --git a/src/vs/workbench/api/node/mainThreadTelemetry.ts b/src/vs/workbench/api/node/mainThreadTelemetry.ts index ee8de9b4c96..5bfd0989768 100644 --- a/src/vs/workbench/api/node/mainThreadTelemetry.ts +++ b/src/vs/workbench/api/node/mainThreadTelemetry.ts @@ -6,15 +6,17 @@ import {TPromise} from 'vs/base/common/winjs.base'; import {ITelemetryService, ITelemetryInfo} from 'vs/platform/telemetry/common/telemetry'; +import {MainThreadTelemetryShape} from './extHost.protocol'; /** * Helper always instantiated in the main process to receive telemetry events from remote telemetry services */ -export class MainThreadTelemetry { +export class MainThreadTelemetry extends MainThreadTelemetryShape { private _telemetryService: ITelemetryService; constructor( @ITelemetryService telemetryService: ITelemetryService) { + super(); this._telemetryService = telemetryService; } diff --git a/src/vs/workbench/api/node/mainThreadWorkspace.ts b/src/vs/workbench/api/node/mainThreadWorkspace.ts index ce5caf37c4c..e5f7a1b6234 100644 --- a/src/vs/workbench/api/node/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/node/mainThreadWorkspace.ts @@ -14,8 +14,9 @@ import {ICommonCodeEditor} from 'vs/editor/common/editorCommon'; import {bulkEdit, IResourceEdit} from 'vs/editor/common/services/bulkEdit'; import {TPromise} from 'vs/base/common/winjs.base'; import {Uri} from 'vscode'; +import {MainThreadWorkspaceShape} from './extHost.protocol'; -export class MainThreadWorkspace { +export class MainThreadWorkspace extends MainThreadWorkspaceShape { private _activeSearches: { [id: number]: TPromise } = Object.create(null); private _searchService: ISearchService; @@ -24,11 +25,14 @@ export class MainThreadWorkspace { private _editorService:IWorkbenchEditorService; private _eventService:IEventService; - constructor( @ISearchService searchService: ISearchService, + constructor( + @ISearchService searchService: ISearchService, @IWorkspaceContextService contextService: IWorkspaceContextService, @ITextFileService textFileService, @IWorkbenchEditorService editorService, - @IEventService eventService) { + @IEventService eventService + ) { + super(); this._searchService = searchService; this._workspace = contextService.getWorkspace(); diff --git a/src/vs/workbench/browser/media/part.css b/src/vs/workbench/browser/media/part.css index c0ae50a59d3..70e4eb61d62 100644 --- a/src/vs/workbench/browser/media/part.css +++ b/src/vs/workbench/browser/media/part.css @@ -10,7 +10,7 @@ /* title styles are defined for two classes because the editor puts the title into the content */ .monaco-workbench > .part > .title, -.monaco-workbench > .part.editor > .content > .one-editor-container > .title { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title { height: 35px; display: flex; box-sizing: border-box; @@ -71,7 +71,7 @@ position: absolute; left: 0; top: 33px; /* at the bottom of the 35px height title container */ - z-index: 1; + z-index: 5; /* on top of things */ height: 2px; } diff --git a/src/vs/workbench/browser/parts/activitybar/media/activityaction.css b/src/vs/workbench/browser/parts/activitybar/media/activityaction.css index cf2c22953ad..09b21680eda 100644 --- a/src/vs/workbench/browser/parts/activitybar/media/activityaction.css +++ b/src/vs/workbench/browser/parts/activitybar/media/activityaction.css @@ -25,7 +25,6 @@ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.8); } -.monaco-workbench > .activitybar > .content .monaco-action-bar .badge:active:before, .monaco-workbench > .activitybar > .content .monaco-action-bar .action-item .action-label:focus:before { content: ""; position: absolute; @@ -35,24 +34,19 @@ border-left: 2px solid; } -.vs .monaco-workbench > .activitybar > .content .monaco-action-bar .badge:active:before, -.vs-dark .monaco-workbench > .activitybar > .content .monaco-action-bar .badge:active:before, .vs .monaco-workbench > .activitybar > .content .monaco-action-bar .action-item .action-label:focus:before, .vs-dark .monaco-workbench > .activitybar > .content .monaco-action-bar .action-item .action-label:focus:before { border-left-color: #007ACC; } -.hc-black .monaco-workbench > .activitybar > .content .monaco-action-bar .badge:active:before, .hc-black .monaco-workbench > .activitybar > .content .monaco-action-bar .action-item .action-label:focus:before { border-left-color: #f38518; } -.monaco-workbench > .activitybar.left > .content .monaco-action-bar .badge:active:before, .monaco-workbench > .activitybar.left > .content .monaco-action-bar .action-item .action-label:focus:before { left: 1px; } -.monaco-workbench > .activitybar.right > .content .monaco-action-bar .badge:active:before, .monaco-workbench > .activitybar.right > .content .monaco-action-bar .action-item .action-label:focus:before { right: 1px; } @@ -135,6 +129,7 @@ } .hc-black .monaco-workbench > .activitybar > .content .monaco-action-bar .action-label:before { + content: ""; opacity: 0.6; position: absolute; top: 4px; diff --git a/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts b/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts index afe662f9788..fb414b5d727 100644 --- a/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts @@ -109,15 +109,15 @@ export class BinaryResourceDiffEditor extends BaseEditor implements IVerticalSas // Render original let original = resolvedModel.originalModel; - this.renderInput(original.getName(), original.getResource(), true); + this.renderInput(original.getName(), original.getResource(), original.getSize(), true); // Render modified let modified = resolvedModel.modifiedModel; - this.renderInput(modified.getName(), modified.getResource(), false); + this.renderInput(modified.getName(), modified.getResource(), modified.getSize(), false); }); } - private renderInput(name: string, resource: URI, isOriginal: boolean): void { + private renderInput(name: string, resource: URI, size: number, isOriginal: boolean): void { // Reset Sash to default 50/50 ratio if needed if (this.leftContainerWidth && this.dimension && this.leftContainerWidth !== this.dimension.width / 2) { @@ -130,7 +130,7 @@ export class BinaryResourceDiffEditor extends BaseEditor implements IVerticalSas let container = isOriginal ? this.leftBinaryContainer : this.rightBinaryContainer; let scrollbar = isOriginal ? this.leftScrollbar : this.rightScrollbar; - ResourceViewer.show(name, resource, container, scrollbar); + ResourceViewer.show({ name, resource, size }, container, scrollbar); } public clearInput(): void { diff --git a/src/vs/workbench/browser/parts/editor/binaryEditor.ts b/src/vs/workbench/browser/parts/editor/binaryEditor.ts index c094e3f8c64..a561fa124a6 100644 --- a/src/vs/workbench/browser/parts/editor/binaryEditor.ts +++ b/src/vs/workbench/browser/parts/editor/binaryEditor.ts @@ -75,8 +75,8 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor { } // Render Input - let binaryResourceModel = resolvedModel; - ResourceViewer.show(binaryResourceModel.getName(), binaryResourceModel.getResource(), this.binaryContainer, this.scrollbar); + let model = resolvedModel; + ResourceViewer.show({ name: model.getName(), resource: model.getResource(), size: model.getSize() }, this.binaryContainer, this.scrollbar); return TPromise.as(null); }); diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 469ac27d19d..2dc18921018 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -91,7 +91,6 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // The following data structures are partitioned into array of Position as provided by Services.POSITION array private visibleEditors: BaseEditor[]; private instantiatedEditors: BaseEditor[][]; - private mapEditorToEditorContainers: { [editorId: string]: Builder; }[]; private mapEditorInstantiationPromiseToEditor: { [editorId: string]: TPromise; }[]; private editorOpenToken: number[]; private pendingEditorInputsToClose: EditorIdentifier[]; @@ -120,7 +119,6 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService this.instantiatedEditors = arrays.fill(POSITIONS.length, () => []); - this.mapEditorToEditorContainers = arrays.fill(POSITIONS.length, () => Object.create(null)); this.mapEditorInstantiationPromiseToEditor = arrays.fill(POSITIONS.length, () => Object.create(null)); this.pendingEditorInputsToClose = []; @@ -205,14 +203,14 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } // Emit early open event to allow for veto - let event = new EditorInputEvent(input); + const event = new EditorInputEvent(input); this._onEditorOpening.fire(event); if (event.isPrevented()) { return TPromise.as(null); } // We need an editor descriptor for the input - let descriptor = Registry.as(EditorExtensions.Editors).getEditor(input); + const descriptor = Registry.as(EditorExtensions.Editors).getEditor(input); if (!descriptor) { return TPromise.wrapError(new Error(strings.format('Can not find a registered editor for the input {0}', input))); } @@ -249,7 +247,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService this.editorOpenToken[position]++; const editorOpenToken = this.editorOpenToken[position]; const monitor = new ProgressMonitor(editorOpenToken, TPromise.timeout(this.partService.isCreated() ? 800 : 3200 /* less ugly initial startup */).then(() => { - let position = this.stacks.positionOfGroup(group); // might have changed due to a rochade meanwhile + const position = this.stacks.positionOfGroup(group); // might have changed due to a rochade meanwhile if (editorOpenToken === this.editorOpenToken[position]) { this.sideBySideControl.updateProgress(position, ProgressState.INFINITE); @@ -268,7 +266,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } private doShowEditor(group: EditorGroup, descriptor: IEditorDescriptor, input: EditorInput, options: EditorOptions, widthRatios: number[], monitor: ProgressMonitor): TPromise { - let position = this.stacks.positionOfGroup(group); + const position = this.stacks.positionOfGroup(group); const editorAtPosition = this.visibleEditors[position]; // Return early if the currently visible editor can handle the input @@ -282,9 +280,9 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } // Create Editor - let timerEvent = timer.start(timer.Topic.WORKBENCH, strings.format('Creating Editor: {0}', descriptor.getName())); + const timerEvent = timer.start(timer.Topic.WORKBENCH, strings.format('Creating Editor: {0}', descriptor.getName())); return this.doCreateEditor(group, descriptor, monitor).then(editor => { - let position = this.stacks.positionOfGroup(group); // might have changed due to a rochade meanwhile + const position = this.stacks.positionOfGroup(group); // might have changed due to a rochade meanwhile // Make sure that the user meanwhile did not open another editor or something went wrong if (!editor || !this.visibleEditors[position] || editor.getId() !== this.visibleEditors[position].getId()) { @@ -295,7 +293,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } // Show in side by side control - this.sideBySideControl.show(editor, this.mapEditorToEditorContainers[position][descriptor.getId()], position, options && options.preserveFocus, widthRatios); + this.sideBySideControl.show(editor, position, options && options.preserveFocus, widthRatios); // Indicate to editor that it is now visible editor.setVisible(true, position); @@ -307,33 +305,14 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService return editor; - }, (e: any) => this.messageService.show(Severity.Error, types.isString(e) ? new Error(e) : e)); + }, e => this.messageService.show(Severity.Error, types.isString(e) ? new Error(e) : e)); } private doCreateEditor(group: EditorGroup, descriptor: IEditorDescriptor, monitor: ProgressMonitor): TPromise { - let position = this.stacks.positionOfGroup(group); - - // We need the container for this editor now - let editorContainer = this.mapEditorToEditorContainers[position][descriptor.getId()]; - let newlyCreatedEditorContainerBuilder: Builder; - if (!editorContainer) { - - // Build Container off-DOM - editorContainer = $().div({ - 'class': 'editor-container', - 'role': 'tabpanel', - id: descriptor.getId() - }, (div) => { - newlyCreatedEditorContainerBuilder = div; - }); - - // Remember editor container - this.mapEditorToEditorContainers[position][descriptor.getId()] = editorContainer; - } // Instantiate editor return this.doInstantiateEditor(group, descriptor).then(editor => { - let position = this.stacks.positionOfGroup(group); // might have changed due to a rochade meanwhile + const position = this.stacks.positionOfGroup(group); // might have changed due to a rochade meanwhile // Make sure that the user meanwhile did not open another editor if (monitor.token !== this.editorOpenToken[position]) { @@ -346,8 +325,12 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService this.visibleEditors[position] = editor; // Create editor as needed - if (newlyCreatedEditorContainerBuilder) { - editor.create(newlyCreatedEditorContainerBuilder); + if (!editor.getContainer()) { + editor.create($().div({ + 'class': 'editor-container', + 'role': 'tabpanel', + id: descriptor.getId() + })); } return editor; @@ -355,27 +338,27 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } private doInstantiateEditor(group: EditorGroup, descriptor: IEditorDescriptor): TPromise { - let position = this.stacks.positionOfGroup(group); + const position = this.stacks.positionOfGroup(group); // Return early if already instantiated - let instantiatedEditor = this.instantiatedEditors[position].filter(e => descriptor.describes(e))[0]; + const instantiatedEditor = this.instantiatedEditors[position].filter(e => descriptor.describes(e))[0]; if (instantiatedEditor) { return TPromise.as(instantiatedEditor); } // Return early if editor is being instantiated at the same time from a previous call - let pendingEditorInstantiate = this.mapEditorInstantiationPromiseToEditor[position][descriptor.getId()]; + const pendingEditorInstantiate = this.mapEditorInstantiationPromiseToEditor[position][descriptor.getId()]; if (pendingEditorInstantiate) { return pendingEditorInstantiate; } // Otherwise instantiate - let progressService = new WorkbenchProgressService(this.eventService, this.sideBySideControl.getProgressBar(position), descriptor.getId(), true); - let editorInstantiationService = this.sideBySideControl.getInstantiationService(position).createChild(new ServiceCollection([IProgressService, progressService])); + const progressService = new WorkbenchProgressService(this.eventService, this.sideBySideControl.getProgressBar(position), descriptor.getId(), true); + const editorInstantiationService = this.sideBySideControl.getInstantiationService(position).createChild(new ServiceCollection([IProgressService, progressService])); let loaded = false; const onInstantiate = (arg: BaseEditor | Error): TPromise => { - let position = this.stacks.positionOfGroup(group); // might have changed due to a rochade meanwhile + const position = this.stacks.positionOfGroup(group); // might have changed due to a rochade meanwhile loaded = true; delete this.mapEditorInstantiationPromiseToEditor[position][descriptor.getId()]; @@ -389,7 +372,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService return TPromise.wrapError(arg); }; - let instantiateEditorPromise = editorInstantiationService.createInstance(descriptor).then(onInstantiate, onInstantiate); + const instantiateEditorPromise = editorInstantiationService.createInstance(descriptor).then(onInstantiate, onInstantiate); if (!loaded) { this.mapEditorInstantiationPromiseToEditor[position][descriptor.getId()] = instantiateEditorPromise; @@ -435,7 +418,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Fullfill promise with Editor that is being used return editor; - }, (e: any) => this.doHandleSetInputError(e, group, editor, input, options, monitor)); + }, e => this.doHandleSetInputError(e, group, editor, input, options, monitor)); } private doHandleSetInputError(e: Error | IMessageWithAction, group: EditorGroup, editor: BaseEditor, input: EditorInput, options: EditorOptions, monitor: ProgressMonitor): void { @@ -446,7 +429,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Report error only if this was not us restoring previous error state if (this.partService.isCreated() && !errors.isPromiseCanceledError(e)) { - let errorMessage = nls.localize('editorOpenError', "Unable to open '{0}': {1}.", input.getName(), errors.toErrorMessage(e)); + const errorMessage = nls.localize('editorOpenError', "Unable to open '{0}': {1}.", input.getName(), errors.toErrorMessage(e)); let error: any; if (e && (e).actions && (e).actions.length) { @@ -486,12 +469,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService }); } - private doCloseEditor(group: EditorGroup, input: EditorInput, focusNext?: boolean): void { - - // Only focus next if the group is the active one - if (!(typeof focusNext === 'boolean')) { - focusNext = this.stacks.isActive(group); - } + private doCloseEditor(group: EditorGroup, input: EditorInput, focusNext = this.stacks.isActive(group)): void { // Closing the active editor of the group is a bit more work if (group.activeEditor && group.activeEditor.matches(input)) { @@ -512,7 +490,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Close group is this is the last editor in group if (group.count === 0) { - this.doCloseGroup(group); + this.doCloseGroup(group, focusNext); } // Otherwise open next active @@ -527,7 +505,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService group.closeEditor(input); } - private doCloseGroup(group: EditorGroup): void { + private doCloseGroup(group: EditorGroup, focusNext = true): void { const position = this.stacks.positionOfGroup(group); // Update stacks model @@ -542,7 +520,11 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Focus next group if we have an active one left const currentActiveGroup = this.stacks.activeGroup; if (currentActiveGroup) { - this.focusGroup(currentActiveGroup); + if (focusNext) { + this.focusGroup(currentActiveGroup); + } else { + this.activateGroup(currentActiveGroup); + } // Explicitly trigger the focus changed handler because the side by side control will not trigger it unless // the user is actively changing focus with the mouse from left to right. @@ -551,11 +533,10 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } private doHideEditor(position: Position, layoutAndRochade: boolean): void { - let editor = this.visibleEditors[position]; - let editorContainer = this.mapEditorToEditorContainers[position][editor.getId()]; + const editor = this.visibleEditors[position]; // Hide in side by side control - let rochade = this.sideBySideControl.hide(editor, editorContainer, position, layoutAndRochade); + const rochade = this.sideBySideControl.hide(editor, position, layoutAndRochade); // Clear any running Progress this.sideBySideControl.updateProgress(position, ProgressState.STOP); @@ -585,7 +566,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } // Check for dirty and veto - let editorsToClose = arrays.flatten(groups.map(group => group.getEditors().map(editor => { return { group, editor }; }))); + const editorsToClose = arrays.flatten(groups.map(group => group.getEditors().map(editor => { return { group, editor }; }))); return this.handleDirty(editorsToClose).then(veto => { if (veto) { @@ -686,7 +667,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } public getActiveEditorInput(): EditorInput { - let lastActiveEditor = this.getActiveEditor(); + const lastActiveEditor = this.getActiveEditor(); return lastActiveEditor ? lastActiveEditor.input : null; } @@ -700,7 +681,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } public getVisibleEditors(): BaseEditor[] { - return this.visibleEditors ? this.visibleEditors.filter((editor) => !!editor) : []; + return this.visibleEditors ? this.visibleEditors.filter(editor => !!editor) : []; } public moveGroup(from: EditorGroup, to: EditorGroup): void; @@ -727,7 +708,6 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService arrays.move(this.editorOpenToken, fromPosition, toPosition); arrays.move(this.mapEditorInstantiationPromiseToEditor, fromPosition, toPosition); arrays.move(this.instantiatedEditors, fromPosition, toPosition); - arrays.move(this.mapEditorToEditorContainers, fromPosition, toPosition); // Restore focus this.focusGroup(fromGroup); @@ -788,7 +768,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService public createContentArea(parent: Builder): Builder { // Content Container - let contentArea = $(parent) + const contentArea = $(parent) .div() .addClass('content'); @@ -806,13 +786,13 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService private onGroupFocusChanged(): void { // Update stacks model - let activePosition = this.sideBySideControl.getActivePosition(); + const activePosition = this.sideBySideControl.getActivePosition(); if (typeof activePosition === 'number') { this.stacks.setActive(this.stacks.groupAt(activePosition)); } // Emit as change event so that clients get aware of new active editor - let activeEditor = this.sideBySideControl.getActiveEditor(); + const activeEditor = this.sideBySideControl.getActiveEditor(); if (activeEditor) { this._onEditorsChanged.fire(); } @@ -908,7 +888,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService activePosition = this.stacks.positionOfGroup(this.stacks.activeGroup); } - let editorState: IEditorPartUIState = this.memento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY]; + const editorState: IEditorPartUIState = this.memento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY]; return this.doOpenEditors(editors, activePosition, editorState && editorState.widthRatio); } @@ -922,7 +902,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService const centerGroup = this.stacks.groupAt(Position.CENTER); const rightGroup = this.stacks.groupAt(Position.RIGHT); - // Compute the imaginary count if we let all editors open as the way requested + // Compute the imaginary count if we const all editors open as the way requested const leftCount = leftEditors.length + (leftGroup ? leftGroup.count : 0); const centerCount = centerEditors.length + (centerGroup ? centerGroup.count : 0); const rightCount = rightEditors.length + (rightGroup ? rightGroup.count : 0); @@ -952,7 +932,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Open each input respecting the options. Since there can only be one active editor in each // position, we have to pick the first input from each position and add the others as inactive - let promises: TPromise[] = []; + const promises: TPromise[] = []; [leftEditors.shift(), centerEditors.shift(), rightEditors.shift()].forEach((editor, position) => { if (!editor) { return; // unused position @@ -1083,7 +1063,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService public layout(dimension: Dimension): Dimension[] { // Pass to super - let sizes = super.layout(dimension); + const sizes = super.layout(dimension); // Pass to Side by Side Control this.dimension = sizes[1]; @@ -1095,7 +1075,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService public shutdown(): void { // Persist UI State - let editorState: IEditorPartUIState = { widthRatio: this.sideBySideControl.getWidthRatios() }; + const editorState: IEditorPartUIState = { widthRatio: this.sideBySideControl.getWidthRatios() }; this.memento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY] = editorState; // Unload all Instantiated Editors @@ -1110,7 +1090,6 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } public dispose(): void { - this.mapEditorToEditorContainers = null; // Emitters this._onEditorsChanged.dispose(); @@ -1128,7 +1107,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService this.sideBySideControl.dispose(); // Pass to active editors - this.visibleEditors.forEach((editor) => { + this.visibleEditors.forEach(editor => { if (editor) { editor.dispose(); } @@ -1137,7 +1116,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService // Pass to instantiated editors for (var i = 0; i < this.instantiatedEditors.length; i++) { for (var j = 0; j < this.instantiatedEditors[i].length; j++) { - if (this.visibleEditors.some((editor) => editor === this.instantiatedEditors[i][j])) { + if (this.visibleEditors.some(editor => editor === this.instantiatedEditors[i][j])) { continue; } @@ -1161,33 +1140,41 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService } // No editor open - let visibleEditors = this.getVisibleEditors(); - let activeEditor = this.getActiveEditor(); + const visibleEditors = this.getVisibleEditors(); + const activeEditor = this.getActiveEditor(); if (visibleEditors.length === 0 || !activeEditor) { return Position.LEFT; // can only be LEFT } // Respect option to reveal an editor if it is already opened if (options && options.revealIfOpened) { - if (typeof arg1 === 'number') { - const desiredGroup = this.stacks.groupAt(arg1); - if (desiredGroup && desiredGroup.contains(input)) { - return arg1; + + // First check over active and visible editors from left to right + const editorsToCheck: BaseEditor[] = []; + if (activeEditor) { editorsToCheck.push(activeEditor); } + visibleEditors.forEach(e => { if (e !== activeEditor) { editorsToCheck.push(e); }}); + for (let i = 0; i < editorsToCheck.length; i++) { + const editorToCheck = editorsToCheck[i]; + if (input.matches(editorToCheck.input)) { + return editorToCheck.position; } } - const groups = this.stacks.groups; - for (let i = 0; i < groups.length; i++) { - const group = groups[i]; - if (group.contains(input)) { - return this.stacks.positionOfGroup(group); + // Then check over active and visible groups from left to right + const groupsToCheck: EditorGroup[] = []; + if (this.stacks.activeGroup) { groupsToCheck.push(this.stacks.activeGroup); } + this.stacks.groups.forEach(g => { if (g !== this.stacks.activeGroup) { groupsToCheck.push(g); }}); + for (let i = 0; i < groupsToCheck.length; i++) { + const groupToCheck = groupsToCheck[i]; + if (groupToCheck.contains(input)) { + return this.stacks.positionOfGroup(groupToCheck); } } } // Position is unknown: pick last active or LEFT if (types.isUndefinedOrNull(arg1) || arg1 === false) { - let lastActivePosition = this.sideBySideControl.getActivePosition(); + const lastActivePosition = this.sideBySideControl.getActivePosition(); return lastActivePosition || Position.LEFT; } @@ -1236,12 +1223,12 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService }); // Close all hidden first - hiddenEditors.forEach(hidden => this.doCloseEditor(hidden.group, hidden.editor)); + hiddenEditors.forEach(hidden => this.doCloseEditor(hidden.group, hidden.editor, false)); // Close visible ones second visibleEditors .sort((a1, a2) => this.stacks.positionOfGroup(a2.group) - this.stacks.positionOfGroup(a1.group)) // reduce layout work by starting right first - .forEach(visible => this.doCloseEditor(visible.group, visible.editor)); + .forEach(visible => this.doCloseEditor(visible.group, visible.editor, false)); // Reset this.pendingEditorInputCloseTimeout = null; @@ -1254,7 +1241,7 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService private rochade(from: Position, to: Position): void; private rochade(arg1: any, arg2?: any): void { if (types.isUndefinedOrNull(arg2)) { - let rochade = arg1; + const rochade = arg1; switch (rochade) { case Rochade.CENTER_TO_LEFT: this.rochade(Position.CENTER, Position.LEFT); @@ -1267,14 +1254,13 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService this.rochade(Position.RIGHT, Position.CENTER); } } else { - let from = arg1; - let to = arg2; + const from = arg1; + const to = arg2; this.doRochade(this.visibleEditors, from, to, null); this.doRochade(this.editorOpenToken, from, to, null); this.doRochade(this.mapEditorInstantiationPromiseToEditor, from, to, Object.create(null)); this.doRochade(this.instantiatedEditors, from, to, []); - this.doRochade(this.mapEditorToEditorContainers, from, to, Object.create(null)); } } diff --git a/src/vs/workbench/browser/parts/editor/media/chevron-inverse.svg b/src/vs/workbench/browser/parts/editor/media/chevron-inverse.svg deleted file mode 100644 index 05ef1e44f25..00000000000 --- a/src/vs/workbench/browser/parts/editor/media/chevron-inverse.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/vs/workbench/browser/parts/editor/media/chevron.svg b/src/vs/workbench/browser/parts/editor/media/chevron.svg deleted file mode 100644 index 894165c2532..00000000000 --- a/src/vs/workbench/browser/parts/editor/media/chevron.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/src/vs/workbench/browser/parts/editor/media/editorpart.css b/src/vs/workbench/browser/parts/editor/media/editorpart.css index 7e0f7a7161a..b739fc7a5c4 100644 --- a/src/vs/workbench/browser/parts/editor/media/editorpart.css +++ b/src/vs/workbench/browser/parts/editor/media/editorpart.css @@ -21,15 +21,15 @@ } .monaco-workbench .part.editor.empty { - background-image: url('./letterpress.png'); + background-image: url('letterpress.png'); } .vs-dark .monaco-workbench .part.editor.empty { - background-image: url('./letterpress-dark.png'); + background-image: url('letterpress-dark.png'); } .hc-black .monaco-workbench .part.editor.empty { - background-image: url('./letterpress-dark.png'); + background-image: url('letterpress-dark.png'); } @media @@ -40,14 +40,14 @@ } .monaco-workbench .part.editor.empty { - background-image: url('./letterpress@2x.png'); + background-image: url('letterpress@2x.png'); } .vs-dark .monaco-workbench .part.editor.empty { - background-image: url('./letterpress-dark@2x.png'); + background-image: url('letterpress-dark@2x.png'); } .hc-black .monaco-workbench .part.editor.empty { - background-image: url('./letterpress-dark@2x.png'); + background-image: url('letterpress-dark@2x.png'); } -} +} \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/editorpicker.css b/src/vs/workbench/browser/parts/editor/media/editorpicker.css index 77daa11a130..079637a13a1 100644 --- a/src/vs/workbench/browser/parts/editor/media/editorpicker.css +++ b/src/vs/workbench/browser/parts/editor/media/editorpicker.css @@ -5,8 +5,4 @@ .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry.editor-preview { font-style: italic; -} - -.monaco-workbench.mac .quick-open-widget .quick-open-tree .quick-open-entry.editor-preview { - font-weight: 300; /* makes the italic font appear the same as normal */ } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/forward-inverse.svg b/src/vs/workbench/browser/parts/editor/media/forward-inverse.svg deleted file mode 100644 index d7280f1c715..00000000000 --- a/src/vs/workbench/browser/parts/editor/media/forward-inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/forward.svg b/src/vs/workbench/browser/parts/editor/media/forward.svg deleted file mode 100644 index c63e7250629..00000000000 --- a/src/vs/workbench/browser/parts/editor/media/forward.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/handle.svg b/src/vs/workbench/browser/parts/editor/media/handle.svg deleted file mode 100644 index 99a20e8a58a..00000000000 --- a/src/vs/workbench/browser/parts/editor/media/handle.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/info.svg b/src/vs/workbench/browser/parts/editor/media/info.svg deleted file mode 100644 index 0834f213db6..00000000000 --- a/src/vs/workbench/browser/parts/editor/media/info.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/notabstitle.css b/src/vs/workbench/browser/parts/editor/media/notabstitle.css index 021cd8cbcbd..ecd1e7dda53 100644 --- a/src/vs/workbench/browser/parts/editor/media/notabstitle.css +++ b/src/vs/workbench/browser/parts/editor/media/notabstitle.css @@ -5,29 +5,29 @@ /* Title Decoration */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-decoration { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-decoration { width: 18px; padding-left: 2px; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-decoration.dirty { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-decoration.dirty { background-size: 16px; background-position: left center; background-repeat: no-repeat; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-decoration.dirty { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-decoration.dirty { background: url('close-dirty.svg') center center no-repeat; } -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-decoration.dirty, -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-decoration.dirty { +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-decoration.dirty, +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-decoration.dirty { background: url('close-dirty-inverse.svg') center center no-repeat; } /* Title Label */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label { line-height: 35px; overflow: hidden; text-overflow: ellipsis; @@ -37,27 +37,27 @@ /* Title Description */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label span { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span { margin-left: 0.5em; font-size: 0.9em; cursor: default; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label span { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span { color: rgba(108, 108, 108, 0.7); } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label span { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span { color: rgba(204, 204, 204, 0.7); } /* Title Actions */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-actions { display: flex; flex: initial; opacity: 0.5; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .title-actions { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .title-actions { opacity: 1; } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/sidebyside.css b/src/vs/workbench/browser/parts/editor/media/sidebyside.css index bc0dea04365..571893bf3f5 100644 --- a/src/vs/workbench/browser/parts/editor/media/sidebyside.css +++ b/src/vs/workbench/browser/parts/editor/media/sidebyside.css @@ -50,76 +50,76 @@ border-right: 1px solid #444; } -.monaco-workbench > .editor > .content > .one-editor-container { +.monaco-workbench > .editor > .content > .one-editor-silo { position: absolute; box-sizing: border-box; /* use border box to be able to draw a border as separator between editors */ } -.monaco-workbench > .editor > .content > .one-editor-container.editor-left { +.monaco-workbench > .editor > .content > .one-editor-silo.editor-left { left: 0; } -.monaco-workbench > .editor > .content > .one-editor-container.editor-right { +.monaco-workbench > .editor > .content > .one-editor-silo.editor-right { right: 0; } -.monaco-workbench > .editor > .content > .one-editor-container.dragging { +.monaco-workbench > .editor > .content > .one-editor-silo.dragging { z-index: 2000000; } -.monaco-workbench > .editor > .content.dragging > .one-editor-container { +.monaco-workbench > .editor > .content.dragging > .one-editor-silo { box-sizing: content-box; } -.vs .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-left, -.vs .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-center { +.vs .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-left, +.vs .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-center { border-right: 1px solid #E7E7E7; } -.vs .monaco-workbench > .editor > .content > .one-editor-container.dragging { +.vs .monaco-workbench > .editor > .content > .one-editor-silo.dragging { border-left: 1px solid #E7E7E7; border-right: 1px solid #E7E7E7; } -.vs .monaco-workbench > .editor > .content > .one-editor-container.editor-center, -.vs .monaco-workbench > .editor > .content > .one-editor-container.editor-right, -.vs .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-right { +.vs .monaco-workbench > .editor > .content > .one-editor-silo.editor-center, +.vs .monaco-workbench > .editor > .content > .one-editor-silo.editor-right, +.vs .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-right { border-left: 1px solid #E7E7E7; } -.vs-dark .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-left, -.vs-dark .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-center { +.vs-dark .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-left, +.vs-dark .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-center { border-right: 1px solid #444; } -.vs-dark .monaco-workbench > .editor > .content > .one-editor-container.dragging { +.vs-dark .monaco-workbench > .editor > .content > .one-editor-silo.dragging { border-left: 1px solid #444; border-right: 1px solid #444; } -.vs-dark .monaco-workbench > .editor > .content > .one-editor-container.editor-center, -.vs-dark .monaco-workbench > .editor > .content > .one-editor-container.editor-right, -.vs-dark .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-right { +.vs-dark .monaco-workbench > .editor > .content > .one-editor-silo.editor-center, +.vs-dark .monaco-workbench > .editor > .content > .one-editor-silo.editor-right, +.vs-dark .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-right { border-left: 1px solid #444; } -.hc-black .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-left, -.hc-black .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-center { +.hc-black .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-left, +.hc-black .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-center { border-right: 1px solid #6FC3DF; } -.hc-black .monaco-workbench > .editor > .content > .one-editor-container.dragging { +.hc-black .monaco-workbench > .editor > .content > .one-editor-silo.dragging { border-left: 1px solid #6FC3DF; border-right: 1px solid #6FC3DF; } -.hc-black .monaco-workbench > .editor > .content > .one-editor-container.editor-center, -.hc-black .monaco-workbench > .editor > .content > .one-editor-container.editor-right, -.hc-black .monaco-workbench > .editor > .content.dragging > .one-editor-container.editor-right { +.hc-black .monaco-workbench > .editor > .content > .one-editor-silo.editor-center, +.hc-black .monaco-workbench > .editor > .content > .one-editor-silo.editor-right, +.hc-black .monaco-workbench > .editor > .content.dragging > .one-editor-silo.editor-right { border-left: 1px solid #6FC3DF; } -.monaco-workbench > .editor > .content > .one-editor-container.draggedunder { +.monaco-workbench > .editor > .content > .one-editor-silo.draggedunder { transition: left 200ms ease-out; } @@ -127,6 +127,10 @@ transition-property: right; } -.monaco-workbench > .editor > .content .editor-container { +.monaco-workbench > .editor > .content > .one-editor-silo > .container { + height: 100%; +} + +.monaco-workbench > .editor > .content > .one-editor-silo > .container > .editor-container { height: calc(100% - 35px); /* Editor is below editor title */ } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/tabstitle.css b/src/vs/workbench/browser/parts/editor/media/tabstitle.css index 6a784cc0625..0e401e46d10 100644 --- a/src/vs/workbench/browser/parts/editor/media/tabstitle.css +++ b/src/vs/workbench/browser/parts/editor/media/tabstitle.css @@ -5,64 +5,58 @@ /* Title decoration */ -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title.tabs { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.tabs { background: #F3F3F3; - mix-blend-mode: luminosity; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title.tabs { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.tabs { background: #252526; - mix-blend-mode: luminosity; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.tabs::before { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.tabs::before { display: block; content: ''; position: absolute; top: 34px; width: 100%; - mix-blend-mode: luminosity; z-index: 1; /* on top of tabs */ } -.monaco-workbench > .part.editor > .content.drag > .one-editor-container > .title.tabs::before { - z-index: auto; -} - -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title.tabs::before { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.tabs::before { border-top: 1px solid #DDDDDD; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title.tabs::before { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.tabs::before { border-top: 1px solid #403F3F; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.tabs > .monaco-scrollable-element { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.tabs > .monaco-scrollable-element { flex: 1; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.tabs > .monaco-scrollable-element .scrollbar { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.tabs > .monaco-scrollable-element .scrollbar { z-index: 3; /* on top of tabs */ + cursor: default; } /* Tabs Container */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container { display: flex; height: 35px; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container.scroll { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container.scroll { overflow: scroll !important; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container::-webkit-scrollbar { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container::-webkit-scrollbar { display: none; } /* Tab */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab { display: flex; width: 120px; min-width: fit-content; @@ -75,73 +69,59 @@ padding-left: 10px; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.active { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.active { z-index: 2; /* on top of the horizontal border of the title */ } -.monaco-workbench > .part.editor > .content.drag > .one-editor-container > .title .tabs-container > .tab.active { +.monaco-workbench > .part.editor > .content.dragged-over > .one-editor-silo > .container > .title .tabs-container > .tab.active { z-index: auto; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab:not(.active) { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab:not(.active) { background-color: #ECECEC; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab:not(.active) { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab:not(.active) { background-color: #2D2D2D; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label, -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label { - opacity: 0.7 !important; -} - -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label { - opacity: 0.5 !important; -} - -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.active .tab-label, -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dropfeedback .tab-label { - opacity: 1 !important; -} - -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab { border-left-color: #DDDDDD; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.active:last-child { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.active:last-child { border-right-color: #DDDDDD; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab { border-left-color: #403F3F; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.active:last-child { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.active:last-child { border-right-color: #403F3F; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab:first-child, -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab:first-child { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab:first-child, +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab:first-child { border-left-color: transparent; } -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.active { +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.active { border: 1px solid #f38518; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container.dropfeedback, -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dropfeedback { - background-color: rgba(51,153,255, 0.18); +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container.dropfeedback, +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dropfeedback { + background-color: #DDECFF; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container.dropfeedback, -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dropfeedback { - background-color: rgba(83, 89, 93, 0.5); +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container.dropfeedback, +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dropfeedback { + background-color: #383B3D; } -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container.dropfeedback, -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dropfeedback { +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container.dropfeedback, +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dropfeedback { background: none !important; outline: 2px dashed #f38518; outline-offset: -2px; @@ -149,37 +129,54 @@ /* Tab Label */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label { margin-top: auto; margin-bottom: auto; } +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label { + opacity: 0.7 !important; +} + +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label { + opacity: 0.5 !important; +} + +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.active .tab-label, +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dropfeedback .tab-label { + opacity: 1 !important; +} + +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label { + opacity: 1 !important; +} + /* Tab Close */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab > .tab-close { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab > .tab-close { margin-top: auto; margin-bottom: auto; width: 28px; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .tabs-container > .tab.active > .tab-close .action-label, /* always show it for active tab */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .tabs-container > .tab > .tab-close .action-label:focus, /* always show it on focus */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .tabs-container > .tab:hover > .tab-close .action-label, /* always show it on hover */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .tabs-container > .tab.active:hover > .tab-close .action-label, /* always show it on hover */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty > .tab-close .action-label { /* always show it for dirty tabs */ +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .tabs-container > .tab.active > .tab-close .action-label, /* always show it for active tab */ +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .tabs-container > .tab > .tab-close .action-label:focus, /* always show it on focus */ +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .tabs-container > .tab:hover > .tab-close .action-label, /* always show it on hover */ +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .tabs-container > .tab.active:hover > .tab-close .action-label, /* always show it on hover */ +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dirty > .tab-close .action-label { /* always show it for dirty tabs */ opacity: 1; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.active > .tab-close .action-label, /* show dimmed for inactive group */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.active:hover > .tab-close .action-label { /* show dimmed for inactive group */ +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.active > .tab-close .action-label, /* show dimmed for inactive group */ +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.active:hover > .tab-close .action-label { /* show dimmed for inactive group */ opacity: 0.5; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab:hover > .tab-close .action-label { /* show more dimmed for inactive group and tab */ +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab:hover > .tab-close .action-label { /* show more dimmed for inactive group and tab */ opacity: 0.4; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab > .tab-close .action-label { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab > .tab-close .action-label { opacity: 0; display: block; height: 16px; @@ -190,39 +187,27 @@ margin-right: 0.5em; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dirty .close-editor-action { background: url('close-dirty.svg') center center no-repeat; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dirty .close-editor-action, +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dirty .close-editor-action { background: url('close-dirty-inverse.svg') center center no-repeat; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:hover { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dirty .close-editor-action:hover { background: url('close.svg') center center no-repeat; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:hover { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dirty .close-editor-action:hover, +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.dirty .close-editor-action:hover { background: url('close-inverse.svg') center center no-repeat; } -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action, -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:hover { - background: none; -} +/* Editor Actions */ -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action { - content: url('close-dirty-inverse.svg'); -} - -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .close-editor-action, -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.dirty .close-editor-action:hover { - content: url('close-inverse.svg'); -} - -/* Group Actions */ - -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .group-actions { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .editor-actions { flex: initial; padding-left: 4px; } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/textdiffeditor.css b/src/vs/workbench/browser/parts/editor/media/textdiffeditor.css index 93b7016896c..58ac50f9b94 100644 --- a/src/vs/workbench/browser/parts/editor/media/textdiffeditor.css +++ b/src/vs/workbench/browser/parts/editor/media/textdiffeditor.css @@ -11,27 +11,12 @@ background: url('previous-diff.svg') center center no-repeat; } -.vs-dark .monaco-workbench .textdiff-editor-action.next { +.vs-dark .monaco-workbench .textdiff-editor-action.next, +.hc-black .monaco-workbench .textdiff-editor-action.next { background: url('next-diff-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .textdiff-editor-action.previous { +.vs-dark .monaco-workbench .textdiff-editor-action.previous, +.hc-black .monaco-workbench .textdiff-editor-action.previous { background: url('previous-diff-inverse.svg') center center no-repeat; -} - -/* High Contrast Theming */ -.hc-black .monaco-workbench .textdiff-editor-action:before { - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} - -.hc-black .monaco-workbench .textdiff-editor-action.next:before { - content: url('next-diff-inverse.svg'); -} - -.hc-black .monaco-workbench .textdiff-editor-action.previous:before { - content: url('previous-diff-inverse.svg'); } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/media/titlecontrol.css b/src/vs/workbench/browser/parts/editor/media/titlecontrol.css index 47d1dcd310e..d1982cc0fde 100644 --- a/src/vs/workbench/browser/parts/editor/media/titlecontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/titlecontrol.css @@ -5,54 +5,53 @@ /* Editor Label */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label, -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label, +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label { white-space: nowrap; flex: 1; font-style: italic; } -.monaco-workbench.mac > .part.editor > .content > .one-editor-container > .title .title-label, -.monaco-workbench.mac > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label { - font-weight: 300; /* makes the italic font appear the same as normal */ -} - -.monaco-workbench > .part.editor > .content > .one-editor-container > .title.pinned .title-label, -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab.pinned .tab-label { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.pinned .title-label, +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab.pinned .tab-label { font-style: normal; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a, -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label a { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label a, +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label a { text-decoration: none; font-size: 13px; cursor: pointer; } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a, -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label a { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span { + cursor: pointer; +} + +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label a, +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label a { color: rgba(51, 51, 51, 0.5); } -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .title-label a, -.vs .monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .tabs-container > .tab .tab-label a { +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .title-label a, +.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .tabs-container > .tab .tab-label a { color: #333333; } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-label a, -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title .tabs-container > .tab .tab-label a { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label a, +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label a { color: rgba(255, 255, 255, 0.5); } -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .title-label a, -.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-container > .title.active .tabs-container > .tab .tab-label a { +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .title-label a, +.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title.active .tabs-container > .tab .tab-label a { color: white; } /* Title Actions */ -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions .action-label, -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .group-actions .action-label { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-actions .action-label, +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .editor-actions .action-label { display: block; height: 35px; line-height: 35px; @@ -62,29 +61,28 @@ background-repeat: no-repeat; } -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions .action-label, -.hc-black .monaco-workbench > .part.editor > .content > .one-editor-container > .title .group-actions .action-label { +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-actions .action-label, +.hc-black .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .editor-actions .action-label { line-height: initial; } -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .group-actions .action-label .label, -.monaco-workbench > .part.editor > .content > .one-editor-container > .title .title-actions .action-label .label { +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .editor-actions .action-label .label, +.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-actions .action-label .label { display: none; } /* Drag Cursor */ -.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container > .title, -.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container > .title .title-label a, -.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container > .title .title-label span { +.monaco-workbench > .part.editor > .content.multiple-editors > .one-editor-silo > .container > .title, +.monaco-workbench > .part.editor > .content.multiple-editors > .one-editor-silo > .container > .title .title-label a, +.monaco-workbench > .part.editor > .content.multiple-editors > .one-editor-silo > .container > .title .title-label span { cursor: -webkit-grab; } #monaco-workbench-editor-move-overlay, -.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.drag, -.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.drag > .title, -.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.drag > .title .title-label a, -.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.drag > .title .title-label span, -.monaco-workbench > .part.editor > .content.multiple-editors .one-editor-container.drag .monaco-editor .view-lines { +.monaco-workbench > .part.editor > .content.multiple-editors > .one-editor-silo.drag, +.monaco-workbench > .part.editor > .content.multiple-editors > .one-editor-silo.drag > .container > .title, +.monaco-workbench > .part.editor > .content.multiple-editors > .one-editor-silo.drag > .container > .title .title-label a, +.monaco-workbench > .part.editor > .content.multiple-editors > .one-editor-silo.drag > .container > .title .title-label span { cursor: -webkit-grabbing; } @@ -94,7 +92,8 @@ background: url('close.svg') center center no-repeat; } -.vs-dark .monaco-workbench .close-editor-action { +.vs-dark .monaco-workbench .close-editor-action, +.hc-black .monaco-workbench .close-editor-action { background: url('close-inverse.svg') center center no-repeat; } @@ -102,7 +101,8 @@ background: url('split-editor.svg') center center no-repeat; } -.vs-dark .monaco-workbench .split-editor-action { +.vs-dark .monaco-workbench .split-editor-action, +.hc-black .monaco-workbench .split-editor-action { background: url('split-editor-inverse.svg') center center no-repeat; } @@ -110,41 +110,7 @@ background: url('stackview.svg') center center no-repeat; } -.vs-dark .monaco-workbench .show-group-editors-action { +.vs-dark .monaco-workbench .show-group-editors-action, +.hc-black .monaco-workbench .show-group-editors-action { background: url('stackview-inverse.svg') center center no-repeat; -} - -/* High Contrast Icons */ - -.hc-black .monaco-workbench .close-editor-action, -.hc-black .monaco-workbench .show-group-editors-action, -.hc-black .monaco-workbench .split-editor-action { - background: none; -} - -.hc-black .monaco-workbench .show-group-editors-action:before { - content: url('stackview-inverse.svg'); - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} - -.hc-black .monaco-workbench .close-editor-action:before { - content: url('close-inverse.svg'); - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} - -.hc-black .monaco-workbench .split-editor-action:before { - content: url('split-editor-inverse.svg'); - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts index c3669c73b0e..70ada147ef1 100644 --- a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts @@ -6,13 +6,9 @@ 'use strict'; import 'vs/css!./media/notabstitle'; -import {IAction} from 'vs/base/common/actions'; -import {prepareActions} from 'vs/workbench/browser/actionBarRegistry'; import errors = require('vs/base/common/errors'); -import arrays = require('vs/base/common/arrays'); -import {IEditorGroup, EditorInput} from 'vs/workbench/common/editor'; +import {IEditorGroup} from 'vs/workbench/common/editor'; import DOM = require('vs/base/browser/dom'); -import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; import {TitleControl} from 'vs/workbench/browser/parts/editor/titleControl'; export class NoTabsTitleControl extends TitleControl { @@ -21,12 +17,6 @@ export class NoTabsTitleControl extends TitleControl { private titleDecoration: HTMLElement; private titleDescription: HTMLElement; - private editorActionsToolbar: ToolBar; - - private currentPrimaryEditorActionIds: string[] = []; - private currentSecondaryEditorActionIds: string[] = []; - - public setContext(group: IEditorGroup): void { super.setContext(group); @@ -34,21 +24,15 @@ export class NoTabsTitleControl extends TitleControl { } public create(parent: HTMLElement): void { + super.create(parent); + this.titleContainer = parent; // Pin on double click - this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.DBLCLICK, (e: MouseEvent) => { - DOM.EventHelper.stop(e); - - this.onTitleDoubleClick(); - })); + this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.DBLCLICK, (e: MouseEvent) => this.onTitleDoubleClick(e))); // Detect mouse click - this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.MOUSE_UP, (e: MouseEvent) => { - DOM.EventHelper.stop(e, false); - - this.onTitleClick(e); - })); + this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.MOUSE_UP, (e: MouseEvent) => this.onTitleClick(e))); // Left Title Decoration this.titleDecoration = document.createElement('div'); @@ -65,21 +49,33 @@ export class NoTabsTitleControl extends TitleControl { this.titleDescription = document.createElement('span'); labelContainer.appendChild(this.titleDescription); + // Detect title label & description click + this.toDispose.push(DOM.addDisposableListener(this.titleLabel, DOM.EventType.CLICK, (e: MouseEvent) => this.onTitleLabelClick(e))); + this.toDispose.push(DOM.addDisposableListener(this.titleDescription, DOM.EventType.CLICK, (e: MouseEvent) => this.onTitleLabelClick(e))); + this.titleContainer.appendChild(labelContainer); // Right Actions Container const actionsContainer = document.createElement('div'); DOM.addClass(actionsContainer, 'title-actions'); - - this.editorActionsToolbar = this.doCreateToolbar(actionsContainer); - this.titleContainer.appendChild(actionsContainer); + // Editor actions toolbar + this.createEditorActionsToolBar(actionsContainer); + // Context Menu this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.CONTEXT_MENU, (e: Event) => this.onContextMenu({ group: this.context, editor: this.context.activeEditor }, e, this.titleContainer))); } - private onTitleDoubleClick(): void { + private onTitleLabelClick(e: MouseEvent): void { + DOM.EventHelper.stop(e, false); + if (!this.dragged) { + this.quickOpenService.show(); + } + } + + private onTitleDoubleClick(e: MouseEvent): void { + DOM.EventHelper.stop(e); if (!this.context) { return; } @@ -90,6 +86,7 @@ export class NoTabsTitleControl extends TitleControl { } private onTitleClick(e: MouseEvent): void { + DOM.EventHelper.stop(e, false); if (!this.context) { return; } @@ -115,10 +112,7 @@ export class NoTabsTitleControl extends TitleControl { this.titleLabel.innerText = ''; this.titleDescription.innerText = ''; - this.editorActionsToolbar.setActions([], [])(); - - this.currentPrimaryEditorActionIds = []; - this.currentSecondaryEditorActionIds = []; + this.clearEditorActionsToolbar(); return; // return early if we are being closed } @@ -141,8 +135,8 @@ export class NoTabsTitleControl extends TitleControl { } // Editor Title - let name = editor.getName() || ''; - let description = isActive ? (editor.getDescription() || '') : ''; + const name = editor.getName() || ''; + const description = isActive ? (editor.getDescription() || '') : ''; let verboseDescription = editor.getDescription(true) || ''; if (description === verboseDescription) { verboseDescription = ''; // dont repeat what is already shown @@ -162,34 +156,6 @@ export class NoTabsTitleControl extends TitleControl { } // Update Editor Actions Toolbar - let primaryEditorActions: IAction[] = []; - let secondaryEditorActions: IAction[] = []; - if (isActive) { - const editorActions = this.getEditorActions({ group, editor }); - primaryEditorActions = prepareActions(editorActions.primary); - if (isActive && editor instanceof EditorInput && editor.supportsSplitEditor()) { - primaryEditorActions.push(this.splitEditorAction); - } - secondaryEditorActions = prepareActions(editorActions.secondary); - } - - const primaryEditorActionIds = primaryEditorActions.map(a => a.id); - primaryEditorActionIds.push(this.closeEditorAction.id); - const secondaryEditorActionIds = secondaryEditorActions.map(a => a.id); - - if (!arrays.equals(primaryEditorActionIds, this.currentPrimaryEditorActionIds) || !arrays.equals(secondaryEditorActionIds, this.currentSecondaryEditorActionIds)) { - this.editorActionsToolbar.setActions(primaryEditorActions, secondaryEditorActions)(); - this.editorActionsToolbar.addPrimaryAction(this.closeEditorAction)(); - - this.currentPrimaryEditorActionIds = primaryEditorActionIds; - this.currentSecondaryEditorActionIds = secondaryEditorActionIds; - } - } - - public dispose(): void { - super.dispose(); - - // Toolbars - this.editorActionsToolbar.dispose(); + this.updateEditorActionsToolbar(); } } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts b/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts index 3aa7ddfe28a..1a2d0e308e0 100644 --- a/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts +++ b/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts @@ -15,7 +15,9 @@ import {Sash, ISashEvent, IVerticalSashLayoutProvider} from 'vs/base/browser/ui/ import {ProgressBar} from 'vs/base/browser/ui/progressbar/progressbar'; import {BaseEditor} from 'vs/workbench/browser/parts/editor/baseEditor'; import DOM = require('vs/base/browser/dom'); +import URI from 'vs/base/common/uri'; import errors = require('vs/base/common/errors'); +import {RunOnceScheduler} from 'vs/base/common/async'; import {isMacintosh} from 'vs/base/common/platform'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IContextMenuService} from 'vs/platform/contextview/browser/contextView'; @@ -33,7 +35,7 @@ import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {TabsTitleControl} from 'vs/workbench/browser/parts/editor/tabsTitleControl'; import {TitleControl} from 'vs/workbench/browser/parts/editor/titleControl'; import {NoTabsTitleControl} from 'vs/workbench/browser/parts/editor/noTabsTitleControl'; -import {IEditorStacksModel, IStacksModelChangeEvent, IWorkbenchEditorConfiguration} from 'vs/workbench/common/editor'; +import {IEditorStacksModel, IStacksModelChangeEvent, IWorkbenchEditorConfiguration, IEditorGroup} from 'vs/workbench/common/editor'; import {ITitleAreaControl} from 'vs/workbench/browser/parts/editor/titleControl'; import {extractResources} from 'vs/base/browser/dnd'; @@ -54,8 +56,8 @@ export interface ISideBySideEditorControl { onGroupFocusChanged: Event; - show(editor: BaseEditor, container: Builder, position: Position, preserveActive: boolean, widthRatios?: number[]): void; - hide(editor: BaseEditor, container: Builder, position: Position, layoutAndRochade: boolean): Rochade; + show(editor: BaseEditor, position: Position, preserveActive: boolean, widthRatios?: number[]): void; + hide(editor: BaseEditor, position: Position, layoutAndRochade: boolean): Rochade; setActive(editor: BaseEditor): void; @@ -84,6 +86,10 @@ export interface ISideBySideEditorControl { */ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerticalSashLayoutProvider { + private static TITLE_AREA_CONTROL_KEY = '__titleAreaControl'; + private static PROGRESS_BAR_CONTROL_KEY = '__progressBar'; + private static INSTANTIATION_SERVICE_KEY = '__instantiationService'; + private static MIN_EDITOR_WIDTH = 170; private static EDITOR_TITLE_HEIGHT = 35; private static SNAP_TO_MINIMIZED_THRESHOLD = 50; @@ -94,15 +100,9 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti private dimension: Dimension; private dragging: boolean; - private instantiationServices: IInstantiationService[]; - - private containers: Builder[]; - private containerWidth: number[]; - private containerInitialRatios: number[]; - - private titleContainer: Builder[]; - private titleAreaControl: ITitleAreaControl[]; - private progressBar: ProgressBar[]; + private silos: Builder[]; + private siloWidths: number[]; + private siloInitialRatios: number[]; private leftSash: Sash; private startLeftContainerWidth: number; @@ -111,7 +111,6 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti private startRightContainerWidth: number; private visibleEditors: BaseEditor[]; - private visibleEditorContainers: Builder[]; private lastActiveEditor: BaseEditor; private lastActivePosition: Position; @@ -120,6 +119,9 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti private _onGroupFocusChanged: Emitter; + private onStacksChangeScheduler: RunOnceScheduler; + private stacksChangedBuffer: IStacksModelChangeEvent[]; + private toDispose: IDisposable[]; constructor( @@ -136,27 +138,22 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti @IInstantiationService private instantiationService: IInstantiationService ) { this.stacks = editorGroupService.getStacksModel(); + this.toDispose = []; this.parent = parent; this.dimension = new Dimension(0, 0); - this.instantiationServices = []; - - this.containers = []; - this.containerWidth = []; - - this.titleContainer = []; - this.titleAreaControl = []; - - this.progressBar = []; + this.silos = []; + this.siloWidths = []; this.visibleEditors = []; - this.visibleEditorContainers = []; this.visibleEditorFocusTrackers = []; this._onGroupFocusChanged = new Emitter(); - this.toDispose = []; + this.onStacksChangeScheduler = new RunOnceScheduler(() => this.handleStacksChanged(), 0); + this.toDispose.push(this.onStacksChangeScheduler); + this.stacksChangedBuffer = []; this.create(this.parent); this.registerListeners(); @@ -172,9 +169,10 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti const useTabs = configuration.workbench.editor.showTabs; POSITIONS.forEach(position => { + const titleControl = this.getTitleAreaControl(position); // TItle Container - const titleContainer = this.titleContainer[position]; + const titleContainer = $(titleControl.getContainer()); if (useTabs) { titleContainer.addClass('tabs'); } else { @@ -182,17 +180,16 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // Title Control - const titleControl = this.titleAreaControl[position]; if (titleControl) { const usingTabs = (titleControl instanceof TabsTitleControl); if (usingTabs !== useTabs) { // Dispose old titleControl.dispose(); - this.titleContainer[position].empty(); + titleContainer.empty(); // Create new - this.createTitleControl(position); + this.createTitleControl(this.stacks.groupAt(position), this.silos[position], titleContainer, this.getInstantiationService(position)); } } }); @@ -201,37 +198,52 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti private onExtensionsReady(): void { // Up to date title areas - POSITIONS.forEach(position => this.titleAreaControl[position].update()); + POSITIONS.forEach(position => this.getTitleAreaControl(position).update()); } private onStacksChanged(e: IStacksModelChangeEvent): void { + this.stacksChangedBuffer.push(e); + this.onStacksChangeScheduler.schedule(); + } - // Up to date context + private handleStacksChanged(): void { + + // Read and reset buffer of events + const buffer = this.stacksChangedBuffer; + this.stacksChangedBuffer = []; + + // Up to date context for all title controls POSITIONS.forEach(position => { - this.titleAreaControl[position].setContext(this.stacks.groupAt(position)); + const titleAreaControl = this.getTitleAreaControl(position); + const context = this.stacks.groupAt(position); + titleAreaControl.setContext(context); + if (!context) { + titleAreaControl.refresh(); // clear out the control if the context is no longer present + } }); // Refresh / update if group is visible and has a position - const position = this.stacks.positionOfGroup(e.group); - if (position >= 0) { - if (e.structural) { - this.titleAreaControl[position].refresh(); - } else { - this.titleAreaControl[position].update(); + buffer.forEach(e => { + const position = this.stacks.positionOfGroup(e.group); + if (position >= 0) { // group could be gone by now because we run from a scheduler with timeout + if (e.structural) { + this.getTitleAreaControl(position).refresh(); + } else { + this.getTitleAreaControl(position).update(); + } } - } + }); } public get onGroupFocusChanged(): Event { return this._onGroupFocusChanged.event; } - public show(editor: BaseEditor, container: Builder, position: Position, preserveActive: boolean, widthRatios?: number[]): void { - let visibleEditorCount = this.getVisibleEditorCount(); + public show(editor: BaseEditor, position: Position, preserveActive: boolean, widthRatios?: number[]): void { + const visibleEditorCount = this.getVisibleEditorCount(); // Store into editor bucket this.visibleEditors[position] = editor; - this.visibleEditorContainers[position] = container; // Store as active unless preserveActive is set if (!preserveActive || !this.lastActiveEditor) { @@ -242,29 +254,29 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.trackFocus(editor, position); // Find target container and build into - let target = this.containers[position]; - container.build(target); + const target = this.silos[position].child(); + editor.getContainer().build(target); // Adjust layout according to provided ratios (used when restoring multiple editors at once) if (widthRatios && (widthRatios.length === 2 || widthRatios.length === 3)) { - let hasLayoutInfo = this.dimension && this.dimension.width; + const hasLayoutInfo = this.dimension && this.dimension.width; // We received width ratios but were not layouted yet. So we keep these ratios for when we layout() if (!hasLayoutInfo) { - this.containerInitialRatios = widthRatios; + this.siloInitialRatios = widthRatios; } // Adjust layout: -> [!][!] if (widthRatios.length === 2) { if (hasLayoutInfo) { - this.containerWidth[position] = this.dimension.width * widthRatios[position]; + this.siloWidths[position] = this.dimension.width * widthRatios[position]; } } // Adjust layout: -> [!][!][!] else if (widthRatios.length === 3) { if (hasLayoutInfo) { - this.containerWidth[position] = this.dimension.width * widthRatios[position]; + this.siloWidths[position] = this.dimension.width * widthRatios[position]; } if (this.rightSash.isHidden()) { @@ -285,15 +297,15 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Adjust layout: -> [!] else if (visibleEditorCount === 0 && this.dimension) { - this.containerWidth[position] = this.dimension.width; + this.siloWidths[position] = this.dimension.width; this.layoutContainers(); } // Adjust layout: [] -> []|[!] else if (position === Position.CENTER && this.leftSash.isHidden() && this.rightSash.isHidden() && this.dimension) { - this.containerWidth[Position.LEFT] = this.dimension.width / 2; - this.containerWidth[Position.CENTER] = this.dimension.width - this.containerWidth[Position.LEFT]; + this.siloWidths[Position.LEFT] = this.dimension.width / 2; + this.siloWidths[Position.CENTER] = this.dimension.width - this.siloWidths[Position.LEFT]; this.leftSash.show(); this.leftSash.layout(); @@ -303,9 +315,9 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Adjust layout: []|[] -> []|[]|[!] else if (position === Position.RIGHT && this.rightSash.isHidden() && this.dimension) { - this.containerWidth[Position.LEFT] = this.dimension.width / 3; - this.containerWidth[Position.CENTER] = this.dimension.width / 3; - this.containerWidth[Position.RIGHT] = this.dimension.width - this.containerWidth[Position.LEFT] - this.containerWidth[Position.CENTER]; + this.siloWidths[Position.LEFT] = this.dimension.width / 3; + this.siloWidths[Position.CENTER] = this.dimension.width / 3; + this.siloWidths[Position.RIGHT] = this.dimension.width - this.siloWidths[Position.LEFT] - this.siloWidths[Position.CENTER]; this.leftSash.layout(); this.rightSash.show(); @@ -315,7 +327,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // Show editor container - container.show(); + editor.getContainer().show(); // Styles this.updateParentStyle(); @@ -350,7 +362,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.doSetActive(editor, this.visibleEditors.indexOf(editor)); // Automatically maximize this position if it has min editor width - if (this.containerWidth[this.lastActivePosition] === SideBySideEditorControl.MIN_EDITOR_WIDTH) { + if (this.siloWidths[this.lastActivePosition] === SideBySideEditorControl.MIN_EDITOR_WIDTH) { // Log this fact in telemetry if (this.telemetryService) { @@ -360,16 +372,16 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti let remainingWidth = this.dimension.width; // Minimize all other positions to min width - POSITIONS.forEach((p) => { + POSITIONS.forEach(p => { if (this.lastActivePosition !== p && !!this.visibleEditors[p]) { - this.containerWidth[p] = SideBySideEditorControl.MIN_EDITOR_WIDTH; - remainingWidth -= this.containerWidth[p]; + this.siloWidths[p] = SideBySideEditorControl.MIN_EDITOR_WIDTH; + remainingWidth -= this.siloWidths[p]; } }); // Grow focussed position if there is more width to spend if (remainingWidth > SideBySideEditorControl.MIN_EDITOR_WIDTH) { - this.containerWidth[this.lastActivePosition] = remainingWidth; + this.siloWidths[this.lastActivePosition] = remainingWidth; if (!this.leftSash.isHidden()) { this.leftSash.layout(); @@ -391,16 +403,16 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti private focusNextNonMinimized(): void { // If the current focussed editor is minimized, try to focus the next largest editor - if (!types.isUndefinedOrNull(this.lastActivePosition) && this.containerWidth[this.lastActivePosition] === SideBySideEditorControl.MIN_EDITOR_WIDTH) { + if (!types.isUndefinedOrNull(this.lastActivePosition) && this.siloWidths[this.lastActivePosition] === SideBySideEditorControl.MIN_EDITOR_WIDTH) { let candidate: Position = null; let currentWidth = SideBySideEditorControl.MIN_EDITOR_WIDTH; POSITIONS.forEach(position => { // Skip current active position and check if the editor is larger than min width if (position !== this.lastActivePosition) { - if (this.visibleEditors[position] && this.containerWidth[position] > currentWidth) { + if (this.visibleEditors[position] && this.siloWidths[position] > currentWidth) { candidate = position; - currentWidth = this.containerWidth[position]; + currentWidth = this.siloWidths[position]; } } }); @@ -412,13 +424,13 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } } - public hide(editor: BaseEditor, container: Builder, position: Position, layoutAndRochade: boolean): Rochade { + public hide(editor: BaseEditor, position: Position, layoutAndRochade: boolean): Rochade { let result = Rochade.NONE; - let visibleEditorCount = this.getVisibleEditorCount(); + const visibleEditorCount = this.getVisibleEditorCount(); - let hasCenter = !!this.visibleEditors[Position.CENTER]; - let hasRight = !!this.visibleEditors[Position.RIGHT]; + const hasCenter = !!this.visibleEditors[Position.CENTER]; + const hasRight = !!this.visibleEditors[Position.RIGHT]; // If editor is not showing for position, return if (editor !== this.visibleEditors[position]) { @@ -429,15 +441,14 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.clearPosition(position); // Take editor container offdom and hide - container.offDOM(); - container.hide(); + editor.getContainer().offDOM().hide(); // Adjust layout and rochade if instructed to do so if (layoutAndRochade) { // Adjust layout: [x] -> if (visibleEditorCount === 1) { - this.containerWidth[position] = 0; + this.siloWidths[position] = 0; this.leftSash.hide(); this.rightSash.hide(); @@ -447,8 +458,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Adjust layout: []|[x] -> [] or [x]|[] -> [] else if (hasCenter && !hasRight) { - this.containerWidth[Position.LEFT] = this.dimension.width; - this.containerWidth[Position.CENTER] = 0; + this.siloWidths[Position.LEFT] = this.dimension.width; + this.siloWidths[Position.CENTER] = 0; this.leftSash.hide(); this.rightSash.hide(); @@ -464,9 +475,9 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Adjust layout: []|[]|[x] -> [ ]|[ ] or []|[x]|[] -> [ ]|[ ] or [x]|[]|[] -> [ ]|[ ] else if (hasCenter && hasRight) { - this.containerWidth[Position.LEFT] = this.dimension.width / 2; - this.containerWidth[Position.CENTER] = this.dimension.width - this.containerWidth[Position.LEFT]; - this.containerWidth[Position.RIGHT] = 0; + this.siloWidths[Position.LEFT] = this.dimension.width / 2; + this.siloWidths[Position.CENTER] = this.dimension.width - this.siloWidths[Position.LEFT]; + this.siloWidths[Position.RIGHT] = 0; this.leftSash.layout(); this.rightSash.hide(); @@ -522,7 +533,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } private updateParentStyle(): void { - let editorCount = this.getVisibleEditorCount(); + const editorCount = this.getVisibleEditorCount(); if (editorCount > 1) { this.parent.addClass('multiple-editors'); } else { @@ -545,26 +556,26 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Clear from active editors this.visibleEditors[position] = null; - this.visibleEditorContainers[position] = null; } private rochade(from: Position, to: Position): void { - // Move editor to new position - let editorContainer = this.visibleEditorContainers[from]; - let editor = this.visibleEditors[from]; - editorContainer.offDOM(); - editorContainer.build(this.containers[to]); + // Move container to new position + const containerFrom = this.silos[from].child(); + containerFrom.appendTo(this.silos[to]); + + const containerTo = this.silos[to].child(); + containerTo.appendTo(this.silos[from]); + + // Inform editor + const editor = this.visibleEditors[from]; editor.changePosition(to); // Change data structures - let listeners = this.visibleEditorFocusTrackers[from]; + const listeners = this.visibleEditorFocusTrackers[from]; this.visibleEditorFocusTrackers[to] = listeners; this.visibleEditorFocusTrackers[from] = null; - this.visibleEditorContainers[to] = editorContainer; - this.visibleEditorContainers[from] = null; - this.visibleEditors[to] = editor; this.visibleEditors[from] = null; @@ -575,26 +586,20 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } public move(from: Position, to: Position): void { - let editorContainerPos1: Builder; - let editorPos1: BaseEditor; - let editorContainerPos2: Builder; - let editorPos2: BaseEditor; // Distance 1: Swap Editors if (Math.abs(from - to) === 1) { - // Move editors to new position - editorContainerPos1 = this.visibleEditorContainers[from]; - editorPos1 = this.visibleEditors[from]; - editorContainerPos1.offDOM(); - editorContainerPos1.build(this.containers[to]); - editorPos1.changePosition(to); + // Move containers to new position + const containerFrom = this.silos[from].child(); + containerFrom.appendTo(this.silos[to]); - editorContainerPos2 = this.visibleEditorContainers[to]; - editorPos2 = this.visibleEditors[to]; - editorContainerPos2.offDOM(); - editorContainerPos2.build(this.containers[from]); - editorPos2.changePosition(from); + const containerTo = this.silos[to].child(); + containerTo.appendTo(this.silos[from]); + + // Inform Editors + this.visibleEditors[from].changePosition(to); + this.visibleEditors[to].changePosition(from); // Update last active position accordingly if (this.lastActivePosition === from) { @@ -622,24 +627,20 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti newRightPosition = Position.LEFT; } - // Move editors to new position - editorContainerPos1 = this.visibleEditorContainers[Position.LEFT]; - editorPos1 = this.visibleEditors[Position.LEFT]; - editorContainerPos1.offDOM(); - editorContainerPos1.build(this.containers[newLeftPosition]); - editorPos1.changePosition(newLeftPosition); + // Move containers to new position + const containerPos1 = this.silos[Position.LEFT].child(); + containerPos1.appendTo(this.silos[newLeftPosition]); - editorContainerPos2 = this.visibleEditorContainers[Position.CENTER]; - editorPos2 = this.visibleEditors[Position.CENTER]; - editorContainerPos2.offDOM(); - editorContainerPos2.build(this.containers[newCenterPosition]); - editorPos2.changePosition(newCenterPosition); + const containerPos2 = this.silos[Position.CENTER].child(); + containerPos2.appendTo(this.silos[newCenterPosition]); - let editorContainerPos3 = this.visibleEditorContainers[Position.RIGHT]; - let editorPos3 = this.visibleEditors[Position.RIGHT]; - editorContainerPos3.offDOM(); - editorContainerPos3.build(this.containers[newRightPosition]); - editorPos3.changePosition(newRightPosition); + const containerPos3 = this.silos[Position.RIGHT].child(); + containerPos3.appendTo(this.silos[newRightPosition]); + + // Inform Editors + this.visibleEditors[Position.LEFT].changePosition(newLeftPosition); + this.visibleEditors[Position.CENTER].changePosition(newCenterPosition); + this.visibleEditors[Position.RIGHT].changePosition(newRightPosition); // Update last active position accordingly if (this.lastActivePosition === Position.LEFT) { @@ -652,10 +653,9 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // Change data structures - arrays.move(this.visibleEditorContainers, from, to); arrays.move(this.visibleEditors, from, to); arrays.move(this.visibleEditorFocusTrackers, from, to); - arrays.move(this.containerWidth, from, to); + arrays.move(this.siloWidths, from, to); // Layout if (!this.leftSash.isHidden()) { @@ -675,7 +675,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } let availableWidth = this.dimension.width; - let visibleEditors = this.getVisibleEditorCount(); + const visibleEditors = this.getVisibleEditorCount(); if (visibleEditors <= 1) { return; // need more editors @@ -686,20 +686,20 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti POSITIONS.forEach(position => { if (this.visibleEditors[position]) { if (position !== this.lastActivePosition) { - this.containerWidth[position] = SideBySideEditorControl.MIN_EDITOR_WIDTH; + this.siloWidths[position] = SideBySideEditorControl.MIN_EDITOR_WIDTH; availableWidth -= SideBySideEditorControl.MIN_EDITOR_WIDTH; } } }); - this.containerWidth[this.lastActivePosition] = availableWidth; + this.siloWidths[this.lastActivePosition] = availableWidth; } // Even Widths else if (arrangement === GroupArrangement.EVEN_WIDTH) { POSITIONS.forEach(position => { if (this.visibleEditors[position]) { - this.containerWidth[position] = availableWidth / visibleEditors; + this.siloWidths[position] = availableWidth / visibleEditors; } }); } @@ -708,14 +708,14 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } public getWidthRatios(): number[] { - let ratio: number[] = []; + const ratio: number[] = []; if (this.dimension) { - let fullWidth = this.dimension.width; + const fullWidth = this.dimension.width; POSITIONS.forEach(position => { if (this.visibleEditors[position]) { - ratio.push(this.containerWidth[position] / fullWidth); + ratio.push(this.siloWidths[position] / fullWidth); } }); } @@ -736,8 +736,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Allow to drop into container to open this.enableDropTarget(parent.getHTMLElement()); - // Left Container - this.containers[Position.LEFT] = $(parent).div({ class: 'one-editor-container editor-left monaco-editor-background' }); + // Left Silo + this.silos[Position.LEFT] = $(parent).div({ class: 'one-editor-silo editor-left monaco-editor-background' }); // Left Sash this.leftSash = new Sash(parent.getHTMLElement(), this, { baseSize: 5 }); @@ -747,8 +747,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.toDispose.push(this.leftSash.addListener2('reset', () => this.onLeftSashReset())); this.leftSash.hide(); - // Center Container - this.containers[Position.CENTER] = $(parent).div({ class: 'one-editor-container editor-center monaco-editor-background' }); + // Center Silo + this.silos[Position.CENTER] = $(parent).div({ class: 'one-editor-silo editor-center monaco-editor-background' }); // Right Sash this.rightSash = new Sash(parent.getHTMLElement(), this, { baseSize: 5 }); @@ -758,33 +758,37 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.toDispose.push(this.rightSash.addListener2('reset', () => this.onRightSashReset())); this.rightSash.hide(); - // Right Container - this.containers[Position.RIGHT] = $(parent).div({ class: 'one-editor-container editor-right monaco-editor-background' }); + // Right Silo + this.silos[Position.RIGHT] = $(parent).div({ class: 'one-editor-silo editor-right monaco-editor-background' }); - // InstantiationServices - POSITIONS.forEach(position => { - this.instantiationServices[position] = this.instantiationService.createChild(new ServiceCollection( - [IKeybindingService, this.keybindingService.createScoped(this.containers[position].getHTMLElement())] - )); - }); - - // Title containers + // For each position const useTabs = !!this.configurationService.getConfiguration().workbench.editor.showTabs; POSITIONS.forEach(position => { - this.titleContainer[position] = $(this.containers[position]).div({ 'class': 'title' }); + const silo = this.silos[position]; + + // Containers (they contain everything and can move between silos) + const container = $(silo).div({ 'class': 'container' }); + + // InstantiationServices + const instantiationService = this.instantiationService.createChild(new ServiceCollection( + [IKeybindingService, this.keybindingService.createScoped(container.getHTMLElement())] + )); + container.setProperty(SideBySideEditorControl.INSTANTIATION_SERVICE_KEY, instantiationService); // associate with container + + // Title containers + const titleContainer = $(container).div({ 'class': 'title' }); if (useTabs) { - this.titleContainer[position].addClass('tabs'); + titleContainer.addClass('tabs'); } - this.hookTitleDragListener(position); + this.hookTitleDragListener(titleContainer); // Title Control - this.createTitleControl(position); - }); + this.createTitleControl(this.stacks.groupAt(position), silo, titleContainer, instantiationService); - // Progress Bars per position - POSITIONS.forEach(position => { - this.progressBar[position] = new ProgressBar($(this.containers[position])); - this.progressBar[position].getContainer().hide(); + // Progress Bar + const progressBar = new ProgressBar($(container)); + progressBar.getContainer().hide(); + container.setProperty(SideBySideEditorControl.PROGRESS_BAR_CONTROL_KEY, progressBar); // associate with container }); } @@ -793,11 +797,25 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti const overlayId = 'monaco-workbench-editor-drop-overlay'; const splitToPropertyKey = 'splitToPosition'; const stacks = this.editorGroupService.getStacksModel(); + let overlay: Builder; + let draggedResources: URI[]; + + function cleanUp(): void { + draggedResources = void 0; + + if (overlay) { + overlay.destroy(); + overlay = void 0; + } + + DOM.removeClass(node, 'dragged-over'); + } function onDrop(e: DragEvent, position: Position, splitTo?: Position): void { + const droppedResources = draggedResources; DOM.removeClass(node, 'dropfeedback'); - destroyOverlay(); + cleanUp(); const editorService = $this.editorService; const groupService = $this.editorGroupService; @@ -846,7 +864,6 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Check for URI transfer else { - const droppedResources = extractResources(e).filter(r => r.scheme === 'file' || r.scheme === 'untitled'); if (droppedResources.length) { window.focus(); // make sure this window has focus so that the open call reaches the right window! @@ -864,13 +881,6 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } } - function destroyOverlay(): void { - if (overlay) { - overlay.destroy(); - overlay = void 0; - } - } - function positionOverlay(e: DragEvent, groups: number, position: Position): void { const target = e.target; const posXOnOverlay = e.offsetX; @@ -945,11 +955,14 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Make sure the overlay is visible overlay.style({ opacity: 1 }); + + // Indicate a drag over is happening + DOM.addClass(node, 'dragged-over'); } function createOverlay(target: HTMLElement): void { if (!overlay) { - const containers = $this.visibleEditorContainers.filter(c => !!c); + const containers = $this.visibleEditors.filter(e => !!e).map(e => e.getContainer()); containers.forEach((container, index) => { if (container && DOM.isAncestor(target, container.getHTMLElement())) { const useTabs = !!$this.configurationService.getConfiguration().workbench.editor.showTabs; @@ -971,14 +984,27 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti }); overlay.on([DOM.EventType.DRAG_LEAVE, DOM.EventType.DRAG_END], () => { - destroyOverlay(); + cleanUp(); + }); + + // Under some circumstances we have seen reports where the drop overlay is not being + // cleaned up and as such the editor area remains under the overlay so that you cannot + // type into the editor anymore. This seems related to using VMs and DND via host and + // guest OS, though some users also saw it without VMs. + // To protect against this issue we always destroy the overlay as soon as we detect a + // mouse event over it. The delay is used to guarantee we are not interfering with the + // actual DROP event that can also trigger a mouse over event. + overlay.once(DOM.EventType.MOUSE_OVER, () => { + setTimeout(() => { + cleanUp(); + }, 100); }); } }); } } - // Let a dropped file open inside Code (only if dropped over editor area) + // const a dropped file open inside Code (only if dropped over editor area) this.toDispose.push(DOM.addDisposableListener(node, DOM.EventType.DROP, (e: DragEvent) => { if (e.target === node) { DOM.EventHelper.stop(e, true); @@ -990,6 +1016,16 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Drag over this.toDispose.push(DOM.addDisposableListener(node, DOM.EventType.DRAG_OVER, (e: DragEvent) => { + + // Upon first drag, detect the dragged resources and only take valid ones + if (!draggedResources) { + draggedResources = extractResources(e).filter(r => r.scheme === 'file' || r.scheme === 'untitled'); + } + + if (!draggedResources.length && !TitleControl.getDraggedEditor()) { + return; // do not show drop feedback if we drag invalid resources or no tab around + } + if (e.target === node) { DOM.addClass(node, 'dropfeedback'); } @@ -997,7 +1033,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti const target = e.target; if (target) { if (overlay && target.id !== overlayId) { - destroyOverlay(); // somehow we managed to move the mouse quickly out of the current overlay, so destroy it + cleanUp(); // somehow we managed to move the mouse quickly out of the current overlay, so destroy it } createOverlay(target); @@ -1016,31 +1052,52 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti [node, window].forEach(container => { this.toDispose.push(DOM.addDisposableListener(container, DOM.EventType.DRAG_END, (e: DragEvent) => { DOM.removeClass(node, 'dropfeedback'); - destroyOverlay(); + cleanUp(); })); }); } - private createTitleControl(position: Position): void { + private createTitleControl(context: IEditorGroup, silo: Builder, container: Builder, instantiationService: IInstantiationService): void { const useTabs = !!this.configurationService.getConfiguration().workbench.editor.showTabs; - this.titleAreaControl[position] = this.instantiationServices[position].createInstance(useTabs ? TabsTitleControl : NoTabsTitleControl); - this.titleAreaControl[position].create(this.titleContainer[position].getHTMLElement()); - this.titleAreaControl[position].setContext(this.stacks.groupAt(position)); - this.titleAreaControl[position].refresh(); + const titleAreaControl = instantiationService.createInstance(useTabs ? TabsTitleControl : NoTabsTitleControl); + titleAreaControl.create(container.getHTMLElement()); + titleAreaControl.setContext(context); + titleAreaControl.refresh(true /* instant */); + + silo.child().setProperty(SideBySideEditorControl.TITLE_AREA_CONTROL_KEY, titleAreaControl); // associate with container } - private hookTitleDragListener(position: Position): void { + private findPosition(element: HTMLElement): Position { + let parent = element.parentElement; + while (parent) { + for (let i = 0; i < POSITIONS.length; i++) { + const position = POSITIONS[i]; + if (this.silos[position].getHTMLElement() === parent) { + return position; + } + } + + parent = parent.parentElement; + } + + return null; + } + + private hookTitleDragListener(titleContainer: Builder): void { let wasDragged = false; // Allow to reorder positions by dragging the title - this.titleContainer[position].on(DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => { - if (!this.titleAreaControl[position].allowDragging(e.target || e.srcElement)) { + titleContainer.on(DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => { + const position = this.findPosition(titleContainer.getHTMLElement()); + const titleAreaControl = this.getTitleAreaControl(position); + if (!titleAreaControl.allowDragging(e.target || e.srcElement)) { return; // return early if we are not in the drag zone of the title widget } // Reset flag wasDragged = false; + titleAreaControl.setDragged(false); // Return early if there is only one editor active or the user clicked into the toolbar if (this.getVisibleEditorCount() <= 1) { @@ -1055,7 +1112,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti DOM.EventHelper.stop(e); // Overlay the editor area with a div to be able to capture all mouse events - let overlayDiv = $('div').style({ + const overlayDiv = $('div').style({ top: SideBySideEditorControl.EDITOR_TITLE_HEIGHT + 'px', height: '100%' }).id('monaco-workbench-editor-move-overlay'); @@ -1064,20 +1121,20 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Update flag this.dragging = true; - let visibleEditorCount = this.getVisibleEditorCount(); - let mouseDownEvent = new StandardMouseEvent(e); - let startX = mouseDownEvent.posx; + const visibleEditorCount = this.getVisibleEditorCount(); + const mouseDownEvent = new StandardMouseEvent(e); + const startX = mouseDownEvent.posx; let oldNewLeft: number = null; - this.containers[position].addClass('drag'); + this.silos[position].addClass('drag'); this.parent.addClass('drag'); - let $window = $(window); + const $window = $(window); $window.on(DOM.EventType.MOUSE_MOVE, (e: MouseEvent) => { DOM.EventHelper.stop(e, false); - let mouseMoveEvent = new StandardMouseEvent(e); - let diffX = mouseMoveEvent.posx - startX; + const mouseMoveEvent = new StandardMouseEvent(e); + const diffX = mouseMoveEvent.posx - startX; let newLeft: number = null; if (Math.abs(diffX) > 5) { @@ -1088,7 +1145,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // [ ! ]|[ ]: Moves only to the right but not outside of dimension width to the right case Position.LEFT: { - newLeft = Math.max(-1 /* 1px border accomodation */, Math.min(diffX, this.dimension.width - this.containerWidth[Position.LEFT])); + newLeft = Math.max(-1 /* 1px border accomodation */, Math.min(diffX, this.dimension.width - this.siloWidths[Position.LEFT])); break; } @@ -1096,19 +1153,19 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // [ ]|[ ! ]: Moves only to the left but not outside of dimension width to the left if (visibleEditorCount === 2) { - newLeft = Math.min(this.containerWidth[Position.LEFT], Math.max(-1 /* 1px border accomodation */, this.containerWidth[Position.LEFT] + diffX)); + newLeft = Math.min(this.siloWidths[Position.LEFT], Math.max(-1 /* 1px border accomodation */, this.siloWidths[Position.LEFT] + diffX)); } // [ ]|[ ! ]|[ ]: Moves to left and right but not outside of dimensions width on both sides else { - newLeft = Math.min(this.dimension.width - this.containerWidth[Position.CENTER], Math.max(-1 /* 1px border accomodation */, this.containerWidth[Position.LEFT] + diffX)); + newLeft = Math.min(this.dimension.width - this.siloWidths[Position.CENTER], Math.max(-1 /* 1px border accomodation */, this.siloWidths[Position.LEFT] + diffX)); } break; } // [ ]|[ ]|[ ! ]: Moves to the right but not outside of dimension width on the left side case Position.RIGHT: { - newLeft = Math.min(this.containerWidth[Position.LEFT] + this.containerWidth[Position.CENTER], Math.max(-1 /* 1px border accomodation */, this.containerWidth[Position.LEFT] + this.containerWidth[Position.CENTER] + diffX)); + newLeft = Math.min(this.siloWidths[Position.LEFT] + this.siloWidths[Position.CENTER], Math.max(-1 /* 1px border accomodation */, this.siloWidths[Position.LEFT] + this.siloWidths[Position.CENTER] + diffX)); break; } } @@ -1121,50 +1178,50 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti oldNewLeft = newLeft; // Live drag Feedback - let moveTo: Position = this.findMoveTarget(position, diffX); + const moveTo: Position = this.findMoveTarget(position, diffX); switch (position) { case Position.LEFT: { if (moveTo === Position.LEFT || moveTo === null) { - this.containers[Position.CENTER].style({ left: this.containerWidth[Position.LEFT] + 'px', right: 'auto', borderLeftWidth: '1px' }); - this.containers[Position.RIGHT].style({ left: 'auto', right: 0 }); + this.silos[Position.CENTER].style({ left: this.siloWidths[Position.LEFT] + 'px', right: 'auto', borderLeftWidth: '1px' }); + this.silos[Position.RIGHT].style({ left: 'auto', right: 0 }); } else if (moveTo === Position.CENTER) { - this.containers[Position.CENTER].style({ left: 0, right: 'auto', borderLeftWidth: 0 }); - this.containers[Position.CENTER].addClass('draggedunder'); - this.containers[Position.RIGHT].style({ left: 'auto', right: 0 }); + this.silos[Position.CENTER].style({ left: 0, right: 'auto', borderLeftWidth: 0 }); + this.silos[Position.CENTER].addClass('draggedunder'); + this.silos[Position.RIGHT].style({ left: 'auto', right: 0 }); } else if (moveTo === Position.RIGHT) { - this.containers[Position.CENTER].style({ left: 0, right: 'auto' }); - this.containers[Position.RIGHT].style({ left: 'auto', right: this.containerWidth[Position.LEFT] + 'px' }); - this.containers[Position.RIGHT].addClass('draggedunder'); + this.silos[Position.CENTER].style({ left: 0, right: 'auto' }); + this.silos[Position.RIGHT].style({ left: 'auto', right: this.siloWidths[Position.LEFT] + 'px' }); + this.silos[Position.RIGHT].addClass('draggedunder'); } break; } case Position.CENTER: { if (moveTo === Position.LEFT) { - this.containers[Position.LEFT].style({ left: this.containerWidth[Position.CENTER] + 'px', right: 'auto' }); - this.containers[Position.LEFT].addClass('draggedunder'); + this.silos[Position.LEFT].style({ left: this.siloWidths[Position.CENTER] + 'px', right: 'auto' }); + this.silos[Position.LEFT].addClass('draggedunder'); } else if (moveTo === Position.CENTER || moveTo === null) { - this.containers[Position.LEFT].style({ left: 0, right: 'auto' }); - this.containers[Position.RIGHT].style({ left: 'auto', right: 0 }); + this.silos[Position.LEFT].style({ left: 0, right: 'auto' }); + this.silos[Position.RIGHT].style({ left: 'auto', right: 0 }); } else if (moveTo === Position.RIGHT) { - this.containers[Position.RIGHT].style({ left: 'auto', right: this.containerWidth[Position.CENTER] + 'px' }); - this.containers[Position.RIGHT].addClass('draggedunder'); - this.containers[Position.LEFT].style({ left: 0, right: 'auto' }); + this.silos[Position.RIGHT].style({ left: 'auto', right: this.siloWidths[Position.CENTER] + 'px' }); + this.silos[Position.RIGHT].addClass('draggedunder'); + this.silos[Position.LEFT].style({ left: 0, right: 'auto' }); } break; } case Position.RIGHT: { if (moveTo === Position.LEFT) { - this.containers[Position.LEFT].style({ left: this.containerWidth[Position.RIGHT] + 'px', right: 'auto' }); - this.containers[Position.LEFT].addClass('draggedunder'); + this.silos[Position.LEFT].style({ left: this.siloWidths[Position.RIGHT] + 'px', right: 'auto' }); + this.silos[Position.LEFT].addClass('draggedunder'); } else if (moveTo === Position.CENTER) { - this.containers[Position.LEFT].style({ left: 0, right: 'auto' }); - this.containers[Position.CENTER].style({ left: (this.containerWidth[Position.LEFT] + this.containerWidth[Position.RIGHT]) + 'px', right: 'auto' }); - this.containers[Position.CENTER].addClass('draggedunder'); + this.silos[Position.LEFT].style({ left: 0, right: 'auto' }); + this.silos[Position.CENTER].style({ left: (this.siloWidths[Position.LEFT] + this.siloWidths[Position.RIGHT]) + 'px', right: 'auto' }); + this.silos[Position.CENTER].addClass('draggedunder'); } else if (moveTo === Position.RIGHT || moveTo === null) { - this.containers[Position.LEFT].style({ left: 0, right: 'auto' }); - this.containers[Position.CENTER].style({ left: this.containerWidth[Position.LEFT] + 'px', right: 'auto' }); + this.silos[Position.LEFT].style({ left: 0, right: 'auto' }); + this.silos[Position.CENTER].style({ left: this.siloWidths[Position.LEFT] + 'px', right: 'auto' }); } break; } @@ -1172,8 +1229,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Move the editor to provide feedback to the user and add class if (newLeft !== null) { - this.containers[position].style({ left: newLeft + 'px' }); - this.containers[position].addClass('dragging'); + this.silos[position].style({ left: newLeft + 'px' }); + this.silos[position].addClass('dragging'); this.parent.addClass('dragging'); } }).once(DOM.EventType.MOUSE_UP, (e: MouseEvent) => { @@ -1184,31 +1241,28 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Update flag this.dragging = false; + if (wasDragged) { + titleAreaControl.setDragged(true); + } // Restore styles this.parent.removeClass('drag'); - this.containers[position].removeClass('drag'); + this.silos[position].removeClass('drag'); this.parent.removeClass('dragging'); - this.containers[position].removeClass('dragging'); - POSITIONS.forEach((p) => this.containers[p].removeClass('draggedunder')); - this.containers[Position.LEFT].style({ left: 0, right: 'auto' }); - this.containers[Position.CENTER].style({ left: 'auto', right: 'auto', borderLeftWidth: '1px' }); - this.containers[Position.RIGHT].style({ left: 'auto', right: 0, borderLeftWidth: '1px' }); + this.silos[position].removeClass('dragging'); + POSITIONS.forEach(p => this.silos[p].removeClass('draggedunder')); + this.silos[Position.LEFT].style({ left: 0, right: 'auto' }); + this.silos[Position.CENTER].style({ left: 'auto', right: 'auto', borderLeftWidth: '1px' }); + this.silos[Position.RIGHT].style({ left: 'auto', right: 0, borderLeftWidth: '1px' }); // Find move target - let mouseUpEvent = new StandardMouseEvent(e); - let diffX = mouseUpEvent.posx - startX; - let moveTo: Position = this.findMoveTarget(position, diffX); + const mouseUpEvent = new StandardMouseEvent(e); + const diffX = mouseUpEvent.posx - startX; + const moveTo: Position = this.findMoveTarget(position, diffX); // Move to valid position if any if (moveTo !== null) { this.editorGroupService.moveGroup(position, moveTo); - - // To reduce flickering during this operation we trigger a refresh of all - // title controls right after. - POSITIONS.forEach(p => { - this.titleAreaControl[p].refresh(true); - }); } // Otherwise layout to restore proper positioning @@ -1227,23 +1281,23 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } private findMoveTarget(position: Position, diffX: number): Position { - let visibleEditorCount = this.getVisibleEditorCount(); + const visibleEditorCount = this.getVisibleEditorCount(); switch (position) { case Position.LEFT: { // [ ! ]|[] -> []|[ ! ] - if (visibleEditorCount === 2 && (diffX >= this.containerWidth[Position.LEFT] / 2 || diffX >= this.containerWidth[Position.CENTER] / 2)) { + if (visibleEditorCount === 2 && (diffX >= this.siloWidths[Position.LEFT] / 2 || diffX >= this.siloWidths[Position.CENTER] / 2)) { return Position.CENTER; } // [ ! ]|[]|[] -> []|[]|[ ! ] - if (visibleEditorCount === 3 && (diffX >= this.containerWidth[Position.LEFT] / 2 + this.containerWidth[Position.CENTER] || diffX >= this.containerWidth[Position.RIGHT] / 2 + this.containerWidth[Position.CENTER])) { + if (visibleEditorCount === 3 && (diffX >= this.siloWidths[Position.LEFT] / 2 + this.siloWidths[Position.CENTER] || diffX >= this.siloWidths[Position.RIGHT] / 2 + this.siloWidths[Position.CENTER])) { return Position.RIGHT; } // [ ! ]|[]|[] -> []|[ ! ]|[] - if (visibleEditorCount === 3 && (diffX >= this.containerWidth[Position.LEFT] / 2 || diffX >= this.containerWidth[Position.CENTER] / 2)) { + if (visibleEditorCount === 3 && (diffX >= this.siloWidths[Position.LEFT] / 2 || diffX >= this.siloWidths[Position.CENTER] / 2)) { return Position.CENTER; } break; @@ -1255,17 +1309,17 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // []|[ ! ] -> [ ! ]|[] - if (visibleEditorCount === 2 && (Math.abs(diffX) >= this.containerWidth[Position.CENTER] / 2 || Math.abs(diffX) >= this.containerWidth[Position.LEFT] / 2)) { + if (visibleEditorCount === 2 && (Math.abs(diffX) >= this.siloWidths[Position.CENTER] / 2 || Math.abs(diffX) >= this.siloWidths[Position.LEFT] / 2)) { return Position.LEFT; } // []|[ ! ]|[] -> [ ! ]|[]|[] - if (visibleEditorCount === 3 && ((diffX < 0 && Math.abs(diffX) >= this.containerWidth[Position.CENTER] / 2) || (diffX < 0 && Math.abs(diffX) >= this.containerWidth[Position.LEFT] / 2))) { + if (visibleEditorCount === 3 && ((diffX < 0 && Math.abs(diffX) >= this.siloWidths[Position.CENTER] / 2) || (diffX < 0 && Math.abs(diffX) >= this.siloWidths[Position.LEFT] / 2))) { return Position.LEFT; } // []|[ ! ]|[] -> []|[]|[ ! ] - if (visibleEditorCount === 3 && ((diffX > 0 && Math.abs(diffX) >= this.containerWidth[Position.CENTER] / 2) || (diffX > 0 && Math.abs(diffX) >= this.containerWidth[Position.RIGHT] / 2))) { + if (visibleEditorCount === 3 && ((diffX > 0 && Math.abs(diffX) >= this.siloWidths[Position.CENTER] / 2) || (diffX > 0 && Math.abs(diffX) >= this.siloWidths[Position.RIGHT] / 2))) { return Position.RIGHT; } break; @@ -1277,12 +1331,12 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // []|[]|[ ! ] -> [ ! ]|[]|[] - if (Math.abs(diffX) >= this.containerWidth[Position.RIGHT] / 2 + this.containerWidth[Position.CENTER] || Math.abs(diffX) >= this.containerWidth[Position.LEFT] / 2 + this.containerWidth[Position.CENTER]) { + if (Math.abs(diffX) >= this.siloWidths[Position.RIGHT] / 2 + this.siloWidths[Position.CENTER] || Math.abs(diffX) >= this.siloWidths[Position.LEFT] / 2 + this.siloWidths[Position.CENTER]) { return Position.LEFT; } // []|[]|[ ! ] -> []|[ ! ]|[] - if (Math.abs(diffX) >= this.containerWidth[Position.RIGHT] / 2 || Math.abs(diffX) >= this.containerWidth[Position.CENTER] / 2) { + if (Math.abs(diffX) >= this.siloWidths[Position.RIGHT] / 2 || Math.abs(diffX) >= this.siloWidths[Position.CENTER] / 2) { return Position.CENTER; } break; @@ -1293,19 +1347,19 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } private centerSash(a: Position, b: Position): void { - let sumWidth = this.containerWidth[a] + this.containerWidth[b]; - let meanWidth = sumWidth / 2; - this.containerWidth[a] = meanWidth; - this.containerWidth[b] = sumWidth - meanWidth; + const sumWidth = this.siloWidths[a] + this.siloWidths[b]; + const meanWidth = sumWidth / 2; + this.siloWidths[a] = meanWidth; + this.siloWidths[b] = sumWidth - meanWidth; this.layoutContainers(); } private onLeftSashDragStart(): void { - this.startLeftContainerWidth = this.containerWidth[Position.LEFT]; + this.startLeftContainerWidth = this.siloWidths[Position.LEFT]; } private onLeftSashDrag(e: ISashEvent): void { - let oldLeftContainerWidth = this.containerWidth[Position.LEFT]; + let oldLeftContainerWidth = this.siloWidths[Position.LEFT]; let newLeftContainerWidth = this.startLeftContainerWidth + e.currentX - e.startX; // Side-by-Side @@ -1331,8 +1385,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti newLeftContainerWidth = this.dimension.width - SideBySideEditorControl.MIN_EDITOR_WIDTH; } - this.containerWidth[Position.LEFT] = newLeftContainerWidth; - this.containerWidth[Position.CENTER] = this.dimension.width - newLeftContainerWidth; + this.siloWidths[Position.LEFT] = newLeftContainerWidth; + this.siloWidths[Position.CENTER] = this.dimension.width - newLeftContainerWidth; } // Side-by-Side-by-Side @@ -1344,22 +1398,22 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // [ ]|[!]|[ ] : center side can not get smaller than MIN_EDITOR_WIDTH - else if (this.dimension.width - newLeftContainerWidth - this.containerWidth[Position.RIGHT] < SideBySideEditorControl.MIN_EDITOR_WIDTH) { + else if (this.dimension.width - newLeftContainerWidth - this.siloWidths[Position.RIGHT] < SideBySideEditorControl.MIN_EDITOR_WIDTH) { // [ ]|[ ]|[!] : right side can not get smaller than MIN_EDITOR_WIDTH - if (this.dimension.width - newLeftContainerWidth - this.containerWidth[Position.CENTER] < SideBySideEditorControl.MIN_EDITOR_WIDTH) { + if (this.dimension.width - newLeftContainerWidth - this.siloWidths[Position.CENTER] < SideBySideEditorControl.MIN_EDITOR_WIDTH) { newLeftContainerWidth = this.dimension.width - (2 * SideBySideEditorControl.MIN_EDITOR_WIDTH); - this.containerWidth[Position.CENTER] = this.containerWidth[Position.RIGHT] = SideBySideEditorControl.MIN_EDITOR_WIDTH; + this.siloWidths[Position.CENTER] = this.siloWidths[Position.RIGHT] = SideBySideEditorControl.MIN_EDITOR_WIDTH; } // [ ]|[ ]|[-> ] : right side can snap into minimized - else if (this.dimension.width - newLeftContainerWidth - this.containerWidth[Position.CENTER] - SideBySideEditorControl.SNAP_TO_MINIMIZED_THRESHOLD <= SideBySideEditorControl.MIN_EDITOR_WIDTH) { - this.containerWidth[Position.RIGHT] = SideBySideEditorControl.MIN_EDITOR_WIDTH; + else if (this.dimension.width - newLeftContainerWidth - this.siloWidths[Position.CENTER] - SideBySideEditorControl.SNAP_TO_MINIMIZED_THRESHOLD <= SideBySideEditorControl.MIN_EDITOR_WIDTH) { + this.siloWidths[Position.RIGHT] = SideBySideEditorControl.MIN_EDITOR_WIDTH; } // [ ]|[ ]|[ ] : right side shrinks else { - this.containerWidth[Position.RIGHT] = this.containerWidth[Position.RIGHT] - (newLeftContainerWidth - oldLeftContainerWidth); + this.siloWidths[Position.RIGHT] = this.siloWidths[Position.RIGHT] - (newLeftContainerWidth - oldLeftContainerWidth); } this.rightSash.layout(); @@ -1371,12 +1425,12 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // [ ]|[-> ]|[ ] : center side can snap into minimized - else if (this.dimension.width - this.containerWidth[Position.RIGHT] - newLeftContainerWidth - SideBySideEditorControl.SNAP_TO_MINIMIZED_THRESHOLD <= SideBySideEditorControl.MIN_EDITOR_WIDTH) { - newLeftContainerWidth = this.dimension.width - this.containerWidth[Position.RIGHT] - SideBySideEditorControl.MIN_EDITOR_WIDTH; + else if (this.dimension.width - this.siloWidths[Position.RIGHT] - newLeftContainerWidth - SideBySideEditorControl.SNAP_TO_MINIMIZED_THRESHOLD <= SideBySideEditorControl.MIN_EDITOR_WIDTH) { + newLeftContainerWidth = this.dimension.width - this.siloWidths[Position.RIGHT] - SideBySideEditorControl.MIN_EDITOR_WIDTH; } - this.containerWidth[Position.LEFT] = newLeftContainerWidth; - this.containerWidth[Position.CENTER] = this.dimension.width - this.containerWidth[Position.LEFT] - this.containerWidth[Position.RIGHT]; + this.siloWidths[Position.LEFT] = newLeftContainerWidth; + this.siloWidths[Position.CENTER] = this.dimension.width - this.siloWidths[Position.LEFT] - this.siloWidths[Position.RIGHT]; } // Pass on to containers @@ -1395,11 +1449,11 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } private onRightSashDragStart(): void { - this.startRightContainerWidth = this.containerWidth[Position.RIGHT]; + this.startRightContainerWidth = this.siloWidths[Position.RIGHT]; } private onRightSashDrag(e: ISashEvent): void { - let oldRightContainerWidth = this.containerWidth[Position.RIGHT]; + let oldRightContainerWidth = this.siloWidths[Position.RIGHT]; let newRightContainerWidth = this.startRightContainerWidth - e.currentX + e.startX; // [ ]|[ ]|[!] : right side can not get smaller than MIN_EDITOR_WIDTH @@ -1408,22 +1462,22 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // [ ]|[!]|[ ] : center side can not get smaller than MIN_EDITOR_WIDTH - else if (this.dimension.width - newRightContainerWidth - this.containerWidth[Position.LEFT] < SideBySideEditorControl.MIN_EDITOR_WIDTH) { + else if (this.dimension.width - newRightContainerWidth - this.siloWidths[Position.LEFT] < SideBySideEditorControl.MIN_EDITOR_WIDTH) { // [!]|[ ]|[ ] : left side can not get smaller than MIN_EDITOR_WIDTH - if (this.dimension.width - newRightContainerWidth - this.containerWidth[Position.CENTER] < SideBySideEditorControl.MIN_EDITOR_WIDTH) { + if (this.dimension.width - newRightContainerWidth - this.siloWidths[Position.CENTER] < SideBySideEditorControl.MIN_EDITOR_WIDTH) { newRightContainerWidth = this.dimension.width - (2 * SideBySideEditorControl.MIN_EDITOR_WIDTH); - this.containerWidth[Position.LEFT] = this.containerWidth[Position.CENTER] = SideBySideEditorControl.MIN_EDITOR_WIDTH; + this.siloWidths[Position.LEFT] = this.siloWidths[Position.CENTER] = SideBySideEditorControl.MIN_EDITOR_WIDTH; } // [ <-]|[ ]|[ ] : left side can snap into minimized - else if (this.dimension.width - newRightContainerWidth - this.containerWidth[Position.CENTER] - SideBySideEditorControl.SNAP_TO_MINIMIZED_THRESHOLD <= SideBySideEditorControl.MIN_EDITOR_WIDTH) { - this.containerWidth[Position.LEFT] = SideBySideEditorControl.MIN_EDITOR_WIDTH; + else if (this.dimension.width - newRightContainerWidth - this.siloWidths[Position.CENTER] - SideBySideEditorControl.SNAP_TO_MINIMIZED_THRESHOLD <= SideBySideEditorControl.MIN_EDITOR_WIDTH) { + this.siloWidths[Position.LEFT] = SideBySideEditorControl.MIN_EDITOR_WIDTH; } // [ ]|[ ]|[ ] : left side shrinks else { - this.containerWidth[Position.LEFT] = this.containerWidth[Position.LEFT] - (newRightContainerWidth - oldRightContainerWidth); + this.siloWidths[Position.LEFT] = this.siloWidths[Position.LEFT] - (newRightContainerWidth - oldRightContainerWidth); } this.leftSash.layout(); @@ -1435,12 +1489,12 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } // [ ]|[ <-]|[ ] : center side can snap into minimized - else if (this.dimension.width - this.containerWidth[Position.LEFT] - newRightContainerWidth - SideBySideEditorControl.SNAP_TO_MINIMIZED_THRESHOLD <= SideBySideEditorControl.MIN_EDITOR_WIDTH) { - newRightContainerWidth = this.dimension.width - this.containerWidth[Position.LEFT] - SideBySideEditorControl.MIN_EDITOR_WIDTH; + else if (this.dimension.width - this.siloWidths[Position.LEFT] - newRightContainerWidth - SideBySideEditorControl.SNAP_TO_MINIMIZED_THRESHOLD <= SideBySideEditorControl.MIN_EDITOR_WIDTH) { + newRightContainerWidth = this.dimension.width - this.siloWidths[Position.LEFT] - SideBySideEditorControl.MIN_EDITOR_WIDTH; } - this.containerWidth[Position.RIGHT] = newRightContainerWidth; - this.containerWidth[Position.CENTER] = this.dimension.width - this.containerWidth[Position.LEFT] - this.containerWidth[Position.RIGHT]; + this.siloWidths[Position.RIGHT] = newRightContainerWidth; + this.siloWidths[Position.CENTER] = this.dimension.width - this.siloWidths[Position.LEFT] - this.siloWidths[Position.RIGHT]; this.layoutContainers(); } @@ -1461,7 +1515,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } public getVerticalSashLeft(sash: Sash): number { - return sash === this.leftSash ? this.containerWidth[Position.LEFT] : this.containerWidth[Position.CENTER] + this.containerWidth[Position.LEFT]; + return sash === this.leftSash ? this.siloWidths[Position.LEFT] : this.siloWidths[Position.CENTER] + this.siloWidths[Position.LEFT]; } public getVerticalSashHeight(sash: Sash): number { @@ -1499,22 +1553,22 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti if (this.visibleEditors[position]) { // Keep minimized editors in tact by not letting them grow if we have width to give - if (this.containerWidth[position] !== SideBySideEditorControl.MIN_EDITOR_WIDTH) { + if (this.siloWidths[position] !== SideBySideEditorControl.MIN_EDITOR_WIDTH) { let sashWidthRatio: number; // We have some stored initial ratios when the editor was restored on startup // Use those ratios over anything else but only once. - if (this.containerInitialRatios && types.isNumber(this.containerInitialRatios[position])) { - sashWidthRatio = this.containerInitialRatios[position]; - delete this.containerInitialRatios[position]; // dont use again + if (this.siloInitialRatios && types.isNumber(this.siloInitialRatios[position])) { + sashWidthRatio = this.siloInitialRatios[position]; + delete this.siloInitialRatios[position]; // dont use again } else { - sashWidthRatio = this.containerWidth[position] / oldDimension.width; + sashWidthRatio = this.siloWidths[position] / oldDimension.width; } - this.containerWidth[position] = Math.max(Math.round(this.dimension.width * sashWidthRatio), SideBySideEditorControl.MIN_EDITOR_WIDTH); + this.siloWidths[position] = Math.max(Math.round(this.dimension.width * sashWidthRatio), SideBySideEditorControl.MIN_EDITOR_WIDTH); } - totalWidth += this.containerWidth[position]; + totalWidth += this.siloWidths[position]; } }); @@ -1530,7 +1584,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // that if the user chose this layout. let positionToGive: Position = null; POSITIONS.forEach(position => { - if (this.visibleEditors[position] && positionToGive === null && this.containerWidth[position] !== SideBySideEditorControl.MIN_EDITOR_WIDTH) { + if (this.visibleEditors[position] && positionToGive === null && this.siloWidths[position] !== SideBySideEditorControl.MIN_EDITOR_WIDTH) { positionToGive = position; } }); @@ -1539,19 +1593,19 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti positionToGive = Position.LEFT; // maybe all are minimized, so give LEFT the extra width } - this.containerWidth[positionToGive] -= overflow; + this.siloWidths[positionToGive] -= overflow; } // We have width to take else if (overflow > 0) { POSITIONS.forEach(position => { - let maxCompensation = this.containerWidth[position] - SideBySideEditorControl.MIN_EDITOR_WIDTH; + const maxCompensation = this.siloWidths[position] - SideBySideEditorControl.MIN_EDITOR_WIDTH; if (maxCompensation >= overflow) { - this.containerWidth[position] -= overflow; + this.siloWidths[position] -= overflow; overflow = 0; } else if (maxCompensation > 0) { - let compensation = overflow - maxCompensation; - this.containerWidth[position] -= compensation; + const compensation = overflow - maxCompensation; + this.siloWidths[position] -= compensation; overflow -= compensation; } }); @@ -1570,22 +1624,22 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Layout containers POSITIONS.forEach(position => { - this.containers[position].size(this.containerWidth[position], this.dimension.height); + this.silos[position].size(this.siloWidths[position], this.dimension.height); }); // Position center depending on visibility of right hand editor if (this.visibleEditors[Position.RIGHT]) { - this.containers[Position.CENTER].position(null, this.containerWidth[Position.RIGHT]); + this.silos[Position.CENTER].position(null, this.siloWidths[Position.RIGHT]); } else { - this.containers[Position.CENTER].position(null, this.dimension.width - this.containerWidth[Position.LEFT] - this.containerWidth[Position.CENTER]); + this.silos[Position.CENTER].position(null, this.dimension.width - this.siloWidths[Position.LEFT] - this.siloWidths[Position.CENTER]); } // Visibility POSITIONS.forEach(position => { - if (this.visibleEditors[position] && this.containers[position].isHidden()) { - this.containers[position].show(); - } else if (!this.visibleEditors[position] && !this.containers[position].isHidden()) { - this.containers[position].hide(); + if (this.visibleEditors[position] && this.silos[position].isHidden()) { + this.silos[position].show(); + } else if (!this.visibleEditors[position] && !this.silos[position].isHidden()) { + this.silos[position].hide(); } }); @@ -1596,35 +1650,43 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Layout title controls POSITIONS.forEach(position => { - this.titleAreaControl[position].layout(); + this.getTitleAreaControl(position).layout(); }); } private layoutEditor(position: Position): void { - let editorWidth = this.containerWidth[position]; + const editorWidth = this.siloWidths[position]; if (editorWidth && this.visibleEditors[position]) { this.visibleEditors[position].layout(new Dimension(editorWidth, this.dimension.height - SideBySideEditorControl.EDITOR_TITLE_HEIGHT)); } } public getInstantiationService(position: Position): IInstantiationService { - return this.instantiationServices[position]; + return this.getFromContainer(position, SideBySideEditorControl.INSTANTIATION_SERVICE_KEY); } public getProgressBar(position: Position): ProgressBar { - return this.progressBar[position]; + return this.getFromContainer(position, SideBySideEditorControl.PROGRESS_BAR_CONTROL_KEY); + } + + private getTitleAreaControl(position: Position): ITitleAreaControl { + return this.getFromContainer(position, SideBySideEditorControl.TITLE_AREA_CONTROL_KEY); + } + + private getFromContainer(position: Position, key: string): any { + return this.silos[position].child().getProperty(key); } public updateProgress(position: Position, state: ProgressState): void { switch (state) { case ProgressState.INFINITE: - this.progressBar[position].infinite().getContainer().show(); + this.getProgressBar(position).infinite().getContainer().show(); break; case ProgressState.DONE: - this.progressBar[position].done().getContainer().hide(); + this.getProgressBar(position).done().getContainer().hide(); break; case ProgressState.STOP: - this.progressBar[position].stop().getContainer().hide(); + this.getProgressBar(position).stop().getContainer().hide(); break; } } @@ -1637,12 +1699,10 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.clearPosition(position); }); - // Title Area Control - this.titleAreaControl.forEach(c => c.dispose()); - - // Progress bars - this.progressBar.forEach((bar) => { - bar.dispose(); + // Controls + POSITIONS.forEach(position => { + this.getTitleAreaControl(position).dispose(); + this.getProgressBar(position).dispose(); }); // Sash @@ -1650,14 +1710,13 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this.rightSash.dispose(); // Destroy Container - this.containers.forEach((container) => { - container.destroy(); + this.silos.forEach(silo => { + silo.destroy(); }); this.lastActiveEditor = null; this.lastActivePosition = null; this.visibleEditors = null; - this.visibleEditorContainers = null; this._onGroupFocusChanged.dispose(); } diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 718a5ccb2da..815c0975e53 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -7,19 +7,15 @@ import 'vs/css!./media/tabstitle'; import nls = require('vs/nls'); -import {IAction} from 'vs/base/common/actions'; -import {prepareActions} from 'vs/workbench/browser/actionBarRegistry'; -import arrays = require('vs/base/common/arrays'); import errors = require('vs/base/common/errors'); import DOM = require('vs/base/browser/dom'); import {isMacintosh} from 'vs/base/common/platform'; import {MIME_BINARY} from 'vs/base/common/mime'; import {Position} from 'vs/platform/editor/common/editor'; import {IEditorGroup, IEditorIdentifier, asFileEditorInput} from 'vs/workbench/common/editor'; -import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent'; import {CommonKeybindings as Kb, KeyCode} from 'vs/base/common/keyCodes'; -import {ActionBar, Separator} from 'vs/base/browser/ui/actionbar/actionbar'; +import {ActionBar} from 'vs/base/browser/ui/actionbar/actionbar'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IContextMenuService} from 'vs/platform/contextview/browser/contextView'; @@ -31,6 +27,7 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat import {IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; import {IMenuService} from 'vs/platform/actions/common/actions'; import {TitleControl} from 'vs/workbench/browser/parts/editor/titleControl'; +import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpenService'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {ScrollableElement} from 'vs/base/browser/ui/scrollbar/scrollableElement'; import {ScrollbarVisibility} from 'vs/base/common/scrollable'; @@ -41,13 +38,8 @@ export class TabsTitleControl extends TitleControl { private tabsContainer: HTMLElement; private activeTab: HTMLElement; private scrollbar: ScrollableElement; - - private groupActionsToolbar: ToolBar; private tabDisposeables: IDisposable[] = []; - private currentPrimaryGroupActionIds: string[] = []; - private currentSecondaryGroupActionIds: string[] = []; - constructor( @IContextMenuService contextMenuService: IContextMenuService, @IInstantiationService instantiationService: IInstantiationService, @@ -58,12 +50,10 @@ export class TabsTitleControl extends TitleControl { @IKeybindingService keybindingService: IKeybindingService, @ITelemetryService telemetryService: ITelemetryService, @IMessageService messageService: IMessageService, - @IMenuService menuService: IMenuService + @IMenuService menuService: IMenuService, + @IQuickOpenService quickOpenService: IQuickOpenService ) { - super(contextMenuService, instantiationService, configurationService, editorService, editorGroupService, keybindingService, telemetryService, messageService, menuService); - - this.currentPrimaryGroupActionIds = []; - this.currentSecondaryGroupActionIds = []; + super(contextMenuService, instantiationService, configurationService, editorService, editorGroupService, keybindingService, telemetryService, messageService, menuService, quickOpenService); this.tabDisposeables = []; } @@ -71,10 +61,12 @@ export class TabsTitleControl extends TitleControl { public setContext(group: IEditorGroup): void { super.setContext(group); - this.groupActionsToolbar.context = { group }; + this.editorActionsToolbar.context = { group }; } public create(parent: HTMLElement): void { + super.create(parent); + this.titleContainer = parent; // Tabs Container @@ -151,37 +143,18 @@ export class TabsTitleControl extends TitleControl { const targetPosition = this.stacks.positionOfGroup(group); const targetIndex = group.count; - // Local DND - const draggedEditor = TitleControl.getDraggedEditor(); - if (draggedEditor) { - DOM.EventHelper.stop(e, true); - - // Move editor to target position and index - if (this.isMoveOperation(e, draggedEditor.group, group)) { - this.editorGroupService.moveEditor(draggedEditor.editor, draggedEditor.group, group, targetIndex); - } - - // Copy: just open editor at target index - else { - this.editorService.openEditor(draggedEditor.editor, { pinned: true, index: targetIndex }, targetPosition).done(null, errors.onUnexpectedError); - } - - this.onEditorDragEnd(); - } - - // External DND - else { - this.handleExternalDrop(e, targetPosition, targetIndex); - } + this.onDrop(e, group, targetPosition, targetIndex); } } })); - // Group Actions - const groupActionsContainer = document.createElement('div'); - DOM.addClass(groupActionsContainer, 'group-actions'); - this.titleContainer.appendChild(groupActionsContainer); - this.groupActionsToolbar = this.doCreateToolbar(groupActionsContainer); + // Editor Actions Container + const editorActionsContainer = document.createElement('div'); + DOM.addClass(editorActionsContainer, 'editor-actions'); + this.titleContainer.appendChild(editorActionsContainer); + + // Editor Actions Toolbar + this.createEditorActionsToolBar(editorActionsContainer); } public allowDragging(element: HTMLElement): boolean { @@ -237,6 +210,9 @@ export class TabsTitleControl extends TitleControl { } }); + // Update Editor Actions Toolbar + this.updateEditorActionsToolbar(); + // Ensure the active tab is always revealed this.layout(); } @@ -247,27 +223,11 @@ export class TabsTitleControl extends TitleControl { if (!editor) { this.clearTabs(); - this.groupActionsToolbar.setActions([], [])(); - - this.currentPrimaryGroupActionIds = []; - this.currentSecondaryGroupActionIds = []; + this.clearEditorActionsToolbar(); return; // return early if we are being closed } - // Refresh Group Actions Toolbar - const groupActions = this.getGroupActions(group); - const primaryGroupActions = groupActions.primary; - const secondaryGroupActions = groupActions.secondary; - const primaryGroupActionIds = primaryGroupActions.map(a => a.id); - const secondaryGroupActionIds = secondaryGroupActions.map(a => a.id); - - if (!arrays.equals(primaryGroupActionIds, this.currentPrimaryGroupActionIds) || !arrays.equals(secondaryGroupActionIds, this.currentSecondaryGroupActionIds)) { - this.groupActionsToolbar.setActions(primaryGroupActions, secondaryGroupActions)(); - this.currentPrimaryGroupActionIds = primaryGroupActionIds; - this.currentSecondaryGroupActionIds = secondaryGroupActionIds; - } - // Refresh Tabs this.refreshTabs(group); @@ -363,10 +323,6 @@ export class TabsTitleControl extends TitleControl { scrollLeft: this.activeTab.offsetLeft }); } - - // Update enablement of certain actions that depend on overflow - const isOverflowing = (totalContainerWidth > visibleContainerWidth); - this.showEditorsInGroupAction.enabled = isOverflowing; } private hookTabListeners(tab: HTMLElement, identifier: IEditorIdentifier): void { @@ -461,10 +417,12 @@ export class TabsTitleControl extends TitleControl { this.onEditorDragStart({ editor, group }); e.dataTransfer.effectAllowed = 'copyMove'; - // Enable support to drag a file to desktop + // Insert transfer accordingly const fileInput = asFileEditorInput(editor, true); if (fileInput) { - e.dataTransfer.setData('DownloadURL', [MIME_BINARY, editor.getName(), fileInput.getResource().toString()].join(':')); + const resource = fileInput.getResource().toString(); + e.dataTransfer.setData('URL', resource); // enables cross window DND of tabs + e.dataTransfer.setData('DownloadURL', [MIME_BINARY, editor.getName(), resource].join(':')); // enables support to drag a tab as file to desktop } })); @@ -492,31 +450,36 @@ export class TabsTitleControl extends TitleControl { const targetPosition = this.stacks.positionOfGroup(group); const targetIndex = group.indexOf(editor); - // Local DND - const draggedEditor = TabsTitleControl.getDraggedEditor(); - if (draggedEditor) { - DOM.EventHelper.stop(e, true); - - // Move editor to target position and index - if (this.isMoveOperation(e, draggedEditor.group, group)) { - this.editorGroupService.moveEditor(draggedEditor.editor, draggedEditor.group, group, targetIndex); - } - - // Copy: just open editor at target index - else { - this.editorService.openEditor(draggedEditor.editor, { pinned: true, index: targetIndex }, targetPosition).done(null, errors.onUnexpectedError); - } - - this.onEditorDragEnd(); - } - - // External DND - else { - this.handleExternalDrop(e, targetPosition, targetIndex); - } + this.onDrop(e, group, targetPosition, targetIndex); })); } + private onDrop(e: DragEvent, group: IEditorGroup, targetPosition: Position, targetIndex: number): void { + + // Local DND + const draggedEditor = TabsTitleControl.getDraggedEditor(); + if (draggedEditor) { + DOM.EventHelper.stop(e, true); + + // Move editor to target position and index + if (this.isMoveOperation(e, draggedEditor.group, group)) { + this.editorGroupService.moveEditor(draggedEditor.editor, draggedEditor.group, group, targetIndex); + } + + // Copy: just open editor at target index + else { + this.editorService.openEditor(draggedEditor.editor, { pinned: true, index: targetIndex }, targetPosition).done(null, errors.onUnexpectedError); + } + + this.onEditorDragEnd(); + } + + // External DND + else { + this.handleExternalDrop(e, targetPosition, targetIndex); + } + } + private handleExternalDrop(e: DragEvent, targetPosition: Position, targetIndex: number): void { const resources = extractResources(e).filter(r => r.scheme === 'file' || r.scheme === 'untitled'); @@ -541,30 +504,4 @@ export class TabsTitleControl extends TitleControl { return !isCopy || source.id === target.id; } - - protected getContextMenuActions(identifier: IEditorIdentifier): IAction[] { - const actions = super.getContextMenuActions(identifier); - const {editor, group} = identifier; - - // Actions: For active editor - if (group.isActive(editor)) { - const editorActions = this.getEditorActions(identifier); - if (editorActions.primary.length) { - actions.push(new Separator(), ...prepareActions(editorActions.primary)); - } - - if (editorActions.secondary.length) { - actions.push(new Separator(), ...prepareActions(editorActions.secondary)); - } - } - - return actions; - } - - public dispose(): void { - super.dispose(); - - // Toolbar - this.groupActionsToolbar.dispose(); - } } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 34af5d78d11..0da21c50778 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -8,28 +8,29 @@ import 'vs/css!./media/titlecontrol'; import nls = require('vs/nls'); import {Registry} from 'vs/platform/platform'; -import {Scope, IActionBarRegistry, Extensions} from 'vs/workbench/browser/actionBarRegistry'; +import {Scope, IActionBarRegistry, Extensions, prepareActions} from 'vs/workbench/browser/actionBarRegistry'; import {IAction, Action} from 'vs/base/common/actions'; import errors = require('vs/base/common/errors'); import DOM = require('vs/base/browser/dom'); import {TPromise} from 'vs/base/common/winjs.base'; import {BaseEditor, IEditorInputActionContext} from 'vs/workbench/browser/parts/editor/baseEditor'; import {RunOnceScheduler} from 'vs/base/common/async'; +import arrays = require('vs/base/common/arrays'); import {IEditorStacksModel, IEditorGroup, IEditorIdentifier, EditorInput, IWorkbenchEditorConfiguration, IStacksModelChangeEvent, getResource} from 'vs/workbench/common/editor'; import {EventType as BaseEventType} from 'vs/base/common/events'; import {IActionItem, ActionsOrientation, Separator} from 'vs/base/browser/ui/actionbar/actionbar'; import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IContextMenuService} from 'vs/platform/contextview/browser/contextView'; -import {Position} from 'vs/platform/editor/common/editor'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService'; import {IMessageService, Severity} from 'vs/platform/message/common/message'; import {StandardMouseEvent} from 'vs/base/browser/mouseEvent'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; +import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpenService'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; -import {CloseEditorsInGroupAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, CloseEditorAction, KeepEditorAction, CloseOtherEditorsInGroupAction, CloseRightEditorsInGroupAction, ShowEditorsInGroupAction} from 'vs/workbench/browser/parts/editor/editorActions'; +import {CloseEditorsInGroupAction, SplitEditorAction, CloseEditorAction, KeepEditorAction, CloseOtherEditorsInGroupAction, CloseRightEditorsInGroupAction, ShowEditorsInGroupAction} from 'vs/workbench/browser/parts/editor/editorActions'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {createActionItem, fillInActions} from 'vs/platform/actions/browser/menuItemActionItem'; import {IMenuService, IMenu, MenuId} from 'vs/platform/actions/common/actions'; @@ -43,7 +44,9 @@ export interface IToolbarActions { export interface ITitleAreaControl { setContext(group: IEditorGroup): void; allowDragging(element: HTMLElement): boolean; + setDragged(dragged: boolean): void; create(parent: HTMLElement): void; + getContainer(): HTMLElement; refresh(instant?: boolean): void; update(instant?: boolean): void; layout(): void; @@ -58,19 +61,25 @@ export abstract class TitleControl implements ITitleAreaControl { protected context: IEditorGroup; protected toDispose: IDisposable[]; + protected dragged: boolean; + protected closeEditorAction: CloseEditorAction; protected pinEditorAction: KeepEditorAction; protected closeOtherEditorsAction: CloseOtherEditorsInGroupAction; protected closeRightEditorsAction: CloseRightEditorsInGroupAction; - protected moveGroupLeftAction: MoveGroupLeftAction; - protected moveGroupRightAction: MoveGroupRightAction; protected closeEditorsInGroupAction: CloseEditorsInGroupAction; protected splitEditorAction: SplitEditorAction; protected showEditorsInGroupAction: ShowEditorsInGroupAction; + private parent: HTMLElement; + private previewEditors: boolean; private showTabs: boolean; + private currentPrimaryEditorActionIds: string[] = []; + private currentSecondaryEditorActionIds: string[] = []; + protected editorActionsToolbar: ToolBar; + private mapActionsToEditors: { [editorId: string]: IToolbarActions; }; private scheduler: RunOnceScheduler; private refreshScheduled: boolean; @@ -88,7 +97,8 @@ export abstract class TitleControl implements ITitleAreaControl { @IKeybindingService protected keybindingService: IKeybindingService, @ITelemetryService protected telemetryService: ITelemetryService, @IMessageService protected messageService: IMessageService, - @IMenuService protected menuService: IMenuService + @IMenuService protected menuService: IMenuService, + @IQuickOpenService protected quickOpenService: IQuickOpenService ) { this.toDispose = []; this.stacks = editorGroupService.getStacksModel(); @@ -113,6 +123,10 @@ export abstract class TitleControl implements ITitleAreaControl { return TitleControl.draggedEditor; } + public setDragged(dragged: boolean): void { + this.dragged = dragged; + } + protected onEditorDragStart(editor: IEditorIdentifier): void { TitleControl.draggedEditor = editor; } @@ -182,7 +196,13 @@ export abstract class TitleControl implements ITitleAreaControl { } } - public abstract create(parent: HTMLElement): void; + public create(parent: HTMLElement): void { + this.parent = parent; + } + + public getContainer(): HTMLElement { + return this.parent; + } protected abstract doRefresh(): void; @@ -195,7 +215,7 @@ export abstract class TitleControl implements ITitleAreaControl { } public allowDragging(element: HTMLElement): boolean { - return !DOM.findParentWithClass(element, 'monaco-action-bar', 'one-editor-container'); + return !DOM.findParentWithClass(element, 'monaco-action-bar', 'one-editor-silo'); } private initActions(): void { @@ -204,16 +224,12 @@ export abstract class TitleControl implements ITitleAreaControl { this.closeRightEditorsAction = this.instantiationService.createInstance(CloseRightEditorsInGroupAction, CloseRightEditorsInGroupAction.ID, nls.localize('closeRight', "Close to the Right")); this.closeEditorsInGroupAction = this.instantiationService.createInstance(CloseEditorsInGroupAction, CloseEditorsInGroupAction.ID, nls.localize('closeAll', "Close All")); this.pinEditorAction = this.instantiationService.createInstance(KeepEditorAction, KeepEditorAction.ID, nls.localize('keepOpen', "Keep Open")); - this.showEditorsInGroupAction = this.instantiationService.createInstance(ShowEditorsInGroupAction, ShowEditorsInGroupAction.ID, ShowEditorsInGroupAction.LABEL); + this.showEditorsInGroupAction = this.instantiationService.createInstance(ShowEditorsInGroupAction, ShowEditorsInGroupAction.ID, nls.localize('showOpenedEditors', "Show Opened Editors")); this.splitEditorAction = this.instantiationService.createInstance(SplitEditorAction, SplitEditorAction.ID, SplitEditorAction.LABEL); - this.moveGroupLeftAction = this.instantiationService.createInstance(MoveGroupLeftAction, MoveGroupLeftAction.ID, nls.localize('moveLeft', "Move Left")); - this.moveGroupRightAction = this.instantiationService.createInstance(MoveGroupRightAction, MoveGroupRightAction.ID, nls.localize('moveRight', "Move Right")); - - this.showEditorsInGroupAction.class = 'show-group-editors-action'; } - protected doCreateToolbar(container: HTMLElement): ToolBar { - const toolbar = new ToolBar(container, this.contextMenuService, { + protected createEditorActionsToolBar(container: HTMLElement): void { + this.editorActionsToolbar = new ToolBar(container, this.contextMenuService, { actionItemProvider: (action: Action) => this.actionItemProvider(action), orientation: ActionsOrientation.HORIZONTAL, ariaLabel: nls.localize('araLabelEditorActions', "Editor actions"), @@ -228,7 +244,7 @@ export abstract class TitleControl implements ITitleAreaControl { }); // Action Run Handling - this.toDispose.push(toolbar.actionRunner.addListener2(BaseEventType.RUN, (e: any) => { + this.toDispose.push(this.editorActionsToolbar.actionRunner.addListener2(BaseEventType.RUN, (e: any) => { // Check for Error if (e.error && !errors.isPromiseCanceledError(e.error)) { @@ -240,8 +256,6 @@ export abstract class TitleControl implements ITitleAreaControl { this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'editorPart' }); } })); - - return toolbar; } protected actionItemProvider(action: Action): IActionItem { @@ -332,43 +346,58 @@ export abstract class TitleControl implements ITitleAreaControl { }; } - protected getGroupActions(group: IEditorGroup): IToolbarActions { - const editor = group.activeEditor; - const primary: IAction[] = []; - - // Overflow - primary.push(this.showEditorsInGroupAction); - - // Splitting - if (editor instanceof EditorInput && editor.supportsSplitEditor()) { - primary.push(this.splitEditorAction); + protected updateEditorActionsToolbar(): void { + const group = this.context; + if (!group) { + return; } - // Enablement - switch (this.stacks.positionOfGroup(group)) { - case Position.LEFT: - this.moveGroupLeftAction.enabled = false; - this.moveGroupRightAction.enabled = this.stacks.groups.length > 1; - break; + const editor = group && group.activeEditor; + const isActive = this.stacks.isActive(group); - case Position.CENTER: - this.moveGroupRightAction.enabled = this.stacks.groups.length > 2; - break; - - case Position.RIGHT: - this.moveGroupRightAction.enabled = false; - break; + // Update Editor Actions Toolbar + let primaryEditorActions: IAction[] = []; + let secondaryEditorActions: IAction[] = []; + if (isActive) { + const editorActions = this.getEditorActions({ group, editor }); + primaryEditorActions = prepareActions(editorActions.primary); + if (isActive && editor instanceof EditorInput && editor.supportsSplitEditor()) { + primaryEditorActions.push(this.splitEditorAction); + } + secondaryEditorActions = prepareActions(editorActions.secondary); } - // Return actions - const secondary = [ - this.moveGroupLeftAction, - this.moveGroupRightAction, - new Separator(), - this.closeEditorsInGroupAction - ]; + if (this.showTabs) { + secondaryEditorActions.push(new Separator()); + secondaryEditorActions.push(this.showEditorsInGroupAction); + secondaryEditorActions.push(new Separator()); + secondaryEditorActions.push(this.closeEditorsInGroupAction); + } - return { primary, secondary }; + const primaryEditorActionIds = primaryEditorActions.map(a => a.id); + if (!this.showTabs) { + primaryEditorActionIds.push(this.closeEditorAction.id); // always show "Close" when tabs are disabled + } + + const secondaryEditorActionIds = secondaryEditorActions.map(a => a.id); + + if (!arrays.equals(primaryEditorActionIds, this.currentPrimaryEditorActionIds) || !arrays.equals(secondaryEditorActionIds, this.currentSecondaryEditorActionIds)) { + this.editorActionsToolbar.setActions(primaryEditorActions, secondaryEditorActions)(); + + if (!this.showTabs) { + this.editorActionsToolbar.addPrimaryAction(this.closeEditorAction)(); + } + + this.currentPrimaryEditorActionIds = primaryEditorActionIds; + this.currentSecondaryEditorActionIds = secondaryEditorActionIds; + } + } + + protected clearEditorActionsToolbar(): void { + this.editorActionsToolbar.setActions([], [])(); + + this.currentPrimaryEditorActionIds = []; + this.currentSecondaryEditorActionIds = []; } protected onContextMenu(identifier: IEditorIdentifier, e: Event, node: HTMLElement): void { @@ -431,11 +460,12 @@ export abstract class TitleControl implements ITitleAreaControl { this.closeRightEditorsAction, this.closeOtherEditorsAction, this.closeEditorsInGroupAction, - this.moveGroupLeftAction, - this.moveGroupRightAction, this.pinEditorAction ].forEach((action) => { action.dispose(); }); + + // Toolbar + this.editorActionsToolbar.dispose(); } } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index 99d9a1a7a39..29a8f145fc6 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -23,25 +23,12 @@ background: url('hide.svg') center center no-repeat; } -.vs-dark .monaco-workbench .hide-panel-action { +.vs-dark .monaco-workbench .hide-panel-action, +.hc-black .monaco-workbench .hide-panel-action { background: url('hide-inverse.svg') center center no-repeat; } /* High Contrast Theming */ .hc-black .monaco-workbench > .part.panel > .title { border-top-color: #6FC3DF; -} - -.hc-black .monaco-workbench .hide-panel-action { - background: none; -} - -.hc-black .monaco-workbench .hide-panel-action:before { - content: url('hide-inverse.svg'); - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} - +} \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 60cb3720063..de20f8b396f 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -147,5 +147,39 @@ class TogglePanelAction extends Action { } } +class FocusPanelAction extends Action { + + public static ID = 'workbench.action.focusPanel'; + public static LABEL = nls.localize('focusPanel', "Focus into Panel"); + + constructor( + id: string, + label: string, + @IPanelService private panelService: IPanelService, + @IPartService private partService: IPartService + ) { + super(id, label); + } + + public run(): TPromise { + + // Show panel + if (this.partService.isPanelHidden()) { + this.partService.setPanelHidden(false); + } + + // Focus into active panel + else { + let panel = this.panelService.getActivePanel(); + if (panel) { + panel.focus(); + } + } + + return TPromise.as(true); + } +} + let actionRegistry = Registry.as(WorkbenchExtensions.WorkbenchActions); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelAction, TogglePanelAction.ID, TogglePanelAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_J }), 'View: Toggle Panel Visibility', nls.localize('view', "View")); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPanelAction, FocusPanelAction.ID, FocusPanelAction.LABEL), 'View: Focus into Panel', nls.localize('view', "View")); diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 87643820c2b..8f8f8a157b3 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -134,7 +134,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe const init = (resolve: (value: IPickOpenEntry | TPromise) => any, reject: (value: any) => any) => { - // open quick pick with just one choise. we will recurse whenever + // open quick pick with just one choice. we will recurse whenever // the validation/success message changes this.doPick(TPromise.as([{ label: currentPick }]), { ignoreFocusLost: true, @@ -289,17 +289,17 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe // Model let model = new QuickOpenModel(); - let entries = picks.map((e) => { + let entries = picks.map(e => { let entry = (e); if (entry.height && entry.render) { - return new PickOpenItem(entry.label, entry.description, entry.height, entry.render.bind(entry), () => progress(e)); + return new PickOpenItem(entry, () => progress(e)); } - return new PickOpenEntry(entry.label, entry.description, entry.detail, () => progress(e), entry.separator && entry.separator.border, entry.separator && entry.separator.label); + return new PickOpenEntry(entry, () => progress(e)); }); if (picks.length === 0) { - entries.push(new PickOpenEntry(nls.localize('emptyPicks', "There are no entries to pick from"))); + entries.push(new PickOpenEntry({ label: nls.localize('emptyPicks', "There are no entries to pick from") })); } model.setEntries(entries); @@ -346,7 +346,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe // Reset filtering if (!value) { - entries.forEach((e) => { + entries.forEach(e => { e.setHighlights(null); e.setHidden(false); }); @@ -354,12 +354,12 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe // Filter by value else { - entries.forEach((entry) => { + entries.forEach(entry => { let labelHighlights = filters.matchesFuzzy(value, entry.getLabel()); let descriptionHighlights = options.matchOnDescription && filters.matchesFuzzy(value, entry.getDescription()); let detailHighlights = options.matchOnDetail && entry.getDetail() && filters.matchesFuzzy(value, entry.getDetail()); - if (labelHighlights || descriptionHighlights || detailHighlights) { + if (entry.shouldAlwaysShow() || labelHighlights || descriptionHighlights || detailHighlights) { entry.setHighlights(labelHighlights, descriptionHighlights, detailHighlights); entry.setHidden(false); } else { @@ -441,7 +441,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe this.previousValue = prefix; - let promiseCompletedOnHide = new TPromise((c) => { + let promiseCompletedOnHide = new TPromise(c => { this.promisesToCompleteOnHide.push(c); }); @@ -660,13 +660,13 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe // Resolve all default handlers let resolvePromises: TPromise[] = []; - defaultHandlers.forEach((defaultHandler) => { + defaultHandlers.forEach(defaultHandler => { resolvePromises.push(this.resolveHandler(defaultHandler)); }); return TPromise.join(resolvePromises).then((resolvedHandlers: QuickOpenHandler[]) => { let resultPromises: TPromise[] = []; - resolvedHandlers.forEach((resolvedHandler) => { + resolvedHandlers.forEach(resolvedHandler => { // Return early if the handler can not run in the current environment let canRun = resolvedHandler.canRun(); @@ -675,7 +675,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe } // Receive Results from Handler and apply - resultPromises.push(resolvedHandler.getResults(value).then((result) => { + resultPromises.push(resolvedHandler.getResults(value).then(result => { if (this.currentResultToken === currentResultToken) { let handlerResults = result && result.entries; @@ -788,7 +788,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe } // Receive Results from Handler and apply - return resolvedHandler.getResults(value).then((result) => { + return resolvedHandler.getResults(value).then(result => { if (this.currentResultToken === currentResultToken) { if (!result || !result.entries.length) { const model = new QuickOpenModel([new PlaceholderQuickOpenEntry(resolvedHandler.getEmptyLabel(value))]); @@ -890,12 +890,21 @@ class PickOpenEntry extends PlaceholderQuickOpenEntry { private _shouldRunWithContext: IEntryRunContext; private description: string; private detail: string; + private hasSeparator: boolean; + private separatorLabel: string; + private alwaysShow: boolean; - constructor(label: string, description?: string, detail?: string, private onPreview?: () => void, private hasSeparator?: boolean, private separatorLabel?: string) { - super(label); + constructor( + item: IPickOpenEntry, + private onPreview?: () => void + ) { + super(item.label); - this.description = description; - this.detail = detail; + this.description = item.description; + this.detail = item.detail; + this.hasSeparator = item.separator && item.separator.border; + this.separatorLabel = item.separator && item.separator.label; + this.alwaysShow = item.alwaysShow; } public get shouldRunWithContext(): IEntryRunContext { @@ -918,6 +927,10 @@ class PickOpenEntry extends PlaceholderQuickOpenEntry { return this.separatorLabel; } + public shouldAlwaysShow(): boolean { + return this.alwaysShow; + } + public run(mode: Mode, context: IEntryRunContext): boolean { if (mode === Mode.OPEN) { this._shouldRunWithContext = context; @@ -935,9 +948,23 @@ class PickOpenEntry extends PlaceholderQuickOpenEntry { class PickOpenItem extends QuickOpenEntryItem { private _shouldRunWithContext: IEntryRunContext; + private label: string; + private description: string; + private height: number; + private renderFn: (tree: ITree, container: HTMLElement, previousCleanupFn: IElementCallback) => IElementCallback; + private alwaysShow: boolean; - constructor(private label: string, private description: string, private height: number, private renderFn: (tree: ITree, container: HTMLElement, previousCleanupFn: IElementCallback) => IElementCallback, private onPreview?: () => void) { + constructor( + item: IPickOpenEntryItem, + private onPreview?: () => void + ) { super(); + + this.label = item.label; + this.description = item.description; + this.height = item.height; + this.renderFn = item.render.bind(item); + this.alwaysShow = item.alwaysShow; } public getHeight(): number { @@ -960,6 +987,10 @@ class PickOpenItem extends QuickOpenEntryItem { return this.description; } + public shouldAlwaysShow(): boolean { + return this.alwaysShow; + } + public run(mode: Mode, context: IEntryRunContext): boolean { if (mode === Mode.OPEN) { this._shouldRunWithContext = context; diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts index 401507bd298..905437314fb 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts @@ -93,7 +93,7 @@ export class SidebarPart extends CompositePart implements IViewletServi } } -export class FocusSideBarAction extends Action { +class FocusSideBarAction extends Action { public static ID = 'workbench.action.focusSideBar'; public static LABEL = nls.localize('focusSideBar', "Focus into Side Bar"); diff --git a/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css b/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css index 967bc1115d7..8c9f24fba7b 100644 --- a/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css +++ b/src/vs/workbench/browser/parts/statusbar/media/statusbarpart.css @@ -74,4 +74,4 @@ .hc-black .monaco-workbench > .part.statusbar { border-top: 1px solid #6FC3DF; background-color: #000; -} +} \ No newline at end of file diff --git a/src/vs/workbench/common/editor/binaryEditorModel.ts b/src/vs/workbench/common/editor/binaryEditorModel.ts index 92dd238c337..4e52f089c91 100644 --- a/src/vs/workbench/common/editor/binaryEditorModel.ts +++ b/src/vs/workbench/common/editor/binaryEditorModel.ts @@ -4,8 +4,10 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import {TPromise} from 'vs/base/common/winjs.base'; import {EditorModel} from 'vs/workbench/common/editor'; import URI from 'vs/base/common/uri'; +import {IFileService} from 'vs/platform/files/common/files'; /** * An editor model that just represents a resource and mime for a resource that can be loaded. @@ -13,8 +15,13 @@ import URI from 'vs/base/common/uri'; export class BinaryEditorModel extends EditorModel { private name: string; private resource: URI; + private size: number; - constructor(resource: URI, name: string) { + constructor( + resource: URI, + name: string, + @IFileService protected fileService: IFileService + ) { super(); this.name = name; @@ -34,4 +41,19 @@ export class BinaryEditorModel extends EditorModel { public getResource(): URI { return this.resource; } + + /** + * The size of the binary file if known. + */ + public getSize(): number { + return this.size; + } + + public load(): TPromise { + return this.fileService.resolveFile(this.resource).then(stat => { + this.size = stat.size; + + return this; + }); + } } \ No newline at end of file diff --git a/src/vs/workbench/common/editor/editorStacksModel.ts b/src/vs/workbench/common/editor/editorStacksModel.ts index 9bde9eee0a8..695cf5b9924 100644 --- a/src/vs/workbench/common/editor/editorStacksModel.ts +++ b/src/vs/workbench/common/editor/editorStacksModel.ts @@ -57,7 +57,7 @@ export class EditorGroup implements IEditorGroup { private editors: EditorInput[]; private mru: EditorInput[]; - private mapResourceToEditor: { [resource: string]: EditorInput }; + private mapResourceToEditorCount: { [resource: string]: number }; private preview: EditorInput; // editor in preview state private active: EditorInput; // editor in active state @@ -86,7 +86,7 @@ export class EditorGroup implements IEditorGroup { this.editors = []; this.mru = []; this.toDispose = []; - this.mapResourceToEditor = Object.create(null); + this.mapResourceToEditorCount = Object.create(null); this.onConfigurationUpdated(configurationService.getConfiguration()); this._onEditorActivated = new Emitter(); @@ -516,7 +516,20 @@ export class EditorGroup implements IEditorGroup { private updateResourceMap(editor: EditorInput, remove: boolean): void { const resource = getUntitledOrFileResource(editor, true /* include diff editors */); if (resource) { - this.mapResourceToEditor[resource.toString()] = remove ? void 0 : editor; + + // It is possible to have the same resource opened twice (once as normal input and once as diff input) + // So we need to do ref counting on the resource to provide the correct picture + let counter = this.mapResourceToEditorCount[resource.toString()] || 0; + let newCounter; + if (remove) { + if (counter > 1) { + newCounter = counter - 1; + } + } else { + newCounter = counter + 1; + } + + this.mapResourceToEditorCount[resource.toString()] = newCounter; } } @@ -541,7 +554,9 @@ export class EditorGroup implements IEditorGroup { return this.indexOf(arg1) >= 0; } - return !!this.mapResourceToEditor[(arg1).toString()]; + const counter = this.mapResourceToEditorCount[(arg1).toString()]; + + return typeof counter === 'number' && counter > 0; } private setMostRecentlyUsed(editor: EditorInput): void { diff --git a/src/vs/workbench/electron-browser/integration.ts b/src/vs/workbench/electron-browser/integration.ts index 8576845fb54..faaa4c2d47e 100644 --- a/src/vs/workbench/electron-browser/integration.ts +++ b/src/vs/workbench/electron-browser/integration.ts @@ -172,9 +172,6 @@ export class ElectronIntegration { private resolveKeybindings(actionIds: string[]): TPromise<{ id: string; binding: number; }[]> { return this.partService.joinCreation().then(() => { return arrays.coalesce(actionIds.map((id) => { - if (!this.commandService.isKnownCommand(id)) { - console.warn('Menu uses unknown command: ' + id); - } let bindings = this.keybindingService.lookupKeybindings(id); // return the first binding that can be represented by electron diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index ecf5815a866..1b99367279f 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -16,11 +16,11 @@ /* Font Families (with CJK support) */ -.monaco-shell { font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback"; } -.monaco-shell:lang(zh-Hans) { font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", "Noto Sans", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans", sans-serif; } -.monaco-shell:lang(zh-Hant) { font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", "Noto Sans", "Microsoft Jhenghei", "PingFang TC", "Source Han Sans TC", "Source Han Sans", "Source Han Sans TW", sans-serif; } -.monaco-shell:lang(ja) { font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", "Noto Sans", "Meiryo", "Hiragino Kaku Gothic Pro", "Source Han Sans J", "Source Han Sans JP", "Source Han Sans", "Sazanami Gothic", "IPA Gothic", sans-serif; } -.monaco-shell:lang(ko) { font-family: "Segoe WPC", "Segoe UI", ".SFNSDisplay-Light", "SFUIText-Light", "HelveticaNeue-Light", "Noto Sans", "Malgun Gothic", "Nanum Gothic", "Dotom", "Apple SD Gothic Neo", "AppleGothic", "Source Han Sans K", "Source Han Sans JR", "Source Han Sans", "UnDotum", "FBaekmuk Gulim", sans-serif; } +.monaco-shell { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Ubuntu", "Droid Sans", sans-serif; } +.monaco-shell:lang(zh-Hans) { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans", sans-serif; } +.monaco-shell:lang(zh-Hant) { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Microsoft Jhenghei", "PingFang TC", "Source Han Sans TC", "Source Han Sans", "Source Han Sans TW", sans-serif; } +.monaco-shell:lang(ja) { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Meiryo", "Hiragino Kaku Gothic Pro", "Source Han Sans J", "Source Han Sans JP", "Source Han Sans", "Sazanami Gothic", "IPA Gothic", sans-serif; } +.monaco-shell:lang(ko) { font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "HelveticaNeue-Light", "Noto Sans", "Malgun Gothic", "Nanum Gothic", "Dotom", "Apple SD Gothic Neo", "AppleGothic", "Source Han Sans K", "Source Han Sans JR", "Source Han Sans", "UnDotum", "FBaekmuk Gulim", sans-serif; } @-webkit-keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @@ -196,10 +196,6 @@ text-decoration: underline; } -.monaco-shell a.strong { - font-weight: bold; -} - a:active { color: inherit; background-color: inherit; @@ -233,25 +229,12 @@ a:active { border-bottom: 5px solid white; } -.monaco-shell .context-view .monaco-menu .actions-container { - min-width: 160px; -} - -.monaco-shell .monaco-menu .action-label.check { - font-weight: bold; -} - -.monaco-shell .monaco-menu .action-label.uncheck { - font-weight: normal; -} - .monaco-shell input:disabled { background-color: #E1E1E1; } -/** - * Dark Theme - */ +/* ---------- Dark Theme ---------- */ + .monaco-shell.vs-dark { color: #BBB; background-color: #1E1E1E; @@ -278,9 +261,8 @@ a:active { background-color: #333; } -/** - * High Contrast Theme - */ +/* ---------- High Contrast Theme ---------- */ + .monaco-shell.hc-black { color: #fff; background-color: #000; } .monaco-shell.hc-black .context-view .tooltip { diff --git a/src/vs/workbench/electron-browser/media/workbench.css b/src/vs/workbench/electron-browser/media/workbench.css index addf9d6594d..d9601b2c0ed 100644 --- a/src/vs/workbench/electron-browser/media/workbench.css +++ b/src/vs/workbench/electron-browser/media/workbench.css @@ -122,7 +122,7 @@ .hc-black .monaco-workbench { color: #FFF; background-color: #000; } -.hc-black .monaco-workbench .sidebar .separator { background-color: #000; border: 1px solid #6FC3DF; } +.hc-black .monaco-workbench .sidebar .separator { background-color: #000; border: 1px solid #6FC3DF; } .hc-black .monaco-workbench input, .hc-black .monaco-workbench textarea { diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index 13a0203ff2f..f841148dc26 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -80,6 +80,7 @@ export class ElectronWindow { function cleanUp(): void { draggedExternalResources = void 0; + if (dropOverlay) { dropOverlay.destroy(); dropOverlay = void 0; diff --git a/src/vs/workbench/parts/debug/browser/debugActions.ts b/src/vs/workbench/parts/debug/browser/debugActions.ts index 2e4afec08ea..5aa07793260 100644 --- a/src/vs/workbench/parts/debug/browser/debugActions.ts +++ b/src/vs/workbench/parts/debug/browser/debugActions.ts @@ -305,6 +305,24 @@ export class PauseAction extends AbstractDebugAction { } } +export class RestartFrameAction extends AbstractDebugAction { + static ID = 'workbench.action.debug.restartFrame'; + static LABEL = nls.localize('restartFrame', "Restart Frame"); + + constructor(id: string, label: string, @IDebugService debugService: IDebugService, @IKeybindingService keybindingService: IKeybindingService) { + super(id, label, 'debug-action restart-frame', debugService, keybindingService); + } + + public run(frame: debug.IStackFrame): TPromise { + + const frameId = (frame && frame instanceof model.StackFrame) + ? frame.frameId + : this.debugService.getViewModel().getFocusedStackFrame().frameId; + + return this.debugService.restartFrame(frameId); + } +} + export class RemoveBreakpointAction extends AbstractDebugAction { static ID = 'workbench.debug.viewlet.action.removeBreakpoint'; static LABEL = nls.localize('removeBreakpoint', "Remove Breakpoint"); diff --git a/src/vs/workbench/parts/debug/browser/media/debug.contribution.css b/src/vs/workbench/parts/debug/browser/media/debug.contribution.css index b4d3f658b9e..030fd67b16e 100644 --- a/src/vs/workbench/parts/debug/browser/media/debug.contribution.css +++ b/src/vs/workbench/parts/debug/browser/media/debug.contribution.css @@ -5,8 +5,7 @@ /* Activity Bar */ .monaco-workbench > .activitybar .monaco-action-bar .action-label.debug { - /* Inline icon to prevent slow loading on startup (original: debug.svg) */ - background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPi5pY29uLWNhbnZhcy10cmFuc3BhcmVudHtvcGFjaXR5OjA7ZmlsbDojRjZGNkY2O30gLmljb24td2hpdGV7ZmlsbDojRkZGRkZGO308L3N0eWxlPjxwYXRoIGNsYXNzPSJpY29uLWNhbnZhcy10cmFuc3BhcmVudCIgZD0iTTMyIDMySDBWMGgzMnYzMnoiIGlkPSJjYW52YXMiLz48ZyBpZD0iaWNvbkJnIj48cGF0aCBjbGFzcz0iaWNvbi13aGl0ZSIgZD0iTTE3IDE5LjQ4OHY0LjI0OGMwIC40NjIuMDkgMS4yNjQtLjM3MyAxLjI2NEgxNXYtMWgxdi0zLjE5bC0uMTczLS4xOGMtMS40NTMgMS4yMDUtMy41MjggMS4yNDgtNC42Ny4xMDhDMTAgMTkuNTc4IDEwLjExOCAxOCAxMS4zNzYgMTZIOHYxSDd2LTEuNjI3QzcgMTQuOTEgNy44MDIgMTUgOC4yNjQgMTVoNC4xMDVMMTcgMTkuNDg4ek0xNCA5aC0xVjhoMS45NTVjLjQ2IDAgMS4wNDUuMjIgMS4wNDUuNjgydjMuMzQ1bC43MzYuODc1Yy4xOC0uOTczLjg5LTEuNzEgMS45MTQtMS43MS4xNDMgMCAuMzUuMDE0LjM1LjA0VjloMXYyLjYxOGMwIC4xMTcuMjY1LjM4Mi4zODIuMzgySDIzdjFoLTIuMjMzYy4wMjcgMCAuMDQyLjE1NC4wNDIuMjk4IDAgMS4wMjUtLjc0IDEuNzUzLTEuNzEyIDEuOTMybC44NzUuNzdIMjMuMzE4Yy40NjIgMCAuNjgyLjU4My42ODIgMS4wNDVWMTloLTF2LTFoLTIuNTJMMTQgMTEuNjk4Vjl6TTE2IDRDOS4zNzMgNCA0IDkuMzczIDQgMTZzNS4zNzMgMTIgMTIgMTIgMTItNS4zNzMgMTItMTJTMjIuNjI3IDQgMTYgNHptMTAgMTJjMCAyLjM5Ny0uODUgNC42LTIuMjYyIDYuMzI0TDkuNjc2IDguMjYyQzExLjQgNi44NSAxMy42MDIgNiAxNiA2YzUuNTE0IDAgMTAgNC40ODYgMTAgMTB6TTYgMTZjMC0yLjM5OC44NS00LjYgMi4yNjItNi4zMjRMMjIuMzI0IDIzLjc0QzIwLjYgMjUuMTUgMTguMzk3IDI2IDE2IDI2Yy01LjUxNCAwLTEwLTQuNDg2LTEwLTEweiIvPjwvZz48L3N2Zz4='); + background-image: url('debug.svg'); } .monaco-editor .debug-top-stack-frame-line { @@ -74,7 +73,8 @@ /* Actionbar actions */ -.monaco-workbench .debug-action.step-over { +.monaco-workbench .debug-action.step-over, +.monaco-workbench .debug-action.step-back { background: url('step-over.svg') center center no-repeat; } @@ -87,14 +87,10 @@ } .monaco-workbench .debug-action.step-back { - background: url('step-over.svg') center center no-repeat; transform: scaleX(-1); } -.monaco-workbench .debug-action.continue { - background: url('continue.svg') center center no-repeat; -} - +.monaco-workbench .debug-action.continue, .monaco-workbench .debug-action.start { background: url('continue.svg') center center no-repeat; } @@ -183,10 +179,6 @@ font-style: italic; } -.monaco-workbench.mac .monaco-tree-row .expression .unavailable { - font-weight: 300; /* makes the italic font appear the same as normal */ -} - .monaco-workbench .monaco-tree-row:not(.selected) .expression .error { color: #E51400; } @@ -287,44 +279,52 @@ background: url('stackframe-and-breakpoint-dark.svg') center center no-repeat; } -.vs-dark .monaco-workbench .debug-action.step-over { +.vs-dark .monaco-workbench .debug-action.step-over, +.vs-dark .monaco-workbench .debug-action.step-back, +.hc-black .monaco-workbench .debug-action.step-over, +.hc-black .monaco-workbench .debug-action.step-back { background: url('step-over-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .debug-action.step-into { +.vs-dark .monaco-workbench .debug-action.step-into, +.hc-black .monaco-workbench .debug-action.step-into { background: url('step-into-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .debug-action.step-out { +.vs-dark .monaco-workbench .debug-action.step-out, +.hc-black .monaco-workbench .debug-action.step-out { background: url('step-out-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .debug-action.step-back { - background: url('step-over-inverse.svg') center center no-repeat; +.vs-dark .monaco-workbench .debug-action.step-back, +.hc-black .monaco-workbench .debug-action.step-back { transform: scaleX(-1); } -.vs-dark .monaco-workbench .debug-action.continue { +.vs-dark .monaco-workbench .debug-action.continue, +.vs-dark .monaco-workbench .debug-action.start, +.hc-black .monaco-workbench .debug-action.continue, +.hc-black .monaco-workbench .debug-action.start { background: url('continue-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .debug-action.start { - background: url('continue-inverse.svg') center center no-repeat; -} - -.vs-dark .monaco-workbench .debug-action.restart { +.vs-dark .monaco-workbench .debug-action.restart, +.hc-black .monaco-workbench .debug-action.restart { background: url('restart-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .debug-action.pause { +.vs-dark .monaco-workbench .debug-action.pause, +.hc-black .monaco-workbench .debug-action.pause { background: url('pause-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .debug-action.stop { +.vs-dark .monaco-workbench .debug-action.stop, +.hc-black .monaco-workbench .debug-action.stop { background: url('stop-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .debug-action.clear-repl { +.vs-dark .monaco-workbench .debug-action.clear-repl, +.hc-black .monaco-workbench .debug-action.clear-repl { background: url('clear-repl-inverse.svg') center center no-repeat; } @@ -339,56 +339,7 @@ color: inherit; } -.hc-black .monaco-workbench > .activitybar .monaco-action-bar .action-label.debug:before { - content: url('debug.svg'); -} - -.hc-black .monaco-workbench .debug-action { - background: none; -} - .hc-black .monaco-workbench .debug-actions-widget { background-color: #333; box-shadow: 0 2px 8px #000; -} - -.hc-black .monaco-workbench .debug-action.step-over { - background: url('step-over-inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .debug-action.step-into { - background: url('step-into-inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .debug-action.step-out { - background: url('step-out-inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .debug-action.step-back { - background: url('step-over-inverse.svg') center center no-repeat; - transform: scaleX(-1); -} - -.hc-black .monaco-workbench .debug-action.continue { - background: url('continue-inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .debug-action.start { - background: url('continue-inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .debug-action.restart { - background: url('restart-inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .debug-action.pause { - background: url('pause-inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .debug-action.stop { - background: url('stop-inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .debug-action.clear-repl { - background: url('clear-repl-inverse.svg') center center no-repeat; } \ No newline at end of file diff --git a/src/vs/workbench/parts/debug/browser/media/debugViewlet.css b/src/vs/workbench/parts/debug/browser/media/debugViewlet.css index 49f1f990a9b..37e47c8c7bf 100644 --- a/src/vs/workbench/parts/debug/browser/media/debugViewlet.css +++ b/src/vs/workbench/parts/debug/browser/media/debugViewlet.css @@ -31,18 +31,12 @@ border: 1px solid white; } -.vs-dark .monaco-workbench .debug-action.configure { - background: url('configure-inverse.svg') center center no-repeat; -} - -.vs-dark .monaco-workbench .debug-action.toggle-repl { - background: url('repl-inverse.svg') center center no-repeat; -} - +.vs-dark .monaco-workbench .debug-action.configure, .hc-black .monaco-workbench .debug-action.configure { background: url('configure-inverse.svg') center center no-repeat; } +.vs-dark .monaco-workbench .debug-action.toggle-repl, .hc-black .monaco-workbench .debug-action.toggle-repl { background: url('repl-inverse.svg') center center no-repeat; } @@ -197,11 +191,6 @@ overflow: hidden; } -.monaco-workbench.mac .debug-viewlet .debug-call-stack .load-more, -.monaco-workbench.mac .debug-viewlet .debug-call-stack .error { - font-weight: 300; /* makes the italic font appear the same as normal */ -} - /* Variables & Expression view */ .debug-viewlet .scope { @@ -264,7 +253,8 @@ } .vs-dark .debug-viewlet .debug-action.add-watch-expression, -.vs-dark .debug-viewlet .debug-action.add-function-breakpoint { +.vs-dark .debug-viewlet .debug-action.add-function-breakpoint, +.hc-black .debug-viewlet .debug-action.add-watch-expression { background: url('add-inverse.svg') center center no-repeat; } @@ -307,23 +297,23 @@ background: url('breakpoints-activate.svg') center center no-repeat; } -.debug-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions .debug-action.remove { - background: url("remove-focus.svg") center center no-repeat; -} - -.vs-dark .debug-viewlet .debug-action.remove { - background: url('remove-inverse.svg') center center no-repeat; -} - -.vs-dark .debug-viewlet .debug-action.remove-all { - background: url('remove-all-inverse.svg') center center no-repeat; -} - +.debug-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions .debug-action.remove, .vs-dark .debug-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions .debug-action.remove { background: url("remove-focus.svg") center center no-repeat; } -.vs-dark .debug-viewlet .debug-action.breakpoints-activate { +.vs-dark .debug-viewlet .debug-action.remove, +.hc-black .debug-viewlet .debug-action.remove { + background: url('remove-inverse.svg') center center no-repeat; +} + +.vs-dark .debug-viewlet .debug-action.remove-all, +.hc-black .debug-viewlet .debug-action.remove-all { + background: url('remove-all-inverse.svg') center center no-repeat; +} + +.vs-dark .debug-viewlet .debug-action.breakpoints-activate, +.hc-black .debug-viewlet .debug-action.breakpoints-activate { background: url('breakpoints-activate-inverse.svg') center center no-repeat; } @@ -343,20 +333,4 @@ background-color: #3C3C3C; border-color: #3C3C3C; color: rgb(204, 204, 204); -} - -.hc-black .debug-viewlet .debug-action.remove { - content: url('remove-inverse.svg'); -} - -.hc-black .debug-viewlet .debug-action.add-watch-expression { - background: url('add-inverse.svg') center center no-repeat; -} - -.hc-black .debug-viewlet .debug-action.breakpoints-activate { - background: url('breakpoints-activate-inverse.svg') center center no-repeat; -} - -.hc-black .debug-viewlet .debug-action.remove-all { - background: url('remove-all-inverse.svg') center center no-repeat; -} +} \ No newline at end of file diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 65868bbba0a..e219ab000c4 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -406,6 +406,7 @@ export interface IDebugService { stepBack(threadId: number): TPromise; continue(threadId: number): TPromise; pause(threadId: number): TPromise; + restartFrame(frameId: number): TPromise; } // Editor interfaces diff --git a/src/vs/workbench/parts/debug/common/debugProtocol.d.ts b/src/vs/workbench/parts/debug/common/debugProtocol.d.ts index 3391d27b9b1..9ffe686726c 100644 --- a/src/vs/workbench/parts/debug/common/debugProtocol.d.ts +++ b/src/vs/workbench/parts/debug/common/debugProtocol.d.ts @@ -393,6 +393,22 @@ declare module DebugProtocol { export interface StepBackResponse extends Response { } + /** RestartFrame request; value of command field is "restartFrame". + The request restarts execution of the specified stackframe. + The debug adapter first sends the RestartFrameResponse and then a StoppedEvent (event type 'restart') after the restart has completed. + */ + export interface RestartFrameRequest extends Request { + arguments: RestartFrameArguments; + } + /** Arguments for "restartFrame" request. */ + export interface RestartFrameArguments { + /** Restart this stackframe. */ + frameId: number; + } + /** Response to "restartFrame" request. This is just an acknowledgement, so no body field is required. */ + export interface RestartFrameResponse extends Response { + } + /** Pause request; value of command field is "pause". The request suspenses the debuggee. The debug adapter first sends the PauseResponse and then a StoppedEvent (event type 'pause') after the thread has been paused successfully. @@ -572,8 +588,10 @@ declare module DebugProtocol { /** Response to "evaluate" request. */ export interface EvaluateResponse extends Response { body: { - /** The result of the evaluate. */ + /** The result of the evaluate request. */ result: string; + /** The optional type of the evaluate result. */ + type?: string; /** If variablesReference is > 0, the evaluate result is structured and its children can be retrieved by passing variablesReference to the VariablesRequest */ variablesReference: number; }; @@ -597,6 +615,8 @@ declare module DebugProtocol { supportsStepBack?: boolean; /** The debug adapter supports setting a variable to a value. */ supportsSetVariable?: boolean; + /** The debug adapter supports restarting a frame. */ + supportsRestartFrame?: boolean; } /** An ExceptionBreakpointsFilter is shown in the UI as an option for configuring how exceptions are dealt with. */ @@ -712,7 +732,7 @@ declare module DebugProtocol { /** A Stackframe contains the source location. */ export interface StackFrame { - /** An identifier for the stack frame. This id can be used to retrieve the scopes of the frame with the 'scopesRequest'. */ + /** An identifier for the stack frame. This id can be used to retrieve the scopes of the frame with the 'scopesRequest' or to restart the execution of a stackframe. */ id: number; /** The name of the stack frame, typically a method name */ name: string; diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 16a8631ed60..e6d5c0f8ec0 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -491,11 +491,19 @@ export class DebugService implements debug.IDebugService { return TPromise.as(null); } - return this.session.setVarialbe({ + return this.session.setVariable({ name: variable.name, value, variablesReference: (variable).parent.reference - }).then(response => variable.value = response.body.value, err => (variable).errorMessage = err.message); + }).then(response => { + variable.value = response.body.value; + // Evaluate all watch expressions again since changing variable value might have changed some #8118. + return this.setFocusedStackFrameAndEvaluate(this.viewModel.getFocusedStackFrame()); + }, err => { + (variable).errorMessage = err.message; + // On error still show bad value so the user can fix it #8055 + (variable).value = value; + }); } public addWatchExpression(name: string): TPromise { @@ -589,7 +597,7 @@ export class DebugService implements debug.IDebugService { timeout: 1000 * 60 * 5, args: [`${ publisher }.${ type }`, JSON.stringify(data), aiKey], env: { - ELECTRON_RUN_AS_NODE: 1, + ATOM_SHELL_INTERNAL_RUN_AS_NODE: 1, PIPE_LOGGING: 'true', AMD_ENTRYPOINT: 'vs/workbench/parts/debug/node/telemetryApp' } @@ -920,6 +928,14 @@ export class DebugService implements debug.IDebugService { return this.session.pause({ threadId }); } + public restartFrame(frameId: number): TPromise { + if (!this.session) { + return TPromise.as(null); + } + + return this.session.restartFrame({ frameId }); + } + private lazyTransitionToRunningState(threadId?: number): void { let setNewFocusedStackFrameScheduler: RunOnceScheduler; const toDispose = this.session.onDidStop(e => { diff --git a/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts b/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts index 38d34657dc3..e2294531226 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts @@ -281,7 +281,7 @@ export class CallStackController extends BaseDebugController { export class CallStackActionProvider implements renderer.IActionProvider { - constructor( @IInstantiationService private instantiationService: IInstantiationService) { + constructor( @IInstantiationService private instantiationService: IInstantiationService, @debug.IDebugService private debugService: debug.IDebugService) { // noop } @@ -294,19 +294,26 @@ export class CallStackActionProvider implements renderer.IActionProvider { } public hasSecondaryActions(tree: tree.ITree, element: any): boolean { - return element instanceof model.Thread; + return element instanceof model.Thread || element instanceof model.StackFrame; } public getSecondaryActions(tree: tree.ITree, element: any): TPromise { const actions: actions.Action[] = []; - const thread = element; - if (thread.stopped) { - actions.push(this.instantiationService.createInstance(debugactions.ContinueAction, debugactions.ContinueAction.ID, debugactions.ContinueAction.LABEL)); - actions.push(this.instantiationService.createInstance(debugactions.StepOverDebugAction, debugactions.StepOverDebugAction.ID, debugactions.StepOverDebugAction.LABEL)); - actions.push(this.instantiationService.createInstance(debugactions.StepIntoDebugAction, debugactions.StepIntoDebugAction.ID, debugactions.StepIntoDebugAction.LABEL)); - actions.push(this.instantiationService.createInstance(debugactions.StepOutDebugAction, debugactions.StepOutDebugAction.ID, debugactions.StepOutDebugAction.LABEL)); - } else { - actions.push(this.instantiationService.createInstance(debugactions.PauseAction, debugactions.PauseAction.ID, debugactions.PauseAction.LABEL)); + if (element instanceof model.Thread) { + const thread = element; + if (thread.stopped) { + actions.push(this.instantiationService.createInstance(debugactions.ContinueAction, debugactions.ContinueAction.ID, debugactions.ContinueAction.LABEL)); + actions.push(this.instantiationService.createInstance(debugactions.StepOverDebugAction, debugactions.StepOverDebugAction.ID, debugactions.StepOverDebugAction.LABEL)); + actions.push(this.instantiationService.createInstance(debugactions.StepIntoDebugAction, debugactions.StepIntoDebugAction.ID, debugactions.StepIntoDebugAction.LABEL)); + actions.push(this.instantiationService.createInstance(debugactions.StepOutDebugAction, debugactions.StepOutDebugAction.ID, debugactions.StepOutDebugAction.LABEL)); + } else { + actions.push(this.instantiationService.createInstance(debugactions.PauseAction, debugactions.PauseAction.ID, debugactions.PauseAction.LABEL)); + } + } else if (element instanceof model.StackFrame) { + const caps = this.debugService.getActiveSession().configuration.capabilities; + if (typeof caps.supportsRestartFrame === 'boolean' && caps.supportsRestartFrame) { + actions.push(this.instantiationService.createInstance(debugactions.RestartFrameAction, debugactions.RestartFrameAction.ID, debugactions.RestartFrameAction.LABEL)); + } } return TPromise.as(actions); diff --git a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts index cc7a33e7bca..a910b876e50 100644 --- a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts +++ b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts @@ -380,7 +380,7 @@ export class ReplExpressionsRenderer implements tree.IRenderer { event.preventDefault(); this.editorService.openEditor({ - resource: resource, + resource, options: { selection: { startLineNumber: line, diff --git a/src/vs/workbench/parts/debug/node/rawDebugSession.ts b/src/vs/workbench/parts/debug/node/rawDebugSession.ts index 5e0d76794ad..034db96e5b0 100644 --- a/src/vs/workbench/parts/debug/node/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/node/rawDebugSession.ts @@ -250,10 +250,14 @@ export class RawDebugSession extends v8.V8Protocol implements debug.IRawDebugSes return this.send('pause', args); } - public setVarialbe(args: DebugProtocol.SetVariableArguments): TPromise { + public setVariable(args: DebugProtocol.SetVariableArguments): TPromise { return this.send('setVariable', args); } + public restartFrame(args: DebugProtocol.RestartFrameArguments): TPromise { + return this.send('restartFrame', args); + } + public disconnect(restart = false, force = false): TPromise { if (this.stopServerPending && force) { return this.stopServer(); diff --git a/src/vs/workbench/parts/debug/test/common/mockDebugService.ts b/src/vs/workbench/parts/debug/test/common/mockDebugService.ts index 6d5533e6a09..0667a03940a 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebugService.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebugService.ts @@ -130,6 +130,10 @@ export class MockDebugService implements debug.IDebugService { public setVariable(variable: debug.IExpression, value: string): TPromise { return TPromise.as(null); } + + public restartFrame(frameId: number): TPromise { + return TPromise.as(null); + } } diff --git a/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.ts b/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.ts index 4d664894043..b1c9f31ed47 100644 --- a/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/execution/electron-browser/terminal.contribution.ts @@ -22,6 +22,8 @@ import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/edito import {asFileEditorInput} from 'vs/workbench/common/editor'; import {KeyMod, KeyCode} from 'vs/base/common/keyCodes'; import {Extensions, IConfigurationRegistry} from 'vs/platform/configuration/common/configurationRegistry'; +import {KbExpr} from 'vs/platform/keybinding/common/keybinding'; +import {KEYBINDING_CONTEXT_TERMINAL_FOCUS} from 'vs/workbench/parts/terminal/electron-browser/terminal'; import {DEFAULT_TERMINAL_WINDOWS, DEFAULT_TERMINAL_LINUX, DEFAULT_TERMINAL_OSX} from 'vs/workbench/parts/execution/electron-browser/terminal'; let configurationRegistry = Registry.as(Extensions.Configuration); @@ -132,7 +134,8 @@ actionBarRegistry.registerActionBarContributor(Scope.VIEWER, FileViewerActionCon OpenConsoleAction, OpenConsoleAction.ID, OpenConsoleAction.Label, - { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C } + { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C }, + KbExpr.and(KbExpr.not(KEYBINDING_CONTEXT_TERMINAL_FOCUS)) ), 'Open New Command Prompt' ); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts index c3b0a840d52..e80dbd06ef9 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionEditor.ts @@ -116,7 +116,6 @@ export class ExtensionEditor extends BaseEditor { setInput(input: ExtensionsInput, options: EditorOptions): TPromise { this.transientDisposables = dispose(this.transientDisposables); - let promise = TPromise.as(null); const extension = input.extension; this.icon.style.backgroundImage = `url("${ extension.iconUrl }")`; @@ -138,24 +137,30 @@ export class ExtensionEditor extends BaseEditor { }); } - const install = this.instantiationService.createInstance(InstallWidget, this.installCount, extension, {}); + const install = this.instantiationService.createInstance(InstallWidget, this.installCount, { extension }); this.transientDisposables.push(install); - const ratings = this.instantiationService.createInstance(RatingsWidget, this.rating, extension, {}); + const ratings = this.instantiationService.createInstance(RatingsWidget, this.rating, { extension }); this.transientDisposables.push(ratings); - const installAction = this.instantiationService.createInstance(CombinedInstallAction, extension); - const updateAction = this.instantiationService.createInstance(UpdateAction, extension); - const enableAction = this.instantiationService.createInstance(EnableAction, extension); + const installAction = this.instantiationService.createInstance(CombinedInstallAction); + const updateAction = this.instantiationService.createInstance(UpdateAction); + const enableAction = this.instantiationService.createInstance(EnableAction); + + installAction.extension = extension; + updateAction.extension = extension; + enableAction.extension = extension; + this.actionBar.clear(); this.actionBar.push([enableAction, updateAction, installAction], { icon: true, label: true }); this.transientDisposables.push(enableAction, updateAction, installAction); this.body.innerHTML = ''; - addClass(this.body, 'loading'); + let promise: TPromise = super.setInput(input, options); if (extension.readmeUrl) { - promise = super.setInput(input, options) + promise = promise + .then(() => addClass(this.body, 'loading')) .then(() => this.requestService.makeRequest({ url: extension.readmeUrl })) .then(response => response.responseText) .then(marked.parse) @@ -174,6 +179,10 @@ export class ExtensionEditor extends BaseEditor { }) .then(null, () => null) .then(() => removeClass(this.body, 'loading')); + } else { + promise = promise + .then(() => append(this.body, $('p'))) + .then(p => p.textContent = localize('noReadme', "No README available.")); } this.transientDisposables.push(toDisposable(() => promise.cancel())); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts index a1569107b8e..91d7bcfd993 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts @@ -16,7 +16,7 @@ import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage' import product from 'vs/platform/product'; import { IMessageService, CloseAction } from 'vs/platform/message/common/message'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ShowExtensionRecommendationsAction } from './extensionsActions'; +import { ShowRecommendedExtensionsAction } from './extensionsActions'; import Severity from 'vs/base/common/severity'; export class ExtensionTipsService implements IExtensionTipsService { @@ -128,7 +128,7 @@ export class ExtensionTipsService implements IExtensionTipsService { ); return Promise.as(true); }); - const recommendationsAction = this.instantiationService.createInstance(ShowExtensionRecommendationsAction, ShowExtensionRecommendationsAction.ID, localize('showRecommendations', "Show Recommendations")); + const recommendationsAction = this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, localize('showRecommendations', "Show Recommendations")); this.messageService.show(Severity.Info, { message, 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 9748988854e..b2def00113c 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensions.contribution.ts @@ -21,7 +21,7 @@ import { IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/co import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { VIEWLET_ID, IExtensionsWorkbenchService } from './extensions'; import { ExtensionsWorkbenchService } from './extensionsWorkbenchService'; -import { OpenExtensionsViewletAction, InstallExtensionsAction, ListOutdatedExtensionsAction, ShowExtensionRecommendationsAction, ShowPopularExtensionsAction } from './extensionsActions'; +import { OpenExtensionsViewletAction, InstallExtensionsAction, ShowOutdatedExtensionsAction, ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowInstalledExtensionsAction } from './extensionsActions'; import { ExtensionsInput } from './extensionsInput'; import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet'; import { ExtensionEditor } from './extensionEditor'; @@ -96,11 +96,14 @@ actionRegistry.registerWorkbenchAction(openViewletActionDescriptor, 'View: Show const installActionDescriptor = new SyncActionDescriptor(InstallExtensionsAction, InstallExtensionsAction.ID, InstallExtensionsAction.LABEL); actionRegistry.registerWorkbenchAction(installActionDescriptor, 'Extensions: Install', ExtensionsLabel); -const listOutdatedActionDescriptor = new SyncActionDescriptor(ListOutdatedExtensionsAction, ListOutdatedExtensionsAction.ID, ListOutdatedExtensionsAction.LABEL); +const listOutdatedActionDescriptor = new SyncActionDescriptor(ShowOutdatedExtensionsAction, ShowOutdatedExtensionsAction.ID, ShowOutdatedExtensionsAction.LABEL); actionRegistry.registerWorkbenchAction(listOutdatedActionDescriptor, 'Extensions: Show Outdated Extensions', ExtensionsLabel); -const recommendationsActionDescriptor = new SyncActionDescriptor(ShowExtensionRecommendationsAction, ShowExtensionRecommendationsAction.ID, ShowExtensionRecommendationsAction.LABEL); -actionRegistry.registerWorkbenchAction(recommendationsActionDescriptor, `Extensions: ${ ShowExtensionRecommendationsAction.LABEL }`, ExtensionsLabel); +const recommendationsActionDescriptor = new SyncActionDescriptor(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, ShowRecommendedExtensionsAction.LABEL); +actionRegistry.registerWorkbenchAction(recommendationsActionDescriptor, `Extensions: ${ ShowRecommendedExtensionsAction.LABEL }`, ExtensionsLabel); const popularActionDescriptor = new SyncActionDescriptor(ShowPopularExtensionsAction, ShowPopularExtensionsAction.ID, ShowPopularExtensionsAction.LABEL); actionRegistry.registerWorkbenchAction(popularActionDescriptor, `Extensions: ${ ShowPopularExtensionsAction.LABEL }`, ExtensionsLabel); + +const installedActionDescriptor = new SyncActionDescriptor(ShowInstalledExtensionsAction, ShowInstalledExtensionsAction.ID, ShowInstalledExtensionsAction.LABEL); +actionRegistry.registerWorkbenchAction(installedActionDescriptor, `Extensions: ${ ShowInstalledExtensionsAction.LABEL }`, ExtensionsLabel); diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts index ede9a31dbbe..ce0e5e9e62d 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsActions.ts @@ -22,9 +22,11 @@ export class InstallAction extends Action { private static InstallLabel = localize('installAction', "Install"); private static InstallingLabel = localize('installing', "Installing"); private disposables: IDisposable[] = []; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { this._extension = extension; this.update(); } constructor( - private extension: IExtension, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService ) { super('extensions.install', InstallAction.InstallLabel, 'extension-action install', false); @@ -34,6 +36,12 @@ export class InstallAction extends Action { } private update(): void { + if (!this.extension) { + this.enabled = false; + this.label = InstallAction.InstallLabel; + return; + } + this.enabled = this.extensionsWorkbenchService.canInstall(this.extension) && this.extension.state === ExtensionState.Uninstalled; this.label = this.extension.state === ExtensionState.Installing ? InstallAction.InstallingLabel : InstallAction.InstallLabel; } @@ -51,20 +59,27 @@ export class InstallAction extends Action { export class UninstallAction extends Action { private disposables: IDisposable[] = []; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { this._extension = extension; this.update(); } constructor( - private extension: IExtension, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, @IMessageService private messageService: IMessageService, @IInstantiationService private instantiationService: IInstantiationService ) { super('extensions.uninstall', localize('uninstall', "Uninstall"), 'extension-action uninstall', false); - this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.updateEnablement())); - this.updateEnablement(); + this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update())); + this.update(); } - private updateEnablement(): void { + private update(): void { + if (!this.extension) { + this.enabled = false; + return; + } + this.enabled = this.extension.state === ExtensionState.Installed || this.extension.state === ExtensionState.NeedsRestart; } @@ -90,26 +105,37 @@ export class UninstallAction extends Action { export class CombinedInstallAction extends Action { + private static NoExtensionClass = 'extension-action install no-extension'; private installAction: InstallAction; private uninstallAction: UninstallAction; private disposables: IDisposable[] = []; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { + this._extension = extension; + this.installAction.extension = extension; + this.uninstallAction.extension = extension; + } constructor( - private extension: IExtension, @IInstantiationService instantiationService: IInstantiationService ) { super('extensions.combinedInstall', '', '', false); - this.installAction = instantiationService.createInstance(InstallAction, extension); - this.uninstallAction = instantiationService.createInstance(UninstallAction, extension); + this.installAction = instantiationService.createInstance(InstallAction); + this.uninstallAction = instantiationService.createInstance(UninstallAction); this.disposables.push(this.installAction, this.uninstallAction); this.installAction.onDidChange(this.update, this, this.disposables); + this.uninstallAction.onDidChange(this.update, this, this.disposables); this.update(); } private update(): void { - if (this.installAction.enabled) { + if (!this.extension) { + this.enabled = false; + this.class = CombinedInstallAction.NoExtensionClass; + } else if (this.installAction.enabled) { this.enabled = true; this.label = this.installAction.label; this.class = this.installAction.class; @@ -123,6 +149,8 @@ export class CombinedInstallAction extends Action { this.class = this.installAction.class; } else { this.enabled = false; + this.label = this.installAction.label; + this.class = this.installAction.class; } } @@ -148,18 +176,26 @@ export class UpdateAction extends Action { private static DisabledClass = `${ UpdateAction.EnabledClass } disabled`; private disposables: IDisposable[] = []; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { this._extension = extension; this.update(); } constructor( - private extension: IExtension, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService ) { super('extensions.update', localize('updateAction', "Update"), UpdateAction.DisabledClass, false); - this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.updateEnablement())); - this.updateEnablement(); + this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update())); + this.update(); } - private updateEnablement(): void { + private update(): void { + if (!this.extension) { + this.enabled = false; + this.class = UpdateAction.DisabledClass; + return; + } + const canInstall = this.extensionsWorkbenchService.canInstall(this.extension); const isInstalled = this.extension.state === ExtensionState.Installed || this.extension.state === ExtensionState.NeedsRestart; @@ -184,19 +220,27 @@ export class EnableAction extends Action { private static DisabledClass = `${ EnableAction.EnabledClass } disabled`; private disposables: IDisposable[] = []; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { this._extension = extension; this.update(); } constructor( - private extension: IExtension, @IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService, @IInstantiationService private instantiationService: IInstantiationService ) { super('extensions.enable', localize('enableAction', "Enable"), EnableAction.DisabledClass, false); - this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.updateEnablement())); - this.updateEnablement(); + this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update())); + this.update(); } - private updateEnablement(): void { + private update(): void { + if (!this.extension) { + this.enabled = false; + this.class = EnableAction.DisabledClass; + return; + } + this.enabled = this.extension.state === ExtensionState.NeedsRestart; this.class = this.enabled ? EnableAction.EnabledClass : EnableAction.DisabledClass; } @@ -258,10 +302,9 @@ export class ClearExtensionsInputAction extends Action { viewlet.focus(); }); } - } -export class ListOutdatedExtensionsAction extends Action { +export class ShowOutdatedExtensionsAction extends Action { static ID = 'workbench.extensions.action.listOutdatedExtensions'; static LABEL = localize('showOutdatedExtensions', "Show Outdated Extensions"); @@ -316,10 +359,10 @@ export class ShowPopularExtensionsAction extends Action { } } -export class ShowExtensionRecommendationsAction extends Action { +export class ShowRecommendedExtensionsAction extends Action { - static ID = 'workbench.extensions.action.showExtensionRecommendations'; - static LABEL = localize('showExtensionRecommendations', "Show Extension Recommendations"); + static ID = 'workbench.extensions.action.showRecommendedExtensions'; + static LABEL = localize('showRecommendedExtensions', "Show Recommended Extensions"); constructor( id: string, diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts index 59ad64fe184..c0a0c963985 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsList.ts @@ -16,16 +16,14 @@ import { CombinedInstallAction, UpdateAction, EnableAction } from './extensionsA import { Label, RatingsWidget, InstallWidget } from './extensionsWidgets'; export interface ITemplateData { - extension: IExtension; element: HTMLElement; - icon: HTMLElement; + icon: HTMLImageElement; name: HTMLElement; - version: HTMLElement; installCount: HTMLElement; ratings: HTMLElement; author: HTMLElement; description: HTMLElement; - actionbar: ActionBar; + extension: IExtension; disposables: IDisposable[]; } @@ -44,68 +42,73 @@ export class Renderer implements IPagedRenderer { renderTemplate(root: HTMLElement): ITemplateData { const element = append(root, $('.extension')); - const icon = append(element, $('.icon')); + const icon = append(element, $('img.icon')); const details = append(element, $('.details')); const header = append(details, $('.header')); const name = append(header, $('span.name')); - const version = append(header, $('span.version.ellipsis')); + const version = append(header, $('span.version')); const installCount = append(header, $('span.install-count')); const ratings = append(header, $('span.ratings')); const description = append(details, $('.description.ellipsis')); const footer = append(details, $('.footer')); const author = append(footer, $('.author.ellipsis')); const actionbar = new ActionBar(footer, { animated: false }); - const disposables = []; + + const versionWidget = this.instantiationService.createInstance(Label, version, e => e.version); + const installCountWidget = this.instantiationService.createInstance(InstallWidget, installCount, { small: true }); + const ratingsWidget = this.instantiationService.createInstance(RatingsWidget, ratings, { small: true }); + + const installAction = this.instantiationService.createInstance(CombinedInstallAction); + const updateAction = this.instantiationService.createInstance(UpdateAction); + const restartAction = this.instantiationService.createInstance(EnableAction); + + actionbar.push([restartAction, updateAction, installAction], actionOptions); + const disposables = [versionWidget, installCountWidget, ratingsWidget, installAction, updateAction, restartAction, actionbar]; return { - extension: null, element, icon, name, version, - installCount, ratings, author, description, - actionbar, disposables + element, icon, name, installCount, ratings, author, description, disposables, + set extension(extension: IExtension) { + versionWidget.extension = extension; + installCountWidget.extension = extension; + ratingsWidget.extension = extension; + installAction.extension = extension; + updateAction.extension = extension; + restartAction.extension = extension; + } }; } renderPlaceholder(index: number, data: ITemplateData): void { - data.disposables = dispose(data.disposables); - addClass(data.element, 'loading'); - data.extension = null; - data.icon.style.backgroundImage = ''; + data.icon.src = ''; data.name.textContent = ''; - data.version.textContent = ''; - data.installCount.style.display = 'none'; - data.ratings.style.display = 'none'; data.author.textContent = ''; data.description.textContent = ''; - data.actionbar.clear(); + data.installCount.style.display = 'none'; + data.ratings.style.display = 'none'; + data.extension = null; } renderElement(extension: IExtension, index: number, data: ITemplateData): void { - data.disposables = dispose(data.disposables); - removeClass(data.element, 'loading'); - data.extension = extension; - data.icon.style.backgroundImage = `url("${ extension.iconUrl }")`; + data.icon.src = extension.iconUrl; + + if (!data.icon.complete) { + data.icon.style.visibility = 'hidden'; + data.icon.onload = () => data.icon.style.visibility = 'inherit'; + } else { + data.icon.style.visibility = 'inherit'; + } + data.name.textContent = extension.displayName; data.author.textContent = extension.publisherDisplayName; data.description.textContent = extension.description; - data.installCount.style.display = 'initial'; - data.ratings.style.display = 'initial'; - - const version = this.instantiationService.createInstance(Label, data.version, extension, e => e.version); - const installCount = this.instantiationService.createInstance(InstallWidget, data.installCount, extension, { small: true }); - const ratings = this.instantiationService.createInstance(RatingsWidget, data.ratings, extension, { small: true }); - - const installAction = this.instantiationService.createInstance(CombinedInstallAction, extension); - const updateAction = this.instantiationService.createInstance(UpdateAction, extension); - const restartAction = this.instantiationService.createInstance(EnableAction, extension); - - data.actionbar.clear(); - data.actionbar.push([restartAction, updateAction, installAction], actionOptions); - - data.disposables.push(version, installCount, ratings, installAction, updateAction, restartAction); + data.installCount.style.display = ''; + data.ratings.style.display = ''; + data.extension = extension; } disposeTemplate(data: ITemplateData): void { - data.actionbar = dispose(data.actionbar); + data.disposables = dispose(data.disposables); } } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts index 5f732cf8572..e7649d56266 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViewlet.ts @@ -18,14 +18,14 @@ import { domEvent } from 'vs/base/browser/event'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Viewlet } from 'vs/workbench/browser/viewlet'; -import { append, emmet as $, addStandardDisposableListener, EventType, addClass, removeClass } from 'vs/base/browser/dom'; +import { append, emmet as $, addStandardDisposableListener, EventType, addClass, removeClass, toggleClass } from 'vs/base/browser/dom'; import { IPager, PagedModel } from 'vs/base/common/paging'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { PagedList } from 'vs/base/browser/ui/list/listPaging'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Delegate, Renderer } from './extensionsList'; import { IExtensionsWorkbenchService, IExtension, IExtensionsViewlet, VIEWLET_ID } from './extensions'; -import { ShowExtensionRecommendationsAction, ShowPopularExtensionsAction, ShowInstalledExtensionsAction, ListOutdatedExtensionsAction, ClearExtensionsInputAction } from './extensionsActions'; +import { ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowInstalledExtensionsAction, ShowOutdatedExtensionsAction, ClearExtensionsInputAction } from './extensionsActions'; import { IExtensionManagementService, IExtensionGalleryService, SortBy } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionsInput } from './extensionsInput'; import { IProgressService } from 'vs/platform/progress/common/progress'; @@ -39,7 +39,6 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet { private extensionsBox: HTMLElement; private list: PagedList; private disposables: IDisposable[] = []; - private focusInvokedByTab: boolean; private clearAction: ClearExtensionsInputAction; constructor( @@ -78,25 +77,19 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet { const onEscape = filterEvent(onKeyDown, e => e.keyCode === KeyCode.Escape); const onUpArrow = filterEvent(onKeyDown, e => e.keyCode === KeyCode.UpArrow); const onDownArrow = filterEvent(onKeyDown, e => e.keyCode === KeyCode.DownArrow); - const onTab = filterEvent(onKeyDown, e => e.keyCode === KeyCode.Tab); + const onPageUpArrow = filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageUp); + const onPageDownArrow = filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageDown); onEnter(this.onEnter, this, this.disposables); onEscape(this.onEscape, this, this.disposables); onUpArrow(this.onUpArrow, this, this.disposables); onDownArrow(this.onDownArrow, this, this.disposables); - onTab(this.onTab, this, this.disposables); + onPageUpArrow(this.onPageUpArrow, this, this.disposables); + onPageDownArrow(this.onPageDownArrow, this, this.disposables); const onInput = domEvent(this.searchBox, 'input'); onInput(() => this.triggerSearch(), null, this.disposables); - this.list.onDOMFocus(focusEvent => { - // Allow tab to move focus out of search box #7966 - if (!this.focusInvokedByTab) { - this.searchBox.focus(); - } - this.focusInvokedByTab = false; - }, null, this.disposables); - const onSelectedExtension = filterEvent(mapEvent(this.list.onSelectionChange, e => e.elements[0]), e => !!e); onSelectedExtension(this.onExtensionSelected, this, this.disposables); @@ -119,8 +112,13 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet { this.searchBox.focus(); } - layout({ height }: Dimension):void { + layout({ height, width }: Dimension):void { this.list.layout(height - 38); + toggleClass(this.root, 'narrow', width <= 300); + } + + getOptimalWidth(): number { + return 400; } getActions(): IAction[] { @@ -136,8 +134,8 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet { getSecondaryActions(): IAction[] { return [ this.instantiationService.createInstance(ShowInstalledExtensionsAction, ShowInstalledExtensionsAction.ID, ShowInstalledExtensionsAction.LABEL), - this.instantiationService.createInstance(ListOutdatedExtensionsAction, ListOutdatedExtensionsAction.ID, ListOutdatedExtensionsAction.LABEL), - this.instantiationService.createInstance(ShowExtensionRecommendationsAction, ShowExtensionRecommendationsAction.ID, ShowExtensionRecommendationsAction.LABEL), + this.instantiationService.createInstance(ShowOutdatedExtensionsAction, ShowOutdatedExtensionsAction.ID, ShowOutdatedExtensionsAction.LABEL), + this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, ShowRecommendedExtensionsAction.LABEL), this.instantiationService.createInstance(ShowPopularExtensionsAction, ShowPopularExtensionsAction.ID, ShowPopularExtensionsAction.LABEL) ]; } @@ -180,7 +178,10 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet { return always(promise, () => progressRunner.done()) .then(result => new PagedModel(result)) - .then(model => this.list.model = model); + .then(model => { + this.list.model = model; + this.list.scrollTop = 0; + }); } private onExtensionSelected(extension: IExtension): void { @@ -199,14 +200,22 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet { private onUpArrow(): void { this.list.focusPrevious(); + this.list.reveal(this.list.getFocus()[0]); } private onDownArrow(): void { this.list.focusNext(); + this.list.reveal(this.list.getFocus()[0]); } - private onTab(): void { - this.focusInvokedByTab = true; + private onPageUpArrow(): void { + this.list.focusPreviousPage(); + this.list.reveal(this.list.getFocus()[0]); + } + + private onPageDownArrow(): void { + this.list.focusNextPage(); + this.list.reveal(this.list.getFocus()[0]); } dispose(): void { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts index 0c58e21e814..172dc8f0287 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts @@ -11,22 +11,28 @@ import { IExtension, IExtensionsWorkbenchService } from './extensions'; import { append, emmet as $, addClass } from 'vs/base/browser/dom'; export interface IOptions { + extension?: IExtension; small?: boolean; } export class Label implements IDisposable { private listener: IDisposable; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { this._extension = extension; this.render(); } constructor( - element: HTMLElement, - extension: IExtension, - fn: (extension: IExtension) => string, + private element: HTMLElement, + private fn: (extension: IExtension) => string, @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService ) { - const render = () => element.textContent = fn(extension); - render(); - this.listener = extensionsWorkbenchService.onChange(render); + this.render(); + this.listener = extensionsWorkbenchService.onChange(this.render, this); + } + + private render(): void { + this.element.textContent = this.extension ? this.fn(this.extension) : ''; } dispose(): void { @@ -37,22 +43,30 @@ export class Label implements IDisposable { export class InstallWidget implements IDisposable { private disposables: IDisposable[] = []; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { this._extension = extension; this.render(); } constructor( private container: HTMLElement, - private extension: IExtension, private options: IOptions, @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService ) { + this._extension = options.extension; this.disposables.push(extensionsWorkbenchService.onChange(() => this.render())); addClass(container, 'extension-install-count'); this.render(); } private render(): void { - const installCount = this.extension.installCount; this.container.innerHTML = ''; + if (!this.extension) { + return; + } + + const installCount = this.extension.installCount; + if (installCount === null) { return; } @@ -80,13 +94,16 @@ export class InstallWidget implements IDisposable { export class RatingsWidget implements IDisposable { private disposables: IDisposable[] = []; + private _extension: IExtension; + get extension(): IExtension { return this._extension; } + set extension(extension: IExtension) { this._extension = extension; this.render(); } constructor( private container: HTMLElement, - private extension: IExtension, private options: IOptions, @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService ) { + this._extension = options.extension; this.disposables.push(extensionsWorkbenchService.onChange(() => this.render())); addClass(container, 'extension-ratings'); @@ -98,27 +115,38 @@ export class RatingsWidget implements IDisposable { } private render(): void { - const rating = Math.round(this.extension.rating * 2) / 2; this.container.innerHTML = ''; - if (rating === null) { + if (!this.extension) { return; } - for (let i = 1; i <= 5; i++) { - if (rating >= i) { - append(this.container, $('span.full.star')); - } else if (rating >= i - 0.5) { - append(this.container, $('span.half.star')); - } else { - append(this.container, $('span.empty.star')); + const rating = Math.round(this.extension.rating * 2) / 2; + + if (this.extension.rating === null) { + return; + } + + if (this.options.small && this.extension.ratingCount === 0) { + return; + } + + if (this.options.small) { + append(this.container, $('span.full.star')); + } else { + for (let i = 1; i <= 5; i++) { + if (rating >= i) { + append(this.container, $('span.full.star')); + } else if (rating >= i - 0.5) { + append(this.container, $('span.half.star')); + } else { + append(this.container, $('span.empty.star')); + } } } - if (!this.options.small) { - const count = append(this.container, $('span.count')); - count.textContent = String(this.extension.ratingCount); - } + const count = append(this.container, $('span.count')); + count.textContent = String(this.options.small ? rating : this.extension.ratingCount); } dispose(): void { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts index fd43bf7a3fc..8233041d58e 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts @@ -5,7 +5,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { localize } from 'vs/nls'; -import { Promise } from 'vs/base/common/winjs.base'; +import { TPromise } from 'vs/base/common/winjs.base'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -51,14 +51,14 @@ export class ExtensionsWorkbenchExtension implements IWorkbenchContribution { }); } - private install(extensions: string[]): Promise { - return Promise.join(extensions.map(extPath => this.extensionManagementService.install(extPath))) - .then(extensions => { + private install(extensions: string[]): TPromise { + return TPromise.join(extensions.map(extPath => this.extensionManagementService.install(extPath))) + .then(() => { this.messageService.show( Severity.Info, { message: extensions.length > 1 ? localize('success', "Extensions were successfully installed. Restart to enable them.") - : localize('successSingle', "{0} was successfully installed. Restart to enable it.", extensions[0].displayName), + : localize('successSingle', "Extension was successfully installed. Restart to enable it."), actions: [this.instantiationService.createInstance(ReloadWindowAction, ReloadWindowAction.ID, localize('reloadNow', "Restart Now"))] } ); @@ -104,4 +104,4 @@ export class StatusUpdater implements IWorkbenchContribution { dispose(): void { this.disposables = dispose(this.disposables); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchService.ts index d2ae8746c2f..a04187c4291 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchService.ts @@ -119,6 +119,10 @@ class Extension implements IExtension { } } +function stripVersion(id: string): string { + return id.replace(/-\d+\.\d+\.\d+$/, ''); +} + export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { private static SyncPeriod = 1000 * 60 * 60 * 12; // 12 hours @@ -152,7 +156,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { get local(): IExtension[] { const installing = this.installing - .filter(e => !this.installed.some(installed => installed.local.id === e.id)) + .filter(e => !this.installed.some(installed => stripVersion(installed.local.id) === e.id)) .map(e => e.extension); return [...this.installed, ...installing]; @@ -276,12 +280,14 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService { } extension.gallery = gallery; - this.installing.push({ id, extension }); + this.installing.push({ id: stripVersion(id), extension }); this._onChange.fire(); } private onDidInstallExtension(id: string, local: ILocalExtension, error: Error): void { + id = stripVersion(id); + const installing = this.installing.filter(e => e.id === id)[0]; if (!installing) { diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionActions.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionActions.css index fc0b00d496f..f1a00390db2 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionActions.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionActions.css @@ -50,6 +50,11 @@ background-color: #6DA770; } +.monaco-action-bar .action-item:not(.disabled) .action-label:focus.extension-action.install, +.monaco-action-bar .action-item:not(.disabled) .action-label:focus.extension-action.update { + outline: 1px solid rgb(14, 99, 156) !important; +} + .monaco-action-bar .action-item .action-label.extension-action.enable { color: white; @@ -62,7 +67,8 @@ background: url('clear.svg') center center no-repeat; } -.vs-dark .monaco-action-bar .action-item .action-label.clear-extensions { +.vs-dark .monaco-action-bar .action-item .action-label.clear-extensions, +.hc-black .monaco-action-bar .action-item .action-label.clear-extensions { background: url('clear-inverse.svg') center center no-repeat; } @@ -74,11 +80,8 @@ background-color: #4294CC } +.monaco-action-bar .action-item.disabled .action-label.extension-action.install.no-extension, .monaco-action-bar .action-item.disabled .action-label.extension-action.update, .monaco-action-bar .action-item.disabled .action-label.extension-action.enable { display: none; -} - -.hc-black .monaco-action-bar .action-item .action-label.clear-extensions { - background: url('clear-inverse.svg') center center no-repeat; } \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionEditor.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionEditor.css index 94e965ec33d..8be8ca4ed44 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionEditor.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionEditor.css @@ -105,8 +105,6 @@ overflow: hidden; } -.extension-editor > .body.loading { - background-image: url('loading.svg'); - background-position: center center; - background-repeat: no-repeat; +.extension-editor > .body > p { + margin: 20px; } \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensions.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensions.css index 333f95eda9a..97ef9e7903f 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensions.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensions.css @@ -8,8 +8,10 @@ height: 48px; } -.quick-open-widget .extension.loading { - background: url('loading.svg') center center no-repeat; +.quick-open-widget .extension.loading, +.extensions-viewlet > .extensions .extension.loading, +.extension-editor > .body.loading { + background: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjU3NSIgaGVpZ2h0PSI2cHgiPg0KICA8c3R5bGU+DQogICAgY2lyY2xlIHsNCiAgICAgIGFuaW1hdGlvbjogYmFsbCAyLjVzIGN1YmljLWJlemllcigwLjAwMCwgMS4wMDAsIDEuMDAwLCAwLjAwMCkgaW5maW5pdGU7DQogICAgICBmaWxsOiAjYmJiOw0KICAgIH0NCg0KICAgICNiYWxscyB7DQogICAgICBhbmltYXRpb246IGJhbGxzIDIuNXMgbGluZWFyIGluZmluaXRlOw0KICAgIH0NCg0KICAgICNjaXJjbGUyIHsgYW5pbWF0aW9uLWRlbGF5OiAwLjFzOyB9DQogICAgI2NpcmNsZTMgeyBhbmltYXRpb24tZGVsYXk6IDAuMnM7IH0NCiAgICAjY2lyY2xlNCB7IGFuaW1hdGlvbi1kZWxheTogMC4zczsgfQ0KICAgICNjaXJjbGU1IHsgYW5pbWF0aW9uLWRlbGF5OiAwLjRzOyB9DQoNCiAgICBAa2V5ZnJhbWVzIGJhbGwgew0KICAgICAgZnJvbSB7IHRyYW5zZm9ybTogbm9uZTsgfQ0KICAgICAgMjAlIHsgdHJhbnNmb3JtOiBub25lOyB9DQogICAgICA4MCUgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoODY0cHgpOyB9DQogICAgICB0byB7IHRyYW5zZm9ybTogdHJhbnNsYXRlWCg4NjRweCk7IH0NCiAgICB9DQoNCiAgICBAa2V5ZnJhbWVzIGJhbGxzIHsNCiAgICAgIGZyb20geyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTQwcHgpOyB9DQogICAgICB0byB7IHRyYW5zZm9ybTogdHJhbnNsYXRlWCgzMHB4KTsgfQ0KICAgIH0NCiAgPC9zdHlsZT4NCiAgPGcgaWQ9ImJhbGxzIj4NCiAgICA8Y2lyY2xlIGNsYXNzPSJjaXJjbGUiIGlkPSJjaXJjbGUxIiBjeD0iLTExNSIgY3k9IjMiIHI9IjMiLz4NCiAgICA8Y2lyY2xlIGNsYXNzPSJjaXJjbGUiIGlkPSJjaXJjbGUyIiBjeD0iLTEzMCIgY3k9IjMiIHI9IjMiIC8+DQogICAgPGNpcmNsZSBjbGFzcz0iY2lyY2xlIiBpZD0iY2lyY2xlMyIgY3g9Ii0xNDUiIGN5PSIzIiByPSIzIiAvPg0KICAgIDxjaXJjbGUgY2xhc3M9ImNpcmNsZSIgaWQ9ImNpcmNsZTQiIGN4PSItMTYwIiBjeT0iMyIgcj0iMyIgLz4NCiAgICA8Y2lyY2xlIGNsYXNzPSJjaXJjbGUiIGlkPSJjaXJjbGU1IiBjeD0iLTE3NSIgY3k9IjMiIHI9IjMiIC8+DQogIDwvZz4NCjwvc3ZnPg==') center center no-repeat; } .quick-open-widget .extension.loading > * { @@ -155,12 +157,16 @@ } .monaco-shell .extensions-statusbar > .icon { - background: url('extensions-status.svg') center center no-repeat; background-size: 14px; width: 14px; height: 14px; } +.monaco-shell .extensions-statusbar > .icon, +.monaco-workbench > .activitybar .monaco-action-bar .action-label.extensions { + background: url('extensions-status.svg') center center no-repeat; +} + .monaco-shell .extensions-statusbar.has-updates::after { content: ''; width: 6px; @@ -203,7 +209,6 @@ /* Global action */ .monaco-workbench > .activitybar .monaco-action-bar .action-label.extensions { - background: url('extensions-status.svg'); background-size: 22px; background-repeat: no-repeat; background-position: 50% !important; diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css index f169d5c8486..96b2a7067be 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsViewlet.css @@ -36,20 +36,16 @@ display: flex; } -.extensions-viewlet > .extensions .extension.loading { - background-image: url('loading.svg'); - background-position: center center; - background-repeat: no-repeat; -} - .extensions-viewlet > .extensions .extension > .icon { width: 42px; height: 42px; padding: 10px 14px 10px 0; flex-shrink: 0; - background-repeat: no-repeat; - background-size: 42px; - background-position: left center; + object-fit: contain; +} + +.extensions-viewlet.narrow > .extensions .extension > .icon { + display: none; } .extensions-viewlet > .extensions .extension.loading > .icon { @@ -65,6 +61,9 @@ .extensions-viewlet > .extensions .extension > .details > .header { display: flex; align-items: baseline; + flex-wrap: wrap; + height: 19px; + overflow: hidden; } .extensions-viewlet > .extensions .extension > .details > .header > .name { @@ -77,6 +76,7 @@ font-size: 80%; padding-left: 6px; flex: 1; + min-width: fit-content; } .extensions-viewlet > .extensions .extension > .details > .header > .install-count:not(:empty) { @@ -93,6 +93,11 @@ text-align: right; } +.extensions-viewlet.narrow > .extensions .extension > .details > .header > .ratings, +.extensions-viewlet.narrow > .extensions .extension > .details > .header > .install-count { + display: none; +} + .extensions-viewlet > .extensions .extension > .details > .footer { display: flex; justify-content: flex-end; @@ -132,10 +137,4 @@ background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMiAyIDE0IDE0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDIgMiAxNCAxNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTkgMTZjLTMuODYgMC03LTMuMTQtNy03czMuMTQtNyA3LTdjMy44NTkgMCA3IDMuMTQxIDcgN3MtMy4xNDEgNy03IDd6bTAtMTIuNmMtMy4wODggMC01LjYgMi41MTMtNS42IDUuNnMyLjUxMiA1LjYgNS42IDUuNiA1LjYtMi41MTIgNS42LTUuNi0yLjUxMi01LjYtNS42LTUuNnptMy44NiA3LjFsLTMuMTYtMS44OTZ2LTMuODA0aC0xLjR2NC41OTZsMy44NCAyLjMwNS43Mi0xLjIwMXoiLz48L3N2Zz4="); background-position: center center; background-repeat: no-repeat; -} - -/*.show-extension-recommendations.octicon { - font-size: 16px; - line-height: 35px; - text-align: center; -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsWidgets.css b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsWidgets.css index 67ed62a2bbd..7ddd1d4c880 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/extensionsWidgets.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/extensionsWidgets.css @@ -7,6 +7,10 @@ display: inline-block; } +.extension-ratings.small { + font-size: 80%; +} + .extension-ratings > .star { display: inline-block; width: 16px; @@ -25,17 +29,21 @@ } .extension-ratings > .full { - background-image: url('./FullStarLight.svg'); + background-image: url('FullStarLight.svg'); } .extension-ratings > .half { - background-image: url('./HalfStarLight.svg'); + background-image: url('HalfStarLight.svg'); } .extension-ratings > .empty { - background-image: url('./EmptyStar.svg'); + background-image: url('EmptyStar.svg'); } .extension-ratings > .count { margin-left: 6px; +} + +.extension-ratings.small > .count { + margin-left: 2px; } \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/loading.svg b/src/vs/workbench/parts/extensions/electron-browser/media/loading.svg deleted file mode 100644 index 0098fd9f264..00000000000 --- a/src/vs/workbench/parts/extensions/electron-browser/media/loading.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/vs/workbench/parts/extensions/electron-browser/media/markdown.css b/src/vs/workbench/parts/extensions/electron-browser/media/markdown.css index 6c0900de1da..1e792945828 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/media/markdown.css +++ b/src/vs/workbench/parts/extensions/electron-browser/media/markdown.css @@ -4,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ body { - font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback"; - font-size: 14px; padding: 10px 20px; line-height: 22px; } diff --git a/src/vs/workbench/parts/feedback/browser/media/feedback.css b/src/vs/workbench/parts/feedback/browser/media/feedback.css index 79956dde5e9..4d2664f9ad7 100644 --- a/src/vs/workbench/parts/feedback/browser/media/feedback.css +++ b/src/vs/workbench/parts/feedback/browser/media/feedback.css @@ -252,7 +252,8 @@ color: #D4D4D4; } -.monaco-shell.vs-dark .feedback-form .cancel { +.monaco-shell.vs-dark .feedback-form .cancel, +.monaco-shell.hc-black .feedback-form .cancel { background: url('close-dark.svg') center center no-repeat; } @@ -322,7 +323,6 @@ float: right; } .monaco-shell.hc-black .feedback-form .cancel { - background: none; opacity: 0.6; } @@ -330,15 +330,6 @@ opacity: 1; } -.monaco-shell.hc-black .feedback-form .cancel:before { - content: url('close-dark.svg'); - position: relative; - top: 4px; - left: 6px; - height: 32px; - width: 32px; -} - .monaco-shell.hc-black .feedback-form .form-buttons .send, .monaco-shell.hc-black .feedback-form .form-buttons .send.in-progress, .monaco-shell.hc-black .feedback-form .form-buttons .send.success { @@ -352,7 +343,6 @@ } .monaco-shell.hc-black .feedback-form .sentiment { - background: none; border: 1px solid transparent; } @@ -360,23 +350,6 @@ border: 1px solid #f38518; } -.monaco-shell.hc-black .feedback-form .sentiment:before { - height: 21px; - width: 21px; - display: inline-block; - position: relative; - top: 3px; - left: 3px; -} - -.monaco-shell.hc-black .feedback-form .sentiment.smile:before { - content: url('happy.svg'); -} - -.monaco-shell.hc-black .feedback-form .sentiment.frown:before { - content: url('sad.svg'); -} - .monaco-shell .feedback-form .infotip { background: none; } diff --git a/src/vs/workbench/parts/files/browser/files.contribution.ts b/src/vs/workbench/parts/files/browser/files.contribution.ts index 7e25315a3e8..96a7d8af4d1 100644 --- a/src/vs/workbench/parts/files/browser/files.contribution.ts +++ b/src/vs/workbench/parts/files/browser/files.contribution.ts @@ -167,7 +167,7 @@ configurationRegistry.registerConfiguration({ 'files.exclude': { 'type': 'object', 'description': nls.localize('exclude', "Configure glob patterns for excluding files and folders."), - 'default': { '**/.git': true, '**/.svn': true, '**/.DS_Store': true }, + 'default': { '**/.git': true, '**/.svn': true, '**/.hg': true, '**/.DS_Store': true }, 'additionalProperties': { 'anyOf': [ { diff --git a/src/vs/workbench/parts/files/browser/media/FileUpload.svg b/src/vs/workbench/parts/files/browser/media/FileUpload.svg deleted file mode 100644 index 39f10c5922e..00000000000 --- a/src/vs/workbench/parts/files/browser/media/FileUpload.svg +++ /dev/null @@ -1,3 +0,0 @@ - -]> \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/FileUpload_inverse.svg b/src/vs/workbench/parts/files/browser/media/FileUpload_inverse.svg deleted file mode 100644 index d6b9280b943..00000000000 --- a/src/vs/workbench/parts/files/browser/media/FileUpload_inverse.svg +++ /dev/null @@ -1,3 +0,0 @@ - -]> \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/Folder.svg b/src/vs/workbench/parts/files/browser/media/Folder.svg deleted file mode 100644 index 5118651d013..00000000000 --- a/src/vs/workbench/parts/files/browser/media/Folder.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/src/vs/workbench/parts/files/browser/media/Folder_inverse.svg b/src/vs/workbench/parts/files/browser/media/Folder_inverse.svg deleted file mode 100644 index f02833c8d7d..00000000000 --- a/src/vs/workbench/parts/files/browser/media/Folder_inverse.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - diff --git a/src/vs/workbench/parts/files/browser/media/add-focus.svg b/src/vs/workbench/parts/files/browser/media/add-focus.svg deleted file mode 100644 index 5e9f5851e8b..00000000000 --- a/src/vs/workbench/parts/files/browser/media/add-focus.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/add-inverse.svg b/src/vs/workbench/parts/files/browser/media/add-inverse.svg deleted file mode 100644 index 3475c1e1963..00000000000 --- a/src/vs/workbench/parts/files/browser/media/add-inverse.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/add.svg b/src/vs/workbench/parts/files/browser/media/add.svg deleted file mode 100644 index bdecdb0e45b..00000000000 --- a/src/vs/workbench/parts/files/browser/media/add.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/explorerviewlet.css b/src/vs/workbench/parts/files/browser/media/explorerviewlet.css index 8aae35cae5f..89e0a383c27 100644 --- a/src/vs/workbench/parts/files/browser/media/explorerviewlet.css +++ b/src/vs/workbench/parts/files/browser/media/explorerviewlet.css @@ -69,10 +69,6 @@ padding: 0 20px 0 20px; } -.explorer-viewlet .action-close-all-files { - background: url("closeall.svg") center center no-repeat; -} - .explorer-viewlet .explorer-item .monaco-inputbox { width: 100%; line-height: normal; @@ -97,6 +93,12 @@ cursor: default; } +/* Bold font style does not go well with CJK fonts */ +.explorer-viewlet:lang(zh-Hans) .explorer-open-editors .monaco-tree .monaco-tree-row .editor-group, +.explorer-viewlet:lang(zh-Hant) .explorer-open-editors .monaco-tree .monaco-tree-row .editor-group, +.explorer-viewlet:lang(ja) .explorer-open-editors .monaco-tree .monaco-tree-row .editor-group, +.explorer-viewlet:lang(ko) .explorer-open-editors .monaco-tree .monaco-tree-row .editor-group { font-weight: normal; } + /* Disable tree twistie */ .explorer-viewlet .explorer-open-editors > .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content:after, .explorer-viewlet .explorer-open-editors > .monaco-tree .monaco-tree-rows > .monaco-tree-row > .content:before { @@ -113,15 +115,6 @@ font-style: italic; } -.monaco-workbench.mac .explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row .open-editor.preview { - font-weight: 300; /* makes the italic font appear the same as normal */ -} - -/* Theming */ -.vs-dark .monaco-workbench .explorer-viewlet .action-close-all-files { - background: url("closeall_inverse.svg") center center no-repeat; -} - /* High Contrast Theming */ .hc-black .monaco-workbench .explorer-viewlet .explorer-item, .hc-black .monaco-workbench .explorer-viewlet .open-editor, diff --git a/src/vs/workbench/parts/files/browser/media/fileactions.css b/src/vs/workbench/parts/files/browser/media/fileactions.css index 379e47de13c..f1acdf53156 100644 --- a/src/vs/workbench/parts/files/browser/media/fileactions.css +++ b/src/vs/workbench/parts/files/browser/media/fileactions.css @@ -3,6 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +.monaco-workbench .explorer-viewlet .action-close-all-files { + background: url("closeall.svg") center center no-repeat; +} + +.vs-dark .monaco-workbench .explorer-viewlet .action-close-all-files, +.hc-black .monaco-workbench .explorer-viewlet .action-close-all-files { + background: url("closeall_inverse.svg") center center no-repeat; +} + .monaco-workbench .explorer-action.new-file { background: url('AddFile.svg') center center no-repeat; } @@ -11,11 +20,13 @@ background: url('saveall.svg') center center no-repeat; } -.vs-dark .monaco-workbench .explorer-action.save-all { +.vs-dark .monaco-workbench .explorer-action.save-all, +.hc-blck .monaco-workbench .explorer-action.save-all { background: url('saveall_inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .explorer-action.new-file { +.vs-dark .monaco-workbench .explorer-action.new-file, +.hc-black .monaco-workbench .explorer-action.new-file { background: url('AddFile_inverse.svg') center center no-repeat; } @@ -23,7 +34,8 @@ background: url('AddFolder.svg') center center no-repeat; } -.vs-dark .monaco-workbench .explorer-action.new-folder { +.vs-dark .monaco-workbench .explorer-action.new-folder, +.hc-black .monaco-workbench .explorer-action.new-folder { background: url('AddFolder_inverse.svg') center center no-repeat; } @@ -31,7 +43,8 @@ background: url('Refresh.svg') center center no-repeat; } -.vs-dark .monaco-workbench .explorer-action.refresh-explorer { +.vs-dark .monaco-workbench .explorer-action.refresh-explorer, +.hc-black .monaco-workbench .explorer-action.refresh-explorer { background: url('Refresh_inverse.svg') center center no-repeat; } @@ -39,7 +52,8 @@ background: url('CollapseAll.svg') center center no-repeat; } -.vs-dark .monaco-workbench .explorer-action.collapse-explorer { +.vs-dark .monaco-workbench .explorer-action.collapse-explorer, +.hc-black .monaco-workbench .explorer-action.collapse-explorer { background: url('CollapseAll_inverse.svg') center center no-repeat; } @@ -47,7 +61,8 @@ background-image: url('SplitEditor.svg'); } -.vs-dark .monaco-workbench .quick-open-sidebyside { +.vs-dark .monaco-workbench .quick-open-sidebyside, +.hc-black .monaco-workbench .quick-open-sidebyside { background-image: url('SplitEditor_inverse.svg'); } @@ -71,7 +86,8 @@ background: url('Preview.svg') center center no-repeat; } -.vs-dark .monaco-workbench .file-editor-action.action-open-preview { +.vs-dark .monaco-workbench .file-editor-action.action-open-preview , +.hc-black .monaco-workbench .file-editor-action.action-open-preview { background: url('Preview_inverse.svg') center center no-repeat; } @@ -91,7 +107,8 @@ background: url("action-close-dirty.svg") center center no-repeat; } -.vs-dark .explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row:not(:hover) > .content.dirty > .monaco-action-bar .close-editor-action { +.vs-dark .explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row:not(:hover) > .content.dirty > .monaco-action-bar .close-editor-action, +.hc-black .monaco-workbench .explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row:not(:hover) > .content.dirty > .monaco-action-bar .close-editor-action { background: url("action-close-dirty-dark.svg") center center no-repeat; } @@ -99,53 +116,7 @@ background: url("action-close-dirty-focus.svg") center center no-repeat; } -.vs-dark .monaco-workbench .explorer-viewlet .explorer-open-editors .close-editor-action { - background: url("action-close-dark.svg") center center no-repeat; -} - -/* High Contrast Theming */ -.hc-black .monaco-workbench .explorer-action, -.hc-black .monaco-workbench .quick-open-sidebyside, -.hc-black .monaco-workbench .file-editor-action.action-open-preview { - background: none; -} - -.hc-black .monaco-workbench .explorer-viewlet .action-close-all-files { - background: url("closeall_inverse.svg") center center no-repeat; -} - -.hc-black .monaco-workbench .explorer-action.save-all { - background: url('saveall_inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .explorer-action.new-file { - background: url('AddFile_inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .explorer-action.new-folder { - background: url('AddFolder_inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .explorer-action.refresh-explorer { - background: url('Refresh_inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .explorer-action.collapse-explorer { - background: url('CollapseAll_inverse.svg') center center no-repeat; -} - -.hc-black .monaco-workbench .quick-open-sidebyside:before { - content: url('SplitEditor_inverse.svg'); -} - -.hc-black .monaco-workbench .file-editor-action.action-open-preview:before { - content: url('Preview_inverse.svg'); -} - +.vs-dark .monaco-workbench .explorer-viewlet .explorer-open-editors .close-editor-action, .hc-black .monaco-workbench .explorer-viewlet .explorer-open-editors .close-editor-action { background: url("action-close-dark.svg") center center no-repeat; -} - -.hc-black .monaco-workbench .explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row:not(:hover) > .content.dirty > .monaco-action-bar .close-editor-action { - background: url("action-close-dirty-dark.svg") center center no-repeat; } \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/media/files.contribution.css b/src/vs/workbench/parts/files/browser/media/files.contribution.css index 51967e0116d..357eb226611 100644 --- a/src/vs/workbench/parts/files/browser/media/files.contribution.css +++ b/src/vs/workbench/parts/files/browser/media/files.contribution.css @@ -5,11 +5,5 @@ /* Activity Bar */ .monaco-workbench > .activitybar .monaco-action-bar .action-label.explore { - /* Inline icon to prevent slow loading on startup (original: files-dark.svg) */ - background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTTE3LjcwNSA4aC04LjcwNXMtMiAuMDc4LTIgMnYxNXMwIDIgMiAybDExLS4wMDRjMiAuMDA0IDItMS45OTYgMi0xLjk5NnYtMTEuNDkxbC00LjI5NS01LjUwOXptLTEuNzA1IDJ2NWg0djEwaC0xMXYtMTVoN3ptNS41MDktNmgtOC40OTNzLTIuMDE2LjAxNi0yLjAzMSAyaDguMDE1di40NTRsMy45MzEgNC41NDZoMS4wNjl2MTJjMiAwIDItMS45OTUgMi0xLjk5NXYtMTEuMzU3bC00LjQ5MS01LjY0OHoiIGZpbGw9IiNmZmYiLz48L3N2Zz4='); -} - -/* High Contrast Theming */ -.hc-black .monaco-workbench > .activitybar .monaco-action-bar .action-label.explore:before { - content: url('files-dark.svg'); + background-image: url('files-dark.svg'); } \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/views/explorerView.ts b/src/vs/workbench/parts/files/browser/views/explorerView.ts index 0b448885dd9..fc810543956 100644 --- a/src/vs/workbench/parts/files/browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/browser/views/explorerView.ts @@ -23,7 +23,6 @@ import {FileEditorInput} from 'vs/workbench/parts/files/common/editors/fileEdito import {FileDragAndDrop, FileFilter, FileSorter, FileController, FileRenderer, FileDataSource, FileViewletState, FileAccessibilityProvider} from 'vs/workbench/parts/files/browser/views/explorerViewer'; import lifecycle = require('vs/base/common/lifecycle'); import {UntitledEditorInput} from 'vs/workbench/common/editor/untitledEditorInput'; -import {IEditor} from 'vs/platform/editor/common/editor'; import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService'; import * as DOM from 'vs/base/browser/dom'; import {CollapseAction, CollapsibleViewletView} from 'vs/workbench/browser/viewlet'; @@ -267,7 +266,7 @@ export class ExplorerView extends CollapsibleViewletView { if (lastActiveFileResource && root && root.find(lastActiveFileResource)) { let editorInput = this.instantiationService.createInstance(FileEditorInput, lastActiveFileResource, void 0, void 0); - this.activateOrOpenEditor(editorInput).done(null, errors.onUnexpectedError); + this.editorService.openEditor(editorInput, { revealIfOpened: true }).done(null, errors.onUnexpectedError); return refreshPromise; } @@ -280,36 +279,15 @@ export class ExplorerView extends CollapsibleViewletView { }); } - private openFocusedElement(keepFocus?: boolean): void { + private openFocusedElement(preserveFocus?: boolean): void { let stat: FileStat = this.explorerViewer.getFocus(); if (stat && !stat.isDirectory) { let editorInput = this.instantiationService.createInstance(FileEditorInput, stat.resource, stat.mime, void 0); - this.activateOrOpenEditor(editorInput, keepFocus).done(null, errors.onUnexpectedError); + this.editorService.openEditor(editorInput, { preserveFocus, revealIfOpened: true }).done(null, errors.onUnexpectedError); } } - private activateOrOpenEditor(input: FileEditorInput, keepFocus?: boolean): TPromise { - - // First try to find if input already visible - let editors = this.editorService.getVisibleEditors(); - if (editors) { - for (let i = 0; i < editors.length; i++) { - let editor = editors[i]; - if (input.matches(editor.input)) { - if (!keepFocus) { - this.editorGroupService.focusGroup(editor.position); - } - - return TPromise.as(editor); - } - } - } - - // Otherwise open in active slot - return this.editorService.openEditor(input, keepFocus ? { preserveFocus: true } : void 0); - } - private getActiveEditorInputResource(): URI { // Try with Editor Input @@ -343,9 +321,9 @@ export class ExplorerView extends CollapsibleViewletView { dnd: dnd, accessibilityProvider: accessibility }, { - autoExpandSingleChildren: true, - ariaLabel: nls.localize('treeAriaLabel', "Files Explorer") - }); + autoExpandSingleChildren: true, + ariaLabel: nls.localize('treeAriaLabel', "Files Explorer") + }); this.toDispose.push(lifecycle.toDisposable(() => renderer.dispose())); diff --git a/src/vs/workbench/parts/files/browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/browser/views/openEditorsView.ts index b9522233277..00bef355655 100644 --- a/src/vs/workbench/parts/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/browser/views/openEditorsView.ts @@ -190,7 +190,11 @@ export class OpenEditorsView extends AdaptiveCollapsibleViewletView { if (openEditor) { this.tree.setFocus(openEditor); this.tree.setSelection([openEditor]); - this.tree.reveal(openEditor).done(null, errors.onUnexpectedError); + const relativeTop = this.tree.getRelativeTop(openEditor); + if (relativeTop <= 0 || relativeTop >= 1) { + // Only reveal the element if it is not visible #8279 + this.tree.reveal(openEditor).done(null, errors.onUnexpectedError); + } } } } diff --git a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts index c4da10c80a3..d283f19f5c0 100644 --- a/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/parts/files/common/editors/fileEditorInput.ts @@ -301,8 +301,7 @@ export class FileEditorInput extends CommonFileEditorInput { if ((error).fileOperationResult === FileOperationResult.FILE_IS_BINARY || (error).fileOperationResult === FileOperationResult.FILE_TOO_LARGE) { textModel.dispose(); - let binaryModel = new BinaryEditorModel(this.resource, this.getName()); - return binaryModel.load(); + return this.instantiationService.createInstance(BinaryEditorModel, this.resource, this.getName()).load(); } // Bubble any other error up diff --git a/src/vs/workbench/parts/files/test/browser/fileEditorInput.test.ts b/src/vs/workbench/parts/files/test/browser/fileEditorInput.test.ts index 3800fc3ac0c..a44f170f58d 100644 --- a/src/vs/workbench/parts/files/test/browser/fileEditorInput.test.ts +++ b/src/vs/workbench/parts/files/test/browser/fileEditorInput.test.ts @@ -6,6 +6,7 @@ import 'vs/workbench/parts/files/browser/files.contribution'; // load our contribution into the test import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import URI from 'vs/base/common/uri'; import {join} from 'vs/base/common/paths'; import {FileEditorInput} from 'vs/workbench/parts/files/common/editors/fileEditorInput'; @@ -19,14 +20,11 @@ import {IConfigurationService} from 'vs/platform/configuration/common/configurat import {ILifecycleService, NullLifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; import {IFileService} from 'vs/platform/files/common/files'; import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpenService'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IPartService} from 'vs/workbench/services/part/common/partService'; import {ITextFileService} from 'vs/workbench/parts/files/common/files'; import {FileTracker} from 'vs/workbench/parts/files/browser/fileTracker'; -import {TestTextFileService, TestEditorGroupService, TestHistoryService, TestFileService, TestEditorService, TestPartService, TestConfigurationService, TestEventService, TestContextService, TestQuickOpenService, TestStorageService} from 'vs/workbench/test/common/servicesTestUtils'; -import {createMockModelService, createMockModeService} from 'vs/editor/test/common/servicesTestUtils'; +import {createMockModelService, TestTextFileService, TestEditorGroupService, TestFileService, TestEditorService, TestPartService, TestConfigurationService, TestEventService, TestContextService, TestQuickOpenService, TestStorageService} from 'vs/test/utils/servicesTestUtils'; import {IHistoryService} from 'vs/workbench/services/history/common/history'; import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService'; @@ -36,28 +34,32 @@ function toResource(path) { suite('Files - FileEditorInput', () => { + let instantiationService: TestInstantiationService; + + setup(() => { + instantiationService= new TestInstantiationService(); + instantiationService.stub(IHistoryService, 'getHistory', []); + }); + test('FileEditorInput', function (done) { let editorService = new TestEditorService(function () { }); let eventService = new TestEventService(); let telemetryService = NullTelemetryService; let contextService = new TestContextService(); - let services = new ServiceCollection(); - let instantiationService = new InstantiationService(services); - - services.set(IEventService, eventService); - services.set(IWorkspaceContextService, contextService); - services.set(IFileService, TestFileService); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkbenchEditorService, editorService); - services.set(IPartService, new TestPartService()); - services.set(IModeService, createMockModeService()); - services.set(IModelService, createMockModelService()); - services.set(ITelemetryService, telemetryService); - services.set(IEditorGroupService, new TestEditorGroupService()); - services.set(ILifecycleService, NullLifecycleService); - services.set(IConfigurationService, new TestConfigurationService()); - services.set(ITextFileService, instantiationService.createInstance( TestTextFileService)); + instantiationService.stub(IEventService, eventService); + instantiationService.stub(IWorkspaceContextService, contextService); + instantiationService.stub(IFileService, TestFileService); + instantiationService.stub(IStorageService, new TestStorageService()); + instantiationService.stub(IWorkbenchEditorService, editorService); + instantiationService.stub(IPartService, new TestPartService()); + instantiationService.stub(IModeService); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + instantiationService.stub(ITelemetryService, telemetryService); + instantiationService.stub(IEditorGroupService, new TestEditorGroupService()); + instantiationService.stub(ILifecycleService, NullLifecycleService); + instantiationService.stub(IConfigurationService, new TestConfigurationService()); + instantiationService.stub(ITextFileService, instantiationService.createInstance( TestTextFileService)); let input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), 'text/javascript', void 0); let otherInput = instantiationService.createInstance(FileEditorInput, toResource('foo/bar/otherfile.js'), 'text/javascript', void 0); @@ -76,7 +78,7 @@ suite('Files - FileEditorInput', () => { input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar.html'), 'text/html', void 0); - let inputToResolve = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), 'text/javascript', void 0); + let inputToResolve:any = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), 'text/javascript', void 0); let sameOtherInput = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), 'text/javascript', void 0); return editorService.resolveEditorModel(inputToResolve, true).then(function (resolved) { @@ -122,12 +124,9 @@ suite('Files - FileEditorInput', () => { let eventService = new TestEventService(); let contextService = new TestContextService(); - let services = new ServiceCollection(); - let instantiationService = new InstantiationService(services); - - services.set(IEventService, eventService); - services.set(IWorkspaceContextService, contextService); - services.set(ITextFileService, instantiationService.createInstance( TestTextFileService)); + instantiationService.stub(IEventService, eventService); + instantiationService.stub(IWorkspaceContextService, contextService); + instantiationService.stub(ITextFileService, instantiationService.createInstance( TestTextFileService)); let fileEditorInput = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), 'text/javascript', void 0); let contentEditorInput2 = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), 'text/javascript', void 0); @@ -144,24 +143,20 @@ suite('Files - FileEditorInput', () => { let eventService = new TestEventService(); - let services = new ServiceCollection(); - let instantiationService = new InstantiationService(services); - - services.set(IEventService, eventService); - services.set(IWorkspaceContextService, contextService); - services.set(IFileService, TestFileService); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkbenchEditorService, editorService); - services.set(IHistoryService, new TestHistoryService()); - services.set(IQuickOpenService, new TestQuickOpenService()); - services.set(IPartService, new TestPartService()); - services.set(IModeService, createMockModeService()); - services.set(IEditorGroupService, new TestEditorGroupService()); - services.set(IModelService, createMockModelService()); - services.set(ITelemetryService, telemetryService); - services.set(ILifecycleService, NullLifecycleService); - services.set(IConfigurationService, new TestConfigurationService()); - services.set(ITextFileService, instantiationService.createInstance( TestTextFileService)); + instantiationService.stub(IEventService, eventService); + instantiationService.stub(IWorkspaceContextService, contextService); + instantiationService.stub(IFileService, TestFileService); + instantiationService.stub(IStorageService, new TestStorageService()); + instantiationService.stub(IWorkbenchEditorService, editorService); + instantiationService.stub(IQuickOpenService, new TestQuickOpenService()); + instantiationService.stub(IPartService, new TestPartService()); + instantiationService.stub(IModeService); + instantiationService.stub(IEditorGroupService, new TestEditorGroupService()); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + instantiationService.stub(ITelemetryService, telemetryService); + instantiationService.stub(ILifecycleService, NullLifecycleService); + instantiationService.stub(IConfigurationService, new TestConfigurationService()); + instantiationService.stub(ITextFileService, instantiationService.createInstance( TestTextFileService)); let tracker = instantiationService.createInstance(FileTracker); @@ -190,24 +185,20 @@ suite('Files - FileEditorInput', () => { let eventService = new TestEventService(); - let services = new ServiceCollection(); - let instantiationService = new InstantiationService(services); - - services.set(IEventService, eventService); - services.set(IWorkspaceContextService, contextService); - services.set(IFileService, TestFileService); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkbenchEditorService, editorService); - services.set(IPartService, new TestPartService()); - services.set(IModeService, createMockModeService()); - services.set(IEditorGroupService, new TestEditorGroupService()); - services.set(IQuickOpenService, new TestQuickOpenService()); - services.set(IModelService, createMockModelService()); - services.set(ITelemetryService, telemetryService); - services.set(ILifecycleService, NullLifecycleService); - services.set(IConfigurationService, new TestConfigurationService()); - services.set(IHistoryService, new TestHistoryService()); - services.set(ITextFileService, instantiationService.createInstance( TestTextFileService)); + instantiationService.stub(IEventService, eventService); + instantiationService.stub(IWorkspaceContextService, contextService); + instantiationService.stub(IFileService, TestFileService); + instantiationService.stub(IStorageService, new TestStorageService()); + instantiationService.stub(IWorkbenchEditorService, editorService); + instantiationService.stub(IPartService, new TestPartService()); + instantiationService.stub(IModeService); + instantiationService.stub(IEditorGroupService, new TestEditorGroupService()); + instantiationService.stub(IQuickOpenService, new TestQuickOpenService()); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + instantiationService.stub(ITelemetryService, telemetryService); + instantiationService.stub(ILifecycleService, NullLifecycleService); + instantiationService.stub(IConfigurationService, new TestConfigurationService()); + instantiationService.stub(ITextFileService, instantiationService.createInstance( TestTextFileService)); let tracker = instantiationService.createInstance(FileTracker); diff --git a/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts b/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts index 8dab922bd91..6d7b44579d6 100644 --- a/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts +++ b/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts @@ -6,13 +6,13 @@ 'use strict'; import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {TPromise} from 'vs/base/common/winjs.base'; import URI from 'vs/base/common/uri'; import paths = require('vs/base/common/paths'); import {FileEditorInput} from 'vs/workbench/parts/files/common/editors/fileEditorInput'; import {TextFileEditorModel, CACHE} from 'vs/workbench/parts/files/common/editors/textFileEditorModel'; -import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; -import {ITelemetryService, NullTelemetryService} from 'vs/platform/telemetry/common/telemetry'; +import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IEventService} from 'vs/platform/event/common/event'; import {IMessageService} from 'vs/platform/message/common/message'; import {IModelService} from 'vs/editor/common/services/modelService'; @@ -22,58 +22,50 @@ import {IStorageService} from 'vs/platform/storage/common/storage'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {ILifecycleService, NullLifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; import {IFileService} from 'vs/platform/files/common/files'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; import {IUntitledEditorService} from 'vs/workbench/services/untitled/common/untitledEditorService'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import PartService = require('vs/workbench/services/part/common/partService'); import {ITextFileService, EventType} from 'vs/workbench/parts/files/common/files'; -import {TestTextFileService, TestFileService, TestPartService, TestEditorService, TestConfigurationService, TestUntitledEditorService, TestStorageService, TestContextService, TestMessageService, TestEventService} from 'vs/workbench/test/common/servicesTestUtils'; -import {createMockModelService, createMockModeService} from 'vs/editor/test/common/servicesTestUtils'; +import {createMockModelService, TestTextFileService, TestFileService, TestPartService, TestEditorService, TestConfigurationService, TestUntitledEditorService, TestStorageService, TestContextService, TestMessageService, TestEventService} from 'vs/test/utils/servicesTestUtils'; function toResource(path) { return URI.file(paths.join('C:\\', path)); } -let baseInstantiationService: IInstantiationService; -let messageService: TestMessageService; -let eventService: TestEventService; +let eventService: IEventService; let textFileService: TestTextFileService; suite('Files - TextFileEditorModel', () => { + let instantiationService: TestInstantiationService; + setup(() => { + instantiationService= new TestInstantiationService(); eventService = new TestEventService(); - messageService = new TestMessageService(); + eventService= instantiationService.stub(IEventService, new TestEventService()); + instantiationService.stub(IMessageService, new TestMessageService()); + instantiationService.stub(IFileService, TestFileService); + instantiationService.stub(IWorkspaceContextService, new TestContextService()); + instantiationService.stub(ITelemetryService); + instantiationService.stub(IStorageService, new TestStorageService()); + instantiationService.stub(IUntitledEditorService, new TestUntitledEditorService()); + instantiationService.stub(IWorkbenchEditorService, new TestEditorService()); + instantiationService.stub(PartService.IPartService, new TestPartService()); + instantiationService.stub(IModeService); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + instantiationService.stub(ILifecycleService, NullLifecycleService); + instantiationService.stub(IConfigurationService, new TestConfigurationService()); - let services = new ServiceCollection(); - - services.set(IEventService, eventService); - services.set(IMessageService, messageService); - services.set(IFileService, TestFileService); - services.set(IWorkspaceContextService, new TestContextService()); - services.set(ITelemetryService, NullTelemetryService); - services.set(IStorageService, new TestStorageService()); - services.set(IUntitledEditorService, new TestUntitledEditorService()); - services.set(IWorkbenchEditorService, new TestEditorService()); - services.set(PartService.IPartService, new TestPartService()); - services.set(IModeService, createMockModeService()); - services.set(IModelService, createMockModelService()); - services.set(ILifecycleService, NullLifecycleService); - services.set(IConfigurationService, new TestConfigurationService()); - - baseInstantiationService = new InstantiationService(services); - textFileService = baseInstantiationService.createInstance(TestTextFileService); - services.set(ITextFileService, textFileService); + textFileService = instantiationService.createInstance(TestTextFileService); + instantiationService.stub(ITextFileService, textFileService); }); teardown(() => { - eventService.dispose(); CACHE.clear(); }); test('Load does not trigger save', function (done) { - let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index.txt'), 'utf8'); + let m1 = instantiationService.createInstance(TextFileEditorModel, toResource('/path/index.txt'), 'utf8'); eventService.addListener2('files:internalFileChanged', () => { assert.ok(false); @@ -97,7 +89,7 @@ suite('Files - TextFileEditorModel', () => { }); test('Load returns dirty model as long as model is dirty', function (done) { - let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); + let m1 = instantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); m1.load().then(() => { m1.textEditorModel.setValue('foo'); @@ -120,7 +112,7 @@ suite('Files - TextFileEditorModel', () => { eventCounter++; }); - let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); + let m1 = instantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); m1.load().then(() => { m1.textEditorModel.setValue('foo'); @@ -140,7 +132,7 @@ suite('Files - TextFileEditorModel', () => { }); test('Conflict Resolution Mode', function (done) { - let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); + let m1 = instantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); m1.load().then(() => { m1.setConflictResolutionMode(); @@ -166,7 +158,7 @@ suite('Files - TextFileEditorModel', () => { test('Auto Save triggered when model changes', function (done) { let eventCounter = 0; - let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index.txt'), 'utf8'); + let m1 = instantiationService.createInstance(TextFileEditorModel, toResource('/path/index.txt'), 'utf8'); (m1).autoSaveAfterMillies = 10; (m1).autoSaveAfterMilliesEnabled = true; @@ -195,7 +187,7 @@ suite('Files - TextFileEditorModel', () => { test('Dirty tracking', function (done) { let resource = toResource('/path/index_async.txt'); - let i1 = baseInstantiationService.createInstance(FileEditorInput, resource, 'text/plain', 'utf8'); + let i1 = instantiationService.createInstance(FileEditorInput, resource, 'text/plain', 'utf8'); i1.resolve().then((m1: TextFileEditorModel) => { let dirty = m1.getLastDirtyTime(); @@ -216,8 +208,8 @@ suite('Files - TextFileEditorModel', () => { }); test('save() and isDirty() - proper with check for mtimes', function (done) { - let c1 = baseInstantiationService.createInstance(FileEditorInput, toResource('/path/index_async2.txt'), 'text/plain', 'utf8'); - let c2 = baseInstantiationService.createInstance(FileEditorInput, toResource('/path/index_async.txt'), 'text/plain', 'utf8'); + let c1 = instantiationService.createInstance(FileEditorInput, toResource('/path/index_async2.txt'), 'text/plain', 'utf8'); + let c2 = instantiationService.createInstance(FileEditorInput, toResource('/path/index_async.txt'), 'text/plain', 'utf8'); c1.resolve().then((m1: TextFileEditorModel) => { c2.resolve().then((m2: TextFileEditorModel) => { @@ -254,7 +246,7 @@ suite('Files - TextFileEditorModel', () => { test('Save Participant', function (done) { let eventCounter = 0; - let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); + let m1 = instantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); eventService.addListener2(EventType.FILE_SAVED, (e) => { assert.equal(m1.getValue(), 'bar'); diff --git a/src/vs/workbench/parts/files/test/browser/textFileEditor.test.ts b/src/vs/workbench/parts/files/test/browser/textFileEditor.test.ts index bc01bf4376a..b83a182b0d1 100644 --- a/src/vs/workbench/parts/files/test/browser/textFileEditor.test.ts +++ b/src/vs/workbench/parts/files/test/browser/textFileEditor.test.ts @@ -8,16 +8,15 @@ import {strictEqual, equal} from 'assert'; import {join} from 'vs/base/common/paths'; import URI from 'vs/base/common/uri'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {FileEditorDescriptor} from 'vs/workbench/parts/files/browser/files'; import {Registry} from 'vs/platform/platform'; import {SyncDescriptor} from 'vs/platform/instantiation/common/descriptors'; import {FileEditorInput} from 'vs/workbench/parts/files/common/editors/fileEditorInput'; import {Extensions} from 'vs/workbench/common/editor'; -import {TestTextFileService, TestEventService, TestContextService} from 'vs/workbench/test/common/servicesTestUtils'; +import {TestTextFileService, TestEventService, TestContextService} from 'vs/test/utils/servicesTestUtils'; import {IEventService} from 'vs/platform/event/common/event'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; import {ITextFileService} from 'vs/workbench/parts/files/common/files'; const ExtensionId = Extensions.Editors; @@ -46,12 +45,11 @@ suite('Files - TextFileEditor', () => { let eventService = new TestEventService(); let contextService = new TestContextService(); - let services = new ServiceCollection(); - let instantiationService = new InstantiationService(services); + let instantiationService = new TestInstantiationService(); - services.set(IEventService, eventService); - services.set(IWorkspaceContextService, contextService); - services.set(ITextFileService, instantiationService.createInstance( TestTextFileService)); + instantiationService.stub(IEventService, eventService); + instantiationService.stub(IWorkspaceContextService, contextService); + instantiationService.stub(ITextFileService, instantiationService.createInstance( TestTextFileService)); strictEqual(Registry.as(ExtensionId).getEditor(instantiationService.createInstance(FileEditorInput, URI.file(join('C:\\', '/foo/bar/foobar.html')), 'test-text/html', void 0)), d1); strictEqual(Registry.as(ExtensionId).getEditor(instantiationService.createInstance(FileEditorInput, URI.file(join('C:\\', '/foo/bar/foobar.js')), 'test-text/javascript', void 0)), d1); diff --git a/src/vs/workbench/parts/git/browser/gitActions.ts b/src/vs/workbench/parts/git/browser/gitActions.ts index 1b276a31923..8917069d086 100644 --- a/src/vs/workbench/parts/git/browser/gitActions.ts +++ b/src/vs/workbench/parts/git/browser/gitActions.ts @@ -9,7 +9,6 @@ import nls = require('vs/nls'); import { IEventEmitter } from 'vs/base/common/eventEmitter'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import strings = require('vs/base/common/strings'); import { isString } from 'vs/base/common/types'; import { Action } from 'vs/base/common/actions'; import { IDiffEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -25,9 +24,8 @@ import { IEventService } from 'vs/platform/event/common/event'; import { IFileService, IFileStat } from 'vs/platform/files/common/files'; import { IMessageService, IConfirmation } from 'vs/platform/message/common/message'; import Severity from 'vs/base/common/severity'; -import { IGitService, IFileStatus, Status, StatusType, ServiceState, - IModel, IBranch, GitErrorCodes, ServiceOperations } - from 'vs/workbench/parts/git/common/git'; +import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; +import { IGitService, IFileStatus, Status, StatusType, ServiceState, IModel, IBranch, GitErrorCodes, IGitConfiguration } from 'vs/workbench/parts/git/common/git'; import { IQuickOpenService } from 'vs/workbench/services/quickopen/common/quickOpenService'; import paths = require('vs/base/common/paths'); import URI from 'vs/base/common/uri'; @@ -1059,10 +1057,16 @@ export class PublishAction extends GitAction { } } -export abstract class BaseSyncAction extends GitAction { +export class SyncAction extends GitAction { - constructor(id: string, label: string, className: string, gitService: IGitService) { - super(id, label, className, gitService); + static ID = 'workbench.action.git.sync'; + static LABEL = 'Sync'; + + constructor(id: string, label: string, + @IGitService gitService: IGitService, + @IConfigurationService private configurationService: IConfigurationService + ) { + super(id, label, 'git-action sync', gitService); } protected isEnabled():boolean { @@ -1089,6 +1093,12 @@ export abstract class BaseSyncAction extends GitAction { return TPromise.as(null); } + const config = this.configurationService.getConfiguration('git'); + + if (config.confirmSync && !window.confirm(nls.localize('sureSync', "Are you sure you want to synchronize your git repository?"))) { + return TPromise.as(null); + } + return this.gitService.sync().then(null, (err) => { if (err.gitErrorCode === GitErrorCodes.AuthenticationFailed) { return Promise.wrapError(errors.create(nls.localize('authFailed', "Authentication failed on the git remote."))); @@ -1099,79 +1109,6 @@ export abstract class BaseSyncAction extends GitAction { } } -export class SyncAction extends BaseSyncAction { - - static ID = 'workbench.action.git.sync'; - static LABEL = 'Sync'; - - constructor(id: string, label: string, @IGitService gitService: IGitService) { - super(id, label, 'git-action sync', gitService); - } -} - -export class LiveSyncAction extends BaseSyncAction { - - static ID = 'workbench.action.git.liveSync'; - static CLASS_NAME = 'git-action live-sync'; - static CLASS_NAME_LOADING = 'git-action live-sync loading'; - - constructor(@IGitService gitService: IGitService) { - super(LiveSyncAction.ID, 'sync', LiveSyncAction.CLASS_NAME, gitService); - } - - protected onGitServiceChange(): void { - super.onGitServiceChange(); - - if (this.gitService.getRunningOperations().some(op => - op.id === ServiceOperations.SYNC || - op.id === ServiceOperations.PULL || - op.id === ServiceOperations.PUSH)) - { - this.label = ''; - this.class = LiveSyncAction.CLASS_NAME_LOADING; - this.tooltip = nls.localize('synchronizing', "Synchronizing..."); - - } else { - this.class = LiveSyncAction.CLASS_NAME; - - var model = this.gitService.getModel(); - var HEAD = model.getHEAD(); - - if (!HEAD) { - this.label = ''; - this.tooltip = ''; - - } else if (!HEAD.name) { - this.label = ''; - this.tooltip = nls.localize('currentlyDetached', "Can't sync in detached mode."); - - } else if (!HEAD.upstream) { - this.label = ''; - this.tooltip = nls.localize('noUpstream', "Current branch '{0} doesn't have an upstream branch configured.", HEAD.name); - - } else if (!HEAD.ahead && !HEAD.behind) { - this.label = ''; - this.tooltip = nls.localize('currentBranch', "Current branch '{0}' is up to date.", HEAD.name); - - } else { - this.label = strings.format('{0}↓ {1}↑', HEAD.behind, HEAD.ahead); - - if (model.getStatus().getGroups().some(g => g.all().length > 0)) { - this.tooltip = nls.localize('dirtyChanges', "Please commit, undo or stash your changes before synchronizing."); - } else if (HEAD.behind === 1 && HEAD.ahead === 1) { - this.tooltip = nls.localize('currentBranchSingle', "Current branch '{0}' is {1} commit behind and {2} commit ahead of '{3}'.", HEAD.name, HEAD.behind, HEAD.ahead, HEAD.upstream); - } else if (HEAD.behind === 1) { - this.tooltip = nls.localize('currentBranchSinglePlural', "Current branch '{0}' is {1} commit behind and {2} commits ahead of '{3}'.", HEAD.name, HEAD.behind, HEAD.ahead, HEAD.upstream); - } else if (HEAD.ahead === 1) { - this.tooltip = nls.localize('currentBranchPluralSingle', "Current branch '{0}' is {1} commits behind and {2} commit ahead of '{3}'.", HEAD.name, HEAD.behind, HEAD.ahead, HEAD.upstream); - } else { - this.tooltip = nls.localize('currentBranchPlural', "Current branch '{0}' is {1} commits behind and {2} commits ahead of '{3}'.", HEAD.name, HEAD.behind, HEAD.ahead, HEAD.upstream); - } - } - } - } -} - export class UndoLastCommitAction extends GitAction { static ID = 'workbench.action.git.undoLastCommit'; diff --git a/src/vs/workbench/parts/git/browser/gitServices.ts b/src/vs/workbench/parts/git/browser/gitServices.ts index 665a06f8613..dc1e1fe6428 100644 --- a/src/vs/workbench/parts/git/browser/gitServices.ts +++ b/src/vs/workbench/parts/git/browser/gitServices.ts @@ -36,6 +36,7 @@ import * as semver from 'semver'; import { shell } from 'electron'; import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage'; import Event from 'vs/base/common/event'; +import { domEvent } from 'vs/base/browser/event'; import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService'; function toReadablePath(path: string): string { @@ -402,6 +403,8 @@ export class GitService extends ee.EventEmitter private statusDelayer: async.ThrottledDelayer; private reactiveStatusDelayer: async.PeriodThrottledDelayer; private autoFetcher: AutoFetcher; + private isStatusPending = false; + private isFocused = true; private _allowHugeRepositories: boolean; get allowHugeRepositories(): boolean { return this._allowHugeRepositories; } @@ -453,7 +456,7 @@ export class GitService extends ee.EventEmitter this.inputCache = this.instantiationService.createInstance(EditorInputCache, this); - this.triggerStatus(); // trigger initial status + this.triggerAutoStatus(true); // trigger initial status if (!storageService.getBoolean(IgnoreOldGitStorageKey, StorageScope.GLOBAL, false)) { this.raw.serviceState().done(state => { @@ -500,10 +503,22 @@ export class GitService extends ee.EventEmitter this._allowHugeRepositories = config.allowLargeRepositories; if (this._allowHugeRepositories) { - this.triggerStatus(); + this.triggerAutoStatus(); } })); this.lifecycleService.onShutdown(this.dispose, this); + + const focusEvent = domEvent(window, 'focus'); + this.toDispose.push(focusEvent(() => { + this.isFocused = true; + + if (this.isStatusPending) { + this.triggerAutoStatus(); + } + })); + + const blurEvent = domEvent(window, 'blur'); + this.toDispose.push(blurEvent(() => this.isFocused = false)); } private onTextFileChange(e:filesCommon.TextFileChangeEvent): void { @@ -513,7 +528,7 @@ export class GitService extends ee.EventEmitter return; } - this.triggerStatus(); + this.triggerAutoStatus(); } private onFileChanges(e: FileChangesEvent): void { @@ -547,12 +562,12 @@ export class GitService extends ee.EventEmitter return; } - this.triggerStatus(); + this.triggerAutoStatus(); } private onGitServiceOperationEnd(e: { operation: git.IGitOperation; }): void { if (e.operation.id === git.ServiceOperations.COMMAND) { - this.triggerStatus(); + this.triggerAutoStatus(); } } @@ -589,7 +604,21 @@ export class GitService extends ee.EventEmitter }); } - private triggerStatus(): void { + private triggerAutoStatus(force = false): void { + this.isStatusPending = true; + + if (!this.isFocused && !force) { + return; + } + + this.isStatusPending = false; + + const config = this.configurationService.getConfiguration('git'); + + if (!config.autorefresh) { + return; + } + this.reactiveStatusDelayer.trigger(() => this.status()).done(null, e => { if (errors.isPromiseCanceledError(e)) { return; @@ -662,6 +691,10 @@ export class GitService extends ee.EventEmitter return this.run(git.ServiceOperations.COMMIT, () => this.raw.commit(message, amend, stage)); } + public getCommitTemplate(): winjs.Promise { + return this.raw.getCommitTemplate(); + } + public detectMimetypes(path: string, treeish: string = '~'): winjs.Promise { return this.raw.detectMimetypes(path, treeish); } diff --git a/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts b/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts index 0a4f9fc7506..5d7edccebe1 100644 --- a/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts +++ b/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts @@ -523,6 +523,11 @@ export function registerContributions(): void { description: nls.localize('gitPath', "Path to the git executable"), default: null }, + 'git.autorefresh': { + type: 'boolean', + description: nls.localize('gitAutoRefresh', "Whether auto refreshing is enabled"), + default: true + }, 'git.autofetch': { type: 'boolean', description: nls.localize('gitAutoFetch', "Whether auto fetching is enabled."), @@ -537,6 +542,11 @@ export function registerContributions(): void { type: 'boolean', description: nls.localize('gitLargeRepos', "Always allow large repositories to be managed by Code."), default: false + }, + 'git.confirmSync': { + type: 'boolean', + description: nls.localize('confirmSync', "Confirm before synchronizing git repositories."), + default: false } } }); diff --git a/src/vs/workbench/parts/git/browser/media/arrow_down.svg b/src/vs/workbench/parts/git/browser/media/arrow_down.svg deleted file mode 100644 index a854c81d94a..00000000000 --- a/src/vs/workbench/parts/git/browser/media/arrow_down.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/media/arrow_up.svg b/src/vs/workbench/parts/git/browser/media/arrow_up.svg deleted file mode 100644 index c6e43092e68..00000000000 --- a/src/vs/workbench/parts/git/browser/media/arrow_up.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/media/branch.svg b/src/vs/workbench/parts/git/browser/media/branch.svg deleted file mode 100644 index 5ed21da0c03..00000000000 --- a/src/vs/workbench/parts/git/browser/media/branch.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/media/git-small.svg b/src/vs/workbench/parts/git/browser/media/git-small.svg deleted file mode 100644 index eb1955a85d9..00000000000 --- a/src/vs/workbench/parts/git/browser/media/git-small.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/media/git.contribution.css b/src/vs/workbench/parts/git/browser/media/git.contribution.css index 6f8d3b64277..d2e76eb5d36 100644 --- a/src/vs/workbench/parts/git/browser/media/git.contribution.css +++ b/src/vs/workbench/parts/git/browser/media/git.contribution.css @@ -13,18 +13,21 @@ background: url('OpenEditor.svg') center center no-repeat; } -.vs-dark .monaco-workbench .git-action.open-in-diff { +.vs-dark .monaco-workbench .git-action.open-in-diff, +.hc-black .monaco-workbench .git-action.open-in-diff { background: url('Compare_inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .git-action.open-in-editor { +.vs-dark .monaco-workbench .git-action.open-in-editor, +.hc-black .monaco-workbench .git-action.open-in-editor { background: url('OpenEditor_inverse.svg') center center no-repeat; } /* Activity Bar */ -.monaco-workbench > .activitybar .monaco-action-bar .action-label.git { - /* Inline icon to prevent slow loading on startup (original: git-dark.svg) */ - background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTTI3LjQ1OSAxNC45MDJsLTEwLjQzOS0xMC40MzljLS4yOTYtLjI5NC0uNjcyLS40NTItMS4wODktLjQ1Mi0uNDE3IDAtLjc5My4xNTctMS4wODkuNDUybC0yLjI0OCAyLjI0NyAyLjU0OSAyLjU0OWMuMjQ5LS4xMTIuNTIyLS4xNzcuODEzLS4xNzcgMS4xMDYgMCAyLjAwMi44OTYgMi4wMDIgMi4wMDIgMCAuMjkxLS4wNjQuNTY1LS4xNzYuODE0bDIuMzExIDIuMzM2Yy4yNS0uMTExLjYzMy0uMjM0LjkyMy0uMjM0IDEuMTA2IDAgMiAuOTExIDIgMi4wMTZzLS44OTQgMS45NjktMiAxLjk2OWMtMS4xMDUtLjAwMS0yLjAxNi0uNzUxLTIuMDE2LTEuOTg1IDAtLjI4LjAxNi0uNDYyLjExOS0uNzA0bC0yLjM3My0yLjM3NC0uMDIzLjAwN3Y2LjI3NGMuNzQ3LjI5NSAxLjI3NyAxLjAyNiAxLjI3NyAxLjg3NSAwIDEuMTA1LS44NzggMi4wMTYtMS45ODQgMi4wMTYtMS4xMDQgMC0yLjAzMS0uOTI2LTIuMDMxLTIuMDMxIDAtLjg0Ni41MzUtMS41NjQgMS4yOC0xLjg1N2wuMDAxLTYuMjVjLS43NjItLjI4Mi0xLjMwOS0xLjAwOS0xLjMwOS0xLjg3MSAwLS4yOC4wNTktLjU0Ni4xNjItLjc4OGwtMi41NTUtMi41NTctNy4xMTUgNy4xMTRjLS41OTkuNjAxLS42MDEgMS41NzYuMDAxIDIuMTc4bDEwLjQ0IDEwLjUxOGMuMjk2LjI5NS42NzEuNDUgMS4wODkuNDUuNDE1IDAgLjc5Ni0uMTU5IDEuMDg5LS40NWwxMC4zOTEtMTAuNDcxYy42MDEtLjU5OS41OTktMS41NzYgMC0yLjE3N3oiIGZpbGw9IiNmZmYiLz48L3N2Zz4='); +.monaco-workbench > .activitybar .monaco-action-bar .action-label.git, +.monaco-shell .git-statusbar-group > .git-statusbar-branch-item, +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.git { + background-image: url('git-dark.svg'); } /* Git viewlet label */ @@ -104,10 +107,6 @@ background-image: url('git.svg'); } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.git { - background-image: url('git-dark.svg'); -} - /* Actions */ .monaco-shell .git-action.live-sync.icon { @@ -115,56 +114,16 @@ } .monaco-shell .git-action.live-sync.icon.loading { - animation: spin-forever 1.6s linear infinite; + animation: spin-forever 1.6s linear infinite; } -@keyframes spin-forever { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } +@keyframes spin-forever { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* High Contrast Theming */ -.hc-black .monaco-workbench > .activitybar .monaco-action-bar .action-label.git:before { - content: url('git-dark.svg'); -} - .hc-black .monaco-workbench > .activitybar .monaco-action-bar .badge.git-viewlet-label-progress .badge-content { - background: none; width: 1px; } -.hc-black .monaco-workbench > .activitybar .monaco-action-bar .badge.git-viewlet-label-progress .badge-content:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCIgdmlld0JveD0iMiAyIDE0IDE0IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDIgMiAxNCAxNCI+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTkgMTZjLTMuODYgMC03LTMuMTQtNy03czMuMTQtNyA3LTdjMy44NTkgMCA3IDMuMTQxIDcgN3MtMy4xNDEgNy03IDd6bTAtMTIuNmMtMy4wODggMC01LjYgMi41MTMtNS42IDUuNnMyLjUxMiA1LjYgNS42IDUuNiA1LjYtMi41MTIgNS42LTUuNi0yLjUxMi01LjYtNS42LTUuNnptMy44NiA3LjFsLTMuMTYtMS44OTZ2LTMuODA0aC0xLjR2NC41OTZsMy44NCAyLjMwNS43Mi0xLjIwMXoiLz48L3N2Zz4="); - position: relative; - top: 2px; - left: -4px; - display: block; - height: 16px; - width: 16px; -} - -.hc-black .monaco-workbench .git-action { - background: none; -} - -.hc-black .monaco-workbench .action-item.disabled .git-action:before { -} - -.hc-black .monaco-workbench .git-action.open-in-diff:before { - content: url('Compare_inverse.svg'); - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} - -.hc-black .monaco-workbench .git-action.open-in-editor:before { - content: url('OpenEditor_inverse.svg'); - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} - /* Status bar */ .monaco-shell .git-statusbar-group > a { @@ -204,7 +163,6 @@ } .monaco-shell .git-statusbar-group > .git-statusbar-branch-item { - background-image: url('../media/git-dark.svg'); background-repeat: no-repeat; background-position: 4px 50%; background-size: 17px; @@ -224,8 +182,4 @@ .monaco-shell .git-statusbar-group > .git-statusbar-branch-item.headless { font-style: italic; -} - -.monaco-shell .monaco-workbench.mac .git-statusbar-group > .git-statusbar-branch-item.headless { - font-weight: 300; /* makes the italic font appear the same as normal */ } \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/media/gitViewlet.css b/src/vs/workbench/parts/git/browser/media/gitViewlet.css index 847ffa17faf..10037adab11 100644 --- a/src/vs/workbench/parts/git/browser/media/gitViewlet.css +++ b/src/vs/workbench/parts/git/browser/media/gitViewlet.css @@ -6,7 +6,7 @@ /* Git viewlet */ .git-viewlet { - height: 100%; + height: 100%; } /* Actionbar actions */ @@ -55,15 +55,17 @@ /* Dark theme actions */ -.vs-dark .git-action.refresh { +.vs-dark .git-action.refresh, +.hc-black .git-action.refresh { background: url('refresh-inverse.svg') center center no-repeat; } -.vs-dark .git-action.commit { - background: url('check-inverse.svg') center center no-repeat; -} - -.vs-dark .git-action.stage-and-commit { +.vs-dark .git-action.commit, +.hc-black .git-action.commit, +.vs-dark .git-action.stage-and-commit, +.hc-black .git-action.stage-and-commit, +.vs-dark .git-action.smart-commit, +.hc-black .git-action.smart-commit { background: url('check-inverse.svg') center center no-repeat; } @@ -75,64 +77,17 @@ background: url('push-inverse.svg') center center no-repeat; } -.vs-dark .git-action.stage { +.vs-dark .git-action.stage, +.hc-black .git-action.stage { background: url('add-inverse.svg') center center no-repeat; } -.vs-dark .git-action.undo { +.vs-dark .git-action.undo, +.hc-black .git-action.undo { background: url('undo-inverse.svg') center center no-repeat; } -.vs-dark .git-action.unstage { +.vs-dark .git-action.unstage, +.hc-black .git-action.unstage { background: url('subtract-inverse.svg') center center no-repeat; -} - -/* High Contrast Theming */ -.hc-black .git-action { - background: none; -} - -.hc-black .title-actions .git-action:before { - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} - -.hc-black .git-action.refresh:before { - content: url('refresh-inverse.svg'); -} - -.hc-black .git-action.smart-commit:before { - content: url('check-inverse.svg'); -} - -.hc-black .git-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions .git-action { - background: none; -} - -.hc-black .git-viewlet .monaco-tree .monaco-tree-rows > .monaco-tree-row.has-children > .content:after, -.hc-black .git-viewlet .monaco-tree .monaco-tree-rows > .monaco-tree-row.expanded > .content:before { - content: ''; -} - -.hc-black .monaco-tree .git-action:before { - display: inline-block; - position: relative; - top: -2px; - height: 16px; - width: 16px; -} - -.hc-black .git-viewlet .git-action.stage:before { - content: url('add-inverse.svg'); -} - -.hc-black .git-viewlet .git-action.undo:before { - content: url('undo-inverse.svg'); -} - -.hc-black .git-viewlet .git-action.unstage:before { - content: url('subtract-inverse.svg'); } \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/media/loading.svg b/src/vs/workbench/parts/git/browser/media/loading.svg deleted file mode 100644 index c5ad0afcce1..00000000000 --- a/src/vs/workbench/parts/git/browser/media/loading.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/media/plus-check-inverse.svg b/src/vs/workbench/parts/git/browser/media/plus-check-inverse.svg deleted file mode 100644 index 891028ff5fb..00000000000 --- a/src/vs/workbench/parts/git/browser/media/plus-check-inverse.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/media/plus-check.svg b/src/vs/workbench/parts/git/browser/media/plus-check.svg deleted file mode 100644 index 02d423716ce..00000000000 --- a/src/vs/workbench/parts/git/browser/media/plus-check.svg +++ /dev/null @@ -1 +0,0 @@ -Layer 1 \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/views/changes/changesView.css b/src/vs/workbench/parts/git/browser/views/changes/changesView.css index 4e69272550d..4fe3736c87e 100644 --- a/src/vs/workbench/parts/git/browser/views/changes/changesView.css +++ b/src/vs/workbench/parts/git/browser/views/changes/changesView.css @@ -69,6 +69,12 @@ cursor: default; } +/* Bold font style does not go well with CJK fonts */ +.git-viewlet:lang(zh-Hans) > .changes-view > .status-view > .monaco-tree .monaco-tree-row .status-group, +.git-viewlet:lang(zh-Hant) > .changes-view > .status-view > .monaco-tree .monaco-tree-row .status-group, +.git-viewlet:lang(ja) > .changes-view > .status-view > .monaco-tree .monaco-tree-row .status-group, +.git-viewlet:lang(ko) > .changes-view > .status-view > .monaco-tree .monaco-tree-row .status-group { font-weight: normal; } + .git-viewlet > .changes-view > .status-view > .monaco-tree .monaco-tree-row .count-badge-wrapper { padding-right: 12px; } diff --git a/src/vs/workbench/parts/git/browser/views/changes/changesView.ts b/src/vs/workbench/parts/git/browser/views/changes/changesView.ts index a4f82b205a2..6ab14fbfc5a 100644 --- a/src/vs/workbench/parts/git/browser/views/changes/changesView.ts +++ b/src/vs/workbench/parts/git/browser/views/changes/changesView.ts @@ -236,14 +236,24 @@ export class ChangesView extends EventEmitter.EventEmitter implements GitView.IV if (visible) { this.tree.onVisible(); + this.updateCommitInputTemplate(); return this.onEditorsChanged(this.editorService.getActiveEditorInput()); - } else { this.tree.onHidden(); return WinJS.TPromise.as(null); } } + private updateCommitInputTemplate(): void { + if (this.commitInputBox.value) { + return; + } + + this.gitService.getCommitTemplate() + .then(template => template && (this.commitInputBox.value = template)) + .done(null, Errors.onUnexpectedError); + } + public getControl(): Tree.ITree { return this.tree; } @@ -395,12 +405,13 @@ export class ChangesView extends EventEmitter.EventEmitter implements GitView.IV } private onGitOperationEnd(e: { operation: git.IGitOperation; error: any; }): void { - if (e.operation.id === git.ServiceOperations.COMMIT) { + if (e.operation.id === git.ServiceOperations.COMMIT || e.operation.id === git.ServiceOperations.RESET) { if (this.commitInputBox) { this.commitInputBox.enable(); if (!e.error) { this.commitInputBox.value = ''; + this.updateCommitInputTemplate(); } } } diff --git a/src/vs/workbench/parts/git/common/git.ts b/src/vs/workbench/parts/git/common/git.ts index 8e50183d165..a15247e15f7 100644 --- a/src/vs/workbench/parts/git/common/git.ts +++ b/src/vs/workbench/parts/git/common/git.ts @@ -230,9 +230,11 @@ export var ServiceOperations = { export interface IGitConfiguration { enabled: boolean; path: string; + autorefresh: boolean; autofetch: boolean; enableLongCommitWarning: boolean; allowLargeRepositories: boolean; + confirmSync: boolean; } // Service interfaces @@ -284,6 +286,7 @@ export interface IRawGitService { commit(message:string, amend?: boolean, stage?: boolean): TPromise; detectMimetypes(path: string, treeish?: string): TPromise; show(path: string, treeish?: string): TPromise; + getCommitTemplate(): TPromise; } export var GIT_SERVICE_ID = 'gitService'; @@ -320,6 +323,7 @@ export interface IGitService extends IEventEmitter { isIdle(): boolean; getRunningOperations(): IGitOperation[]; getAutoFetcher(): IAutoFetcher; + getCommitTemplate(): TPromise; } export interface IAskpassService { diff --git a/src/vs/workbench/parts/git/common/gitIpc.ts b/src/vs/workbench/parts/git/common/gitIpc.ts index e4bf45ad1dd..b7e8caf9c56 100644 --- a/src/vs/workbench/parts/git/common/gitIpc.ts +++ b/src/vs/workbench/parts/git/common/gitIpc.ts @@ -87,6 +87,7 @@ export interface IGitChannel extends IChannel { call(command: 'detectMimetypes', args: [string, string]): TPromise; call(command: 'show', args: [string, string]): TPromise; call(command: 'onOutput'): TPromise; + call(command: 'getCommitTemplate'): TPromise; call(command: string, args: any): TPromise; } @@ -117,6 +118,7 @@ export class GitChannel implements IGitChannel { case 'detectMimetypes': return this.service.then(s => s.detectMimetypes(args[0], args[1])); case 'show': return this.service.then(s => s.show(args[0], args[1])); case 'onOutput': return this.service.then(s => eventToCall(s.onOutput)); + case 'getCommitTemplate': return this.service.then(s => s.getCommitTemplate()); } } } @@ -217,6 +219,10 @@ export class GitChannelClient implements IRawGitService { show(path: string, treeish?: string): TPromise { return this.channel.call('show', [path, treeish]); } + + getCommitTemplate(): TPromise { + return this.channel.call('getCommitTemplate'); + } } export interface IAskpassChannel extends IChannel { diff --git a/src/vs/workbench/parts/git/common/noopGitService.ts b/src/vs/workbench/parts/git/common/noopGitService.ts index ddfd63bbab6..572fe151c73 100644 --- a/src/vs/workbench/parts/git/common/noopGitService.ts +++ b/src/vs/workbench/parts/git/common/noopGitService.ts @@ -101,4 +101,8 @@ export class NoOpGitService implements IRawGitService { show(path: string, treeish?: string): TPromise { return TPromise.as(null); } + + getCommitTemplate(): TPromise { + return TPromise.as(null); + } } \ No newline at end of file diff --git a/src/vs/workbench/parts/git/electron-browser/electronGitService.ts b/src/vs/workbench/parts/git/electron-browser/electronGitService.ts index 2e2d28d17b2..18c83311cb9 100644 --- a/src/vs/workbench/parts/git/electron-browser/electronGitService.ts +++ b/src/vs/workbench/parts/git/electron-browser/electronGitService.ts @@ -157,7 +157,7 @@ function createRemoteRawGitService(gitPath: string, workspaceRoot: string, encod timeout: 1000 * 60, args: [path, workspaceRoot, encoding, remote.process.execPath, version], env: { - ELECTRON_RUN_AS_NODE: 1, + ATOM_SHELL_INTERNAL_RUN_AS_NODE: 1, PIPE_LOGGING: 'true', AMD_ENTRYPOINT: 'vs/workbench/parts/git/node/gitApp', VERBOSE_LOGGING: String(verbose) diff --git a/src/vs/workbench/parts/git/node/git.lib.ts b/src/vs/workbench/parts/git/node/git.lib.ts index 08d9df169ab..fd58c51162a 100644 --- a/src/vs/workbench/parts/git/node/git.lib.ts +++ b/src/vs/workbench/parts/git/node/git.lib.ts @@ -3,8 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as os from 'os'; +import * as path from 'path'; import { Promise, TPromise } from 'vs/base/common/winjs.base'; import { del } from 'vs/base/node/extfs'; +import * as pfs from 'vs/base/node/pfs'; import { guessMimeTypes, isBinaryMime } from 'vs/base/common/mime'; import { IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle'; import { assign } from 'vs/base/common/objects'; @@ -697,6 +700,21 @@ export class Repository { }); } + getCommitTemplate(): TPromise { + return this.run(['config', '--get', 'commit.template']).then(result => { + if (!result.stdout) { + return ''; + } + + // https://github.com/git/git/blob/3a0f269e7c82aa3a87323cb7ae04ac5f129f036b/path.c#L612 + const homedir = os.homedir(); + const templatePath = result.stdout.trim() + .replace(/^~([^\/]*)\//, (_, user) => `${ user ? path.join(path.dirname(homedir), user) : homedir }/`); + + return pfs.readFile(templatePath, 'utf8').then(null, () => ''); + }, () => ''); + } + onOutput(listener: (output: string) => void): () => void { return this.git.onOutput(listener); } diff --git a/src/vs/workbench/parts/git/node/rawGitService.ts b/src/vs/workbench/parts/git/node/rawGitService.ts index 3f3541ec61f..92514243b8b 100644 --- a/src/vs/workbench/parts/git/node/rawGitService.ts +++ b/src/vs/workbench/parts/git/node/rawGitService.ts @@ -195,6 +195,10 @@ export class RawGitService implements IRawGitService { return TPromise.wrapError(e); }); } + + getCommitTemplate(): TPromise { + return this.repo.getCommitTemplate(); + } } export class DelayedRawGitService implements IRawGitService { @@ -220,4 +224,5 @@ export class DelayedRawGitService implements IRawGitService { commit(message:string, amend?: boolean, stage?: boolean): TPromise { return this.raw.then(r => r.commit(message, amend, stage)); } detectMimetypes(path: string, treeish?: string): TPromise { return this.raw.then(r => r.detectMimetypes(path, treeish)); } show(path: string, treeish?: string): TPromise { return this.raw.then(r => r.show(path, treeish)); } + getCommitTemplate(): TPromise { return this.raw.then(r => r.getCommitTemplate()); } } \ No newline at end of file diff --git a/src/vs/workbench/parts/lib/node/systemVariables.ts b/src/vs/workbench/parts/lib/node/systemVariables.ts index 56d126f3df7..1abb522c018 100644 --- a/src/vs/workbench/parts/lib/node/systemVariables.ts +++ b/src/vs/workbench/parts/lib/node/systemVariables.ts @@ -48,6 +48,10 @@ export class SystemVariables extends AbstractSystemVariables { return this.getFilePath(); } + public get relativeFile(): string { + return (this.workspaceRoot) ? Paths.relative(this.workspaceRoot, this.file) : this.file; + } + public get fileBasename(): string { return Paths.basename(this.getFilePath()); } diff --git a/src/vs/workbench/parts/markers/browser/markersStatisticsWidget.ts b/src/vs/workbench/parts/markers/browser/markersStatisticsWidget.ts deleted file mode 100644 index becce94dc41..00000000000 --- a/src/vs/workbench/parts/markers/browser/markersStatisticsWidget.ts +++ /dev/null @@ -1,55 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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/markers-statistics-widget'; -import * as dom from 'vs/base/browser/dom'; -import { MarkerStatistics } from 'vs/platform/markers/common/markers'; -import { MarkersModel } from 'vs/workbench/parts/markers/common/markersModel'; - -export default class MarkerStatisticsWidget { - - private errorElement: HTMLElement; - private warningElement: HTMLElement; - private infoElement: HTMLElement; - private labelElement: HTMLElement; - - constructor(container: HTMLElement, private short: boolean = true, private stats?: MarkerStatistics) { - if (short) { - let widget= dom.append(container, dom.emmet('.markers-statistics-widget')); - this.errorElement = dom.append(widget, dom.emmet('.item-label-hidden')); - this.warningElement = dom.append(widget, dom.emmet('.item-label-hidden')); - this.infoElement = dom.append(widget, dom.emmet('.item-label-hidden')); - } else { - this.labelElement = dom.append(container, dom.emmet('span')); - } - if (this.stats) { - this.setStatistics(stats); - } - } - - public setStatistics(stats: MarkerStatistics): void { - this.stats = stats; - this.render(); - } - - private render(): void { - if (this.short) { - dom.toggleClass(this.errorElement, 'item-label-hidden', this.stats.errors <= 0); - dom.toggleClass(this.errorElement, 'item-label-error', this.stats.errors > 0); - this.errorElement.innerHTML = '' + this.stats.errors; - - dom.toggleClass(this.warningElement, 'item-label-hidden', this.stats.warnings <= 0); - dom.toggleClass(this.warningElement, 'item-label-warning', this.stats.warnings > 0); - this.warningElement.innerHTML = '' + this.stats.warnings; - - dom.toggleClass(this.infoElement, 'item-label-hidden', this.stats.infos <= 0); - dom.toggleClass(this.infoElement, 'item-label-info', this.stats.infos > 0); - this.infoElement.innerHTML = '' + this.stats.infos; - } else { - this.labelElement.textContent = MarkersModel.getStatisticsLabel(this.stats); - } - } -} \ No newline at end of file diff --git a/src/vs/workbench/parts/markers/browser/markersTreeController.ts b/src/vs/workbench/parts/markers/browser/markersTreeController.ts index 8376ec97cc9..1160e2fc87a 100644 --- a/src/vs/workbench/parts/markers/browser/markersTreeController.ts +++ b/src/vs/workbench/parts/markers/browser/markersTreeController.ts @@ -46,7 +46,7 @@ export class Controller extends treedefaults.DefaultController { return false; } - private openFileAtElement(element: any, preserveFocus: boolean, sideByside: boolean, pinned: boolean) { + private openFileAtElement(element: any, preserveFocus: boolean, sideByside: boolean, pinned: boolean): boolean { if (element instanceof Marker) { this.telemetryService.publicLog('problems.marker.opened', {source: element.source}); let marker = element.marker; @@ -59,8 +59,8 @@ export class Controller extends treedefaults.DefaultController { endLineNumber: marker.endLineNumber, endColumn: marker.endColumn }, - preserveFocus: preserveFocus, - pinned: pinned + preserveFocus, + pinned }, }, sideByside).done(null, errors.onUnexpectedError); return true; diff --git a/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts index 6435e25aec3..e9ab660716a 100644 --- a/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts @@ -16,12 +16,10 @@ import { FileLabel } from 'vs/base/browser/ui/fileLabel/fileLabel'; import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; import { IMarker } from 'vs/platform/markers/common/markers'; import { MarkersModel, Resource, Marker } from 'vs/workbench/parts/markers/common/markersModel'; -import MarkersStatisticsWidget from 'vs/workbench/parts/markers/browser/markersStatisticsWidget'; import Messages from 'vs/workbench/parts/markers/common/messages'; interface IResourceTemplateData { file: FileLabel; - statistics: MarkersStatisticsWidget; count: CountBadge; } diff --git a/src/vs/workbench/parts/markers/browser/media/markers-statistics-widget.css b/src/vs/workbench/parts/markers/browser/media/markers-statistics-widget.css deleted file mode 100644 index 59cdc0a9ab1..00000000000 --- a/src/vs/workbench/parts/markers/browser/media/markers-statistics-widget.css +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -.markers-statistics-widget > * { - display: inline-block; - margin-left: 2px; -} - -.markers-statistics-widget .item-label-hidden { - display: none; - margin-left: 0px; -} - -.markers-statistics-widget .item-label-error { - display: inline-block; - padding: 2px 0px 0px 16px; - background: url('stats-label-error.svg') 0px 6px no-repeat; -} - -.markers-statistics-widget .item-label-warning { - display: inline-block; - padding: 2px 0px 0px 22px; - background: url('stats-label-warning.svg') 6px 6px no-repeat; -} - -.markers-statistics-widget .item-label-info { - display: inline-block; - padding: 2px 0px 0px 22px; - background: url('stats-label-info.svg') 6px 6px no-repeat; -} \ No newline at end of file diff --git a/src/vs/workbench/parts/markers/browser/media/stats-label-error.svg b/src/vs/workbench/parts/markers/browser/media/stats-label-error.svg deleted file mode 100644 index 61b16362cb1..00000000000 --- a/src/vs/workbench/parts/markers/browser/media/stats-label-error.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/markers/browser/media/stats-label-info.svg b/src/vs/workbench/parts/markers/browser/media/stats-label-info.svg deleted file mode 100644 index 16306356ba0..00000000000 --- a/src/vs/workbench/parts/markers/browser/media/stats-label-info.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/markers/browser/media/stats-label-warning.svg b/src/vs/workbench/parts/markers/browser/media/stats-label-warning.svg deleted file mode 100644 index 5951d69539a..00000000000 --- a/src/vs/workbench/parts/markers/browser/media/stats-label-warning.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/output/browser/media/output.contribution.css b/src/vs/workbench/parts/output/browser/media/output.contribution.css index f177d54ec91..093845880a3 100644 --- a/src/vs/workbench/parts/output/browser/media/output.contribution.css +++ b/src/vs/workbench/parts/output/browser/media/output.contribution.css @@ -7,21 +7,7 @@ background: url('clear_output.svg') center center no-repeat; } -.vs-dark .monaco-workbench .output-action.clear-output { - background: url('clear_output_inverse.svg') center center no-repeat; -} - -/* High Contrast Theming */ - +.vs-dark .monaco-workbench .output-action.clear-output, .hc-black .monaco-workbench .output-action.clear-output { - background: none; -} - -.hc-black .monaco-workbench .output-action.clear-output:before { - content: url('clear_output_inverse.svg'); - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} + background: url('clear_output_inverse.svg') center center no-repeat; +} \ No newline at end of file diff --git a/src/vs/workbench/parts/output/browser/output.contribution.ts b/src/vs/workbench/parts/output/browser/output.contribution.ts index e176c6163b9..97da228857b 100644 --- a/src/vs/workbench/parts/output/browser/output.contribution.ts +++ b/src/vs/workbench/parts/output/browser/output.contribution.ts @@ -8,7 +8,7 @@ import nls = require('vs/nls'); import {KeyMod, KeyCode} from 'vs/base/common/keyCodes'; import {ModesRegistry} from 'vs/editor/common/modes/modesRegistry'; import platform = require('vs/platform/platform'); -import {MenuId, SyncActionDescriptor} from 'vs/platform/actions/common/actions'; +import {MenuId, MenuRegistry, SyncActionDescriptor} from 'vs/platform/actions/common/actions'; import {IKeybindings} from 'vs/platform/keybinding/common/keybinding'; import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry'; import {registerSingleton} from 'vs/platform/instantiation/common/extensions'; @@ -20,7 +20,6 @@ import panel = require('vs/workbench/browser/panel'); import {KEYBINDING_CONTEXT_EDITOR_LANGUAGE_ID} from 'vs/editor/common/editorCommon'; import {CommandsRegistry, ICommandHandler} from 'vs/platform/commands/common/commands'; import {KbExpr} from 'vs/platform/keybinding/common/keybinding'; -import {MenuRegistry} from 'vs/platform/actions/browser/menuService'; // Register Service registerSingleton(IOutputService, OutputService); diff --git a/src/vs/workbench/parts/output/test/outputWorker.test.ts b/src/vs/workbench/parts/output/test/outputWorker.test.ts index 592155c5541..364c04daae8 100644 --- a/src/vs/workbench/parts/output/test/outputWorker.test.ts +++ b/src/vs/workbench/parts/output/test/outputWorker.test.ts @@ -9,7 +9,7 @@ import * as assert from 'assert'; import URI from 'vs/base/common/uri'; import {isMacintosh, isLinux} from 'vs/base/common/platform'; import {OutputWorker} from 'vs/workbench/parts/output/common/outputWorker'; -import {TestContextService} from 'vs/workbench/test/common/servicesTestUtils'; +import {TestContextService} from 'vs/test/utils/servicesTestUtils'; function toOSPath(p: string): string { if (isMacintosh || isLinux) { diff --git a/src/vs/workbench/parts/quickopen/browser/commandsHandler.ts b/src/vs/workbench/parts/quickopen/browser/commandsHandler.ts index 41b72533989..5411bb6815a 100644 --- a/src/vs/workbench/parts/quickopen/browser/commandsHandler.ts +++ b/src/vs/workbench/parts/quickopen/browser/commandsHandler.ts @@ -21,9 +21,7 @@ import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workb import {Registry} from 'vs/platform/platform'; import {QuickOpenHandler, QuickOpenAction} from 'vs/workbench/browser/quickopen'; import {matchesWords, matchesPrefix, matchesContiguousSubString, or} from 'vs/base/common/filters'; -import {ICommonCodeEditor, IEditorActionDescriptorData} from 'vs/editor/common/editorCommon'; import {EditorAction} from 'vs/editor/common/editorAction'; -import {Behaviour} from 'vs/editor/common/editorActionEnablement'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IMessageService, Severity, IMessageWithAction} from 'vs/platform/message/common/message'; @@ -385,33 +383,3 @@ export class EditorCommandsHandler extends CommandsHandler { return false; } } - -export class QuickCommandsEditorAction extends EditorAction { - - public static ID = 'editor.action.quickCommand'; - - constructor( - descriptor: IEditorActionDescriptorData, - editor: ICommonCodeEditor, - @IQuickOpenService private quickOpenService: IQuickOpenService - ) { - super(descriptor, editor, Behaviour.WidgetFocus | Behaviour.ShowInContextMenu); - - this.label = nls.localize('QuickCommandsAction.label', "Show Editor Commands"); - } - - public getGroupId(): string { - return '4_tools/1_commands'; - } - - public run(): TPromise { - - // Pass focus to editor first before running quick open action - this.editor.focus(); - - // Show with prefix - this.quickOpenService.show('$'); - - return super.run(); - } -} \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/media/gotoSymbolHandler.css b/src/vs/workbench/parts/quickopen/browser/media/gotoSymbolHandler.css index c0b3a88d39f..b24077d3084 100644 --- a/src/vs/workbench/parts/quickopen/browser/media/gotoSymbolHandler.css +++ b/src/vs/workbench/parts/quickopen/browser/media/gotoSymbolHandler.css @@ -30,139 +30,61 @@ .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.method, .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.function, .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.constructor { background-position: 0 -4px; } -.vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.variable { background-position: -22px -4px; } +.vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.variable { background-position: -22px -4px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.class { background-position: -43px -3px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.interface { background-position: -63px -4px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.object, .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.namespace, .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.package, .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.module { background-position: -82px -4px; } -.vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.property { background-position: -102px -3px; } +.vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.property { background-position: -102px -3px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.enum { background-position: -122px -3px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.key, .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.string { background-position: -202px -3px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.rule { background-position: -242px -4px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.file { background-position: -262px -4px; } -.vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.array { background-position: -302px -4px; } +.vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.array { background-position: -302px -4px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.number { background-position: -322px -4px; } .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.null, .vs .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.boolean { background-position: -343px -4px; } .vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.method, .vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.function, -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.constructor { background-position: 0 -24px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.variable { background-position: -22px -24px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.class { background-position: -43px -23px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.interface { background-position: -63px -24px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.constructor, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.method, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.function, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.constructor { background-position: 0 -24px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.variable, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.variable { background-position: -22px -24px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.class, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.class { background-position: -43px -23px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.interface, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.interface { background-position: -63px -24px; } .vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.object, .vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.namespace, .vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.package, -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.module { background-position: -82px -24px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.property { background-position: -102px -23px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.key, -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.string { background-position: -202px -23px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.enum { background-position: -122px -23px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.rule { background-position: -242px -24px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.file { background-position: -262px -24px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.array { background-position: -302px -24px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.number { background-position: -322px -24px; } -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.null, -.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.boolean { background-position: -342px -24px; } - -/* High Contrast Theming */ - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.method, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.function, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.constructor, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.variable, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.class, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.interface, +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.module, .hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.object, .hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.namespace, .hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.package, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.module, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.property, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.enum, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.module { background-position: -82px -24px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.property, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.property { background-position: -102px -23px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.key, +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.string, .hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.key, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.string, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.rule, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.file, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.array, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.number, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.string { background-position: -202px -23px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.enum, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.enum { background-position: -122px -23px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.rule, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.rule { background-position: -242px -24px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.file, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.file { background-position: -262px -24px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.array, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.array { background-position: -302px -24px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.number, +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.number { background-position: -322px -24px; } +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.null, +.vs-dark .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.boolean, .hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.null, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.boolean { - background: none; - display: inline; -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.method:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.function:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.constructor:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.variable:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.class:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.interface:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.object:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.namespace:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.package:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.module:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.property:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.enum:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.key:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.string:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.rule:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.file:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.array:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.number:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.null:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.boolean:before { - height: 16px; - width: 16px; - display: inline-block; -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.method:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.function:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.constructor:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iI0IxODBENyIgZD0iTTUuNSAzbC00LjUgMi44NTd2NC4yODVsNC41IDIuODU4IDQuNS0yLjg1N3YtNC4yODZsLTQuNS0yLjg1N3ptLS41IDguNDk4bC0zLTEuOTA1di0yLjgxNmwzIDEuOTA1djIuODE2em0tMi4zNTgtNS40OThsMi44NTgtMS44MTUgMi44NTggMS44MTUtMi44NTggMS44MTUtMi44NTgtMS44MTV6bTYuMzU4IDMuNTkzbC0zIDEuOTA1di0yLjgxNWwzLTEuOTA1djIuODE1eiIvPjwvc3ZnPg=="); - margin-left: 2px; -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.field:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.variable:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iIzc1QkVGRiIgZD0iTTEgNnY0bDQgMiA2LTN2LTRsLTQtMi02IDN6bTQgMWwtMi0xIDQtMiAyIDEtNCAyeiIvPjwvc3ZnPg=="); - margin-left: 2px; -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.class:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBvbHlnb24gZmlsbD0iI0U4QUI1MyIgcG9pbnRzPSIxMS45OTgsMTEuMDAyIDksMTEgOSw3IDExLDcgMTAsOCAxMiwxMCAxNSw3IDEzLDUgMTIsNiA3LDYgOSw0IDYsMSAxLDYgNCw5IDYsNyA4LDcgOCwxMiAxMSwxMiAxMCwxMyAxMiwxNSAxNSwxMiAxMywxMCIvPjwvc3ZnPg=="); -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.interface:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iIzc1QkVGRiIgZD0iTTExLjUgNGMtMS43NTkgMC0zLjIwNCAxLjMwOC0zLjQ0OSAzaC0zLjEyMmMtLjIyMy0uODYxLS45OTgtMS41LTEuOTI5LTEuNS0xLjEwNCAwLTIgLjg5NS0yIDIgMCAxLjEwNC44OTYgMiAyIDIgLjkzMSAwIDEuNzA2LS42MzkgMS45MjktMS41aDMuMTIyYy4yNDUgMS42OTEgMS42OSAzIDMuNDQ5IDMgMS45MyAwIDMuNS0xLjU3IDMuNS0zLjUgMC0xLjkzMS0xLjU3LTMuNS0zLjUtMy41em0wIDVjLS44MjcgMC0xLjUtLjY3NC0xLjUtMS41IDAtLjgyOC42NzMtMS41IDEuNS0xLjVzMS41LjY3MiAxLjUgMS41YzAgLjgyNi0uNjczIDEuNS0xLjUgMS41eiIvPjwvc3ZnPg=="); -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.object:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.namespace:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.package:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.module:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iI0M1QzVDNSIgZD0iTTkgMTF2LTFjMC0uODM0LjQ5Ni0xLjczOCAxLTItLjUwNC0uMjctMS0xLjE2OC0xLTJ2LTFjMC0uODQtLjU4NC0xLTEtMXYtMWMyLjA4MyAwIDIgMS4xNjYgMiAydjFjMCAuOTY5LjcwMy45OCAxIDF2MmMtLjMyMi4wMi0xIC4wNTMtMSAxdjFjMCAuODM0LjA4MyAyLTIgMnYtMWMuODMzIDAgMS0xIDEtMXptLTYgMHYtMWMwLS44MzQtLjQ5Ni0xLjczOC0xLTIgLjUwNC0uMjcgMS0xLjE2OCAxLTJ2LTFjMC0uODQuNTg0LTEgMS0xdi0xYy0yLjA4MyAwLTIgMS4xNjYtMiAydjFjMCAuOTY5LS43MDMuOTgtMSAxdjJjLjMyMi4wMiAxIC4wNTMgMSAxdjFjMCAuODM0LS4wODMgMiAyIDJ2LTFjLS44MzMgMC0xLTEtMS0xeiIvPjwvc3ZnPg=="); - margin-left: 2px; -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.property:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iI0M1QzVDNSIgZD0iTTEyLjA5IDQuMzU5bC0yLjY0MSAyLjY0MS0yLTIgMi42NDEtMi42NDFjLS41MDItLjIyNi0xLjA1NS0uMzU5LTEuNjQxLS4zNTktMi4yMDkgMC00IDEuNzkxLTQgNCAwIC41ODYuMTMzIDEuMTM5LjM1OSAxLjY0bC0zLjM1OSAzLjM2cy0xIDEgMCAyaDJsMy4zNTktMy4zNmMuNTAzLjIyNiAxLjA1NS4zNiAxLjY0MS4zNiAyLjIwOSAwIDQtMS43OTEgNC00IDAtLjU4Ni0uMTMzLTEuMTM5LS4zNTktMS42NDF6Ii8+PC9zdmc+"); - margin-left: 1px; -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.value:before, -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.enum:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PGcgZmlsbD0iIzc1QkVGRiI+PHBhdGggZD0iTTEyIDNoLTRsLTEgMXYyaDV2MWgtMnYxaDJsMS0xdi0zbC0xLTF6bTAgMmgtNHYtMWg0djF6TTMgMTJoNnYtNWgtNnY1em0xLTNoNHYxaC00di0xeiIvPjwvZz48L3N2Zz4="); -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.rule:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxMiI+PHBhdGggZmlsbD0iI0M1QzVDNSIgZD0iTTEwIDVoLTh2LTJoOHYyem0wIDFoLTZ2MWg2di0xem0wIDJoLTZ2MWg2di0xeiIvPjwvc3ZnPg=="); -} - -.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.file:before { - content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iI0M1QzVDNSIgZD0iTTkuNjc2IDJoLTYuNjc2djEyaDEwdi05bC0zLjMyNC0zem0yLjMyNCAxMWgtOHYtMTBoNXYzaDN2N3oiLz48L3N2Zz4="); -} \ No newline at end of file +.hc-black .monaco-workbench .quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon.boolean { background-position: -342px -24px; } \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/media/markerHandler.css b/src/vs/workbench/parts/quickopen/browser/media/markerHandler.css deleted file mode 100644 index 3ec474d2f6a..00000000000 --- a/src/vs/workbench/parts/quickopen/browser/media/markerHandler.css +++ /dev/null @@ -1,48 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -.quick-open-widget.marker-handler .inline { - display: inline-block; - vertical-align: top; -} - -.quick-open-widget.marker-handler .row { - height: 22px; -} - -.quick-open-widget.marker-handler .severity { - display: inline-block; - width: 16px; - height: 22px; - margin-right: 4px; -} - -.quick-open-widget.marker-handler .severity.warning { - background: url('status-warning.svg') center center no-repeat; -} - -.quick-open-widget.marker-handler .severity.error { - background: url('status-error.svg') center center no-repeat; -} - -.quick-open-widget.marker-handler .severity.info:before { - background: url('status-info.svg') center center no-repeat; -} - -.vs-dark .quick-open-widget.marker-handler .severity.warning { - background: url('status-warning-inverse.svg') center center no-repeat; -} - -.vs-dark .quick-open-widget.marker-handler .severity.error { - background: url('status-error-inverse.svg') center center no-repeat; -} - -.vs-dark .quick-open-widget.marker-handler .severity.info:before { - background: url('status-info-inverse.svg') center center no-repeat; -} - -.quick-open-widget.marker-handler .description { - margin-left: 20px; -} \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/media/status-error-inverse.svg b/src/vs/workbench/parts/quickopen/browser/media/status-error-inverse.svg deleted file mode 100644 index 3c852a7ffde..00000000000 --- a/src/vs/workbench/parts/quickopen/browser/media/status-error-inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/media/status-error.svg b/src/vs/workbench/parts/quickopen/browser/media/status-error.svg deleted file mode 100644 index a1ddb39fed6..00000000000 --- a/src/vs/workbench/parts/quickopen/browser/media/status-error.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/media/status-info-inverse.svg b/src/vs/workbench/parts/quickopen/browser/media/status-info-inverse.svg deleted file mode 100644 index d38c363e0e4..00000000000 --- a/src/vs/workbench/parts/quickopen/browser/media/status-info-inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/media/status-info.svg b/src/vs/workbench/parts/quickopen/browser/media/status-info.svg deleted file mode 100644 index f1245e7bcfe..00000000000 --- a/src/vs/workbench/parts/quickopen/browser/media/status-info.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/media/status-warning-inverse.svg b/src/vs/workbench/parts/quickopen/browser/media/status-warning-inverse.svg deleted file mode 100644 index df44e61b326..00000000000 --- a/src/vs/workbench/parts/quickopen/browser/media/status-warning-inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/quickopen/browser/media/status-warning.svg b/src/vs/workbench/parts/quickopen/browser/media/status-warning.svg deleted file mode 100644 index f4e2a84b0af..00000000000 --- a/src/vs/workbench/parts/quickopen/browser/media/status-warning.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/search/browser/media/search.contribution.css b/src/vs/workbench/parts/search/browser/media/search.contribution.css index bcdd6b207c0..e0b787ff3ba 100644 --- a/src/vs/workbench/parts/search/browser/media/search.contribution.css +++ b/src/vs/workbench/parts/search/browser/media/search.contribution.css @@ -5,11 +5,5 @@ /* Activity Bar */ .monaco-workbench > .activitybar .monaco-action-bar .action-label.search { - /* Inline icon to prevent slow loading on startup (original: search-dark.svg) */ - background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiI+PHBhdGggZD0iTTE5LjIzIDQuMDk1Yy00Ljg0MiAwLTguNzY5IDMuOTI4LTguNzY5IDguNzcxIDAgMS43ODEuNTM5IDMuNDMgMS40NDkgNC44MTUgMCAwLTUuNDgyIDUuNDU1LTcuMTAyIDcuMTAyLTEuNjIxIDEuNjQ2IDEuMDAxIDQuMDcxIDIuNjAyIDIuNDA5IDEuNjAyLTEuNjU5IDcuMDA2LTcuMDA1IDcuMDA2LTcuMDA1IDEuMzg0LjkxMSAzLjAzNSAxLjQ1IDQuODE0IDEuNDUgNC44NDUgMCA4Ljc3Mi0zLjkzIDguNzcyLTguNzcxLjAwMS00Ljg0NC0zLjkyNy04Ljc3MS04Ljc3Mi04Ljc3MXptMCAxNS4wMzVjLTMuNDU5IDAtNi4yNjUtMi44MDQtNi4yNjUtNi4yNjQgMC0zLjQ2IDIuODA1LTYuMjY1IDYuMjY1LTYuMjY1IDMuNDYyIDAgNi4yNjYgMi44MDQgNi4yNjYgNi4yNjUgMCAzLjQ2LTIuODA0IDYuMjY0LTYuMjY2IDYuMjY0eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg=='); -} - -/* High Contrast Theming */ -.hc-black .monaco-workbench > .activitybar .monaco-action-bar .action-label.search:before { - content: url('search-dark.svg'); + background-image: url('search-dark.svg'); } \ No newline at end of file diff --git a/src/vs/workbench/parts/search/browser/media/search.svg b/src/vs/workbench/parts/search/browser/media/search.svg deleted file mode 100644 index 25859d3a69f..00000000000 --- a/src/vs/workbench/parts/search/browser/media/search.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/parts/search/browser/media/searchviewlet.css b/src/vs/workbench/parts/search/browser/media/searchviewlet.css index 32fa71925ab..529523ec73c 100644 --- a/src/vs/workbench/parts/search/browser/media/searchviewlet.css +++ b/src/vs/workbench/parts/search/browser/media/searchviewlet.css @@ -70,10 +70,7 @@ height: 13px; } -.hc-black .monaco-workbench .search-viewlet .query-details .more { - background: url('ellipsis-inverse.svg') top center no-repeat; -} - +.hc-black .monaco-workbench .search-viewlet .query-details .more, .vs-dark .monaco-workbench .search-viewlet .query-details .more { background: url('ellipsis-inverse.svg') top center no-repeat; } @@ -213,11 +210,6 @@ font-style: italic; } -.monaco-workbench.mac .search-viewlet .label, -.monaco-workbench.mac .search-viewlet .linematch.changedOrRemoved { - font-weight: 300; /* makes the italic font appear the same as normal */ -} - .search-viewlet .monaco-count-badge { margin-right: 12px; } @@ -237,7 +229,8 @@ background-color: #333; } -.search-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions .action-remove { +.search-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions .action-remove, +.vs-dark .monaco-workbench .search-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions .action-remove { background: url("action-remove-focus.svg") center center no-repeat; } @@ -245,7 +238,8 @@ background: url('Refresh.svg') center center no-repeat; } -.vs-dark .monaco-workbench .search-action.refresh { +.vs-dark .monaco-workbench .search-action.refresh, +.hc-black .monaco-workbench .search-action.refresh { background: url('Refresh_inverse.svg') center center no-repeat; } @@ -253,7 +247,8 @@ background: url('CollapseAll.svg') center center no-repeat; } -.vs-dark .monaco-workbench .search-action.collapse { +.vs-dark .monaco-workbench .search-action.collapse, +.hc-black .monaco-workbench .search-action.collapse { background: url('CollapseAll_inverse.svg') center center no-repeat; } @@ -261,28 +256,18 @@ background: url('clear-search-results.svg') center center no-repeat; } -.vs-dark .monaco-workbench .search-action.clear-search-results { +.vs-dark .monaco-workbench .search-action.clear-search-results, +.hc-black .monaco-workbench .search-action.clear-search-results { background: url('clear-search-results-dark.svg') center center no-repeat; } -.vs-dark .monaco-workbench .search-viewlet .action-remove { - background: url("action-remove-dark.svg") center center no-repeat; -} - -.vs-dark .monaco-workbench .search-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions .action-remove { - background: url("action-remove-focus.svg") center center no-repeat; -} - .vs .monaco-workbench .search-viewlet .query-details .file-types .controls > .custom-checkbox.pattern { background: url('pattern.svg') center center no-repeat; } -.vs-dark .monaco-workbench .search-viewlet .query-details .file-types .controls > .custom-checkbox.pattern { - background: url('pattern-dark.svg') center center no-repeat; -} - +.vs-dark .monaco-workbench .search-viewlet .query-details .file-types .controls > .custom-checkbox.pattern, .hc-black .monaco-workbench .search-viewlet .query-details .file-types .controls > .custom-checkbox.pattern:before { - content: url('pattern-dark.svg'); + background: url('pattern-dark.svg') center center no-repeat; } .search-viewlet .findInFileMatch, @@ -363,7 +348,8 @@ background: url("action-query-clear-dark.svg") center center no-repeat; } -.vs-dark .search-viewlet .action-remove { +.vs-dark .search-viewlet .action-remove, +.hc-black .search-viewlet .action-remove { background: url("action-remove-dark.svg") center center no-repeat; } @@ -391,44 +377,6 @@ background-color: #000; } -.hc-black .monaco-workbench .search-action { - background: none; -} - -.hc-black .monaco-workbench .search-action:before { - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} - -.hc-black .monaco-workbench .search-action.refresh:before { - content: url('Refresh_inverse.svg'); -} - -.hc-black .monaco-workbench .search-action.collapse:before { - content: url('CollapseAll_inverse.svg'); -} - -.hc-black .monaco-workbench .search-action.clear-search-results:before { - content: url('clear-search-results-dark.svg'); -} - -.hc-black .monaco-workbench .search-viewlet .query-clear { - background: none; -} - -.hc-black .monaco-workbench .search-viewlet .query-clear:before, -.hc-black .monaco-workbench .search-viewlet .action-remove:before { - content: url('action-remove-dark.svg'); - position: absolute; - top: 2px; - left: 5px; - height: 16px; - width: 16px; -} - .hc-black .monaco-workbench .input-box { border: 1px solid #6FC3DF; } @@ -437,11 +385,6 @@ border: none; } -.hc-black .monaco-workbench .search-viewlet .action-remove, -.hc-black .monaco-workbench .search-viewlet .focused .monaco-tree-row.selected:not(.highlighted) > .content.actions > .primary-action-bar .action-remove { - background: none !important; -} - .hc-black .monaco-workbench .search-viewlet .filematch, .hc-black .monaco-workbench .search-viewlet .linematch { line-height: 20px; diff --git a/src/vs/workbench/parts/search/browser/replaceService.ts b/src/vs/workbench/parts/search/browser/replaceService.ts index bc4d5de445b..f099fb6a2c7 100644 --- a/src/vs/workbench/parts/search/browser/replaceService.ts +++ b/src/vs/workbench/parts/search/browser/replaceService.ts @@ -23,27 +23,25 @@ import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; class EditorInputCache { private cache: Map.SimpleMap>; - private replaceTextcache: Map.SimpleMap; constructor(private replaceService: ReplaceService, private editorService: IWorkbenchEditorService, private modelService: IModelService) { this.cache= new Map.SimpleMap>(); - this.replaceTextcache= new Map.SimpleMap(); } - public getInput(fileMatch: FileMatch, text: string): TPromise { + public getInput(fileMatch: FileMatch): TPromise { let editorInputPromise= this.cache.get(fileMatch.resource()); if (!editorInputPromise) { editorInputPromise= this.createInput(fileMatch); this.cache.set(fileMatch.resource(), editorInputPromise); - this.refreshInput(fileMatch, text, true); + this.refreshInput(fileMatch, true); fileMatch.onDispose(() => this.disposeInput(fileMatch)); - fileMatch.onChange((modelChange) => this.refreshInput(fileMatch, this.replaceTextcache.get(fileMatch.resource()), modelChange)); + fileMatch.onChange((modelChange) => this.refreshInput(fileMatch, modelChange)); } return editorInputPromise; } - public refreshInput(fileMatch: FileMatch, text: string, reloadFromSource: boolean= false): void { + public refreshInput(fileMatch: FileMatch, reloadFromSource: boolean= false): void { let editorInputPromise= this.cache.get(fileMatch.resource()); if (editorInputPromise) { editorInputPromise.done(() => { @@ -51,14 +49,13 @@ class EditorInputCache { this.editorService.resolveEditorModel({resource: fileMatch.resource()}).then((value: ITextEditorModel) => { let replaceResource= this.getReplaceResource(fileMatch.resource()); this.modelService.getModel(replaceResource).setValue(( value.textEditorModel).getValue()); - this.replaceService.replace(fileMatch, text, null, replaceResource); + this.replaceService.replace(fileMatch, null, replaceResource); }); } else { let replaceResource= this.getReplaceResource(fileMatch.resource()); this.modelService.getModel(replaceResource).undo(); - this.replaceService.replace(fileMatch, text, null, replaceResource); + this.replaceService.replace(fileMatch, null, replaceResource); } - this.replaceTextcache.set(fileMatch.resource(), text); }); } } @@ -73,7 +70,6 @@ class EditorInputCache { editorInputPromise.done((diffInput) => { this.disposeReplaceInput(this.getReplaceResource(resourceUri), diffInput); this.cache.delete(resourceUri); - this.replaceTextcache.delete(resourceUri); }); } } @@ -127,16 +123,17 @@ export class ReplaceService implements IReplaceService { this.cache= new EditorInputCache(this, editorService, modelService); } - public replace(match: Match, text: string): TPromise - public replace(files: FileMatch[], text: string, progress?: IProgressRunner): TPromise - public replace(match: FileMatchOrMatch, text: string, progress?: IProgressRunner, resource?: URI): TPromise - public replace(arg: any, text: string, progress: IProgressRunner= null, resource: URI= null): TPromise { + public replace(match: Match): TPromise + public replace(files: FileMatch[], progress?: IProgressRunner): TPromise + public replace(match: FileMatchOrMatch, progress?: IProgressRunner, resource?: URI): TPromise + public replace(arg: any, progress: IProgressRunner= null, resource: URI= null): TPromise { let bulkEdit: BulkEdit = createBulkEdit(this.eventService, this.editorService, null); bulkEdit.progress(progress); if (arg instanceof Match) { - bulkEdit.add([this.createEdit(arg, text, resource)]); + let match= arg; + bulkEdit.add([this.createEdit(match, match.replaceString, resource)]); } if (arg instanceof FileMatch) { @@ -148,7 +145,7 @@ export class ReplaceService implements IReplaceService { let fileMatch = element; if (fileMatch.count() > 0) { fileMatch.matches().forEach(match => { - bulkEdit.add([this.createEdit(match, text, resource)]); + bulkEdit.add([this.createEdit(match, match.replaceString, resource)]); }); } }); @@ -157,12 +154,12 @@ export class ReplaceService implements IReplaceService { return bulkEdit.finish(); } - public getInput(element: FileMatch, text: string): TPromise { - return this.cache.getInput(element, text); + public getInput(element: FileMatch): TPromise { + return this.cache.getInput(element); } - public refreshInput(element: FileMatch, text: string, reload: boolean= false): void { - this.cache.refreshInput(element, text, reload); + public refreshInput(element: FileMatch, reload: boolean= false): void { + this.cache.refreshInput(element, reload); } public disposeAllInputs(): void { diff --git a/src/vs/workbench/parts/search/browser/searchActions.ts b/src/vs/workbench/parts/search/browser/searchActions.ts index 72907f038e6..638cc097f6f 100644 --- a/src/vs/workbench/parts/search/browser/searchActions.ts +++ b/src/vs/workbench/parts/search/browser/searchActions.ts @@ -185,7 +185,7 @@ export class ReplaceAllAction extends Action { public run(): TPromise { this.telemetryService.publicLog('replaceAll.action.selected'); - return this.fileMatch.parent().replace(this.fileMatch, this.fileMatch.parent().searchModel.replaceText).then(() => { + return this.fileMatch.parent().replace(this.fileMatch).then(() => { this.viewlet.open(this.fileMatch); }); } @@ -206,7 +206,7 @@ export class ReplaceAction extends Action { public run(): TPromise { this.telemetryService.publicLog('replace.action.selected'); - return this.element.parent().replace(this.element, this.element.parent().parent().searchModel.replaceText).then(() => { + return this.element.parent().replace(this.element).then(() => { this.viewlet.open(this.element); }); } diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index 5342b1ed6b2..c1b82d7d713 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -161,20 +161,19 @@ export class SearchRenderer extends ActionsRenderer { // Match else if (element instanceof Match) { dom.addClass(domElement, 'linematch'); - + let match= element; let elements: string[] = []; - let preview = element.preview(); + let preview = match.preview(); elements.push(''); elements.push(strings.escape(preview.before)); - let input= tree.getInput(); - let showReplaceText= input.searchModel.hasReplaceText(); + let showReplaceText= (tree.getInput()).searchModel.hasReplaceString(); elements.push(''); elements.push(strings.escape(preview.inside)); if (showReplaceText) { elements.push(''); - elements.push(strings.escape(input.searchModel.replaceText)); + elements.push(strings.escape(match.replaceString)); } elements.push(''); elements.push(strings.escape(preview.after)); @@ -182,7 +181,7 @@ export class SearchRenderer extends ActionsRenderer { $('a.plain') .innerHtml(elements.join(strings.empty)) - .title((preview.before + (input.searchModel.isReplaceActive() ? input.searchModel.replaceText : preview.inside) + preview.after).trim().substr(0, 999)) + .title((preview.before + (showReplaceText ? match.replaceString : preview.inside) + preview.after).trim().substr(0, 999)) .appendTo(domElement); } @@ -203,12 +202,13 @@ export class SearchAccessibilityProvider implements IAccessibilityProvider { } if (element instanceof Match) { + let match= element; let input= tree.getInput(); if (input.searchModel.isReplaceActive()) { - let preview = element.preview(); - return nls.localize('replacePreviewResultAria', "Replace preview result, {0}", preview.before + input.searchModel.replaceText + preview.after); + let preview = match.preview(); + return nls.localize('replacePreviewResultAria', "Replace preview result, {0}", preview.before + match.replaceString + preview.after); } - return nls.localize('searchResultAria', "{0}, Search result", element.text()); + return nls.localize('searchResultAria', "{0}, Search result", match.text()); } } } diff --git a/src/vs/workbench/parts/search/browser/searchViewlet.ts b/src/vs/workbench/parts/search/browser/searchViewlet.ts index fb6e3db8541..dd487bcdddb 100644 --- a/src/vs/workbench/parts/search/browser/searchViewlet.ts +++ b/src/vs/workbench/parts/search/browser/searchViewlet.ts @@ -290,11 +290,11 @@ export class SearchViewlet extends Viewlet { this.toUnbind.push(this.searchWidget.onReplaceToggled(() => this.onReplaceToggled())); this.toUnbind.push(this.searchWidget.onReplaceStateChange((state) => { - this.viewModel.replaceText= this.searchWidget.getReplaceValue(); + this.viewModel.replaceString= this.searchWidget.getReplaceValue(); this.tree.refresh(); })); this.toUnbind.push(this.searchWidget.onReplaceValueChanged((value) => { - this.viewModel.replaceText= this.searchWidget.getReplaceValue(); + this.viewModel.replaceString= this.searchWidget.getReplaceValue(); this.refreshInputs(); this.tree.refresh(); })); @@ -344,7 +344,7 @@ export class SearchViewlet extends Viewlet { private refreshInputs(): void { this.viewModel.searchResult.matches().forEach((fileMatch) => { - this.replaceService.refreshInput(fileMatch, this.viewModel.replaceText); + this.replaceService.refreshInput(fileMatch); }); } @@ -370,7 +370,7 @@ export class SearchViewlet extends Viewlet { if (this.messageService.confirm(confirmation)) { this.searchWidget.setReplaceAllActionState(false); - this.viewModel.searchResult.replaceAll(replaceValue, progressRunner).then(() => { + this.viewModel.searchResult.replaceAll(progressRunner).then(() => { progressRunner.done(); this.showMessage(afterReplaceAllMessage); }, (error) => { @@ -731,7 +731,7 @@ export class SearchViewlet extends Viewlet { } this.onSearchResultsChanged().then(() => autoExpand(true)); - this.viewModel.replaceText= this.searchWidget.getReplaceValue(); + this.viewModel.replaceString= this.searchWidget.getReplaceValue(); let hasResults = !this.viewModel.searchResult.isEmpty(); this.loading = false; @@ -902,7 +902,7 @@ export class SearchViewlet extends Viewlet { this.telemetryService.publicLog('searchResultChosen'); - return this.viewModel.hasReplaceText() ? this.openReplacePreviewEditor(lineMatch, preserveFocus, sideBySide, pinned) : this.open(lineMatch, preserveFocus, sideBySide, pinned); + return this.viewModel.hasReplaceString() ? this.openReplacePreviewEditor(lineMatch, preserveFocus, sideBySide, pinned) : this.open(lineMatch, preserveFocus, sideBySide, pinned); } public open(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise { @@ -911,17 +911,17 @@ export class SearchViewlet extends Viewlet { return this.editorService.openEditor({ resource: resource, options: { - preserveFocus: preserveFocus, - pinned: pinned, - selection: selection + preserveFocus, + pinned, + selection } }, sideBySide); } private openReplacePreviewEditor(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise { this.telemetryService.publicLog('replace.open.previewEditor'); - return this.replaceService.getInput(element instanceof Match ? element.parent() : element, this.viewModel.replaceText).then((editorInput) => { - this.editorService.openEditor(editorInput, {preserveFocus: preserveFocus, pinned: pinned}).then((editor) => { + return this.replaceService.getInput(element instanceof Match ? element.parent() : element).then((editorInput) => { + this.editorService.openEditor(editorInput, {preserveFocus: preserveFocus, pinned}).then((editor) => { let editorControl= (editor.getControl()); if (element instanceof Match) { editorControl.revealLineInCenter(element.range().startLineNumber); @@ -941,12 +941,12 @@ export class SearchViewlet extends Viewlet { if (match) { let range= match.range(); if (this.viewModel.isReplaceActive()) { - let replaceText= this.viewModel.replaceText; + let replaceString= match.replaceString; return { startLineNumber: range.startLineNumber, - startColumn: range.startColumn + replaceText.length, + startColumn: range.startColumn + replaceString.length, endLineNumber: range.startLineNumber, - endColumn: range.startColumn + replaceText.length + endColumn: range.startColumn + replaceString.length }; } return range; diff --git a/src/vs/workbench/parts/search/common/replace.ts b/src/vs/workbench/parts/search/common/replace.ts index 678e186bf7e..847896322a8 100644 --- a/src/vs/workbench/parts/search/common/replace.ts +++ b/src/vs/workbench/parts/search/common/replace.ts @@ -16,26 +16,26 @@ export interface IReplaceService { _serviceBrand: any; /** - * Replace the match with the given text. + * Replaces the given match in the file that match belongs to */ - replace(match: Match, text: string): TPromise; + replace(match: Match): TPromise; /** - * Replace all the matches in the given file matches with provided text. + * Replace all the matches from the given file matches in the files * You can also pass the progress runner to update the progress of replacing. */ - replace(files: FileMatch[], text: string, progress?: IProgressRunner): TPromise; + replace(files: FileMatch[], progress?: IProgressRunner): TPromise; /** - * Gets the input for the file match with given text + * Gets the input for the file match */ - getInput(element: FileMatch, text: string): TPromise; + getInput(element: FileMatch): TPromise; /** - * Refresh the input for the fiel match with given text. If reload, content of repalced editor is reloaded completely + * Refresh the input for the file match. If reload, content of repalced editor is reloaded completely * Otherwise undo the last changes and refreshes with new text. */ - refreshInput(element: FileMatch, text: string, reload?: boolean): void; + refreshInput(element: FileMatch, reload?: boolean): void; /** * Disposes all Inputs diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index 484e0c8b3d5..e670cb6b0a1 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -16,6 +16,7 @@ import { ArraySet } from 'vs/base/common/set'; import Event, { Emitter } from 'vs/base/common/event'; import * as Search from 'vs/platform/search/common/search'; import { ISearchProgressItem, ISearchComplete, ISearchQuery } from 'vs/platform/search/common/search'; +import { ReplacePattern } from 'vs/platform/search/common/replace'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { Range } from 'vs/editor/common/core/range'; import { IModel, IModelDeltaDecoration, OverviewRulerLane, TrackedRangeStickiness, IModelDecorationOptions } from 'vs/editor/common/editorCommon'; @@ -66,6 +67,10 @@ export class Match { after, }; } + + public get replaceString(): string { + return this.parent().parent().searchModel.replacePattern.getReplaceString(this.preview().inside); + } } export class FileMatch extends Disposable { @@ -108,7 +113,7 @@ export class FileMatch extends Disposable { } private createMatches(): void { - let model = this.modelService ? this.modelService.getModel(this._resource) : null; + let model = this.modelService.getModel(this._resource); if (model) { this.bindModel(model); this.updateMatches(); @@ -116,20 +121,18 @@ export class FileMatch extends Disposable { this.rawMatch.lineMatches.forEach((rawLineMatch) => { rawLineMatch.offsetAndLengths.forEach(offsetAndLength => { let match = new Match(this, rawLineMatch.preview, rawLineMatch.lineNumber, offsetAndLength[0], offsetAndLength[1]); - this._matches.set(match.id(), match); + this.add(match); }); }); } } private registerListeners(): void { - if (this.modelService) { - this._register(this.modelService.onModelAdded((model: IModel) => { - if (model.uri.toString() === this._resource.toString()) { - this.bindModel(model); - } - })); - } + this._register(this.modelService.onModelAdded((model: IModel) => { + if (model.uri.toString() === this._resource.toString()) { + this.bindModel(model); + } + })); } private bindModel(model: IModel): void { @@ -169,7 +172,7 @@ export class FileMatch extends Disposable { matches.forEach(range => { let match= new Match(this, this._model.getLineContent(range.startLineNumber), range.startLineNumber - 1, range.startColumn - 1, range.endColumn - range.startColumn); if (!this._removedMatches.contains(match.id())) { - this._matches.set(match.id(), match); + this.add(match); } }); @@ -210,8 +213,8 @@ export class FileMatch extends Disposable { this._onChange.fire(false); } - public replace(match: Match, replaceText: string): TPromise { - return this.replaceService.replace(match, replaceText).then(() => { + public replace(match: Match): TPromise { + return this.replaceService.replace(match).then(() => { this._matches.delete(match.id()); this._onChange.fire(false); }); @@ -234,6 +237,13 @@ export class FileMatch extends Disposable { this._onDispose.fire(); super.dispose(); } + + public add(match: Match, trigger?: boolean) { + this._matches.set(match.id(), match); + if (trigger) { + this._onChange.fire(true); + } + } } export interface IChangeEvent { @@ -292,19 +302,18 @@ export class SearchResult extends Disposable { public remove(match: FileMatch): void { this.doRemove(match); - this._onChange.fire({elements: [match], removed: true}); } - public replace(match: FileMatch, replaceText: string): TPromise { - return this.replaceService.replace([match], replaceText).then(() => { - this.doRemove(match, false); + public replace(match: FileMatch): TPromise { + return this.replaceService.replace([match]).then(() => { + this.doRemove(match, false, true); }); } - public replaceAll(replaceText: string, progressRunner: IProgressRunner): TPromise { + public replaceAll(progressRunner: IProgressRunner): TPromise { this._replacingAll= true; let replaceAllTimer = this.telemetryService.timedPublicLog('replaceAll.started'); - return this.replaceService.replace(this.matches(), replaceText, progressRunner).then(() => { + return this.replaceService.replace(this.matches(), progressRunner).then(() => { replaceAllTimer.stop(); this._replacingAll= false; this.clear(); @@ -352,7 +361,7 @@ export class SearchResult extends Disposable { added= true; } if (fileMatch.count() === 0) { - this.doRemove(fileMatch, false); + this.doRemove(fileMatch, false, false); added= false; removed= true; } @@ -368,13 +377,17 @@ export class SearchResult extends Disposable { } } - private doRemove(fileMatch: FileMatch, dispose:boolean= true): void { + private doRemove(fileMatch: FileMatch, dispose:boolean= true, trigger: boolean= true): void { this._fileMatches.delete(fileMatch.resource()); if (dispose) { fileMatch.dispose(); } else { this._unDisposedFileMatches.set(fileMatch.resource(), fileMatch); } + + if (trigger) { + this._onChange.fire({elements: [fileMatch], removed: true}); + } } private disposeMatches(): void { @@ -394,7 +407,8 @@ export class SearchModel extends Disposable { private _searchResult: SearchResult; private _searchQuery: ISearchQuery= null; - private _replaceText: string= null; + private _replaceString: string= null; + private _replacePattern: ReplacePattern= null; private currentRequest: PPromise; private progressTimer: timer.ITimerEvent; @@ -410,7 +424,15 @@ export class SearchModel extends Disposable { * Return true if replace is enabled otherwise false */ public isReplaceActive():boolean { - return this.replaceText !== null && this.replaceText !== void 0; + return this._replaceString !== null && this._replaceString !== void 0; + } + + /** + * Return true if replace is enabled and replace text is not empty, otherwise false. + * This is necessary in cases handling empty replace text when replace is active. + */ + public hasReplaceString():boolean { + return this.isReplaceActive() && !!this._replaceString; } /** @@ -418,37 +440,34 @@ export class SearchModel extends Disposable { * Can be null if replace is not enabled. Use replace() before. * Can be empty. */ - public get replaceText(): string { - return this._replaceText; + public get replacePattern(): ReplacePattern { + return this._replacePattern; } - public set replaceText(replace: string) { - this._replaceText= replace; + public set replaceString(replaceString: string) { + this._replaceString= replaceString; + if (this._searchQuery) { + this._replacePattern= new ReplacePattern(replaceString, this._searchQuery.contentPattern); + } } public get searchResult():SearchResult { return this._searchResult; } - /** - * Return true if replace is enabled and replace text is not empty, otherwise false. - * This is necessary in cases handling empty replace text when replace is active. - */ - public hasReplaceText():boolean { - return this.isReplaceActive() && !!this.replaceText; - } - public search(query: ISearchQuery): PPromise { this.cancelSearch(); this.searchResult.clear(); this._searchQuery= query; this._searchResult.query= this._searchQuery.contentPattern; + this._replacePattern= new ReplacePattern(this._replaceString, this._searchQuery.contentPattern); + this.progressTimer = this.telemetryService.timedPublicLog('searchResultsFirstRender'); this.doneTimer = this.telemetryService.timedPublicLog('searchResultsFinished'); this.timerEvent = timer.start(timer.Topic.WORKBENCH, 'Search'); - this.currentRequest = this.searchService.search(this._searchQuery); + this.currentRequest = this.searchService.search(this._searchQuery); this.currentRequest.then(value => this.onSearchCompleted(value), e => this.onSearchError(e), p => this.onSearchProgress(p)); @@ -457,12 +476,13 @@ export class SearchModel extends Disposable { } private onSearchCompleted(completed: ISearchComplete): ISearchComplete { + this.progressTimer.stop(); this.timerEvent.stop(); - this.telemetryService.publicLog('searchResultsShown', { count: this._searchResult.count(), fileCount: this._searchResult.fileCount() }); this.doneTimer.stop(); if (completed) { this._searchResult.add(completed.results, false); } + this.telemetryService.publicLog('searchResultsShown', { count: this._searchResult.count(), fileCount: this._searchResult.fileCount() }); return completed; } @@ -472,6 +492,7 @@ export class SearchModel extends Disposable { } else { this.progressTimer.stop(); this.doneTimer.stop(); + this.timerEvent.stop(); } } diff --git a/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts b/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts index cfe291d29e9..1aa46fb8eb1 100644 --- a/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts +++ b/src/vs/workbench/parts/search/test/browser/searchViewlet.test.ts @@ -7,25 +7,18 @@ import * as assert from 'assert'; import uri from 'vs/base/common/uri'; import {Match, FileMatch, SearchResult} from 'vs/workbench/parts/search/common/searchModel'; -import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {SearchSorter, SearchDataSource} from 'vs/workbench/parts/search/browser/searchResultsView'; import {IFileMatch, ILineMatch} from 'vs/platform/search/common/search'; - -function aFileMatch(path: string, searchResult?: SearchResult, ...lineMatches: ILineMatch[]): FileMatch { - let rawMatch: IFileMatch= { - resource: uri.file('C:\\' + path), - lineMatches: lineMatches - }; - return new FileMatch(null, searchResult, rawMatch, null, null); -} +import { createMockModelService } from 'vs/test/utils/servicesTestUtils'; +import { IModelService } from 'vs/editor/common/services/modelService'; suite('Search - Viewlet', () => { - let instantiation: IInstantiationService; + let instantiation: TestInstantiationService; setup(() => { - instantiation = new InstantiationService(new ServiceCollection()); + instantiation = new TestInstantiationService(); + instantiation.stub(IModelService, createMockModelService(instantiation)); }); test('Data Source', function () { @@ -68,4 +61,12 @@ suite('Search - Viewlet', () => { assert(s.compare(null, lineMatch2, lineMatch1) > 0); assert(s.compare(null, lineMatch2, lineMatch3) === 0); }); + + function aFileMatch(path: string, searchResult?: SearchResult, ...lineMatches: ILineMatch[]): FileMatch { + let rawMatch: IFileMatch= { + resource: uri.file('C:\\' + path), + lineMatches: lineMatches + }; + return instantiation.createInstance(FileMatch, null, searchResult, rawMatch); + } }); \ No newline at end of file diff --git a/src/vs/workbench/parts/search/test/common/searchModel.test.ts b/src/vs/workbench/parts/search/test/common/searchModel.test.ts index d575589cabe..16fb5fd2b78 100644 --- a/src/vs/workbench/parts/search/test/common/searchModel.test.ts +++ b/src/vs/workbench/parts/search/test/common/searchModel.test.ts @@ -5,134 +5,303 @@ 'use strict'; import * as assert from 'assert'; -import {Match, FileMatch, SearchResult} from 'vs/workbench/parts/search/common/searchModel'; +import * as sinon from 'sinon'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; +import { DeferredPPromise } from 'vs/test/utils/promiseTestUtils'; +import { PPromise } from 'vs/base/common/winjs.base'; +import { nullEvent } from 'vs/base/common/timer'; +import { SearchModel } from 'vs/workbench/parts/search/common/searchModel'; import URI from 'vs/base/common/uri'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; -import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IFileMatch, ILineMatch} from 'vs/platform/search/common/search'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { ISearchService, ISearchComplete, ISearchProgressItem } from 'vs/platform/search/common/search'; +import { Range } from 'vs/editor/common/core/range'; +import { createMockModelService } from 'vs/test/utils/servicesTestUtils'; +import { IModelService } from 'vs/editor/common/services/modelService'; -function aFileMatch(path: string, searchResult?: SearchResult, ...lineMatches: ILineMatch[]): FileMatch { - let rawMatch: IFileMatch= { - resource: URI.file('C:\\' + path), - lineMatches: lineMatches - }; - return new FileMatch(null, searchResult, rawMatch, null, null); -} +suite('SearchModel', () => { -suite('Search - Model', () => { - let instantiation: IInstantiationService; + let instantiationService: TestInstantiationService; + let restoreStubs; setup(() => { - instantiation = new InstantiationService(new ServiceCollection()); + restoreStubs= []; + instantiationService= new TestInstantiationService(); + instantiationService.stub(ITelemetryService); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); }); - test('Line Match', function () { - let fileMatch = aFileMatch('folder\\file.txt'); - let lineMatch = new Match(fileMatch, 'foo bar', 1, 0, 3); - assert.equal(lineMatch.text(), 'foo bar'); - assert.equal(lineMatch.range().startLineNumber, 2); - assert.equal(lineMatch.range().endLineNumber, 2); - assert.equal(lineMatch.range().startColumn, 1); - assert.equal(lineMatch.range().endColumn, 4); + teardown(() => { + restoreStubs.forEach(element => { + element.restore(); + }); }); - test('Line Match - Remove', function () { - let fileMatch = aFileMatch('folder\\file.txt', null, ...[{ - preview: 'foo bar', - lineNumber: 1, - offsetAndLengths: [[0, 3]] - }]); - let lineMatch = fileMatch.matches()[0]; - fileMatch.remove(lineMatch); - assert.equal(fileMatch.matches().length, 0); + test('Search Model: Search adds to results', function () { + let results= [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + instantiationService.stub(ISearchService, 'search', PPromise.as({results: results})); + + let testObject= instantiationService.createInstance(SearchModel); + testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + + let actual= testObject.searchResult.matches(); + + assert.equal(2, actual.length); + assert.equal('file://c:/1', actual[0].resource().toString()); + + let actuaMatches= actual[0].matches(); + assert.equal(2, actuaMatches.length); + assert.equal('preview 1', actuaMatches[0].text()); + assert.ok(new Range(2, 2, 2, 5).equalsRange(actuaMatches[0].range())); + assert.equal('preview 1', actuaMatches[1].text()); + assert.ok(new Range(2, 5, 2, 12).equalsRange(actuaMatches[1].range())); + + actuaMatches= actual[1].matches(); + assert.equal(1, actuaMatches.length); + assert.equal('preview 2', actuaMatches[0].text()); + assert.ok(new Range(2, 1, 2, 2).equalsRange(actuaMatches[0].range())); }); - test('File Match', function () { - let fileMatch = aFileMatch('folder\\file.txt'); - assert.equal(fileMatch.matches(), 0); - assert.equal(fileMatch.resource().toString(), 'file:///c%3A/folder/file.txt'); - assert.equal(fileMatch.name(), 'file.txt'); + test('Search Model: Search adds to results during progress', function (done) { + let results= [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + let promise= new DeferredPPromise(); + instantiationService.stub(ISearchService, 'search', promise); - fileMatch = aFileMatch('file.txt'); - assert.equal(fileMatch.matches(), 0); - assert.equal(fileMatch.resource().toString(), 'file:///c%3A/file.txt'); - assert.equal(fileMatch.name(), 'file.txt'); + let testObject= instantiationService.createInstance(SearchModel); + let result= testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + + promise.progress(results[0]); + promise.progress(results[1]); + promise.complete({results: []}); + + result.done(() => { + let actual= testObject.searchResult.matches(); + + assert.equal(2, actual.length); + assert.equal('file://c:/1', actual[0].resource().toString()); + + let actuaMatches= actual[0].matches(); + assert.equal(2, actuaMatches.length); + assert.equal('preview 1', actuaMatches[0].text()); + assert.ok(new Range(2, 2, 2, 5).equalsRange(actuaMatches[0].range())); + assert.equal('preview 1', actuaMatches[1].text()); + assert.ok(new Range(2, 5, 2, 12).equalsRange(actuaMatches[1].range())); + + actuaMatches= actual[1].matches(); + assert.equal(1, actuaMatches.length); + assert.equal('preview 2', actuaMatches[0].text()); + assert.ok(new Range(2, 1, 2, 2).equalsRange(actuaMatches[0].range())); + + done(); + }); }); - test('Search Result', function () { + test('Search Model: Search reports telemetry on search completed', function () { + let target= instantiationService.spy(ITelemetryService, 'publicLog'); + let results= [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + instantiationService.stub(ISearchService, 'search', PPromise.as({results: results})); - let searchResult = instantiation.createInstance(SearchResult, null); - assert.equal(searchResult.isEmpty(), true); + let testObject= instantiationService.createInstance(SearchModel); + testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); - let raw: IFileMatch[] = []; - for (let i = 0; i < 10; i++) { - raw.push({ - resource: URI.parse('file://c:/' + i), - lineMatches: [{ - preview: String(i), - lineNumber: 1, - offsetAndLengths: [[0, 1]] - }] - }); - } - searchResult.add(raw); - - assert.equal(searchResult.isEmpty(), false); - assert.equal(searchResult.matches().length, 10); + assert.ok(target.calledOnce); + assert.deepEqual(['searchResultsShown', {count: 3, fileCount: 2}], target.args[0]); }); - test('Alle Drei Zusammen', function () { + test('Search Model: Search reports timed telemetry on search when progress is not called', function () { + let target2= sinon.spy(); + stub(nullEvent, 'stop', target2); + let target1= sinon.stub().returns(nullEvent); + instantiationService.stub(ITelemetryService, 'timedPublicLog', target1); - let searchResult = instantiation.createInstance(SearchResult, null); - let fileMatch = aFileMatch('far\\boo', searchResult); - let lineMatch = new Match(fileMatch, 'foo bar', 1, 0, 3); + instantiationService.stub(ISearchService, 'search', PPromise.as({results: []})); - assert(lineMatch.parent() === fileMatch); - assert(fileMatch.parent() === searchResult); + let testObject= instantiationService.createInstance(SearchModel); + testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + + assert.ok(target1.calledTwice); + assert.ok(target1.calledWith('searchResultsFirstRender')); + assert.ok(target1.calledWith('searchResultsFinished')); + assert.ok(target2.calledThrice); }); - //// ----- utils - //function lineHasDecorations(model: editor.IModel, lineNumber: number, decorations: { start: number; end: number; }[]): void { - // let lineDecorations:typeof decorations = []; - // let decs = model.getLineDecorations(lineNumber); - // for (let i = 0, len = decs.length; i < len; i++) { - // lineDecorations.push({ - // start: decs[i].range.startColumn, - // end: decs[i].range.endColumn - // }); - // } - // assert.deepEqual(lineDecorations, decorations); - //} - // - //function lineHasNoDecoration(model: editor.IModel, lineNumber: number): void { - // lineHasDecorations(model, lineNumber, []); - //} - // - //function lineHasDecoration(model: editor.IModel, lineNumber: number, start: number, end: number): void { - // lineHasDecorations(model, lineNumber, [{ - // start: start, - // end: end - // }]); - //} - //// ----- end utils - // - //test('Model Highlights', function () { - // - // let fileMatch = instantiation.createInstance(FileMatch, null, toUri('folder\\file.txt')); - // fileMatch.add(new Match(fileMatch, 'line2', 1, 0, 2)); - // fileMatch.connect(); - // lineHasDecoration(oneModel, 2, 1, 3); - //}); - // - //test('Dispose', function () { - // - // let fileMatch = instantiation.createInstance(FileMatch, null, toUri('folder\\file.txt')); - // fileMatch.add(new Match(fileMatch, 'line2', 1, 0, 2)); - // fileMatch.connect(); - // lineHasDecoration(oneModel, 2, 1, 3); - // - // fileMatch.dispose(); - // lineHasNoDecoration(oneModel, 2); - //}); + test('Search Model: Search reports timed telemetry on search when progress is called', function (done) { + let target2= sinon.spy(); + stub(nullEvent, 'stop', target2); + let target1= sinon.stub().returns(nullEvent); + instantiationService.stub(ITelemetryService, 'timedPublicLog', target1); + + let promise= new DeferredPPromise(); + instantiationService.stub(ISearchService, 'search', promise); + + let testObject= instantiationService.createInstance(SearchModel); + let result= testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + + promise.progress(aRawMatch('file://c:/1', aLineMatch('some preview'))); + promise.complete({results: []}); + + result.done(() => { + assert.ok(target1.calledTwice); + assert.ok(target1.calledWith('searchResultsFirstRender')); + assert.ok(target1.calledWith('searchResultsFinished')); + assert.equal(4, target2.callCount); + + done(); + }); + }); + + test('Search Model: Search reports timed telemetry on search when error is called', function (done) { + let target2= sinon.spy(); + stub(nullEvent, 'stop', target2); + let target1= sinon.stub().returns(nullEvent); + instantiationService.stub(ITelemetryService, 'timedPublicLog', target1); + + let promise= new DeferredPPromise(); + instantiationService.stub(ISearchService, 'search', promise); + + let testObject= instantiationService.createInstance(SearchModel); + let result= testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + + promise.error('error'); + + result.done(() => {}, () => { + assert.ok(target1.calledTwice); + assert.ok(target1.calledWith('searchResultsFirstRender')); + assert.ok(target1.calledWith('searchResultsFinished')); + assert.ok(target2.calledThrice); + + done(); + }); + }); + + test('Search Model: Search reports timed telemetry on search when error is cancelled error', function (done) { + let target2= sinon.spy(); + stub(nullEvent, 'stop', target2); + let target1= sinon.stub().returns(nullEvent); + instantiationService.stub(ITelemetryService, 'timedPublicLog', target1); + + let promise= new DeferredPPromise(); + instantiationService.stub(ISearchService, 'search', promise); + + let testObject= instantiationService.createInstance(SearchModel); + let result= testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + + promise.cancel(); + + result.done(() => {}, () => { + assert.ok(target1.calledTwice); + assert.ok(target1.calledWith('searchResultsFirstRender')); + assert.ok(target1.calledWith('searchResultsFinished')); + assert.ok(target2.calledThrice); + done(); + }); + }); + + test('Search Model: Search results are cleared during search', function () { + let results= [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + instantiationService.stub(ISearchService, 'search', PPromise.as({results: results})); + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + assert.ok(!testObject.searchResult.isEmpty()); + + instantiationService.stub(ISearchService, 'search', new DeferredPPromise()); + + testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + assert.ok(testObject.searchResult.isEmpty()); + }); + + test('Search Model: Previous search is cancelled when new search is called', function () { + let target= sinon.spy(); + instantiationService.stub(ISearchService, 'search', new DeferredPPromise((c, e, p) => {}, target)); + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + + testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + instantiationService.stub(ISearchService, 'search', new DeferredPPromise()); + testObject.search({contentPattern: {pattern: 'somestring'}, type: 1}); + + assert.ok(target.calledOnce); + }); + + test('Search Model: isReplaceActive return false if no replace text is set', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + + assert.ok(!testObject.isReplaceActive()); + }); + + test('Search Model: isReplaceActive return false if replace text is set to null', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.replaceString= null; + + assert.ok(!testObject.isReplaceActive()); + }); + + test('Search Model: isReplaceActive return false if replace text is set to undefined', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.replaceString= void 0; + + assert.ok(!testObject.isReplaceActive()); + }); + + test('Search Model: isReplaceActive return true if replace text is set to empty string', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.replaceString= ''; + + assert.ok(testObject.isReplaceActive()); + }); + + test('Search Model: isReplaceActive return true if replace text is set to non empty string', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.replaceString= 'some value'; + + assert.ok(testObject.isReplaceActive()); + }); + + test('Search Model: hasReplaceText return false if no replace text is set', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + + assert.ok(!testObject.hasReplaceString()); + }); + + test('Search Model: hasReplaceText return false if replace text is set to null', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.replaceString= null; + + assert.ok(!testObject.hasReplaceString()); + }); + + test('Search Model: hasReplaceText return false if replace text is set to undefined', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.replaceString= void 0; + + assert.ok(!testObject.hasReplaceString()); + }); + + test('Search Model: hasReplaceText return false if replace text is set to empty string', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.replaceString= ''; + + assert.ok(!testObject.hasReplaceString()); + }); + + test('Search Model: hasReplaceText return true if replace text is set to non empty string', function () { + let testObject:SearchModel= instantiationService.createInstance(SearchModel); + testObject.replaceString= 'some value'; + + assert.ok(testObject.hasReplaceString()); + }); + + function aRawMatch(resource: string, ...lineMatches: ILineMatch[]): IFileMatch { + return { resource: URI.parse(resource), lineMatches }; + } + + function aLineMatch(preview: string, lineNumber: number = 1, offsetAndLengths: number[][] = [[0, 1]]): ILineMatch { + return { preview, lineNumber, offsetAndLengths }; + } + + function stub(arg1, arg2, arg3) : sinon.SinonStub { + const stub= sinon.stub(arg1, arg2, arg3); + restoreStubs.push(stub); + return stub; + } + }); \ No newline at end of file diff --git a/src/vs/workbench/parts/search/test/common/searchResult.test.ts b/src/vs/workbench/parts/search/test/common/searchResult.test.ts new file mode 100644 index 00000000000..918185da691 --- /dev/null +++ b/src/vs/workbench/parts/search/test/common/searchResult.test.ts @@ -0,0 +1,276 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as sinon from 'sinon'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; +import { Match, FileMatch, SearchResult, SearchModel } from 'vs/workbench/parts/search/common/searchModel'; +import URI from 'vs/base/common/uri'; +import {IFileMatch, ILineMatch} from 'vs/platform/search/common/search'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { Range } from 'vs/editor/common/core/range'; +import { createMockModelService } from 'vs/test/utils/servicesTestUtils'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { IReplaceService } from 'vs/workbench/parts/search/common/replace'; + +suite('SearchResult', () => { + + let instantiationService: TestInstantiationService; + + setup(() => { + instantiationService= new TestInstantiationService(); + instantiationService.stub(ITelemetryService); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + }); + + test('Line Match', function () { + let fileMatch = aFileMatch('folder\\file.txt', null); + let lineMatch = new Match(fileMatch, 'foo bar', 1, 0, 3); + assert.equal(lineMatch.text(), 'foo bar'); + assert.equal(lineMatch.range().startLineNumber, 2); + assert.equal(lineMatch.range().endLineNumber, 2); + assert.equal(lineMatch.range().startColumn, 1); + assert.equal(lineMatch.range().endColumn, 4); + }); + + test('Line Match - Remove', function () { + let fileMatch = aFileMatch('folder\\file.txt', aSearchResult(), ...[{ + preview: 'foo bar', + lineNumber: 1, + offsetAndLengths: [[0, 3]] + }]); + let lineMatch = fileMatch.matches()[0]; + fileMatch.remove(lineMatch); + assert.equal(fileMatch.matches().length, 0); + }); + + test('File Match', function () { + let fileMatch = aFileMatch('folder\\file.txt'); + assert.equal(fileMatch.matches(), 0); + assert.equal(fileMatch.resource().toString(), 'file:///c%3A/folder/file.txt'); + assert.equal(fileMatch.name(), 'file.txt'); + + fileMatch = aFileMatch('file.txt'); + assert.equal(fileMatch.matches(), 0); + assert.equal(fileMatch.resource().toString(), 'file:///c%3A/file.txt'); + assert.equal(fileMatch.name(), 'file.txt'); + }); + + test('Alle Drei Zusammen', function () { + let searchResult = instantiationService.createInstance(SearchResult, null); + let fileMatch = aFileMatch('far\\boo', searchResult); + let lineMatch = new Match(fileMatch, 'foo bar', 1, 0, 3); + + assert(lineMatch.parent() === fileMatch); + assert(fileMatch.parent() === searchResult); + }); + + test('Adding a raw match will add a file match with line matches', function () { + let testObject = aSearchResult(); + let target= [aRawMatch('file://c:/', aLineMatch('preview 1', 1, [[1, 3], [4, 7]]), aLineMatch('preview 2'))]; + + testObject.add(target); + + assert.equal(3, testObject.count()); + + let actual= testObject.matches(); + assert.equal(1, actual.length); + assert.equal('file://c:/', actual[0].resource().toString()); + + let actuaMatches= actual[0].matches(); + assert.equal(3, actuaMatches.length); + + assert.equal('preview 1', actuaMatches[0].text()); + assert.ok(new Range(2, 2, 2, 5).equalsRange(actuaMatches[0].range())); + + assert.equal('preview 1', actuaMatches[1].text()); + assert.ok(new Range(2, 5, 2, 12).equalsRange(actuaMatches[1].range())); + + assert.equal('preview 2', actuaMatches[2].text()); + assert.ok(new Range(2, 1, 2, 2).equalsRange(actuaMatches[2].range())); + }); + + test('Adding multiple raw matches', function () { + let testObject = aSearchResult(); + let target= [aRawMatch('file://c:/1', aLineMatch('preview 1', 1, [[1, 3], [4, 7]])), aRawMatch('file://c:/2', aLineMatch('preview 2'))]; + + testObject.add(target); + + assert.equal(3, testObject.count()); + + let actual= testObject.matches(); + assert.equal(2, actual.length); + assert.equal('file://c:/1', actual[0].resource().toString()); + + let actuaMatches= actual[0].matches(); + assert.equal(2, actuaMatches.length); + assert.equal('preview 1', actuaMatches[0].text()); + assert.ok(new Range(2, 2, 2, 5).equalsRange(actuaMatches[0].range())); + assert.equal('preview 1', actuaMatches[1].text()); + assert.ok(new Range(2, 5, 2, 12).equalsRange(actuaMatches[1].range())); + + actuaMatches= actual[1].matches(); + assert.equal(1, actuaMatches.length); + assert.equal('preview 2', actuaMatches[0].text()); + assert.ok(new Range(2, 1, 2, 2).equalsRange(actuaMatches[0].range())); + }); + + test('Dispose disposes matches', function () { + let target1= sinon.spy(); + let target2= sinon.spy(); + + let testObject = aSearchResult(); + testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1')), aRawMatch('file://c:/2', aLineMatch('preview 2'))]); + + testObject.matches()[0].onDispose(target1); + testObject.matches()[1].onDispose(target2); + + testObject.dispose(); + + assert.ok(testObject.isEmpty()); + assert.ok(target1.calledOnce); + assert.ok(target2.calledOnce); + }); + + test('remove triggers change event', function () { + let target= sinon.spy(); + let testObject = aSearchResult(); + testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + let objectRoRemove= testObject.matches()[0]; + testObject.onChange(target); + + testObject.remove(objectRoRemove); + + assert.ok(target.calledOnce); + assert.deepEqual([{elements: [objectRoRemove], removed: true}], target.args[0]); + }); + + test('remove triggers change event', function () { + let target= sinon.spy(); + let testObject = aSearchResult(); + testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + let objectRoRemove= testObject.matches()[0]; + testObject.onChange(target); + + testObject.remove(objectRoRemove); + + assert.ok(target.calledOnce); + assert.deepEqual([{elements: [objectRoRemove], removed: true}], target.args[0]); + }); + + test('Removing all line matches and adding back will add file back to result', function () { + let testObject = aSearchResult(); + testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + let target= testObject.matches()[0]; + let matchToRemove= target.matches()[0]; + target.remove(matchToRemove); + + assert.ok(testObject.isEmpty()); + target.add(matchToRemove, true); + + assert.equal(1, testObject.fileCount()); + assert.equal(target, testObject.matches()[0]); + }); + + test('replace should remove the file match', function () { + instantiationService.stubPromise(IReplaceService, 'replace', null); + let testObject = aSearchResult(); + testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + + testObject.replace(testObject.matches()[0]); + + assert.ok(testObject.isEmpty()); + }); + + test('replace should trigger the change event', function () { + let target= sinon.spy(); + instantiationService.stubPromise(IReplaceService, 'replace', null); + let testObject = aSearchResult(); + testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1'))]); + testObject.onChange(target); + let objectRoRemove= testObject.matches()[0]; + + testObject.replace(objectRoRemove); + + assert.ok(target.calledOnce); + assert.deepEqual([{elements: [objectRoRemove], removed: true}], target.args[0]); + }); + + test('replaceAll should remove all file matches', function () { + instantiationService.stubPromise(IReplaceService, 'replace', null); + let testObject = aSearchResult(); + testObject.add([aRawMatch('file://c:/1', aLineMatch('preview 1')), aRawMatch('file://c:/2', aLineMatch('preview 2'))]); + + testObject.replaceAll(null); + + assert.ok(testObject.isEmpty()); + }); + + //// ----- utils + //function lineHasDecorations(model: editor.IModel, lineNumber: number, decorations: { start: number; end: number; }[]): void { + // let lineDecorations:typeof decorations = []; + // let decs = model.getLineDecorations(lineNumber); + // for (let i = 0, len = decs.length; i < len; i++) { + // lineDecorations.push({ + // start: decs[i].range.startColumn, + // end: decs[i].range.endColumn + // }); + // } + // assert.deepEqual(lineDecorations, decorations); + //} + // + //function lineHasNoDecoration(model: editor.IModel, lineNumber: number): void { + // lineHasDecorations(model, lineNumber, []); + //} + // + //function lineHasDecoration(model: editor.IModel, lineNumber: number, start: number, end: number): void { + // lineHasDecorations(model, lineNumber, [{ + // start: start, + // end: end + // }]); + //} + //// ----- end utils + // + //test('Model Highlights', function () { + // + // let fileMatch = instantiation.createInstance(FileMatch, null, toUri('folder\\file.txt')); + // fileMatch.add(new Match(fileMatch, 'line2', 1, 0, 2)); + // fileMatch.connect(); + // lineHasDecoration(oneModel, 2, 1, 3); + //}); + // + //test('Dispose', function () { + // + // let fileMatch = instantiation.createInstance(FileMatch, null, toUri('folder\\file.txt')); + // fileMatch.add(new Match(fileMatch, 'line2', 1, 0, 2)); + // fileMatch.connect(); + // lineHasDecoration(oneModel, 2, 1, 3); + // + // fileMatch.dispose(); + // lineHasNoDecoration(oneModel, 2); + //}); + + function aFileMatch(path: string, searchResult?: SearchResult, ...lineMatches: ILineMatch[]): FileMatch { + let rawMatch: IFileMatch = { + resource: URI.file('C:\\' + path), + lineMatches: lineMatches + }; + return instantiationService.createInstance(FileMatch, null, searchResult, rawMatch); + } + + function aSearchResult(): SearchResult { + let searchModel = instantiationService.createInstance(SearchModel); + return searchModel.searchResult; + } + + function aRawMatch(resource: string, ...lineMatches: ILineMatch[]): IFileMatch { + return { resource: URI.parse(resource), lineMatches }; + } + + function aLineMatch(preview: string, lineNumber: number = 1, offsetAndLengths: number[][] = [[0, 1]]): ILineMatch { + return { preview, lineNumber, offsetAndLengths }; + } +}); \ No newline at end of file diff --git a/src/vs/workbench/parts/terminal/electron-browser/media/terminal.css b/src/vs/workbench/parts/terminal/electron-browser/media/terminal.css index d31dc46deb5..d4696394a5f 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/media/terminal.css +++ b/src/vs/workbench/parts/terminal/electron-browser/media/terminal.css @@ -36,17 +36,6 @@ /* Light theme */ .monaco-workbench .terminal-action.kill { background: url('kill.svg') center center no-repeat; } .monaco-workbench .terminal-action.new { background: url('new.svg') center center no-repeat; } -/* Dark theme */ -.vs-dark .monaco-workbench .terminal-action.kill { background: url('kill-inverse.svg') center center no-repeat; } -.vs-dark .monaco-workbench .terminal-action.new { background: url('new-inverse.svg') center center no-repeat; } -/* High contrast black theme */ -.hc-black .monaco-workbench .terminal-action { background: none; } -.hc-black .monaco-workbench .terminal-action:before { - position: absolute; - top: 12px; - left: 8px; - height: 16px; - width: 16px; -} -.hc-black .monaco-workbench .terminal-action.kill:before { content: url('kill-inverse.svg'); } -.hc-black .monaco-workbench .terminal-action.new:before { content: url('new-inverse.svg'); } +/* Dark theme / HC theme */ +.vs-dark .monaco-workbench .terminal-action.kill, .hc-black .monaco-workbench .terminal-action.kill { background: url('kill-inverse.svg') center center no-repeat; } +.vs-dark .monaco-workbench .terminal-action.new, .hc-black .monaco-workbench .terminal-action.new { background: url('new-inverse.svg') center center no-repeat; } \ No newline at end of file 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 052cb0b9e8a..cb9789cf8bb 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.contribution.ts @@ -5,17 +5,19 @@ import 'vs/css!./media/terminal'; import 'vs/css!./media/xterm'; -import nls = require('vs/nls'); -import {KeyMod, KeyCode} from 'vs/base/common/keyCodes'; -import {SyncActionDescriptor} from 'vs/platform/actions/common/actions'; -import {registerSingleton} from 'vs/platform/instantiation/common/extensions'; -import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workbench/common/actionRegistry'; -import {TerminalService} from 'vs/workbench/parts/terminal/electron-browser/terminalService'; -import {KillTerminalAction, CreateNewTerminalAction, FocusTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, RunSelectedTextInTerminalAction, ToggleTerminalAction} from 'vs/workbench/parts/terminal/electron-browser/terminalActions'; -import {ITerminalService, TERMINAL_PANEL_ID, TERMINAL_DEFAULT_SHELL_LINUX, TERMINAL_DEFAULT_SHELL_OSX, TERMINAL_DEFAULT_SHELL_WINDOWS} from 'vs/workbench/parts/terminal/electron-browser/terminal'; import * as panel from 'vs/workbench/browser/panel'; -import {Registry} from 'vs/platform/platform'; +import * as platform from 'vs/base/common/platform'; +import nls = require('vs/nls'); import {Extensions, IConfigurationRegistry} from 'vs/platform/configuration/common/configurationRegistry'; +import {KbExpr} from 'vs/platform/keybinding/common/keybinding'; +import {ITerminalService, KEYBINDING_CONTEXT_TERMINAL_FOCUS, TERMINAL_PANEL_ID, TERMINAL_DEFAULT_SHELL_LINUX, TERMINAL_DEFAULT_SHELL_OSX, TERMINAL_DEFAULT_SHELL_WINDOWS} from 'vs/workbench/parts/terminal/electron-browser/terminal'; +import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workbench/common/actionRegistry'; +import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; +import {KillTerminalAction, CopyTerminalSelectionAction, CreateNewTerminalAction, FocusTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, RunSelectedTextInTerminalAction, TerminalPasteAction, ToggleTerminalAction} from 'vs/workbench/parts/terminal/electron-browser/terminalActions'; +import {Registry} from 'vs/platform/platform'; +import {SyncActionDescriptor} from 'vs/platform/actions/common/actions'; +import {TerminalService} from 'vs/workbench/parts/terminal/electron-browser/terminalService'; +import {registerSingleton} from 'vs/platform/instantiation/common/extensions'; let configurationRegistry = Registry.as(Extensions.Configuration); configurationRegistry.registerConfiguration({ @@ -73,6 +75,16 @@ configurationRegistry.registerConfiguration({ 'description': nls.localize('terminal.integrated.lineHeight', "Controls the line height of the terminal, this defaults to normal."), 'type': 'number', 'default': 0 + }, + 'terminal.integrated.cursorBlinking': { + 'description': nls.localize('terminal.integrated.cursorBlinking', "Controls whether the terminal cursor blinks."), + 'type': 'boolean', + 'default': true + }, + 'terminal.integrated.setLocaleVariables': { + 'description': nls.localize('terminal.integrated.setLocaleVariables', "Controls whether locale variables are set at startup of the terminal, this defaults to true on OS X, false on other platforms."), + 'type': 'boolean', + 'default': platform.isMacintosh } } }); @@ -90,6 +102,9 @@ registerSingleton(ITerminalService, TerminalService); // On mac cmd+` is reserved to cycle between windows, that's why the keybindings use WinCtrl let actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(KillTerminalAction, KillTerminalAction.ID, KillTerminalAction.LABEL), KillTerminalAction.LABEL); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C +}, KbExpr.and(KbExpr.has(KEYBINDING_CONTEXT_TERMINAL_FOCUS))), CopyTerminalSelectionAction.LABEL); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_BACKTICK, mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.US_BACKTICK } @@ -97,6 +112,9 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewTermina actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalAction, FocusTerminalAction.ID, FocusTerminalAction.LABEL), FocusTerminalAction.LABEL); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextTerminalAction, FocusNextTerminalAction.ID, FocusNextTerminalAction.LABEL), KillTerminalAction.LABEL); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousTerminalAction, FocusPreviousTerminalAction.ID, FocusPreviousTerminalAction.LABEL), KillTerminalAction.LABEL); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TerminalPasteAction, TerminalPasteAction.ID, TerminalPasteAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V +}, KbExpr.and(KbExpr.has(KEYBINDING_CONTEXT_TERMINAL_FOCUS))), CopyTerminalSelectionAction.LABEL); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunSelectedTextInTerminalAction, RunSelectedTextInTerminalAction.ID, RunSelectedTextInTerminalAction.LABEL), RunSelectedTextInTerminalAction.LABEL); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleTerminalAction, ToggleTerminalAction.ID, ToggleTerminalAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.US_BACKTICK, diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminal.ts b/src/vs/workbench/parts/terminal/electron-browser/terminal.ts index 92f4198fc1e..b7054c55728 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminal.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminal.ts @@ -20,6 +20,11 @@ export const TERMINAL_DEFAULT_SHELL_LINUX = !platform.isWindows ? (process.env.S export const TERMINAL_DEFAULT_SHELL_OSX = !platform.isWindows ? (process.env.SHELL || 'sh') : 'sh'; export const TERMINAL_DEFAULT_SHELL_WINDOWS = processes.getWindowsShell(); +/** + * A context key that is set when the integrated terminal has focus. + */ +export const KEYBINDING_CONTEXT_TERMINAL_FOCUS = 'terminalFocus'; + export var ITerminalService = createDecorator(TERMINAL_SERVICE_ID); export interface ITerminalConfiguration { @@ -34,10 +39,12 @@ export interface ITerminalConfiguration { linux: string[], osx: string[] }, + cursorBlinking: boolean, fontFamily: string, fontLigatures: boolean, fontSize: number, - lineHeight: number + lineHeight: number, + setLocaleVariables: boolean } }; } @@ -54,11 +61,13 @@ export interface ITerminalService { onInstanceTitleChanged: Event; close(): TPromise; + copySelection(): TPromise; createNew(): TPromise; focus(): TPromise; focusNext(): TPromise; focusPrevious(): TPromise; hide(): TPromise; + paste(): TPromise; runSelectedText(): TPromise; setActiveTerminal(index: number): TPromise; toggle(): TPromise; diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts index 56b9b719051..a8354dfb803 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalActions.ts @@ -45,6 +45,27 @@ export class KillTerminalAction extends Action { } } +/** + * Copies the terminal selection. Note that since the command palette takes focus from the terminal, + * this can only be triggered via a keybinding. + */ +export class CopyTerminalSelectionAction extends Action { + + public static ID = 'workbench.action.terminal.copySelection'; + public static LABEL = nls.localize('workbench.action.terminal.copySelection', "Terminal: Copy Selection"); + + constructor( + id: string, label: string, + @ITerminalService private terminalService: ITerminalService + ) { + super(id, label); + } + + public run(event?: any): TPromise { + return this.terminalService.copySelection(); + } +} + export class CreateNewTerminalAction extends Action { public static ID = 'workbench.action.terminal.new'; @@ -114,6 +135,22 @@ export class FocusPreviousTerminalAction extends Action { return this.terminalService.focusPrevious(); } } +export class TerminalPasteAction extends Action { + + public static ID = 'workbench.action.terminal.paste'; + public static LABEL = nls.localize('workbench.action.terminal.paste', "Terminal: Paste into Active Terminal"); + + constructor( + id: string, label: string, + @ITerminalService private terminalService: ITerminalService + ) { + super(id, label); + } + + public run(event?: any): TPromise { + return this.terminalService.paste(); + } +} export class RunSelectedTextInTerminalAction extends Action { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts index 896f2d574b5..81da5d941a9 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts @@ -8,6 +8,7 @@ import {IConfiguration} from 'vs/editor/common/config/defaultConfig'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {ITerminalConfiguration} from 'vs/workbench/parts/terminal/electron-browser/terminal'; import {Builder} from 'vs/base/browser/builder'; +import {DefaultConfig} from 'vs/editor/common/config/defaultConfig'; const DEFAULT_ANSI_COLORS = { 'hc-black': [ @@ -130,18 +131,22 @@ export class TerminalConfigHelper { let fontFamily = terminalConfig.fontFamily || editorConfig.editor.fontFamily; let fontSize = this.toInteger(terminalConfig.fontSize, 0) || editorConfig.editor.fontSize; + if (fontSize <= 0) { + fontSize = DefaultConfig.editor.fontSize; + } let lineHeight = this.toInteger(terminalConfig.lineHeight, 0); return this.measureFont(fontFamily, fontSize + 'px', lineHeight === 0 ? 'normal' : lineHeight + 'px'); } public getFontLigaturesEnabled(): boolean { - return this.configurationService.getConfiguration().terminal.integrated.fontLigatures; + let terminalConfig = this.configurationService.getConfiguration().terminal.integrated; + return terminalConfig.fontLigatures; } public getCursorBlink(): boolean { - let editorConfig = this.configurationService.getConfiguration(); - return editorConfig.editor.cursorBlinking === 'blink'; + let terminalConfig = this.configurationService.getConfiguration().terminal.integrated; + return terminalConfig.cursorBlinking; } public getShell(): IShell { @@ -162,6 +167,11 @@ export class TerminalConfigHelper { return shell; } + public isSetLocaleVariables() { + let config = this.configurationService.getConfiguration(); + return config.terminal.integrated.setLocaleVariables; + } + private toInteger(source: any, minimum?: number): number { let r = parseInt(source, 10); if (isNaN(r)) { diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 4f99d11e8cd..1efa2680a57 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -6,15 +6,20 @@ import DOM = require('vs/base/browser/dom'); import lifecycle = require('vs/base/common/lifecycle'); import nls = require('vs/nls'); +import os = require('os'); import platform = require('vs/base/common/platform'); import xterm = require('xterm'); import {Dimension} from 'vs/base/browser/builder'; +import {IKeybindingContextKey} from 'vs/platform/keybinding/common/keybinding'; import {IMessageService, Severity} from 'vs/platform/message/common/message'; import {ITerminalFont} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper'; import {ITerminalProcess, ITerminalService} from 'vs/workbench/parts/terminal/electron-browser/terminal'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; export class TerminalInstance { + + private static eolRegex = /\r?\n/g; + private isExiting: boolean = false; private toDispose: lifecycle.IDisposable[]; @@ -29,6 +34,7 @@ export class TerminalInstance { private contextService: IWorkspaceContextService, private terminalService: ITerminalService, private messageService: IMessageService, + private terminalFocusContextKey: IKeybindingContextKey, private onExitCallback: (TerminalInstance) => void ) { this.toDispose = []; @@ -45,7 +51,7 @@ export class TerminalInstance { this.xterm.on('data', (data) => { this.terminalProcess.process.send({ event: 'input', - data: data + data: this.sanitizeInput(data) }); return false; }); @@ -80,10 +86,23 @@ export class TerminalInstance { })); this.xterm.open(this.terminalDomElement); + + let self = this; + this.toDispose.push(DOM.addDisposableListener(this.xterm.element, 'focus', (event: KeyboardEvent) => { + self.terminalFocusContextKey.set(true); + })); + this.toDispose.push(DOM.addDisposableListener(this.xterm.element, 'blur', (event: KeyboardEvent) => { + self.terminalFocusContextKey.reset(); + })); + this.wrapperElement.appendChild(this.terminalDomElement); this.parentDomElement.appendChild(this.wrapperElement); } + private sanitizeInput(data: any) { + return typeof data === 'string' ? data.replace(TerminalInstance.eolRegex, os.EOL) : data; + } + public layout(dimension: Dimension): void { if (!this.font || !this.font.charWidth || !this.font.charHeight) { return; diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts index 0bfc113bc0f..091b33543b2 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts @@ -12,6 +12,7 @@ import {Builder, Dimension} from 'vs/base/browser/builder'; import {KillTerminalAction, CreateNewTerminalAction, SwitchTerminalInstanceAction, SwitchTerminalInstanceActionItem} from 'vs/workbench/parts/terminal/electron-browser/terminalActions'; import {IActionItem} from 'vs/base/browser/ui/actionbar/actionbar'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; +import {IKeybindingContextKey} from 'vs/platform/keybinding/common/keybinding'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IMessageService} from 'vs/platform/message/common/message'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; @@ -98,8 +99,8 @@ export class TerminalPanel extends Panel { return this.terminalService.createNew(); } - public createNewTerminalInstance(terminalProcess: ITerminalProcess): TPromise { - return this.createTerminal(terminalProcess).then(() => { + public createNewTerminalInstance(terminalProcess: ITerminalProcess, terminalFocusContextKey: IKeybindingContextKey): TPromise { + return this.createTerminal(terminalProcess, terminalFocusContextKey).then(() => { this.updateConfig(); this.focus(); }); @@ -130,9 +131,9 @@ export class TerminalPanel extends Panel { return super.setVisible(visible); } - private createTerminal(terminalProcess: ITerminalProcess): TPromise { + private createTerminal(terminalProcess: ITerminalProcess, terminalFocusContextKey: IKeybindingContextKey): TPromise { return new TPromise(resolve => { - var terminalInstance = new TerminalInstance(terminalProcess, this.terminalContainer, this.contextService, this.terminalService, this.messageService, this.onTerminalInstanceExit.bind(this)); + var terminalInstance = new TerminalInstance(terminalProcess, this.terminalContainer, this.contextService, this.terminalService, this.messageService, terminalFocusContextKey, this.onTerminalInstanceExit.bind(this)); this.terminalInstances.push(terminalInstance); this.setActiveTerminal(this.terminalInstances.length - 1); this.toDispose.push(this.themeService.onDidThemeChange(this.updateTheme.bind(this))); diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalProcess.js b/src/vs/workbench/parts/terminal/electron-browser/terminalProcess.js index 138b671def3..21c47a26878 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalProcess.js +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalProcess.js @@ -63,7 +63,7 @@ function getArgs() { function cleanEnv() { var keys = [ - 'ELECTRON_RUN_AS_NODE', + 'ATOM_SHELL_INTERNAL_RUN_AS_NODE', 'PTYCWD', 'PTYPID', 'PTYSHELL' diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts index e7e09a3e86f..42dc3514f76 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalService.ts @@ -6,6 +6,7 @@ import URI from 'vs/base/common/uri'; import Event, {Emitter} from 'vs/base/common/event'; import cp = require('child_process'); +import nls = require('vs/nls'); import os = require('os'); import path = require('path'); import platform = require('vs/base/common/platform'); @@ -13,13 +14,15 @@ import {Builder} from 'vs/base/browser/builder'; import {EndOfLinePreference} from 'vs/editor/common/editorCommon'; import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; +import {IKeybindingContextKey, IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; +import {IMessageService, Severity} from 'vs/platform/message/common/message'; import {IPanelService} from 'vs/workbench/services/panel/common/panelService'; import {IPartService} from 'vs/workbench/services/part/common/partService'; import {IStringDictionary} from 'vs/base/common/collections'; -import {ITerminalProcess, ITerminalService, TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/electron-browser/terminal'; -import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; +import {ITerminalProcess, ITerminalService, KEYBINDING_CONTEXT_TERMINAL_FOCUS, TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/electron-browser/terminal'; +import {IWorkspaceContextService, IWorkspace} from 'vs/platform/workspace/common/workspace'; import {TPromise} from 'vs/base/common/winjs.base'; -import {TerminalConfigHelper} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper'; +import {TerminalConfigHelper, IShell} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper'; import {TerminalPanel} from 'vs/workbench/parts/terminal/electron-browser/terminalPanel'; export class TerminalService implements ITerminalService { @@ -27,6 +30,7 @@ export class TerminalService implements ITerminalService { private activeTerminalIndex: number = 0; private terminalProcesses: ITerminalProcess[] = []; + protected _terminalFocusContextKey: IKeybindingContextKey; private configHelper: TerminalConfigHelper; private _onActiveInstanceChanged: Emitter; @@ -36,6 +40,8 @@ export class TerminalService implements ITerminalService { constructor( @ICodeEditorService private codeEditorService: ICodeEditorService, @IConfigurationService private configurationService: IConfigurationService, + @IKeybindingService private keybindingService: IKeybindingService, + @IMessageService private messageService: IMessageService, @IPanelService private panelService: IPanelService, @IPartService private partService: IPartService, @IWorkspaceContextService private contextService: IWorkspaceContextService @@ -43,6 +49,7 @@ export class TerminalService implements ITerminalService { this._onActiveInstanceChanged = new Emitter(); this._onInstancesChanged = new Emitter(); this._onInstanceTitleChanged = new Emitter(); + this._terminalFocusContextKey = this.keybindingService.createKey(KEYBINDING_CONTEXT_TERMINAL_FOCUS, undefined); } public get onActiveInstanceChanged(): Event { @@ -160,7 +167,7 @@ export class TerminalService implements ITerminalService { } self.initConfigHelper(terminalPanel.getContainer()); - terminalPanel.createNewTerminalInstance(self.createTerminalProcess()); + terminalPanel.createNewTerminalInstance(self.createTerminalProcess(), this._terminalFocusContextKey); self._onInstancesChanged.fire(); return TPromise.as(void 0); }); @@ -172,6 +179,21 @@ export class TerminalService implements ITerminalService { }); } + public copySelection(): TPromise { + if (document.activeElement.classList.contains('xterm')) { + document.execCommand('copy'); + } else { + this.messageService.show(Severity.Warning, nls.localize('terminal.integrated.copySelection.noSelection', 'Cannot copy terminal selection when terminal does not have focus')); + } + return TPromise.as(void 0); + } + + public paste(): TPromise { + return this.showAndGetTerminalPanel().then((terminalPanel) => { + document.execCommand('paste'); + }); + } + private showAndGetTerminalPanel(): TPromise { return new TPromise((complete) => { let panel = this.panelService.getActivePanel(); @@ -222,14 +244,8 @@ export class TerminalService implements ITerminalService { } private createTerminalProcess(): ITerminalProcess { - let env = this.cloneEnv(); - let shell = this.configHelper.getShell(); - env['PTYPID'] = process.pid.toString(); - env['PTYSHELL'] = shell.executable; - shell.args.forEach((arg, i) => { - env[`PTYSHELLARG${i}`] = arg; - }); - env['PTYCWD'] = this.contextService.getWorkspace() ? this.contextService.getWorkspace().resource.fsPath : os.homedir(); + let locale = this.configHelper.isSetLocaleVariables() ? platform.locale : undefined; + let env = TerminalService.createTerminalEnv(process.env, this.configHelper.getShell(), this.contextService.getWorkspace(), locale); let terminalProcess = { title: '', process: cp.fork('./terminalProcess', [], { @@ -250,11 +266,34 @@ export class TerminalService implements ITerminalService { return terminalProcess; } - private cloneEnv(): IStringDictionary { + public static createTerminalEnv(parentEnv: IStringDictionary, shell: IShell, workspace: IWorkspace, locale?: string): IStringDictionary { + let env = this.cloneEnv(parentEnv); + env['PTYPID'] = process.pid.toString(); + env['PTYSHELL'] = shell.executable; + shell.args.forEach((arg, i) => { + env[`PTYSHELLARG${i}`] = arg; + }); + env['PTYCWD'] = workspace ? workspace.resource.fsPath : os.homedir(); + if (locale) { + env['LANG'] = this.getLangEnvVariable(locale); + } + return env; + } + + private static cloneEnv(env: IStringDictionary): IStringDictionary { let newEnv: IStringDictionary = Object.create(null); - Object.keys(process.env).forEach((key) => { - newEnv[key] = process.env[key]; + Object.keys(env).forEach((key) => { + newEnv[key] = env[key]; }); return newEnv; } + + private static getLangEnvVariable(locale: string) { + const parts = locale.split('-'); + const n = parts.length; + if (n > 1) { + parts[n - 1] = parts[n - 1].toUpperCase(); + } + return parts.join('_') + '.UTF-8'; + } } \ No newline at end of file diff --git a/src/vs/workbench/parts/terminal/test/terminalConfigHelper.test.ts b/src/vs/workbench/parts/terminal/test/terminalConfigHelper.test.ts index 829e5319699..db60dc9027d 100644 --- a/src/vs/workbench/parts/terminal/test/terminalConfigHelper.test.ts +++ b/src/vs/workbench/parts/terminal/test/terminalConfigHelper.test.ts @@ -11,6 +11,7 @@ import {IConfigurationService} from 'vs/platform/configuration/common/configurat import {Platform} from 'vs/base/common/platform'; import {TPromise} from 'vs/base/common/winjs.base'; import {TerminalConfigHelper} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper'; +import {DefaultConfig} from 'vs/editor/common/config/defaultConfig'; class MockConfigurationService implements IConfigurationService { @@ -30,7 +31,7 @@ suite('Workbench - TerminalConfigHelper', () => { fixture = new Builder(document.body, false); }); - test('TerminalConfigHelper - getFont', function () { + test('TerminalConfigHelper - getFont fontFamily', function () { let configurationService: IConfigurationService; let configHelper: TerminalConfigHelper; @@ -59,6 +60,11 @@ suite('Workbench - TerminalConfigHelper', () => { }); configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, fixture); assert.equal(configHelper.getFont().fontFamily, 'foo', 'editor.fontFamily should be the fallback when terminal.integrated.fontFamily not set'); + }); + + test('TerminalConfigHelper - getFont fontSize', function () { + let configurationService: IConfigurationService; + let configHelper: TerminalConfigHelper; configurationService = new MockConfigurationService({ editor: { @@ -90,6 +96,41 @@ suite('Workbench - TerminalConfigHelper', () => { configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, fixture); assert.equal(configHelper.getFont().fontSize, '1px', 'editor.fontSize should be the fallback when terminal.integrated.fontSize not set'); + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo', + fontSize: 0 + }, + terminal: { + integrated: { + fontFamily: 0, + fontSize: 0 + } + } + }); + configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, fixture); + assert.equal(configHelper.getFont().fontSize, `${DefaultConfig.editor.fontSize}px`, 'The default editor font size should be used when editor.fontSize is 0 and terminal.integrated.fontSize not set'); + + configurationService = new MockConfigurationService({ + editor: { + fontFamily: 'foo', + fontSize: 0 + }, + terminal: { + integrated: { + fontFamily: 0, + fontSize: -10 + } + } + }); + configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, fixture); + assert.equal(configHelper.getFont().fontSize, `${DefaultConfig.editor.fontSize}px`, 'The default editor font size should be used when editor.fontSize is < 0 and terminal.integrated.fontSize not set'); + }); + + test('TerminalConfigHelper - getFont lineHeight', function () { + let configurationService: IConfigurationService; + let configHelper: TerminalConfigHelper; + configurationService = new MockConfigurationService({ editor: { fontFamily: 'foo', diff --git a/src/vs/workbench/parts/terminal/test/terminalService.test.ts b/src/vs/workbench/parts/terminal/test/terminalService.test.ts new file mode 100644 index 00000000000..698287b007d --- /dev/null +++ b/src/vs/workbench/parts/terminal/test/terminalService.test.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 * as assert from 'assert'; +import * as os from 'os'; +import {IStringDictionary} from 'vs/base/common/collections'; +import {IWorkspace} from 'vs/platform/workspace/common/workspace'; +import {TerminalService} from 'vs/workbench/parts/terminal/electron-browser/terminalService'; + + +suite('Workbench - TerminalService', () => { + + test('TerminalService - createTerminalEnv', function () { + const shell1 = { + executable: '/bin/foosh', + args: ['-bar', 'baz'] + }; + const parentEnv1: IStringDictionary = { + ok: true + }; + const env1 = TerminalService.createTerminalEnv(parentEnv1, shell1, null, 'en-au'); + assert.ok(env1['ok'], 'Parent environment is copied'); + assert.deepStrictEqual(parentEnv1, { ok: true }, 'Parent environment is unchanged'); + assert.equal(env1['PTYPID'], process.pid.toString(), 'PTYPID is equal to the current PID'); + assert.equal(env1['PTYSHELL'], '/bin/foosh', 'PTYSHELL is equal to the requested shell'); + assert.equal(env1['PTYSHELLARG0'], '-bar', 'PTYSHELLARG0 is equal to the first shell argument'); + assert.equal(env1['PTYSHELLARG1'], 'baz', 'PTYSHELLARG1 is equal to the first shell argument'); + assert.ok(!('PTYSHELLARG2' in env1), 'PTYSHELLARG2 is unset'); + assert.equal(env1['PTYCWD'], os.homedir(), 'PTYCWD is equal to the home folder'); + assert.equal(env1['LANG'], 'en_AU.UTF-8', 'LANG is equal to the requested locale with UTF-8'); + + const shell2 = { + executable: '/bin/foosh', + args: [] + }; + const parentEnv2: IStringDictionary = { + LANG: 'en_US.UTF-8' + }; + const workspace2: IWorkspace = { + resource: { + fsPath: '/my/dev/folder' + } + }; + const env2 = TerminalService.createTerminalEnv(parentEnv2, shell2, workspace2, 'en-au'); + assert.ok(!('PTYSHELLARG0' in env2), 'PTYSHELLARG0 is unset'); + assert.equal(env2['PTYCWD'], '/my/dev/folder', 'PTYCWD is equal to the workspace folder'); + assert.equal(env2['LANG'], 'en_AU.UTF-8', 'LANG is equal to the requested locale with UTF-8'); + + const env3 = TerminalService.createTerminalEnv(parentEnv1, shell1, null, null); + assert.ok(!('LANG' in env3), 'LANG is unset'); + + const env4 = TerminalService.createTerminalEnv(parentEnv2, shell1, null, null); + assert.equal(env4['LANG'], 'en_US.UTF-8', 'LANG is equal to the parent environment\'s LANG'); + }); +}); \ No newline at end of file diff --git a/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts b/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts index de2dfa81f88..e046e3758d4 100644 --- a/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts +++ b/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts @@ -2,24 +2,29 @@ * 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 nls = require('vs/nls'); -import winjs = require('vs/base/common/winjs.base'); -import actions = require('vs/base/common/actions'); +import {localize} from 'vs/nls'; +import {TPromise} from 'vs/base/common/winjs.base'; +import {Action} from 'vs/base/common/actions'; +import {firstIndex} from 'vs/base/common/arrays'; import {SyncActionDescriptor} from 'vs/platform/actions/common/actions'; import {IMessageService, Severity} from 'vs/platform/message/common/message'; -import platform = require('vs/platform/platform'); -import workbenchActionRegistry = require('vs/workbench/common/actionRegistry'); +import {Registry} from 'vs/platform/platform'; +import {IWorkbenchActionRegistry, Extensions} from 'vs/workbench/common/actionRegistry'; import {IQuickOpenService, IPickOpenEntry} from 'vs/workbench/services/quickopen/common/quickOpenService'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {IThemeService} from 'vs/workbench/services/themes/common/themeService'; -import {RunOnceScheduler} from 'vs/base/common/async'; +import {VIEWLET_ID, IExtensionsViewlet} from 'vs/workbench/parts/extensions/electron-browser/extensions'; +import {IExtensionGalleryService} from 'vs/platform/extensionManagement/common/extensionManagement'; +import {IViewletService} from 'vs/workbench/services/viewlet/common/viewletService'; +import {Delayer} from 'vs/base/common/async'; -class SelectThemeAction extends actions.Action { +class SelectThemeAction extends Action { - public static ID = 'workbench.action.selectTheme'; - public static LABEL = nls.localize('selectTheme.label', "Color Theme"); + static ID = 'workbench.action.selectTheme'; + static LABEL = localize('selectTheme.label', "Color Theme"); constructor( id: string, @@ -27,60 +32,60 @@ class SelectThemeAction extends actions.Action { @IWorkspaceContextService private contextService: IWorkspaceContextService, @IQuickOpenService private quickOpenService: IQuickOpenService, @IMessageService private messageService: IMessageService, - @IThemeService private themeService: IThemeService + @IThemeService private themeService: IThemeService, + @IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService, + @IViewletService private viewletService: IViewletService ) { super(id, label); } - public run(): winjs.TPromise { + run(): TPromise { + return this.themeService.getThemes().then(themes => { + const currentThemeId = this.themeService.getTheme(); + const currentTheme = themes.filter(theme => theme.id === currentThemeId)[0]; - return this.themeService.getThemes().then(contributedThemes => { - let currentTheme = this.themeService.getTheme(); + const picks: IPickOpenEntry[] = themes + .map(theme => ({ id: theme.id, label: theme.label, description: theme.description })) + .sort((t1, t2) => t1.label.localeCompare(t2.label)); - let picks: IPickOpenEntry[] = []; - - contributedThemes.forEach(theme => { - picks.push({ id: theme.id, label: theme.label, description: theme.description }); - contributedThemes[theme.id] = theme; - }); - - picks = picks.sort((t1, t2) => t1.label.localeCompare(t2.label)); - - let selectedPickIndex: number; - picks.forEach((p, index) => { - if (p.id === currentTheme) { - selectedPickIndex = index; - } - }); - - let selectTheme = (pick, broadcast) => { - if (pick) { - let themeId = pick.id; - this.themeService.setTheme(themeId, broadcast).then(null, error => { - this.messageService.show(Severity.Info, nls.localize('problemChangingTheme', "Problem loading theme: {0}", error.message)); - }); - } else { - this.themeService.setTheme(currentTheme, broadcast); - } + const selectTheme = (theme, broadcast) => { + this.themeService.setTheme(theme.id, broadcast) + .done(null, err => this.messageService.show(Severity.Info, localize('problemChangingTheme', "Problem loading theme: {0}", err.message))); }; - let themeToPreview : IPickOpenEntry = null; - let previewThemeScheduler = new RunOnceScheduler(() => { - selectTheme(themeToPreview, false); - }, 100); - let previewTheme = pick => { - themeToPreview = pick; - previewThemeScheduler.schedule(); - }; - let pickTheme = pick => { - previewThemeScheduler.dispose(); - selectTheme(pick, true); - }; - return this.quickOpenService.pick(picks, { placeHolder: nls.localize('themes.selectTheme', "Select Color Theme"), autoFocus: { autoFocusIndex: selectedPickIndex } }).then(pickTheme, null, previewTheme); + const placeHolder = localize('themes.selectTheme', "Select Color Theme"); + const autoFocusIndex = firstIndex(picks, p => p.id === currentThemeId); + const delayer = new Delayer(100); + + if (this.extensionGalleryService.isEnabled()) { + const run = () => { + return this.viewletService.openViewlet(VIEWLET_ID, true) + .then(viewlet => viewlet as IExtensionsViewlet) + .then(viewlet => { + viewlet.search('category:themes', true); + viewlet.focus(); + }); + }; + + picks.push({ + id: 'themes.findmore', + label: localize('findMore', "Find more in the Marketplace..."), + separator: { border: true }, + alwaysShow: true, + run + }); + } + + return this.quickOpenService.pick(picks, { placeHolder, autoFocus: { autoFocusIndex }}) + .then( + theme => delayer.trigger(() => selectTheme(theme || currentTheme, true), 0), + null, + theme => delayer.trigger(() => selectTheme(theme, false)) + ); }); } } -const category = nls.localize('preferences', "Preferences"); -let workbenchActionsRegistry = platform.Registry.as(workbenchActionRegistry.Extensions.WorkbenchActions); -workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectThemeAction, SelectThemeAction.ID, SelectThemeAction.LABEL), 'Preferences: Color Theme', category); +const category = localize('preferences', "Preferences"); +const descriptor = new SyncActionDescriptor(SelectThemeAction, SelectThemeAction.ID, SelectThemeAction.LABEL); +Registry.as(Extensions.WorkbenchActions).registerWorkbenchAction(descriptor, 'Preferences: Color Theme', category); diff --git a/src/vs/workbench/parts/welcome/test/common/gettingStarted.test.ts b/src/vs/workbench/parts/welcome/test/common/gettingStarted.test.ts index 894c0c7aecd..3e57cf0d786 100644 --- a/src/vs/workbench/parts/welcome/test/common/gettingStarted.test.ts +++ b/src/vs/workbench/parts/welcome/test/common/gettingStarted.test.ts @@ -6,14 +6,11 @@ 'use strict'; import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {AbstractGettingStarted} from 'vs/workbench/parts/welcome/common/abstractGettingStarted'; -import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IStorageService} from 'vs/platform/storage/common/storage'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; -import {TPromise} from 'vs/base/common/winjs.base'; class TestGettingStarted extends AbstractGettingStarted { public lastUrl: string; @@ -24,15 +21,15 @@ class TestGettingStarted extends AbstractGettingStarted { } suite('Workbench - GettingStarted', () => { - let instantiation: IInstantiationService = null; + let instantiation: TestInstantiationService = null; let welcomePageEnvConfig: string = null; let hideWelcomeSettingsValue: string = null; let machineId: string = null; let appName: string = null; suiteSetup(() => { - let services = new ServiceCollection(); - services.set(IWorkspaceContextService, { + instantiation = new TestInstantiationService(); + instantiation.stub(IWorkspaceContextService, { getConfiguration: () => { return { env: { @@ -42,14 +39,10 @@ suite('Workbench - GettingStarted', () => { }; } }); - services.set(ITelemetryService, { - getTelemetryInfo: () => TPromise.as({ machineId: machineId }) - }); - services.set(IStorageService, { + instantiation.stub(IStorageService, { get: () => hideWelcomeSettingsValue, store: (value) => hideWelcomeSettingsValue = value }); - instantiation = new InstantiationService(services); }); suiteTeardown(() => { @@ -71,6 +64,7 @@ suite('Workbench - GettingStarted', () => { welcomePageEnvConfig = 'base url'; appName = 'some app'; machineId = '123'; + instantiation.stubPromise(ITelemetryService, 'getTelemetryInfo', { machineId: machineId }); let gettingStarted = instantiation.createInstance(TestGettingStarted); assert(gettingStarted.lastUrl === `${welcomePageEnvConfig}&&from=${appName}&&id=${machineId}`, 'a page is opened when welcomePage is configured && first run'); assert(hideWelcomeSettingsValue !== null, 'a flag is set to hide welcome page'); diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 618d7ebee05..3ba2dc65fc4 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -15,7 +15,7 @@ import {BaseTextEditor} from 'vs/workbench/browser/parts/editor/textEditor'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IHistoryService} from 'vs/workbench/services/history/common/history'; import {Selection} from 'vs/editor/common/core/selection'; -import {Position, IEditorInput, ITextEditorOptions} from 'vs/platform/editor/common/editor'; +import {IEditorInput, ITextEditorOptions} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; @@ -311,8 +311,15 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic private navigate(): void { let state = this.stack[this.index]; + let options = state.options; + if (options) { + options.revealIfOpened = true; + } else { + options = { revealIfOpened: true }; + } + this.blockStackChanges = true; - this.editorService.openEditor(state.input, state.options, this.findVisibleEditorPosition(state.input)).done(() => { + this.editorService.openEditor(state.input, options).done(() => { this.blockStackChanges = false; }, (error) => { this.blockStackChanges = false; @@ -320,23 +327,6 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic }); } - private findVisibleEditorPosition(input: IEditorInput): Position { - let activeEditor = this.editorService.getActiveEditor(); - if (activeEditor && input.matches(activeEditor.input)) { - return activeEditor.position; - } - - let editors = this.editorService.getVisibleEditors(); - for (let i = 0; i < editors.length; i++) { - let editor = editors[i]; - if (editor !== activeEditor && input.matches(editor.input)) { - return editor.position; - } - } - - return null; - } - protected handleEditorSelectionChangeEvent(editor?: IBaseEditor): void { this.handleEditorEventInStack(editor, true); } diff --git a/src/vs/workbench/services/quickopen/common/quickOpenService.ts b/src/vs/workbench/services/quickopen/common/quickOpenService.ts index 1adade277c0..5bdda84a0ca 100644 --- a/src/vs/workbench/services/quickopen/common/quickOpenService.ts +++ b/src/vs/workbench/services/quickopen/common/quickOpenService.ts @@ -15,6 +15,7 @@ export interface IPickOpenEntry { description?: string; detail?: string; separator?: ISeparator; + alwaysShow?: boolean; run?: (context: IEntryRunContext) => void; } diff --git a/src/vs/workbench/test/browser/part.test.ts b/src/vs/workbench/test/browser/part.test.ts index 7190431e047..e8a83e1964d 100644 --- a/src/vs/workbench/test/browser/part.test.ts +++ b/src/vs/workbench/test/browser/part.test.ts @@ -9,7 +9,7 @@ import * as assert from 'assert'; import {Build, Builder} from 'vs/base/browser/builder'; import {Part} from 'vs/workbench/browser/part'; import * as Types from 'vs/base/common/types'; -import * as TestUtils from 'vs/workbench/test/common/servicesTestUtils'; +import * as TestUtils from 'vs/test/utils/servicesTestUtils'; import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {IStorageService} from 'vs/platform/storage/common/storage'; diff --git a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts index d3251f6aa4b..d97d2ca2622 100644 --- a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts @@ -8,8 +8,8 @@ import * as assert from 'assert'; import {BaseEditor, EditorInputAction, EditorInputActionContributor, EditorDescriptor} from 'vs/workbench/browser/parts/editor/baseEditor'; import {EditorInput, EditorOptions, Extensions, IEditorRegistry, IEditorInputFactory} from 'vs/workbench/common/editor'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; import * as Platform from 'vs/platform/platform'; import {SyncDescriptor} from 'vs/platform/instantiation/common/descriptors'; import {StringEditorInput} from 'vs/workbench/common/editor/stringEditorInput'; @@ -190,7 +190,7 @@ suite('Workbench BaseEditor', () => { EditorRegistry.registerEditor(d2, new SyncDescriptor(StringEditorInput)); EditorRegistry.registerEditor(d1, new SyncDescriptor(MyStringInput)); - let inst = new InstantiationService(); + let inst = new TestInstantiationService(); inst.createInstance(EditorRegistry.getEditor(inst.createInstance(MyStringInput, 'fake', '', '', mime.MIME_TEXT, false)), 'id').then(function (editor) { assert.strictEqual(editor.getId(), 'myEditor'); @@ -211,7 +211,7 @@ suite('Workbench BaseEditor', () => { EditorRegistry.registerEditor(d1, new SyncDescriptor(StringEditorInput)); - let inst = new InstantiationService(); + let inst = new TestInstantiationService(); inst.createInstance(EditorRegistry.getEditor(inst.createInstance(MyStringInput, 'fake', '', '', mime.MIME_TEXT, false)), 'id').then(function (editor) { assert.strictEqual('myOtherEditor', editor.getId()); @@ -221,7 +221,7 @@ suite('Workbench BaseEditor', () => { }); test('Editor Input Action - triggers isEnabled properly', function () { - let inst = new InstantiationService(); + let inst = new TestInstantiationService(); let action = new MyAction('id', 'label'); action.input = inst.createInstance(StringEditorInput, 'input', '', '', mime.MIME_TEXT, false); @@ -229,7 +229,7 @@ suite('Workbench BaseEditor', () => { }); test('Editor Input Action Contributor', function () { - let inst = new InstantiationService(); + let inst = new TestInstantiationService(); let contributor = new MyEditorInputActionContributor(); @@ -265,7 +265,7 @@ suite('Workbench BaseEditor', () => { }); test('Editor Input Factory', function () { - EditorRegistry.setInstantiationService(new InstantiationService()); + EditorRegistry.setInstantiationService(new TestInstantiationService()); EditorRegistry.registerEditorInputFactory('myInputId', MyInputFactory); let factory = EditorRegistry.getEditorInputFactory('myInputId'); diff --git a/src/vs/workbench/test/browser/parts/quickOpen/quickopen.test.ts b/src/vs/workbench/test/browser/parts/quickOpen/quickopen.test.ts index b735ff398c0..733980a421a 100644 --- a/src/vs/workbench/test/browser/parts/quickOpen/quickopen.test.ts +++ b/src/vs/workbench/test/browser/parts/quickOpen/quickopen.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import 'vs/workbench/browser/parts/editor/editor.contribution'; // make sure to load all contributed editor things into tests -import {TestQuickOpenService} from 'vs/workbench/test/common/servicesTestUtils'; +import {TestQuickOpenService} from 'vs/test/utils/servicesTestUtils'; import {Registry} from 'vs/platform/platform'; import {QuickOpenHandlerDescriptor, IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenAction} from 'vs/workbench/browser/quickopen'; import {Extensions} from 'vs/workbench/common/editor'; diff --git a/src/vs/workbench/test/browser/services.test.ts b/src/vs/workbench/test/browser/services.test.ts index 080825826fd..ed527a31e5f 100644 --- a/src/vs/workbench/test/browser/services.test.ts +++ b/src/vs/workbench/test/browser/services.test.ts @@ -6,6 +6,7 @@ 'use strict'; import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {Promise, TPromise} from 'vs/base/common/winjs.base'; import paths = require('vs/base/common/paths'); import URI from 'vs/base/common/uri'; @@ -17,8 +18,6 @@ import {IStorageService} from 'vs/platform/storage/common/storage'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {ILifecycleService, NullLifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; import {IFileService} from 'vs/platform/files/common/files'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import PartService = require('vs/workbench/services/part/common/partService'); import {BaseEditor} from 'vs/workbench/browser/parts/editor/baseEditor'; @@ -28,7 +27,7 @@ import {StringEditorModel} from 'vs/workbench/common/editor/stringEditorModel'; import {FileEditorInput} from 'vs/workbench/parts/files/common/editors/fileEditorInput'; import {TextFileEditorModel} from 'vs/workbench/parts/files/common/editors/textFileEditorModel'; import {ITextFileService} from 'vs/workbench/parts/files/common/files'; -import {TestTextFileService, TestEventService, TestPartService, TestStorageService, TestConfigurationService, TestRequestService, TestContextService, TestWorkspace, TestEditorService, MockRequestService} from 'vs/workbench/test/common/servicesTestUtils'; +import {createMockModelService, TestTextFileService, TestEventService, TestPartService, TestStorageService, TestConfigurationService, TestRequestService, TestContextService, TestWorkspace, TestEditorService, MockRequestService} from 'vs/test/utils/servicesTestUtils'; import {Viewlet} from 'vs/workbench/browser/viewlet'; import {EventType} from 'vs/workbench/common/events'; import {ITelemetryService, NullTelemetryService} from 'vs/platform/telemetry/common/telemetry'; @@ -39,7 +38,6 @@ import {IViewletService} from 'vs/workbench/services/viewlet/common/viewletServi import {IViewlet} from 'vs/workbench/common/viewlet'; import {Position, Direction, IEditor} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; -import {createMockModeService, createMockModelService} from 'vs/editor/test/common/servicesTestUtils'; let activeViewlet: Viewlet = {}; let activeEditor: BaseEditor = { @@ -269,32 +267,29 @@ suite('Workbench UI Services', () => { return null; }); - let telemetryService = NullTelemetryService; - let services = new ServiceCollection(); - let inst = new InstantiationService(services); - services.set(IEventService, eventService); - services.set(IWorkspaceContextService, contextService); - services.set(IRequestService, requestService); - services.set(ITelemetryService, telemetryService); - services.set(IConfigurationService, new TestConfigurationService()); - services.set(IUntitledEditorService, inst.createInstance(UntitledEditorService)); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkbenchEditorService, editorService); - services.set(PartService.IPartService, new TestPartService()); - services.set(IModeService, createMockModeService()); - services.set(IModelService, createMockModelService()); - services.set(ILifecycleService, NullLifecycleService); - services.set(IFileService, TestFileService); + let instantiationService= new TestInstantiationService(); + instantiationService.stub(IEventService, eventService); + instantiationService.stub(IWorkspaceContextService, contextService); + instantiationService.stub(IRequestService, requestService); + instantiationService.stub(ITelemetryService); + instantiationService.stub(IConfigurationService, new TestConfigurationService()); + instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService)); + instantiationService.stub(IStorageService, new TestStorageService()); + instantiationService.stub(IWorkbenchEditorService, editorService); + instantiationService.stub(PartService.IPartService, new TestPartService()); + instantiationService.stub(IModeService); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + instantiationService.stub(ILifecycleService, NullLifecycleService); + instantiationService.stub(IFileService, TestFileService); - services.set(ITextFileService, inst.createInstance(TestTextFileService)); - services['instantiationService'] = inst; + instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); - let activeInput: EditorInput = inst.createInstance(FileEditorInput, toResource('/something.js'), 'text/javascript', void 0); + let activeInput: EditorInput = instantiationService.createInstance(FileEditorInput, toResource('/something.js'), 'text/javascript', void 0); let testEditorPart = new TestEditorPart(); testEditorPart.setActiveEditorInput(activeInput); - let service: WorkbenchEditorService = inst.createInstance(WorkbenchEditorService, testEditorPart); + let service: WorkbenchEditorService = instantiationService.createInstance(WorkbenchEditorService, testEditorPart); assert.strictEqual(service.getActiveEditor(), activeEditor); assert.strictEqual(service.getActiveEditorInput(), activeInput); @@ -331,7 +326,7 @@ suite('Workbench UI Services', () => { }); // Resolve Editor Model (Typed EditorInput) - let input = inst.createInstance(StringEditorInput, 'name', 'description', 'hello world', 'text/plain', false); + let input = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'hello world', 'text/plain', false); service.resolveEditorModel(input, true).then((model: StringEditorModel) => { assert(model instanceof StringEditorModel); @@ -357,25 +352,24 @@ suite('Workbench UI Services', () => { let requestService = new TestRequestService(); let telemetryService = NullTelemetryService; - let services = new ServiceCollection(); - let inst = new InstantiationService(services); - services.set(IEventService, eventService); - services.set(IWorkspaceContextService, contextService); - services.set(IRequestService, requestService); - services.set(ITelemetryService, telemetryService); - services.set(IStorageService, new TestStorageService()); - services.set(IUntitledEditorService, inst.createInstance(UntitledEditorService)); - services.set(IWorkbenchEditorService, editorService); - services.set(PartService.IPartService, new TestPartService()); - services.set(ILifecycleService, NullLifecycleService); - services.set(IConfigurationService, new TestConfigurationService()); - services.set(ITextFileService, inst.createInstance(TestTextFileService)); - let activeInput: EditorInput = inst.createInstance(FileEditorInput, toResource('/something.js'), 'text/javascript', void 0); + let instantiationService = new TestInstantiationService(); + instantiationService.stub(IEventService, eventService); + instantiationService.stub(IRequestService, requestService); + instantiationService.stub(ITelemetryService, telemetryService); + instantiationService.stub(IStorageService, new TestStorageService()); + instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService)); + instantiationService.stub(IWorkbenchEditorService, editorService); + instantiationService.stub(PartService.IPartService, new TestPartService()); + instantiationService.stub(ILifecycleService, NullLifecycleService); + instantiationService.stub(IWorkspaceContextService, contextService); + instantiationService.stub(IConfigurationService, new TestConfigurationService()); + instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); + let activeInput: EditorInput = instantiationService.createInstance(FileEditorInput, toResource('/something.js'), 'text/javascript', void 0); let testEditorPart = new TestEditorPart(); testEditorPart.setActiveEditorInput(activeInput); - inst.createInstance(WorkbenchEditorService, testEditorPart); + instantiationService.createInstance(WorkbenchEditorService, testEditorPart); class MyEditor extends BaseEditor { constructor(id: string) { @@ -394,10 +388,10 @@ suite('Workbench UI Services', () => { } } - let ed = inst.createInstance(MyEditor, 'my.editor'); + let ed = instantiationService.createInstance(MyEditor, 'my.editor'); - let inp = inst.createInstance(StringEditorInput, 'name', 'description', 'hello world', 'text/plain', false); - let delegate: any = inst.createInstance(DelegatingWorkbenchEditorService, (input: EditorInput, options?: EditorOptions, arg3?: any) => { + let inp = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'hello world', 'text/plain', false); + let delegate: any = instantiationService.createInstance(DelegatingWorkbenchEditorService, (input: EditorInput, options?: EditorOptions, arg3?: any) => { assert.strictEqual(input, inp); return TPromise.as(ed); diff --git a/src/vs/workbench/test/common/editor/editorModel.test.ts b/src/vs/workbench/test/common/editor/editorModel.test.ts index 1c49d3f07d0..bd69729cd87 100644 --- a/src/vs/workbench/test/common/editor/editorModel.test.ts +++ b/src/vs/workbench/test/common/editor/editorModel.test.ts @@ -6,6 +6,7 @@ 'use strict'; import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {EditorModel} from 'vs/workbench/common/editor'; import {BaseTextEditorModel} from 'vs/workbench/common/editor/textEditorModel'; import {TextDiffEditorModel} from 'vs/workbench/common/editor/textDiffEditorModel'; @@ -13,15 +14,21 @@ import {DiffEditorInput} from 'vs/workbench/common/editor/diffEditorInput'; import {StringEditorInput} from 'vs/workbench/common/editor/stringEditorInput'; import {IModelService} from 'vs/editor/common/services/modelService'; import {IModeService} from 'vs/editor/common/services/modeService'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; -import {createMockModelService, createMockModeService} from 'vs/editor/test/common/servicesTestUtils'; +import { createMockModelService } from 'vs/test/utils/servicesTestUtils'; class MyEditorModel extends EditorModel { } class MyTextEditorModel extends BaseTextEditorModel { } suite('Workbench - EditorModel', () => { + let instantiationService: TestInstantiationService; + let modeService: IModeService; + + setup(() => { + instantiationService= new TestInstantiationService(); + modeService= instantiationService.stub(IModeService); + }); + test('EditorModel', function (done) { let m = new MyEditorModel(); m.load().then(function (model) { @@ -31,8 +38,7 @@ suite('Workbench - EditorModel', () => { }); test('BaseTextEditorModel', function (done) { - let modelService = createMockModelService(); - let modeService = createMockModeService(); + let modelService = createMockModelService(instantiationService); let m = new MyTextEditorModel(modelService, modeService); m.load().then(function (model: any) { @@ -47,12 +53,9 @@ suite('Workbench - EditorModel', () => { }); test('TextDiffEditorModel', function (done) { - let services = new ServiceCollection(); - services.set(IModeService, createMockModeService()); - services.set(IModelService, createMockModelService()); - let inst = new InstantiationService(services); - let input = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'text/plain', false); - let otherInput = inst.createInstance(StringEditorInput, 'name2', 'description', 'value2', 'text/plain', false); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + let input = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'value', 'text/plain', false); + let otherInput = instantiationService.createInstance(StringEditorInput, 'name2', 'description', 'value2', 'text/plain', false); let diffInput = new DiffEditorInput('name', 'description', input, otherInput); diffInput.resolve(true).then(function (model: any) { diff --git a/src/vs/workbench/test/common/editor/editorStacksModel.test.ts b/src/vs/workbench/test/common/editor/editorStacksModel.test.ts index 13fd92ec52b..9a2410d238d 100644 --- a/src/vs/workbench/test/common/editor/editorStacksModel.test.ts +++ b/src/vs/workbench/test/common/editor/editorStacksModel.test.ts @@ -9,10 +9,9 @@ import * as assert from 'assert'; import {EditorStacksModel, EditorGroup} from 'vs/workbench/common/editor/editorStacksModel'; import {EditorInput, IFileEditorInput, IEditorIdentifier, IEditorGroup, IStacksModelChangeEvent, IEditorRegistry, Extensions as EditorExtensions, IEditorInputFactory} from 'vs/workbench/common/editor'; import URI from 'vs/base/common/uri'; -import {TestStorageService, TestConfigurationService, TestLifecycleService, TestContextService, TestWorkspace, TestConfiguration} from 'vs/workbench/test/common/servicesTestUtils'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; +import {TestStorageService, TestConfigurationService, TestLifecycleService, TestContextService, TestWorkspace, TestConfiguration} from 'vs/test/utils/servicesTestUtils'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; import {IStorageService} from 'vs/platform/storage/common/storage'; import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService'; @@ -23,16 +22,15 @@ import {DiffEditorInput} from 'vs/workbench/common/editor/diffEditorInput'; import 'vs/workbench/browser/parts/editor/baseEditor'; function create(): EditorStacksModel { - let services = new ServiceCollection(); - services.set(IStorageService, new TestStorageService()); - services.set(ILifecycleService, new TestLifecycleService()); - services.set(IWorkspaceContextService, new TestContextService()); + let inst = new TestInstantiationService(); + inst.stub(IStorageService, new TestStorageService()); + inst.stub(ILifecycleService, new TestLifecycleService()); + inst.stub(IWorkspaceContextService, new TestContextService()); const config = new TestConfigurationService(); config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); - services.set(IConfigurationService, config); + inst.stub(IConfigurationService, config); - let inst = new InstantiationService(services); return inst.createInstance(EditorStacksModel); } @@ -637,16 +635,15 @@ suite('Editor Stacks Model', () => { }); test('Stack - Multiple Editors - Pinned and Active (DEFAULT_OPEN_EDITOR_DIRECTION = Direction.LEFT)', function () { - let services = new ServiceCollection(); - services.set(IStorageService, new TestStorageService()); - services.set(ILifecycleService, new TestLifecycleService()); - services.set(IWorkspaceContextService, new TestContextService()); + let inst = new TestInstantiationService(); + inst.stub(IStorageService, new TestStorageService()); + inst.stub(ILifecycleService, new TestLifecycleService()); + inst.stub(IWorkspaceContextService, new TestContextService()); const config = new TestConfigurationService(); - services.set(IConfigurationService, config); + inst.stub(IConfigurationService, config); config.setUserConfiguration('workbench', { editor: { openPositioning: 'left' } }); - let inst = new InstantiationService(services); const model = inst.createInstance(EditorStacksModel); @@ -1170,17 +1167,16 @@ suite('Editor Stacks Model', () => { }); test('Stack - Single Group, Single Editor - persist', function () { - let services = new ServiceCollection(); + let inst = new TestInstantiationService(); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkspaceContextService, new TestContextService()); + inst.stub(IStorageService, new TestStorageService()); + inst.stub(IWorkspaceContextService, new TestContextService()); const lifecycle = new TestLifecycleService(); - services.set(ILifecycleService, lifecycle); + inst.stub(ILifecycleService, lifecycle); const config = new TestConfigurationService(); config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); - services.set(IConfigurationService, config); + inst.stub(IConfigurationService, config); - let inst = new InstantiationService(services); (Registry.as(EditorExtensions.Editors)).setInstantiationService(inst); @@ -1214,17 +1210,16 @@ suite('Editor Stacks Model', () => { }); test('Stack - Multiple Groups, Multiple editors - persist', function () { - let services = new ServiceCollection(); + let inst = new TestInstantiationService(); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkspaceContextService, new TestContextService()); + inst.stub(IStorageService, new TestStorageService()); + inst.stub(IWorkspaceContextService, new TestContextService()); const lifecycle = new TestLifecycleService(); - services.set(ILifecycleService, lifecycle); + inst.stub(ILifecycleService, lifecycle); const config = new TestConfigurationService(); config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); - services.set(IConfigurationService, config); + inst.stub(IConfigurationService, config); - let inst = new InstantiationService(services); (Registry.as(EditorExtensions.Editors)).setInstantiationService(inst); @@ -1296,17 +1291,16 @@ suite('Editor Stacks Model', () => { }); test('Stack - Single group, multiple editors - persist (some not persistable)', function () { - let services = new ServiceCollection(); + let inst = new TestInstantiationService(); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkspaceContextService, new TestContextService()); + inst.stub(IStorageService, new TestStorageService()); + inst.stub(IWorkspaceContextService, new TestContextService()); const lifecycle = new TestLifecycleService(); - services.set(ILifecycleService, lifecycle); + inst.stub(ILifecycleService, lifecycle); const config = new TestConfigurationService(); config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); - services.set(IConfigurationService, config); + inst.stub(IConfigurationService, config); - let inst = new InstantiationService(services); (Registry.as(EditorExtensions.Editors)).setInstantiationService(inst); @@ -1346,17 +1340,16 @@ suite('Editor Stacks Model', () => { }); test('Stack - Multiple groups, multiple editors - persist (some not persistable, causes empty group)', function () { - let services = new ServiceCollection(); + let inst = new TestInstantiationService(); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkspaceContextService, new TestContextService()); + inst.stub(IStorageService, new TestStorageService()); + inst.stub(IWorkspaceContextService, new TestContextService()); const lifecycle = new TestLifecycleService(); - services.set(ILifecycleService, lifecycle); + inst.stub(ILifecycleService, lifecycle); const config = new TestConfigurationService(); config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); - services.set(IConfigurationService, config); + inst.stub(IConfigurationService, config); - let inst = new InstantiationService(services); (Registry.as(EditorExtensions.Editors)).setInstantiationService(inst); @@ -1388,17 +1381,16 @@ suite('Editor Stacks Model', () => { }); test('Stack - Multiple groups, multiple editors - persist (ignore persisted when editors to open on startup)', function () { - let services = new ServiceCollection(); + let inst = new TestInstantiationService(); - services.set(IStorageService, new TestStorageService()); - services.set(IWorkspaceContextService, new TestContextService(TestWorkspace, TestConfiguration, { filesToCreate: [true] })); + inst.stub(IStorageService, new TestStorageService()); + inst.stub(IWorkspaceContextService, new TestContextService(TestWorkspace, TestConfiguration, { filesToCreate: [true] })); const lifecycle = new TestLifecycleService(); - services.set(ILifecycleService, lifecycle); + inst.stub(ILifecycleService, lifecycle); const config = new TestConfigurationService(); config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); - services.set(IConfigurationService, config); + inst.stub(IConfigurationService, config); - let inst = new InstantiationService(services); (Registry.as(EditorExtensions.Editors)).setInstantiationService(inst); diff --git a/src/vs/workbench/test/common/editor/stringEditorInput.test.ts b/src/vs/workbench/test/common/editor/stringEditorInput.test.ts index c2c7136ed24..723b5d4fd1a 100644 --- a/src/vs/workbench/test/common/editor/stringEditorInput.test.ts +++ b/src/vs/workbench/test/common/editor/stringEditorInput.test.ts @@ -6,33 +6,38 @@ 'use strict'; import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import URI from 'vs/base/common/uri'; import {StringEditorInput} from 'vs/workbench/common/editor/stringEditorInput'; import {ResourceEditorInput} from 'vs/workbench/common/editor/resourceEditorInput'; import {ResourceEditorModel} from 'vs/workbench/common/editor/resourceEditorModel'; -import {TestEditorService} from 'vs/workbench/test/common/servicesTestUtils'; +import {createMockModelService, TestEditorService} from 'vs/test/utils/servicesTestUtils'; import {IModelService} from 'vs/editor/common/services/modelService'; import {IModeService} from 'vs/editor/common/services/modeService'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; - -import {createMockModelService, createMockModeService} from 'vs/editor/test/common/servicesTestUtils'; +import WorkbenchEditorService = require('vs/workbench/services/editor/common/editorService'); suite('Workbench - StringEditorInput', () => { + let instantiationService: TestInstantiationService; + let editorService: WorkbenchEditorService.IWorkbenchEditorService; + let modelService: IModelService; + let modeService: IModeService; + + setup(() => { + instantiationService= new TestInstantiationService(); + editorService= instantiationService.stub(WorkbenchEditorService.IWorkbenchEditorService, new TestEditorService(function () { })); + modeService= instantiationService.stub(IModeService); + modelService= instantiationService.stub(IModelService, createMockModelService(instantiationService)); + }); + test('StringEditorInput', function (done) { - let editorService = new TestEditorService(function () { }); - let services = new ServiceCollection(); - services.set(IModeService, createMockModeService()); - services.set(IModelService, createMockModelService()); - let inst = new InstantiationService(services); - let input = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); - let otherInput = inst.createInstance(StringEditorInput, 'name', 'description', 'othervalue', 'mime', false); - let otherInputSame = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); + let input = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); + let otherInput = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'othervalue', 'mime', false); + let otherInputSame = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); - let inputSingleton = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', true); - let otherInputSingleton = inst.createInstance(StringEditorInput, 'name', 'description', 'othervalue', 'mime', true); + let inputSingleton = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', true); + let otherInputSingleton = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'othervalue', 'mime', true); assert(inputSingleton.matches(otherInputSingleton)); (otherInputSingleton).singleton = false; assert(!inputSingleton.matches(otherInputSingleton)); @@ -43,15 +48,15 @@ suite('Workbench - StringEditorInput', () => { assert(!input.matches(null)); assert(input.getName()); - input = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); + input = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); - input = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); + input = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); editorService.resolveEditorModel(input, true).then(function (resolved) { let resolvedModelA = resolved; return editorService.resolveEditorModel(input, true).then(function (resolved) { assert(resolvedModelA === resolved); // assert: Resolved Model cached per instance - let otherInput = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); + let otherInput = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); return editorService.resolveEditorModel(otherInput, true).then(function (resolved) { assert(resolvedModelA !== resolved); // NOT assert: Different instance, different model @@ -73,11 +78,7 @@ suite('Workbench - StringEditorInput', () => { }); test('StringEditorInput - setValue, clearValue, append', function () { - let services = new ServiceCollection(); - services.set(IModeService, createMockModeService()); - services.set(IModelService, createMockModelService()); - let inst = new InstantiationService(services); - let input = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); + let input = instantiationService.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); assert.strictEqual(input.getValue(), 'value'); input.setValue('foo'); @@ -91,7 +92,7 @@ suite('Workbench - StringEditorInput', () => { }); test('Input.matches() - StringEditorInput', function () { - let inst = new InstantiationService(); + let inst = new TestInstantiationService(); let stringEditorInput = inst.createInstance(StringEditorInput, 'name', 'description', 'value', 'mime', false); let promiseEditorInput = inst.createInstance(ResourceEditorInput, 'name', 'description', URI.from({ scheme: 'inMemory', authority: null, path: 'thePath' })); @@ -110,16 +111,9 @@ suite('Workbench - StringEditorInput', () => { }); test('ResourceEditorInput', function (done) { - let modelService = createMockModelService(); - let modeService = createMockModeService(); - let services = new ServiceCollection(); - services.set(IModeService, modeService); - services.set(IModelService, modelService); - let inst = new InstantiationService(services); - let resource = URI.from({ scheme: 'inMemory', authority: null, path: 'thePath' }); modelService.createModel('function test() {}', modeService.getOrCreateMode('text'), resource); - let input: ResourceEditorInput = inst.createInstance(ResourceEditorInput, 'The Name', 'The Description', resource); + let input: ResourceEditorInput = instantiationService.createInstance(ResourceEditorInput, 'The Name', 'The Description', resource); input.resolve().then((model: ResourceEditorModel) => { assert.ok(model); diff --git a/src/vs/workbench/test/common/editor/stringEditorModel.test.ts b/src/vs/workbench/test/common/editor/stringEditorModel.test.ts index fd7d5a864ec..e2909991dcf 100644 --- a/src/vs/workbench/test/common/editor/stringEditorModel.test.ts +++ b/src/vs/workbench/test/common/editor/stringEditorModel.test.ts @@ -6,22 +6,24 @@ 'use strict'; import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {StringEditorModel} from 'vs/workbench/common/editor/stringEditorModel'; import {IModelService} from 'vs/editor/common/services/modelService'; import {IModeService} from 'vs/editor/common/services/modeService'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; - -import {createMockModelService, createMockModeService} from 'vs/editor/test/common/servicesTestUtils'; +import {createMockModelService} from 'vs/test/utils/servicesTestUtils'; suite('Workbench - StringEditorModel', () => { + let instantiationService: TestInstantiationService; + + setup(() => { + instantiationService= new TestInstantiationService(); + instantiationService.stub(IModeService); + }); + test('StringEditorModel', function (done) { - let services = new ServiceCollection(); - services.set(IModeService, createMockModeService()); - services.set(IModelService, createMockModelService()); - let inst = new InstantiationService(services); - let m = inst.createInstance(StringEditorModel, 'value', 'mime', null); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + let m = instantiationService.createInstance(StringEditorModel, 'value', 'mime', null); m.load().then(function (model) { assert(model === m); @@ -42,11 +44,8 @@ suite('Workbench - StringEditorModel', () => { }); test('StringEditorModel - setValue, clearValue, append, trim', function (done) { - let services = new ServiceCollection(); - services.set(IModeService, createMockModeService()); - services.set(IModelService, createMockModelService()); - let inst = new InstantiationService(services); - let m = inst.createInstance(StringEditorModel, 'value', 'mime', null); + instantiationService.stub(IModelService, createMockModelService(instantiationService)); + let m = instantiationService.createInstance(StringEditorModel, 'value', 'mime', null); m.load().then(function (model) { assert(model === m); diff --git a/src/vs/workbench/test/common/memento.test.ts b/src/vs/workbench/test/common/memento.test.ts index fe3475ec0bf..fb0c32ce991 100644 --- a/src/vs/workbench/test/common/memento.test.ts +++ b/src/vs/workbench/test/common/memento.test.ts @@ -8,7 +8,7 @@ import * as assert from 'assert'; import {BaseWorkspaceContextService} from 'vs/platform/workspace/common/baseWorkspaceContextService'; import {StorageScope} from 'vs/platform/storage/common/storage'; -import * as TestUtils from 'vs/workbench/test/common/servicesTestUtils'; +import * as TestUtils from 'vs/test/utils/servicesTestUtils'; import {Memento, Scope} from 'vs/workbench/common/memento'; import {Storage, InMemoryLocalStorage} from 'vs/workbench/common/storage'; diff --git a/src/vs/workbench/test/common/storage.test.ts b/src/vs/workbench/test/common/storage.test.ts index 0e95c4b61dd..185393de3a8 100644 --- a/src/vs/workbench/test/common/storage.test.ts +++ b/src/vs/workbench/test/common/storage.test.ts @@ -8,7 +8,7 @@ import * as assert from 'assert'; import {clone} from 'vs/base/common/objects'; import {StorageScope} from 'vs/platform/storage/common/storage'; -import {TestContextService, TestWorkspace} from 'vs/workbench/test/common/servicesTestUtils'; +import {TestContextService, TestWorkspace} from 'vs/test/utils/servicesTestUtils'; import {Storage, InMemoryLocalStorage} from 'vs/workbench/common/storage'; suite('Workbench Storage', () => { diff --git a/src/vs/workbench/test/node/api/extHostApiCommands.test.ts b/src/vs/workbench/test/node/api/extHostApiCommands.test.ts index 77f673f8a38..c73809e74cb 100644 --- a/src/vs/workbench/test/node/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/node/api/extHostApiCommands.test.ts @@ -7,14 +7,13 @@ import * as assert from 'assert'; import {setUnexpectedErrorHandler, errorHandler} from 'vs/base/common/errors'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import URI from 'vs/base/common/uri'; import {TPromise} from 'vs/base/common/winjs.base'; import * as types from 'vs/workbench/api/node/extHostTypes'; import * as EditorCommon from 'vs/editor/common/editorCommon'; import {Model as EditorModel} from 'vs/editor/common/model/model'; import {TestThreadService} from 'vs/workbench/test/node/api/testThreadService'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; import {MarkerService} from 'vs/platform/markers/common/markerService'; import {IMarkerService} from 'vs/platform/markers/common/markers'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; @@ -27,7 +26,7 @@ import {ExtHostCommands} from 'vs/workbench/api/node/extHostCommands'; import {MainThreadCommands} from 'vs/workbench/api/node/mainThreadCommands'; import {ExtHostDocuments} from 'vs/workbench/api/node/extHostDocuments'; import * as ExtHostTypeConverters from 'vs/workbench/api/node/extHostTypeConverters'; -import {MainContext, ExtHostContext} from 'vs/workbench/api/node/extHostProtocol'; +import {MainContext, ExtHostContext} from 'vs/workbench/api/node/extHost.protocol'; import {ExtHostDiagnostics} from 'vs/workbench/api/node/extHostDiagnostics'; const defaultSelector = { scheme: 'far' }; @@ -55,23 +54,19 @@ suite('ExtHostLanguageFeatureCommands', function() { originalErrorHandler = errorHandler.getUnexpectedErrorHandler(); setUnexpectedErrorHandler(() => { }); - let services = new ServiceCollection(); - let instantiationService = new InstantiationService(services); + let instantiationService = new TestInstantiationService(); threadService = new TestThreadService(); - services.set(ICommandService, { + instantiationService.stub(ICommandService, { _serviceBrand: undefined, executeCommand(id, args): any { let {handler} = CommandsRegistry.getCommands()[id]; return TPromise.as(instantiationService.invokeFunction(handler, args)); - }, - isKnownCommand(id) { - return true; } }); - services.set(IMarkerService, new MarkerService()); - services.set(IThreadService, threadService); - services.set(IModelService, { + instantiationService.stub(IMarkerService, new MarkerService()); + instantiationService.stub(IThreadService, threadService); + instantiationService.stub(IModelService, { _serviceBrand: IModelService, getModel(): any { return model; }, createModel(): any { throw new Error(); }, @@ -85,7 +80,7 @@ suite('ExtHostLanguageFeatureCommands', function() { const extHostDocuments = new ExtHostDocuments(threadService); threadService.set(ExtHostContext.ExtHostDocuments, extHostDocuments); - extHostDocuments._acceptModelAdd({ + extHostDocuments.$acceptModelAdd({ isDirty: false, versionId: model.getVersionId(), modeId: model.getModeId(), diff --git a/src/vs/workbench/test/node/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/node/api/extHostLanguageFeatures.test.ts index c929e246976..5f5dd58b34e 100644 --- a/src/vs/workbench/test/node/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/node/api/extHostLanguageFeatures.test.ts @@ -6,6 +6,7 @@ 'use strict'; import * as assert from 'assert'; +import { TestInstantiationService } from 'vs/test/utils/instantiationTestUtils'; import {setUnexpectedErrorHandler, errorHandler} from 'vs/base/common/errors'; import URI from 'vs/base/common/uri'; import * as types from 'vs/workbench/api/node/extHostTypes'; @@ -14,9 +15,6 @@ import {Model as EditorModel} from 'vs/editor/common/model/model'; import {Position as EditorPosition} from 'vs/editor/common/core/position'; import {Range as EditorRange} from 'vs/editor/common/core/range'; import {TestThreadService} from './testThreadService'; -import {ServiceCollection} from 'vs/platform/instantiation/common/serviceCollection'; -import {InstantiationService} from 'vs/platform/instantiation/common/instantiationService'; -import {MarkerService} from 'vs/platform/markers/common/markerService'; import {IMarkerService} from 'vs/platform/markers/common/markers'; import {IThreadService} from 'vs/workbench/services/thread/common/threadService'; import {ExtHostLanguageFeatures} from 'vs/workbench/api/node/extHostLanguageFeatures'; @@ -38,7 +36,7 @@ import {provideSignatureHelp} from 'vs/editor/contrib/parameterHints/common/para import {provideCompletionItems} from 'vs/editor/contrib/suggest/common/suggest'; import {getDocumentFormattingEdits, getDocumentRangeFormattingEdits, getOnTypeFormattingEdits} from 'vs/editor/contrib/format/common/format'; import {asWinJsPromise} from 'vs/base/common/async'; -import {MainContext, ExtHostContext} from 'vs/workbench/api/node/extHostProtocol'; +import {MainContext, ExtHostContext} from 'vs/workbench/api/node/extHost.protocol'; import {ExtHostDiagnostics} from 'vs/workbench/api/node/extHostDiagnostics'; const defaultSelector = { scheme: 'far' }; @@ -62,18 +60,17 @@ suite('ExtHostLanguageFeatures', function() { suiteSetup(() => { - let services = new ServiceCollection(); - let instantiationService = new InstantiationService(services); threadService = new TestThreadService(); - services.set(IMarkerService, new MarkerService()); - services.set(IThreadService, threadService); + let instantiationService= new TestInstantiationService(); + instantiationService.stub(IThreadService, threadService); + instantiationService.stub(IMarkerService); originalErrorHandler = errorHandler.getUnexpectedErrorHandler(); setUnexpectedErrorHandler(() => { }); const extHostDocuments = new ExtHostDocuments(threadService); threadService.set(ExtHostContext.ExtHostDocuments, extHostDocuments); - extHostDocuments._acceptModelAdd({ + extHostDocuments.$acceptModelAdd({ isDirty: false, versionId: model.getVersionId(), modeId: model.getModeId(), @@ -102,7 +99,7 @@ suite('ExtHostLanguageFeatures', function() { extHost = new ExtHostLanguageFeatures(threadService, extHostDocuments, commands, diagnostics); threadService.set(ExtHostContext.ExtHostLanguageFeatures, extHost); - mainThread = threadService.setTestInstance(MainContext.MainThreadLanguageFeatures, instantiationService.createInstance(MainThreadLanguageFeatures)); + mainThread = threadService.setTestInstance(MainContext.MainThreadLanguageFeatures, instantiationService.createInstance(MainThreadLanguageFeatures)); }); suiteTeardown(() => {