Merge branch 'master' into sandy081/userDataProvider

This commit is contained in:
Sandeep Somavarapu
2019-09-10 15:17:32 +02:00
376 changed files with 7822 additions and 6945 deletions
@@ -102,23 +102,28 @@ steps:
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
# Figure out the full absolute path of the product we just built
# including the remote server and configure the integration tests
# to run with these builds instead of running out of sources.
set -e
APP_ROOT=$(agent.builddirectory)/VSCode-darwin
APP_NAME="`ls $APP_ROOT | head -n 1`"
INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin" \
./scripts/test-integration.sh --build --tfs "Integration Tests"
displayName: Run integration tests
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
set -e
cd test/smoke
yarn compile
cd -
yarn smoketest --web --headless
continueOnError: true
displayName: Run web smoke tests
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
# Web Smoke Tests disabled due to https://github.com/microsoft/vscode/issues/80308
# - script: |
# set -e
# cd test/smoke
# yarn compile
# cd -
# yarn smoketest --web --headless
# continueOnError: true
# displayName: Run web smoke tests
# condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
set -e
@@ -105,10 +105,14 @@ steps:
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- script: |
# Figure out the full absolute path of the product we just built
# including the remote server and configure the integration tests
# to run with these builds instead of running out of sources.
set -e
APP_ROOT=$(agent.builddirectory)/VSCode-linux-x64
APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName")
INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-x64" \
DISPLAY=:10 ./scripts/test-integration.sh --build --tfs "Integration Tests"
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-x64"
displayName: Run integration tests
@@ -104,6 +104,7 @@ steps:
AZURE_WEBVIEW_STORAGE_ACCESS_KEY="$(vscode-webview-storage-key)" \
./build/azure-pipelines/common/publish-webview.sh
displayName: Publish Webview
condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true'))
- script: |
set -e
@@ -15,6 +15,22 @@ steps:
inputs:
versionSpec: "1.x"
- bash: |
TAG_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`)
CHANNEL="G1C14HJ2F"
if [ "$TAG_VERSION" == "1.999.0" ]; then
MESSAGE="<!here>. Someone pushed 1.999.0 tag. Please delete it ASAP from remote and local."
curl -X POST -H "Authorization: Bearer $(SLACK_TOKEN)" \
-H 'Content-type: application/json; charset=utf-8' \
--data '{"channel":"'"$CHANNEL"'", "link_names": true, "text":"'"$MESSAGE"'"}' \
https://slack.com/api/chat.postMessage
exit 1
fi
displayName: Check 1.999.0 tag
- bash: |
# Install build dependencies
(cd build && yarn)
@@ -113,12 +113,15 @@ steps:
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
- powershell: |
# Figure out the full absolute path of the product we just built
# including the remote server and configure the integration tests
# to run with these builds instead of running out of sources.
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)"
$AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json
$AppNameShort = $AppProductJson.nameShort
exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; .\scripts\test-integration.bat --build --tfs "Integration Tests" }
exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"; .\scripts\test-integration.bat --build --tfs "Integration Tests" }
displayName: Run integration tests
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
+19 -16
View File
@@ -21,7 +21,6 @@ const nlsDev = require('vscode-nls-dev');
const root = path.dirname(__dirname);
const commit = util.getVersion(root);
const plumber = require('gulp-plumber');
const _ = require('underscore');
const ext = require('./lib/extensions');
const extensionsPath = path.join(path.dirname(__dirname), 'extensions');
@@ -37,16 +36,16 @@ const tasks = compilations.map(function (tsconfigFile) {
const absolutePath = path.join(extensionsPath, tsconfigFile);
const relativeDirname = path.dirname(tsconfigFile);
const tsconfig = require(absolutePath);
const tsOptions = _.assign({}, tsconfig.extends ? require(path.join(extensionsPath, relativeDirname, tsconfig.extends)).compilerOptions : {}, tsconfig.compilerOptions);
tsOptions.verbose = false;
tsOptions.sourceMap = true;
const overrideOptions = {};
overrideOptions.sourceMap = true;
const name = relativeDirname.replace(/\//g, '-');
const root = path.join('extensions', relativeDirname);
const srcBase = path.join(root, 'src');
const src = path.join(srcBase, '**');
const srcOpts = { cwd: path.dirname(__dirname), base: srcBase };
const out = path.join(root, 'out');
const baseUrl = getBaseUrl(out);
@@ -63,12 +62,12 @@ const tasks = compilations.map(function (tsconfigFile) {
function createPipeline(build, emitError) {
const reporter = createReporter();
tsOptions.inlineSources = !!build;
tsOptions.base = path.dirname(absolutePath);
overrideOptions.inlineSources = Boolean(build);
overrideOptions.base = path.dirname(absolutePath);
const compilation = tsb.create(tsOptions, null, null, err => reporter(err.toString()));
const compilation = tsb.create(absolutePath, overrideOptions, false, err => reporter(err.toString()));
return function () {
const pipeline = function () {
const input = es.through();
const tsFilter = filter(['**/*.ts', '!**/lib/lib*.d.ts', '!**/node_modules/**'], { restore: true });
const output = input
@@ -98,15 +97,19 @@ const tasks = compilations.map(function (tsconfigFile) {
return es.duplex(input, output);
};
}
const srcOpts = { cwd: path.dirname(__dirname), base: srcBase };
// add src-stream for project files
pipeline.tsProjectSrc = () => {
return compilation.src(srcOpts);
};
return pipeline;
}
const cleanTask = task.define(`clean-extension-${name}`, util.rimraf(out));
const compileTask = task.define(`compile-extension:${name}`, task.series(cleanTask, () => {
const pipeline = createPipeline(false, true);
const input = gulp.src(src, srcOpts);
const input = pipeline.tsProjectSrc();
return input
.pipe(pipeline())
@@ -115,8 +118,8 @@ const tasks = compilations.map(function (tsconfigFile) {
const watchTask = task.define(`watch-extension:${name}`, task.series(cleanTask, () => {
const pipeline = createPipeline(false);
const input = gulp.src(src, srcOpts);
const watchInput = watcher(src, srcOpts);
const input = pipeline.tsProjectSrc();
const watchInput = watcher(src, { ...srcOpts, ...{ readDelay: 200 } });
return watchInput
.pipe(util.incremental(pipeline, input))
@@ -125,7 +128,7 @@ const tasks = compilations.map(function (tsconfigFile) {
const compileBuildTask = task.define(`compile-build-extension-${name}`, task.series(cleanTask, () => {
const pipeline = createPipeline(true, true);
const input = gulp.src(src, srcOpts);
const input = pipeline.tsProjectSrc();
return input
.pipe(pipeline())
@@ -160,4 +163,4 @@ const compileExtensionsBuildTask = task.define('compile-extensions-build', task.
));
gulp.task(compileExtensionsBuildTask);
exports.compileExtensionsBuildTask = compileExtensionsBuildTask;
exports.compileExtensionsBuildTask = compileExtensionsBuildTask;
+3 -3
View File
@@ -49,7 +49,6 @@ const nodeModules = ['electron', 'original-fs']
const vscodeEntryPoints = _.flatten([
buildfile.entrypoint('vs/workbench/workbench.desktop.main'),
buildfile.base,
buildfile.serviceWorker,
buildfile.workbenchDesktop,
buildfile.code
]);
@@ -94,6 +93,7 @@ const optimizeVSCodeTask = task.define('optimize-vscode', task.series(
resources: vscodeResources,
loaderConfig: common.loaderConfig(nodeModules),
out: 'out-vscode',
inlineAmdImages: true,
bundleInfo: undefined
})
));
@@ -480,7 +480,7 @@ gulp.task(task.define(
optimizeVSCodeTask,
function () {
const pathToMetadata = './out-vscode/nls.metadata.json';
const pathToExtensions = './extensions/*';
const pathToExtensions = '.build/extensions/*';
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
return es.merge(
@@ -501,7 +501,7 @@ gulp.task(task.define(
optimizeVSCodeTask,
function () {
const pathToMetadata = './out-vscode/nls.metadata.json';
const pathToExtensions = './extensions/*';
const pathToExtensions = '.build/extensions/*';
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
return es.merge(
+2 -1
View File
@@ -238,7 +238,8 @@ function prepareSnapPackage(arch) {
function buildSnapPackage(arch) {
const snapBuildPath = getSnapBuildPath(arch);
return shell.task(`cd ${snapBuildPath} && snapcraft build`);
// Default target for snapcraft runs: pull, build, stage and prime, and finally assembles the snap.
return shell.task(`cd ${snapBuildPath} && snapcraft`);
}
const BUILD_TARGETS = [
+7 -4
View File
@@ -34,7 +34,8 @@ const nodeModules = Object.keys(product.dependencies || {})
const vscodeWebResources = [
// Workbench
'out-build/vs/{base,platform,editor,workbench}/**/*.{svg,png,html}',
'out-build/vs/{base,platform,editor,workbench}/**/*.{svg,png}',
'out-build/vs/code/browser/workbench/workbench.html',
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
'out-build/vs/**/markdown.css',
@@ -56,7 +57,6 @@ const buildfile = require('../src/buildfile');
const vscodeWebEntryPoints = _.flatten([
buildfile.entrypoint('vs/workbench/workbench.web.api'),
buildfile.base,
buildfile.serviceWorker,
buildfile.workerExtensionHost,
buildfile.keyboardMaps,
buildfile.workbenchWeb
@@ -118,7 +118,10 @@ function packageTask(sourceFolderName, destinationFolderName) {
const favicon = gulp.src('resources/server/favicon.ico', { base: 'resources/server' });
const manifest = gulp.src('resources/server/manifest.json', { base: 'resources/server' });
const pwaicon = gulp.src('resources/server/code.png', { base: 'resources/server' });
const pwaicons = es.merge(
gulp.src('resources/server/code-192.png', { base: 'resources/server' }),
gulp.src('resources/server/code-512.png', { base: 'resources/server' })
);
let all = es.merge(
packageJsonStream,
@@ -128,7 +131,7 @@ function packageTask(sourceFolderName, destinationFolderName) {
deps,
favicon,
manifest,
pwaicon
pwaicons
);
let result = all
+9 -24
View File
@@ -11,7 +11,6 @@ const bom = require("gulp-bom");
const sourcemaps = require("gulp-sourcemaps");
const tsb = require("gulp-tsb");
const path = require("path");
const _ = require("underscore");
const monacodts = require("../monaco/api");
const nls = require("./nls");
const reporter_1 = require("./reporter");
@@ -22,14 +21,7 @@ const watch = require('./watch');
const reporter = reporter_1.createReporter();
function getTypeScriptCompilerOptions(src) {
const rootDir = path.join(__dirname, `../../${src}`);
const tsconfig = require(`../../${src}/tsconfig.json`);
let options;
if (tsconfig.extends) {
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
}
else {
options = tsconfig.compilerOptions;
}
let options = {};
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
@@ -38,14 +30,13 @@ function getTypeScriptCompilerOptions(src) {
options.rootDir = rootDir;
options.baseUrl = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 0 : 1;
return options;
}
function createCompile(src, build, emitError) {
const opts = _.clone(getTypeScriptCompilerOptions(src));
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));
const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json');
const overrideOptions = Object.assign(Object.assign({}, getTypeScriptCompilerOptions(src)), { inlineSources: Boolean(build) });
const ts = tsb.create(projectPath, overrideOptions, false, err => reporter(err));
return function (token) {
const utf8Filter = util.filter(data => /(\/|\\)test(\/|\\).*utf8/.test(data.path));
const tsFilter = util.filter(data => /\.ts$/.test(data.path));
@@ -64,23 +55,17 @@ function createCompile(src, build, emitError) {
.pipe(sourcemaps.write('.', {
addComment: false,
includeContent: !!build,
sourceRoot: opts.sourceRoot
sourceRoot: overrideOptions.sourceRoot
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(!!emitError));
return es.duplex(input, output);
};
}
const typesDts = [
'node_modules/typescript/lib/*.d.ts',
'node_modules/@types/**/*.d.ts',
'!node_modules/@types/webpack/**/*',
'!node_modules/@types/uglify-js/**/*',
];
function compileTask(src, out, build) {
return function () {
const compile = createCompile(src, build, true);
const srcPipe = es.merge(gulp.src(`${src}/**`, { base: `${src}` }), gulp.src(typesDts));
const srcPipe = gulp.src(`${src}/**`, { base: `${src}` });
let generator = new MonacoGenerator(false);
if (src === 'src') {
generator.execute();
@@ -95,8 +80,8 @@ exports.compileTask = compileTask;
function watchTask(out, build) {
return function () {
const compile = createCompile('src', build);
const src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src(typesDts));
const watchSrc = watch('src/**', { base: 'src' });
const src = gulp.src('src/**', { base: 'src' });
const watchSrc = watch('src/**', { base: 'src', readDelay: 200 });
let generator = new MonacoGenerator(true);
generator.execute();
return watchSrc
+11 -31
View File
@@ -12,27 +12,21 @@ import * as bom from 'gulp-bom';
import * as sourcemaps from 'gulp-sourcemaps';
import * as tsb from 'gulp-tsb';
import * as path from 'path';
import * as _ from 'underscore';
import * as monacodts from '../monaco/api';
import * as nls from './nls';
import { createReporter } from './reporter';
import * as util from './util';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
import ts = require('typescript');
const watch = require('./watch');
const reporter = createReporter();
function getTypeScriptCompilerOptions(src: string) {
function getTypeScriptCompilerOptions(src: string): ts.CompilerOptions {
const rootDir = path.join(__dirname, `../../${src}`);
const tsconfig = require(`../../${src}/tsconfig.json`);
let options: { [key: string]: any };
if (tsconfig.extends) {
options = Object.assign({}, require(path.join(rootDir, tsconfig.extends)).compilerOptions, tsconfig.compilerOptions);
} else {
options = tsconfig.compilerOptions;
}
let options: ts.CompilerOptions = {};
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
@@ -41,16 +35,15 @@ function getTypeScriptCompilerOptions(src: string) {
options.rootDir = rootDir;
options.baseUrl = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 'CRLF' : 'LF';
options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 0 : 1;
return options;
}
function createCompile(src: string, build: boolean, emitError?: boolean): (token?: util.ICancellationToken) => NodeJS.ReadWriteStream {
const opts = _.clone(getTypeScriptCompilerOptions(src));
opts.inlineSources = !!build;
opts.noFilesystemLookup = true;
const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json');
const overrideOptions = { ...getTypeScriptCompilerOptions(src), inlineSources: Boolean(build) };
const ts = tsb.create(opts, true, undefined, err => reporter(err.toString()));
const ts = tsb.create(projectPath, overrideOptions, false, err => reporter(err));
return function (token?: util.ICancellationToken) {
@@ -72,7 +65,7 @@ function createCompile(src: string, build: boolean, emitError?: boolean): (token
.pipe(sourcemaps.write('.', {
addComment: false,
includeContent: !!build,
sourceRoot: opts.sourceRoot
sourceRoot: overrideOptions.sourceRoot
}))
.pipe(tsFilter.restore)
.pipe(reporter.end(!!emitError));
@@ -81,22 +74,12 @@ function createCompile(src: string, build: boolean, emitError?: boolean): (token
};
}
const typesDts = [
'node_modules/typescript/lib/*.d.ts',
'node_modules/@types/**/*.d.ts',
'!node_modules/@types/webpack/**/*',
'!node_modules/@types/uglify-js/**/*',
];
export function compileTask(src: string, out: string, build: boolean): () => NodeJS.ReadWriteStream {
return function () {
const compile = createCompile(src, build, true);
const srcPipe = es.merge(
gulp.src(`${src}/**`, { base: `${src}` }),
gulp.src(typesDts),
);
const srcPipe = gulp.src(`${src}/**`, { base: `${src}` });
let generator = new MonacoGenerator(false);
if (src === 'src') {
@@ -115,11 +98,8 @@ export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteSt
return function () {
const compile = createCompile('src', build);
const src = es.merge(
gulp.src('src/**', { base: 'src' }),
gulp.src(typesDts),
);
const watchSrc = watch('src/**', { base: 'src' });
const src = gulp.src('src/**', { base: 'src' });
const watchSrc = watch('src/**', { base: 'src', readDelay: 200 });
let generator = new MonacoGenerator(true);
generator.execute();
+5 -5
View File
@@ -580,7 +580,7 @@ function createXlfFilesForExtensions() {
}
return _xlf;
}
gulp.src([`./extensions/${extensionName}/package.nls.json`, `./extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(event_stream_1.through(function (file) {
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(event_stream_1.through(function (file) {
if (file.isBuffer()) {
const buffer = file.contents;
const basename = path.basename(file.path);
@@ -603,7 +603,7 @@ function createXlfFilesForExtensions() {
}
else if (basename === 'nls.metadata.json') {
const json = JSON.parse(buffer.toString('utf8'));
const relPath = path.relative(`./extensions/${extensionName}`, path.dirname(file.path));
const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path));
for (let file in json) {
const fileContent = json[file];
getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages);
@@ -906,8 +906,8 @@ function pullCoreAndExtensionsXlfFiles(apiHostname, username, password, language
_coreAndExtensionResources.push(...json.workbench);
// extensions
let extensionsToLocalize = Object.create(null);
glob.sync('./extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('./extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('.build/extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('.build/extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
Object.keys(extensionsToLocalize).forEach(extension => {
_coreAndExtensionResources.push({ name: extension, project: extensionsProject });
});
@@ -1080,7 +1080,7 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pse
resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' });
this.queue(translatedMainFile);
for (let extension in extensionsPacks) {
const translatedExtFile = createI18nFile(`./extensions/${extension}`, extensionsPacks[extension]);
const translatedExtFile = createI18nFile(`.build/extensions/${extension}`, extensionsPacks[extension]);
this.queue(translatedExtFile);
const externalExtensionId = externalExtensions[extension];
if (externalExtensionId) {
+5 -5
View File
@@ -701,7 +701,7 @@ export function createXlfFilesForExtensions(): ThroughStream {
}
return _xlf;
}
gulp.src([`./extensions/${extensionName}/package.nls.json`, `./extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(through(function (file: File) {
gulp.src([`.build/extensions/${extensionName}/package.nls.json`, `.build/extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(through(function (file: File) {
if (file.isBuffer()) {
const buffer: Buffer = file.contents as Buffer;
const basename = path.basename(file.path);
@@ -721,7 +721,7 @@ export function createXlfFilesForExtensions(): ThroughStream {
getXlf().addFile(`extensions/${extensionName}/package`, keys, messages);
} else if (basename === 'nls.metadata.json') {
const json: BundledExtensionFormat = JSON.parse(buffer.toString('utf8'));
const relPath = path.relative(`./extensions/${extensionName}`, path.dirname(file.path));
const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path));
for (let file in json) {
const fileContent = json[file];
getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages);
@@ -1045,8 +1045,8 @@ export function pullCoreAndExtensionsXlfFiles(apiHostname: string, username: str
// extensions
let extensionsToLocalize = Object.create(null);
glob.sync('./extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('./extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('.build/extensions/**/*.nls.json').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
glob.sync('.build/extensions/*/node_modules/vscode-nls').forEach(extension => extensionsToLocalize[extension.split('/')[2]] = true);
Object.keys(extensionsToLocalize).forEach(extension => {
_coreAndExtensionResources.push({ name: extension, project: extensionsProject });
@@ -1245,7 +1245,7 @@ export function prepareI18nPackFiles(externalExtensions: Map<string>, resultingT
this.queue(translatedMainFile);
for (let extension in extensionsPacks) {
const translatedExtFile = createI18nFile(`./extensions/${extension}`, extensionsPacks[extension]);
const translatedExtFile = createI18nFile(`.build/extensions/${extension}`, extensionsPacks[extension]);
this.queue(translatedExtFile);
const externalExtensionId = externalExtensions[extension];
+42 -3
View File
@@ -5,6 +5,7 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const es = require("event-stream");
const fs = require("fs");
const gulp = require("gulp");
const concat = require("gulp-concat");
const minifyCSS = require("gulp-cssnano");
@@ -132,6 +133,14 @@ function optimizeTask(opts) {
if (err || !result) {
return bundlesStream.emit('error', JSON.stringify(err));
}
if (opts.inlineAmdImages) {
try {
result = inlineAmdImages(src, result);
}
catch (err) {
return bundlesStream.emit('error', JSON.stringify(err));
}
}
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
const filteredResources = resources.slice();
@@ -167,6 +176,39 @@ function optimizeTask(opts) {
};
}
exports.optimizeTask = optimizeTask;
function inlineAmdImages(src, result) {
for (const outputFile of result.files) {
for (const sourceFile of outputFile.sources) {
if (sourceFile.path && /\.js$/.test(sourceFile.path)) {
sourceFile.contents = sourceFile.contents.replace(/\([^.]+\.registerAndGetAmdImageURL\(([^)]+)\)\)/g, (_, m0) => {
let imagePath = m0;
// remove `` or ''
if ((imagePath.charAt(0) === '`' && imagePath.charAt(imagePath.length - 1) === '`')
|| (imagePath.charAt(0) === '\'' && imagePath.charAt(imagePath.length - 1) === '\'')) {
imagePath = imagePath.substr(1, imagePath.length - 2);
}
if (!/\.(png|svg)$/.test(imagePath)) {
console.log(`original: ${_}`);
return _;
}
const repoLocation = path.join(src, imagePath);
const absoluteLocation = path.join(REPO_ROOT_PATH, repoLocation);
if (!fs.existsSync(absoluteLocation)) {
const message = `Invalid amd image url in file ${sourceFile.path}: ${imagePath}`;
console.log(message);
throw new Error(message);
}
const fileContents = fs.readFileSync(absoluteLocation);
const mime = /\.svg$/.test(imagePath) ? 'image/svg+xml' : 'image/png';
// Mark the file as inlined so we don't ship it by itself
result.cssInlinedResources.push(repoLocation);
return `("data:${mime};base64,${fileContents.toString('base64')}")`;
});
}
}
}
return result;
}
/**
* Wrap around uglify and allow the preserveComments function
* to have a file "context" to include our copyright only once per file.
@@ -202,9 +244,6 @@ function uglifyWithCopyrights() {
const output = input
.pipe(flatmap((stream, f) => {
return stream.pipe(minify({
compress: {
hoist_funs: true // required due to https://github.com/microsoft/vscode/issues/80202
},
output: {
comments: preserveComments(f),
max_line_len: 1024
+49 -3
View File
@@ -6,6 +6,7 @@
'use strict';
import * as es from 'event-stream';
import * as fs from 'fs';
import * as gulp from 'gulp';
import * as concat from 'gulp-concat';
import * as minifyCSS from 'gulp-cssnano';
@@ -159,6 +160,10 @@ export interface IOptimizeTaskOpts {
* (emit bundleInfo.json file)
*/
bundleInfo: boolean;
/**
* replace calls to `registerAndGetAmdImageURL` with data uris
*/
inlineAmdImages: boolean;
/**
* (out folder name)
*/
@@ -192,6 +197,14 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
bundle.bundle(entryPoints, loaderConfig, function (err, result) {
if (err || !result) { return bundlesStream.emit('error', JSON.stringify(err)); }
if (opts.inlineAmdImages) {
try {
result = inlineAmdImages(src, result);
} catch (err) {
return bundlesStream.emit('error', JSON.stringify(err));
}
}
toBundleStream(src, bundledFileHeader, result.files).pipe(bundlesStream);
// Remove css inlined resources
@@ -236,6 +249,42 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
};
}
function inlineAmdImages(src: string, result: bundle.IBundleResult): bundle.IBundleResult {
for (const outputFile of result.files) {
for (const sourceFile of outputFile.sources) {
if (sourceFile.path && /\.js$/.test(sourceFile.path)) {
sourceFile.contents = sourceFile.contents.replace(/\([^.]+\.registerAndGetAmdImageURL\(([^)]+)\)\)/g, (_, m0) => {
let imagePath = m0;
// remove `` or ''
if ((imagePath.charAt(0) === '`' && imagePath.charAt(imagePath.length - 1) === '`')
|| (imagePath.charAt(0) === '\'' && imagePath.charAt(imagePath.length - 1) === '\'')) {
imagePath = imagePath.substr(1, imagePath.length - 2);
}
if (!/\.(png|svg)$/.test(imagePath)) {
console.log(`original: ${_}`);
return _;
}
const repoLocation = path.join(src, imagePath);
const absoluteLocation = path.join(REPO_ROOT_PATH, repoLocation);
if (!fs.existsSync(absoluteLocation)) {
const message = `Invalid amd image url in file ${sourceFile.path}: ${imagePath}`;
console.log(message);
throw new Error(message);
}
const fileContents = fs.readFileSync(absoluteLocation);
const mime = /\.svg$/.test(imagePath) ? 'image/svg+xml' : 'image/png';
// Mark the file as inlined so we don't ship it by itself
result.cssInlinedResources.push(repoLocation);
return `("data:${mime};base64,${fileContents.toString('base64')}")`;
});
}
}
}
return result;
}
declare class FileWithCopyright extends VinylFile {
public __hasOurCopyright: boolean;
}
@@ -278,9 +327,6 @@ function uglifyWithCopyrights(): NodeJS.ReadWriteStream {
const output = input
.pipe(flatmap((stream, f) => {
return stream.pipe(minify({
compress: {
hoist_funs: true // required due to https://github.com/microsoft/vscode/issues/80202
},
output: {
comments: preserveComments(<FileWithCopyright>f),
max_line_len: 1024
@@ -11,6 +11,9 @@ const Lint = require("tslint");
*/
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
if (/\.d.ts$/.test(sourceFile.fileName)) {
return [];
}
return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions()));
}
}
@@ -11,6 +11,9 @@ import * as Lint from 'tslint';
*/
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
if (/\.d.ts$/.test(sourceFile.fileName)) {
return [];
}
return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions()));
}
}
+4 -5
View File
@@ -7,10 +7,9 @@ declare module "gulp-tsb" {
}
export interface IncrementalCompiler {
(token?:ICancellationToken): NodeJS.ReadWriteStream;
// program?: ts.Program;
(token?: ICancellationToken): NodeJS.ReadWriteStream;
src(): NodeJS.ReadStream;
}
export function create(projectPath: string, existingOptions: any, verbose?: boolean, onError?: (message: any) => void): IncrementalCompiler;
export function create(configOrName: { [option: string]: string | number | boolean; } | string, verbose?: boolean, json?: boolean, onError?: (message: any) => void): IncrementalCompiler;
}
}
+3 -2
View File
@@ -148,8 +148,9 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName,
}
});
}
result = result.replace(/export default/g, 'export');
result = result.replace(/export declare/g, 'export');
result = result.replace(/export default /g, 'export ');
result = result.replace(/export declare /g, 'export ');
result = result.replace(/declare /g, '');
if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
result = result.replace(/const enum/, 'enum');
enums.push(result);
+3 -2
View File
@@ -178,8 +178,9 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
}
});
}
result = result.replace(/export default/g, 'export');
result = result.replace(/export declare/g, 'export');
result = result.replace(/export default /g, 'export ');
result = result.replace(/export declare /g, 'export ');
result = result.replace(/declare /g, '');
if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
result = result.replace(/const enum/, 'enum');
+1
View File
@@ -62,6 +62,7 @@ export interface ICommandHandler {
#includeAll(vs/editor/common/editorCommon;editorOptions.=>): IScrollEvent
#includeAll(vs/editor/common/model/textModelEvents):
#includeAll(vs/editor/common/controller/cursorEvents):
#include(vs/platform/accessibility/common/accessibility): AccessibilitySupport
#includeAll(vs/editor/common/config/editorOptions):
#includeAll(vs/editor/browser/editorBrowser;editorCommon.=>;editorOptions.=>):
#include(vs/editor/common/config/fontInfo): FontInfo, BareFontInfo
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "monaco-editor-core",
"private": true,
"version": "0.16.0",
"version": "0.18.0",
"description": "A browser based code editor",
"author": "Microsoft Corporation",
"license": "MIT",
-13
View File
@@ -80,19 +80,6 @@ if (fs.existsSync(processTreeDts)) {
fs.unlinkSync(processTreeDts);
}
// Rewrite the @types/node typings avoid a conflict with es2018 typings.
// This is caused by our build not understanding `typesVersions` in the package.json
//
// TODO: Fix this
{
console.log('Rewriting node_modules/@types/node to workaround lack of typesVersions support');
const indexPath = path.join('node_modules', '@types', 'node', 'index.d.ts');
const contents = fs.readFileSync(indexPath).toString()
.replace(/interface IteratorResult<T> \{ \}/, '// VSCODE EDIT — remove IteratorResult\n// interface IteratorResult<T> { }');
fs.writeFileSync(indexPath, contents);
}
function getInstalledVersion(packageName, cwd) {
const opts = {};
if (cwd) {
+1 -1
View File
@@ -40,7 +40,7 @@
"mime": "^1.3.4",
"minimist": "^1.2.0",
"request": "^2.85.0",
"terser": "^4.2.1",
"terser": "4.3.1",
"tslint": "^5.9.1",
"typescript": "3.6.2",
"vsce": "1.48.0",
+10 -1
View File
@@ -2169,7 +2169,7 @@ supports-color@^5.3.0:
dependencies:
has-flag "^3.0.0"
terser@*, terser@^4.2.1:
terser@*:
version "4.2.1"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.2.1.tgz#1052cfe17576c66e7bc70fcc7119f22b155bdac1"
integrity sha512-cGbc5utAcX4a9+2GGVX4DsenG6v0x3glnDi5hx8816X1McEAwPlPgRtXPJzSBsbpILxZ8MQMT0KvArLuE0HP5A==
@@ -2178,6 +2178,15 @@ terser@*, terser@^4.2.1:
source-map "~0.6.1"
source-map-support "~0.5.12"
terser@4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.1.tgz#09820bcb3398299c4b48d9a86aefc65127d0ed65"
integrity sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==
dependencies:
commander "^2.20.0"
source-map "~0.6.1"
source-map-support "~0.5.12"
through2@2.X, through2@^2.0.0, through2@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
@@ -745,6 +745,10 @@
{
"fileMatch": "*.css-data.json",
"url": "https://raw.githubusercontent.com/Microsoft/vscode-css-languageservice/master/docs/customData.schema.json"
},
{
"fileMatch": "package.json",
"url": "./schemas/package.schema.json"
}
]
},
@@ -0,0 +1,20 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "CSS contributions to package.json",
"type": "object",
"properties": {
"contributes": {
"type": "object",
"properties": {
"css.customData": {
"type": "array",
"markdownDescription": "A list of relative file paths pointing to JSON files following the [custom data format](https://github.com/Microsoft/vscode-css-languageservice/blob/master/docs/customData.md).\n\nVS Code loads custom data on startup to enhance its CSS support for the custom CSS properties, at directives, pseudo classes and pseudo elements you specify in the JSON files.\n\nThe file paths are relative to workspace and only workspace folder settings are considered.",
"items": {
"type": "string",
"description": "Relative path to a CSS custom data file"
}
}
}
}
}
}
@@ -128,7 +128,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
const capabilities: ServerCapabilities = {
// Tell the client that the server works in FULL text document sync mode
textDocumentSync: documents.syncKind,
completionProvider: snippetSupport ? { resolveProvider: false, triggerCharacters: ['/'] } : undefined,
completionProvider: snippetSupport ? { resolveProvider: false, triggerCharacters: ['/', '-'] } : undefined,
hoverProvider: true,
documentSymbolProvider: true,
referencesProvider: true,
@@ -231,6 +231,21 @@ export function expandEmmetAbbreviation(args: any): Thenable<boolean | undefined
return fallbackTab();
}
if (vscode.window.activeTextEditor.selections.length === 1 &&
vscode.window.activeTextEditor.selection.isEmpty
) {
const anchor = vscode.window.activeTextEditor.selection.anchor;
if (anchor.character === 0) {
return fallbackTab();
}
const prevPositionAnchor = anchor.translate(0, -1);
const prevText = vscode.window.activeTextEditor.document.getText(new vscode.Range(prevPositionAnchor, anchor));
if (prevText === ' ' || prevText === '\t') {
return fallbackTab();
}
}
args = args || {};
if (!args['language']) {
args['language'] = vscode.window.activeTextEditor.document.languageId;
+11 -14
View File
@@ -3,13 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { window, workspace, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider, ThemeColor } from 'vscode';
import { window, workspace, Uri, Disposable, Event, EventEmitter, Decoration, DecorationProvider, ThemeColor } from 'vscode';
import * as path from 'path';
import { Repository, GitResourceGroup } from './repository';
import { Model } from './model';
import { debounce } from './decorators';
import { filterEvent, dispose, anyEvent, fireEvent } from './util';
import { GitErrorCodes, Status } from './api/git';
import { GitErrorCodes } from './api/git';
type Callback = { resolve: (status: boolean) => void, reject: (err: any) => void };
@@ -29,7 +29,7 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
this.disposables.push(window.registerDecorationProvider(this));
}
provideDecoration(uri: Uri): Promise<DecorationData | undefined> {
provideDecoration(uri: Uri): Promise<Decoration | undefined> {
const repository = this.model.getRepository(uri);
if (!repository) {
@@ -48,7 +48,7 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
this.checkIgnoreSoon();
}).then(ignored => {
if (ignored) {
return <DecorationData>{
return <Decoration>{
priority: 3,
color: new ThemeColor('gitDecoration.ignoredResourceForeground')
};
@@ -89,7 +89,7 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
class GitDecorationProvider implements DecorationProvider {
private static SubmoduleDecorationData: DecorationData = {
private static SubmoduleDecorationData: Decoration = {
title: 'Submodule',
letter: 'S',
color: new ThemeColor('gitDecoration.submoduleResourceForeground')
@@ -99,7 +99,7 @@ class GitDecorationProvider implements DecorationProvider {
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
private disposables: Disposable[] = [];
private decorations = new Map<string, DecorationData>();
private decorations = new Map<string, Decoration>();
constructor(private repository: Repository) {
this.disposables.push(
@@ -109,7 +109,7 @@ class GitDecorationProvider implements DecorationProvider {
}
private onDidRunGitStatus(): void {
let newDecorations = new Map<string, DecorationData>();
let newDecorations = new Map<string, Decoration>();
this.collectSubmoduleDecorationData(newDecorations);
this.collectDecorationData(this.repository.indexGroup, newDecorations);
@@ -121,25 +121,22 @@ class GitDecorationProvider implements DecorationProvider {
this._onDidChangeDecorations.fire([...uris.values()].map(value => Uri.parse(value, true)));
}
private collectDecorationData(group: GitResourceGroup, bucket: Map<string, DecorationData>): void {
private collectDecorationData(group: GitResourceGroup, bucket: Map<string, Decoration>): void {
group.resourceStates.forEach(r => {
if (r.resourceDecoration
&& r.type !== Status.DELETED
&& r.type !== Status.INDEX_DELETED
) {
if (r.resourceDecoration) {
// not deleted and has a decoration
bucket.set(r.original.toString(), r.resourceDecoration);
}
});
}
private collectSubmoduleDecorationData(bucket: Map<string, DecorationData>): void {
private collectSubmoduleDecorationData(bucket: Map<string, Decoration>): void {
for (const submodule of this.repository.submodules) {
bucket.set(Uri.file(path.join(this.repository.root, submodule.path)).toString(), GitDecorationProvider.SubmoduleDecorationData);
}
}
provideDecoration(uri: Uri): DecorationData | undefined {
provideDecoration(uri: Uri): Decoration | undefined {
return this.decorations.get(uri.toString());
}
+1 -1
View File
@@ -1766,7 +1766,7 @@ export class Repository {
}
const raw = await readfile(templatePath, 'utf8');
return raw.replace(/\n?#.*/g, '');
return raw.replace(/^\s*#.*$\n?/gm, '');
} catch (err) {
return '';
+4 -7
View File
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env, ProgressOptions, CancellationToken } from 'vscode';
import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, Decoration, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env, ProgressOptions, CancellationToken } from 'vscode';
import { Repository as BaseRepository, Commit, Stash, GitError, Submodule, CommitOptions, ForcePushMode } from './git';
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, combinedDisposable } from './util';
import { memoize, throttle, debounce } from './decorators';
@@ -157,10 +157,7 @@ export class Resource implements SourceControlResourceState {
const tooltip = this.tooltip;
const strikeThrough = this.strikeThrough;
const faded = this.faded;
const letter = this.letter;
const color = this.color;
return { strikeThrough, faded, tooltip, light, dark, letter, color, source: 'git.resource' /*todo@joh*/ };
return { strikeThrough, faded, tooltip, light, dark };
}
get letter(): string {
@@ -247,12 +244,12 @@ export class Resource implements SourceControlResourceState {
}
}
get resourceDecoration(): DecorationData {
get resourceDecoration(): Decoration {
const title = this.tooltip;
const letter = this.letter;
const color = this.color;
const priority = this.priority;
return { bubble: true, source: 'git.resource', title, letter, color, priority };
return { bubble: true, title, letter, color, priority };
}
constructor(
+1
View File
@@ -71,6 +71,7 @@ class SyncStatusBar {
const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.enableStatusBarSync'));
onEnablementChange(this.updateEnablement, this, this.disposables);
this.updateEnablement();
this._onDidChange.fire();
}
+11 -4
View File
@@ -62,8 +62,10 @@ function getOutputChannel(): vscode.OutputChannel {
function showError() {
vscode.window.showWarningMessage(localize('gulpTaskDetectError', 'Problem finding gulp tasks. See the output for more information.'),
localize('gulpShowOutput', 'Go to output')).then(() => {
_channel.show(true);
localize('gulpShowOutput', 'Go to output')).then((choice) => {
if (choice !== undefined) {
_channel.show(true);
}
});
}
@@ -156,8 +158,13 @@ class FolderDetector {
try {
let { stdout, stderr } = await exec(commandLine, { cwd: rootPath });
if (stderr && stderr.length > 0) {
getOutputChannel().appendLine(stderr);
showError();
// Filter out "No license field"
const errors = stderr.split('\n');
errors.pop(); // The last line is empty.
if (!errors.every(value => value.indexOf('No license field') >= 0)) {
getOutputChannel().appendLine(stderr);
showError();
}
}
let result: vscode.Task[] = [];
if (stdout) {
@@ -188,6 +188,10 @@
{
"fileMatch": "*.html-data.json",
"url": "https://raw.githubusercontent.com/Microsoft/vscode-html-languageservice/master/docs/customData.schema.json"
},
{
"fileMatch": "package.json",
"url": "./schemas/package.schema.json"
}
]
},
@@ -0,0 +1,20 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "HTML contributions to package.json",
"type": "object",
"properties": {
"contributes": {
"type": "object",
"properties": {
"html.customData": {
"type": "array",
"markdownDescription": "A list of relative file paths pointing to JSON files following the [custom data format](https://github.com/Microsoft/vscode-html-languageservice/blob/master/docs/customData.md).\n\nVS Code loads custom data on startup to enhance its HTML support for the custom HTML tags, attributes and attribute values you specify in the JSON files.\n\nThe file paths are relative to workspace and only workspace folder settings are considered.",
"items": {
"type": "string",
"description": "Relative path to a HTML custom data file"
}
}
}
}
}
}
@@ -46,8 +46,8 @@ suite('HTML Embedded Formatting', () => {
}
function assertFormatWithFixture(fixtureName: string, expectedPath: string, options?: any, formatOptions?: FormattingOptions): void {
let input = fs.readFileSync(path.join(__dirname, 'fixtures', 'inputs', fixtureName)).toString().replace(/\r\n/mg, '\n');
let expected = fs.readFileSync(path.join(__dirname, 'fixtures', 'expected', expectedPath)).toString().replace(/\r\n/mg, '\n');
let input = fs.readFileSync(path.join(__dirname, '..', '..', 'src', 'test', 'fixtures', 'inputs', fixtureName)).toString().replace(/\r\n/mg, '\n');
let expected = fs.readFileSync(path.join(__dirname, '..', '..', 'src', 'test', 'fixtures', 'expected', expectedPath)).toString().replace(/\r\n/mg, '\n');
assertFormat(input, expected, options, formatOptions, expectedPath);
}
@@ -208,4 +208,4 @@ preserve_newlines: true
unformatted: Array(1)["wbr"]
wrap_attributes: "auto"
wrap_attributes_indent_size: undefined
wrap_line_length: 120*/
wrap_line_length: 120*/
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,13 +1,7 @@
{
"extends": "../../shared.tsconfig.json",
"compilerOptions": {
"outDir": "./dist/",
"module": "commonjs",
"target": "es6",
"jsx": "react",
"sourceMap": true,
"strict": true,
"strictBindCallApply": true,
"noImplicitAny": true,
"noUnusedLocals": true
"jsx": "react"
}
}
}
@@ -1,7 +1,7 @@
[
{
"c": "{",
"t": "source.json.comments meta.structure.dictionary.json.comments punctuation.definition.dictionary.begin.json.comments",
"t": "source.json meta.structure.dictionary.json punctuation.definition.dictionary.begin.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -12,7 +12,7 @@
},
{
"c": "\t",
"t": "source.json.comments meta.structure.dictionary.json.comments",
"t": "source.json meta.structure.dictionary.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -23,7 +23,7 @@
},
{
"c": "\"",
"t": "source.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments punctuation.support.type.property-name.begin.json.comments",
"t": "source.json meta.structure.dictionary.json string.json support.type.property-name.json punctuation.support.type.property-name.begin.json",
"r": {
"dark_plus": "support.type.property-name: #9CDCFE",
"light_plus": "support.type.property-name.json: #0451A5",
@@ -34,7 +34,7 @@
},
{
"c": "compilerOptions",
"t": "source.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments",
"t": "source.json meta.structure.dictionary.json string.json support.type.property-name.json",
"r": {
"dark_plus": "support.type.property-name: #9CDCFE",
"light_plus": "support.type.property-name.json: #0451A5",
@@ -45,7 +45,7 @@
},
{
"c": "\"",
"t": "source.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments punctuation.support.type.property-name.end.json.comments",
"t": "source.json meta.structure.dictionary.json string.json support.type.property-name.json punctuation.support.type.property-name.end.json",
"r": {
"dark_plus": "support.type.property-name: #9CDCFE",
"light_plus": "support.type.property-name.json: #0451A5",
@@ -56,7 +56,7 @@
},
{
"c": ":",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments punctuation.separator.dictionary.key-value.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.separator.dictionary.key-value.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -67,7 +67,7 @@
},
{
"c": " ",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -78,7 +78,7 @@
},
{
"c": "{",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments punctuation.definition.dictionary.begin.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json punctuation.definition.dictionary.begin.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -89,7 +89,7 @@
},
{
"c": "\t\t",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -100,7 +100,7 @@
},
{
"c": "\"",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments punctuation.support.type.property-name.begin.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.json support.type.property-name.json punctuation.support.type.property-name.begin.json",
"r": {
"dark_plus": "support.type.property-name: #9CDCFE",
"light_plus": "support.type.property-name.json: #0451A5",
@@ -111,7 +111,7 @@
},
{
"c": "target",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.json support.type.property-name.json",
"r": {
"dark_plus": "support.type.property-name: #9CDCFE",
"light_plus": "support.type.property-name.json: #0451A5",
@@ -122,7 +122,7 @@
},
{
"c": "\"",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments string.json.comments support.type.property-name.json.comments punctuation.support.type.property-name.end.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json string.json support.type.property-name.json punctuation.support.type.property-name.end.json",
"r": {
"dark_plus": "support.type.property-name: #9CDCFE",
"light_plus": "support.type.property-name.json: #0451A5",
@@ -133,7 +133,7 @@
},
{
"c": ":",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments punctuation.separator.dictionary.key-value.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json punctuation.separator.dictionary.key-value.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -144,7 +144,7 @@
},
{
"c": " ",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -155,7 +155,7 @@
},
{
"c": "\"",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments string.quoted.double.json.comments punctuation.definition.string.begin.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json punctuation.definition.string.begin.json",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
@@ -166,7 +166,7 @@
},
{
"c": "es6",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments string.quoted.double.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
@@ -177,7 +177,7 @@
},
{
"c": "\"",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments string.quoted.double.json.comments punctuation.definition.string.end.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json punctuation.definition.string.end.json",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
@@ -188,7 +188,7 @@
},
{
"c": "\t",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -199,7 +199,7 @@
},
{
"c": "}",
"t": "source.json.comments meta.structure.dictionary.json.comments meta.structure.dictionary.value.json.comments meta.structure.dictionary.json.comments punctuation.definition.dictionary.end.json.comments",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json punctuation.definition.dictionary.end.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -210,7 +210,7 @@
},
{
"c": "}",
"t": "source.json.comments meta.structure.dictionary.json.comments punctuation.definition.dictionary.end.json.comments",
"t": "source.json meta.structure.dictionary.json punctuation.definition.dictionary.end.json",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -78,21 +78,26 @@ export function activate(context: vscode.ExtensionContext) {
}
const { updateUrl, commit, quality, serverDataFolderName, dataFolderName } = getProductConfiguration();
const serverCommand = process.platform === 'win32' ? 'server.bat' : 'server.sh';
const commandArgs = ['--port=0', '--disable-telemetry'];
const env = getNewEnv();
const remoteDataDir = process.env['TESTRESOLVER_DATA_FOLDER'] || path.join(os.homedir(), serverDataFolderName || `${dataFolderName}-testresolver`);
env['VSCODE_AGENT_FOLDER'] = remoteDataDir;
outputChannel.appendLine(`Using data folder at ${remoteDataDir}`);
if (!commit || env['TEST_RESOLVER_USE_SERVER_FROM_SOURCES']) { // dev mode
if (!commit) { // dev mode
const serverCommand = process.platform === 'win32' ? 'server.bat' : 'server.sh';
const vscodePath = path.resolve(path.join(context.extensionPath, '..', '..'));
const serverCommandPath = path.join(vscodePath, 'resources', 'server', 'bin-dev', serverCommand);
extHostProcess = cp.spawn(serverCommandPath, commandArgs, { env, cwd: vscodePath });
} else {
const serverBin = path.join(remoteDataDir, 'bin');
progress.report({ message: 'Installing VSCode Server' });
const serverLocation = await downloadAndUnzipVSCodeServer(updateUrl, commit, quality, serverBin);
const serverCommand = process.platform === 'win32' ? 'server.cmd' : 'server.sh';
let serverLocation = env['VSCODE_REMOTE_SERVER_PATH']; // support environment variable to specify location of server on disk
if (!serverLocation) {
const serverBin = path.join(remoteDataDir, 'bin');
progress.report({ message: 'Installing VSCode Server' });
serverLocation = await downloadAndUnzipVSCodeServer(updateUrl, commit, quality, serverBin);
}
outputChannel.appendLine(`Using server build at ${serverLocation}`);
extHostProcess = cp.spawn(path.join(serverLocation, serverCommand), commandArgs, { env, cwd: serverLocation });
+3 -4
View File
@@ -1,7 +1,7 @@
{
"name": "code-oss-dev",
"version": "1.39.0",
"distro": "323c0a11187dcde94de3a5d913cd44437e85369a",
"distro": "8516b3c6e37976c7f4a183ec1196a939f0ff11bf",
"author": {
"name": "Microsoft Corporation"
},
@@ -52,7 +52,7 @@
"vscode-ripgrep": "^1.5.6",
"vscode-sqlite3": "4.0.8",
"vscode-textmate": "^4.2.2",
"xterm": "3.15.0-beta101",
"xterm": "3.15.0-beta108",
"xterm-addon-search": "0.2.0-beta5",
"xterm-addon-web-links": "0.1.0-beta10",
"yauzl": "^2.9.2",
@@ -97,7 +97,7 @@
"gulp-rename": "^1.2.0",
"gulp-replace": "^0.5.4",
"gulp-shell": "^0.6.5",
"gulp-tsb": "2.0.7",
"gulp-tsb": "4.0.1",
"gulp-tslint": "^8.1.3",
"gulp-untar": "^0.0.7",
"gulp-vinyl-zip": "^2.1.2",
@@ -120,7 +120,6 @@
"optimist": "0.3.5",
"p-all": "^1.0.0",
"pump": "^1.0.1",
"puppeteer": "^1.19.0",
"queue": "3.0.6",
"rcedit": "^1.1.0",
"rimraf": "^2.2.8",
+1 -1
View File
@@ -21,7 +21,7 @@
"vscode-proxy-agent": "0.4.0",
"vscode-ripgrep": "^1.5.6",
"vscode-textmate": "^4.2.2",
"xterm": "3.15.0-beta101",
"xterm": "3.15.0-beta108",
"xterm-addon-search": "0.2.0-beta5",
"xterm-addon-web-links": "0.1.0-beta10",
"yauzl": "^2.9.2",
+1 -1
View File
@@ -6,7 +6,7 @@
"onigasm-umd": "^2.2.2",
"semver-umd": "^5.5.3",
"vscode-textmate": "^4.2.2",
"xterm": "3.15.0-beta101",
"xterm": "3.15.0-beta108",
"xterm-addon-search": "0.2.0-beta5",
"xterm-addon-web-links": "0.1.0-beta10"
}
+4 -4
View File
@@ -109,7 +109,7 @@ xterm-addon-web-links@0.1.0-beta10:
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23"
integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg==
xterm@3.15.0-beta101:
version "3.15.0-beta101"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta101.tgz#38ffa0df5a3e9bdcb1818e74fe59b2f98b0fff69"
integrity sha512-HRa7+FDqQ8iWBTvb1Ni+uMGILnu6k9mF7JHMHRHfWxFoQlSoGYCyfdyXlJjk68YN8GsEQREmrII6cPLiQizdEQ==
xterm@3.15.0-beta108:
version "3.15.0-beta108"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta108.tgz#d113f6d1e4d4b7645ab3ff002c81a4dba8a78a28"
integrity sha512-btZXgI9BeawFzitw3EZvFPsH3kfBgJS55LOdz9DjEany3y9FfvmnVhq7wn4x1PmTU/djHobGGhMNemxptk+ryg==
+4 -4
View File
@@ -1173,10 +1173,10 @@ xterm-addon-web-links@0.1.0-beta10:
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23"
integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg==
xterm@3.15.0-beta101:
version "3.15.0-beta101"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta101.tgz#38ffa0df5a3e9bdcb1818e74fe59b2f98b0fff69"
integrity sha512-HRa7+FDqQ8iWBTvb1Ni+uMGILnu6k9mF7JHMHRHfWxFoQlSoGYCyfdyXlJjk68YN8GsEQREmrII6cPLiQizdEQ==
xterm@3.15.0-beta108:
version "3.15.0-beta108"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta108.tgz#d113f6d1e4d4b7645ab3ff002c81a4dba8a78a28"
integrity sha512-btZXgI9BeawFzitw3EZvFPsH3kfBgJS55LOdz9DjEany3y9FfvmnVhq7wn4x1PmTU/djHobGGhMNemxptk+ryg==
yauzl@^2.9.2:
version "2.10.0"
+1 -1
View File
@@ -26,7 +26,7 @@ if grep -qi Microsoft /proc/version; then
# use the Remote WSL extension if installed
WSL_EXT_ID="ms-vscode-remote.remote-wsl"
if [ $WSL_BUILD -ge 41955 ]; then
if [ $WSL_BUILD -ge 41955 -a $WSL_BUILD -lt 41959 ]; then
# WSL2 in workaround for https://github.com/microsoft/WSL/issues/4337
CWD="$(pwd)"
cd "$VSCODE_PATH"
+6 -3
View File
@@ -5,11 +5,14 @@ pushd %~dp0\..
set VSCODEUSERDATADIR=%TMP%\vscodeuserfolder-%RANDOM%-%TIME:~6,5%
:: Figure out which Electron to use for running tests
if "%INTEGRATION_TEST_ELECTRON_PATH%"=="" (
:: code.bat makes sure Test Extensions are compiled
:: Run out of sources: no need to compile as code.sh takes care of it
set INTEGRATION_TEST_ELECTRON_PATH=.\scripts\code.bat
echo "Running integration tests out of sources."
) else (
:: Compile Test Extensions
:: Run from a built: need to compile all test extensions
call yarn gulp compile-extension:vscode-api-tests
call yarn gulp compile-extension:vscode-colorize-tests
call yarn gulp compile-extension:markdown-language-features
@@ -18,7 +21,7 @@ if "%INTEGRATION_TEST_ELECTRON_PATH%"=="" (
call yarn gulp compile-extension:html-language-features-server
call yarn gulp compile-extension:json-language-features-server
echo "Using %INTEGRATION_TEST_ELECTRON_PATH% as Electron path"
echo "Running integration tests with '%INTEGRATION_TEST_ELECTRON_PATH%' as build."
)
:: Integration & performance tests in AMD
+5 -3
View File
@@ -15,10 +15,12 @@ cd $ROOT
# Figure out which Electron to use for running tests
if [ -z "$INTEGRATION_TEST_ELECTRON_PATH" ]
then
# code.sh makes sure Test Extensions are compiled
# Run out of sources: no need to compile as code.sh takes care of it
INTEGRATION_TEST_ELECTRON_PATH="./scripts/code.sh"
echo "Running integration tests out of sources."
else
# Compile Test Extensions
# Run from a built: need to compile all test extensions
yarn gulp compile-extension:vscode-api-tests
yarn gulp compile-extension:vscode-colorize-tests
yarn gulp compile-extension:markdown-language-features
@@ -27,7 +29,7 @@ else
yarn gulp compile-extension:html-language-features-server
yarn gulp compile-extension:json-language-features-server
echo "Using $INTEGRATION_TEST_ELECTRON_PATH as Electron path"
echo "Running integration tests with '$INTEGRATION_TEST_ELECTRON_PATH' as build."
fi
# Integration tests in AMD
+1 -1
View File
@@ -34,7 +34,7 @@ exports.load = function (modulePaths, resultCallback, options) {
* // configuration: IWindowConfiguration
* @type {{
* zoomLevel?: number,
* extensionDevelopmentPath?: string | string[],
* extensionDevelopmentPath?: string[],
* extensionTestsPath?: string,
* userEnv?: { [key: string]: string | undefined },
* appRoot?: string,
-8
View File
@@ -15,14 +15,6 @@ exports.base = [{
dest: 'vs/base/worker/workerMain.js'
}];
exports.serviceWorker = [{
name: 'vs/workbench/contrib/resources/browser/resourceServiceWorker',
// include: ['vs/editor/common/services/editorSimpleWorker'],
prepend: ['vs/loader.js'],
append: ['vs/workbench/contrib/resources/browser/resourceServiceWorkerMain'],
dest: 'vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.js'
}];
exports.workerExtensionHost = [entrypoint('vs/workbench/services/extensions/worker/extensionHostWorker')];
exports.workbenchDesktop = require('./vs/workbench/buildfile.desktop').collectModules();
+4 -1
View File
@@ -24,6 +24,9 @@
"./vs"
],
"exclude": [
"./typings/require-monaco.d.ts"
"./typings/require-monaco.d.ts",
"./typings/xterm.d.ts",
"./typings/xterm-addon-search.d.ts",
"./typings/xterm-addon-web-links.d.ts"
]
}
-36
View File
@@ -1043,39 +1043,3 @@ declare module 'xterm' {
addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable;
}
}
// Modifications to official .d.ts below
declare module 'xterm' {
interface TerminalCore {
_onScroll: IEventEmitter<number>;
_onKey: IEventEmitter<{ key: string }>;
_charSizeService: {
width: number;
height: number;
};
_coreService: {
triggerDataEvent(data: string, wasUserInput?: boolean): void;
}
_renderService: {
_renderer: {
_renderLayers: any[];
};
_onIntersectionChange: any;
};
}
interface IEventEmitter<T> {
fire(e: T): void;
}
interface Terminal {
_core: TerminalCore;
}
}
+3 -2
View File
@@ -14,6 +14,7 @@ import { parse } from 'vs/base/common/marshalling';
import { cloneAndChange } from 'vs/base/common/objects';
import { escape } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
export interface MarkdownRenderOptions extends FormattedTextRenderOptions {
codeBlockRenderer?: (modeId: string, value: string) => Promise<string>;
@@ -172,9 +173,9 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
renderer
};
const allowedSchemes = ['http', 'https', 'mailto', 'data'];
const allowedSchemes = [Schemas.http, Schemas.https, Schemas.mailto, Schemas.data, Schemas.file, Schemas.vscodeRemote];
if (markdown.isTrusted) {
allowedSchemes.push('command');
allowedSchemes.push(Schemas.command);
}
const renderedMarkdown = marked.parse(markdown.value, markedOptions);
-2
View File
@@ -92,8 +92,6 @@ export class Dialog extends Disposable {
checkboxMessageElement.innerText = this.options.checkboxLabel;
}
const toolbarRowElement = this.element.appendChild($('.dialog-toolbar-row'));
this.toolbarContainer = toolbarRowElement.appendChild($('.dialog-toolbar'));
}
@@ -64,6 +64,10 @@
outline: none;
}
.monaco-inputbox > .wrapper > textarea.input.empty {
white-space: nowrap;
}
.monaco-inputbox > .wrapper > textarea.input::-webkit-scrollbar {
display: none;
}
+4 -2
View File
@@ -159,7 +159,7 @@ export class InputBox extends Widget {
let tagName = this.options.flexibleHeight ? 'textarea' : 'input';
let wrapper = dom.append(this.element, $('.wrapper'));
this.input = dom.append(wrapper, $(tagName + '.input'));
this.input = dom.append(wrapper, $(tagName + '.input.empty'));
this.input.setAttribute('autocorrect', 'off');
this.input.setAttribute('autocapitalize', 'off');
this.input.setAttribute('spellcheck', 'false');
@@ -240,6 +240,7 @@ export class InputBox extends Widget {
}
public setPlaceHolder(placeHolder: string): void {
this.placeholder = placeHolder;
this.input.setAttribute('placeholder', placeHolder);
this.input.title = placeHolder;
}
@@ -506,6 +507,7 @@ export class InputBox extends Widget {
this.validate();
this.updateMirror();
dom.toggleClass(this.input, 'empty', !this.value);
if (this.state === 'open' && this.contextViewProvider) {
this.contextViewProvider.layout();
@@ -517,7 +519,7 @@ export class InputBox extends Widget {
return;
}
const value = this.value || this.placeholder;
const value = this.value;
const lastCharCode = value.charCodeAt(value.length - 1);
const suffix = lastCharCode === 10 ? ' ' : '';
const mirrorTextContent = value + suffix;
+6 -8
View File
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { getOrDefault } from 'vs/base/common/objects';
import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
import * as DOM from 'vs/base/browser/dom';
import { Event, Emitter } from 'vs/base/common/event';
@@ -188,7 +188,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
private currentDragFeedbackDisposable: IDisposable = Disposable.None;
private onDragLeaveTimeout: IDisposable = Disposable.None;
private disposables: IDisposable[];
private readonly disposables: DisposableStore = new DisposableStore();
private _onDidChangeContentHeight = new Emitter<number>();
readonly onDidChangeContentHeight: Event<number> = Event.latch(this._onDidChangeContentHeight.event);
@@ -214,7 +214,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
this.renderers.set(renderer.templateId, renderer);
}
this.cache = new RowCache(this.renderers);
this.cache = this.disposables.add(new RowCache(this.renderers));
this.lastRenderTop = 0;
this.lastRenderHeight = 0;
@@ -238,18 +238,16 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
this.rowsContainer.className = 'monaco-list-rows';
Gesture.addTarget(this.rowsContainer);
this.scrollableElement = new ScrollableElement(this.rowsContainer, {
this.scrollableElement = this.disposables.add(new ScrollableElement(this.rowsContainer, {
alwaysConsumeMouseWheel: true,
horizontal: this.horizontalScrolling ? ScrollbarVisibility.Auto : ScrollbarVisibility.Hidden,
vertical: getOrDefault(options, o => o.verticalScrollMode, DefaultOptions.verticalScrollMode),
useShadows: getOrDefault(options, o => o.useShadows, DefaultOptions.useShadows)
});
}));
this.domNode.appendChild(this.scrollableElement.getDomNode());
container.appendChild(this.domNode);
this.disposables = [this.scrollableElement, this.cache];
this.scrollableElement.onScroll(this.onScroll, this, this.disposables);
domEvent(this.rowsContainer, TouchEventType.Change)(this.onTouchChange, this, this.disposables);
@@ -1178,6 +1176,6 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
this.domNode.parentNode.removeChild(this.domNode);
}
this.disposables = dispose(this.disposables);
dispose(this.disposables);
}
}
@@ -1,7 +1,7 @@
@font-face {
font-family: "octicons2";
src: url("./octicons2.ttf?81972c7f658ef56eeefe672e514d35a3") format("truetype"),
url("./octicons2.svg?81972c7f658ef56eeefe672e514d35a3#octicons2") format("svg");
src: url("./octicons2.ttf?04609cb7b40cfe676d00e166656be7e8") format("truetype"),
url("./octicons2.svg?04609cb7b40cfe676d00e166656be7e8#octicons2") format("svg");
}
.octicon, .mega-octicon {
@@ -247,5 +247,6 @@ body[data-octicons-update="enabled"] .octicon-warning:before { content: "\f02d"
body[data-octicons-update="enabled"] .octicon-controls:before { content: "\26ad" }
body[data-octicons-update="enabled"] .octicon-event:before { content: "\26ae" }
body[data-octicons-update="enabled"] .octicon-record-keys:before { content: "\26af" }
body[data-octicons-update="enabled"] .octicon-archive:before { content: "\f101" }
body[data-octicons-update="enabled"] .octicon-arrow-both:before { content: "\f102" }
body[data-octicons-update="enabled"] .octicon-Vector:before { content: "\f101" }
body[data-octicons-update="enabled"] .octicon-archive:before { content: "\f102" }
body[data-octicons-update="enabled"] .octicon-arrow-both:before { content: "\f103" }
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 226 KiB

+1 -1
View File
@@ -143,7 +143,7 @@ export class Sash extends Disposable {
this._register(domEvent(this.el, EventType.Start)(this.onTouchStart, this));
if (isIPad) {
// see also http://ux.stackexchange.com/questions/39023/what-is-the-optimum-button-size-of-touch-screen-applications
// see also https://ux.stackexchange.com/questions/39023/what-is-the-optimum-button-size-of-touch-screen-applications
addClass(this.el, 'touch');
}
+3 -13
View File
@@ -21,24 +21,15 @@
}
.monaco-split-view2 > .split-view-container {
display: flex;
width: 100%;
height: 100%;
white-space: nowrap;
}
.monaco-split-view2.vertical > .split-view-container {
flex-direction: column;
}
.monaco-split-view2.horizontal > .split-view-container {
flex-direction: row;
position: relative;
}
.monaco-split-view2 > .split-view-container > .split-view-view {
white-space: initial;
flex: none;
position: relative;
position: absolute;
}
.monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) {
@@ -51,7 +42,6 @@
.monaco-split-view2.horizontal > .split-view-container > .split-view-view {
height: 100%;
display: inline-block;
}
.monaco-split-view2.separator-border > .split-view-container > .split-view-view:not(:first-child)::before {
@@ -72,4 +62,4 @@
.monaco-split-view2.separator-border.vertical > .split-view-container > .split-view-view:not(:first-child)::before {
height: 1px;
width: 100%;
}
}
+15 -7
View File
@@ -125,10 +125,13 @@ abstract class ViewItem {
}
}
layout(orthogonalSize: number | undefined): void {
layout(position: number, orthogonalSize: number | undefined): void {
this.layoutContainer(position);
this.view.layout(this.size, orthogonalSize);
}
abstract layoutContainer(position: number): void;
dispose(): IView {
this.disposable.dispose();
return this.view;
@@ -137,16 +140,16 @@ abstract class ViewItem {
class VerticalViewItem extends ViewItem {
layout(orthogonalSize: number | undefined): void {
super.layout(orthogonalSize);
layoutContainer(position: number): void {
this.container.style.top = `${position}px`;
this.container.style.height = `${this.size}px`;
}
}
class HorizontalViewItem extends ViewItem {
layout(orthogonalSize: number | undefined): void {
super.layout(orthogonalSize);
layoutContainer(position: number): void {
this.container.style.left = `${position}px`;
this.container.style.width = `${this.size}px`;
}
}
@@ -846,7 +849,12 @@ export class SplitView extends Disposable {
this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
// Layout views
this.viewItems.forEach(item => item.layout(this.orthogonalSize));
let position = 0;
for (const viewItem of this.viewItems) {
viewItem.layout(position, this.orthogonalSize);
position += viewItem.size;
}
// Layout sashes
this.sashItems.forEach(item => item.sash.layout());
@@ -903,7 +911,7 @@ export class SplitView extends Disposable {
position += this.viewItems[i].size;
if (this.sashItems[i].sash === sash) {
return position;
return Math.min(position, this.contentSize - 2);
}
}
+12 -6
View File
@@ -1053,13 +1053,15 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
return super.onPointer(e);
}
const model = ((this.tree as any).model as ITreeModel<T, TFilterData, TRef>); // internal
const location = model.getNodeLocation(node);
const recursive = e.browserEvent.altKey;
model.setCollapsed(location, undefined, recursive);
if (node.collapsible) {
const model = ((this.tree as any).model as ITreeModel<T, TFilterData, TRef>); // internal
const location = model.getNodeLocation(node);
const recursive = e.browserEvent.altKey;
model.setCollapsed(location, undefined, recursive);
if (expandOnlyOnTwistieClick && onTwistie) {
return;
if (expandOnlyOnTwistieClick && onTwistie) {
return;
}
}
super.onPointer(e);
@@ -1418,6 +1420,10 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
return this.model.isCollapsible(location);
}
setCollapsible(location: TRef, collapsible?: boolean): boolean {
return this.model.setCollapsible(location, collapsible);
}
isCollapsed(location: TRef): boolean {
return this.model.isCollapsed(location);
}
+35 -21
View File
@@ -24,7 +24,7 @@ interface IAsyncDataTreeNode<TInput, T> {
readonly parent: IAsyncDataTreeNode<TInput, T> | null;
readonly children: IAsyncDataTreeNode<TInput, T>[];
readonly id?: string | null;
loading: boolean;
refreshPromise: Promise<void> | undefined;
hasChildren: boolean;
stale: boolean;
slow: boolean;
@@ -41,7 +41,7 @@ function createAsyncDataTreeNode<TInput, T>(props: IAsyncDataTreeNodeRequiredPro
return {
...props,
children: [],
loading: false,
refreshPromise: undefined,
stale: true,
slow: false,
collapsedByDefault: undefined
@@ -451,7 +451,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
const viewStateContext = viewState && { viewState, focus: [], selection: [] } as IAsyncDataTreeViewStateContext<TInput, T>;
await this.updateChildren(input, true, viewStateContext);
await this._updateChildren(input, true, viewStateContext);
if (viewStateContext) {
this.tree.setFocus(viewStateContext.focus);
@@ -463,13 +463,17 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
}
}
async updateChildren(element: TInput | T = this.root.element, recursive = true, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
async updateChildren(element: TInput | T = this.root.element, recursive = true): Promise<void> {
await this._updateChildren(element, recursive);
}
private async _updateChildren(element: TInput | T = this.root.element, recursive = true, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
if (typeof this.root.element === 'undefined') {
throw new TreeError(this.user, 'Tree input not set');
}
if (this.root.loading) {
await this.subTreeRefreshPromises.get(this.root)!;
if (this.root.refreshPromise) {
await this.root.refreshPromise;
await Event.toPromise(this._onDidRender.event);
}
@@ -519,21 +523,26 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
throw new TreeError(this.user, 'Tree input not set');
}
if (this.root.loading) {
await this.subTreeRefreshPromises.get(this.root)!;
if (this.root.refreshPromise) {
await this.root.refreshPromise;
await Event.toPromise(this._onDidRender.event);
}
const node = this.getDataNode(element);
if (node !== this.root && !node.loading && !this.tree.isCollapsed(node)) {
if (node.refreshPromise) {
await this.root.refreshPromise;
await Event.toPromise(this._onDidRender.event);
}
if (node !== this.root && !node.refreshPromise && !this.tree.isCollapsed(node)) {
return false;
}
const result = this.tree.expand(node === this.root ? null : node, recursive);
if (node.loading) {
await this.subTreeRefreshPromises.get(node)!;
if (node.refreshPromise) {
await this.root.refreshPromise;
await Event.toPromise(this._onDidRender.event);
}
@@ -677,18 +686,18 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
return result;
}
result = this.doRefreshSubTree(node, recursive, viewStateContext);
this.subTreeRefreshPromises.set(node, result);
try {
await result;
} finally {
this.subTreeRefreshPromises.delete(node);
}
return this.doRefreshSubTree(node, recursive, viewStateContext);
}
private async doRefreshSubTree(node: IAsyncDataTreeNode<TInput, T>, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): Promise<void> {
node.loading = true;
let done: () => void;
node.refreshPromise = new Promise(c => done = c);
this.subTreeRefreshPromises.set(node, node.refreshPromise);
node.refreshPromise.finally(() => {
node.refreshPromise = undefined;
this.subTreeRefreshPromises.delete(node);
});
try {
const childrenToRefresh = await this.doRefreshNode(node, recursive, viewStateContext);
@@ -696,7 +705,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
await Promise.all(childrenToRefresh.map(child => this.doRefreshSubTree(child, recursive, viewStateContext)));
} finally {
node.loading = false;
done!();
}
}
@@ -869,6 +878,11 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
private render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
const children = node.children.map(c => asTreeElement(c, viewStateContext));
this.tree.setChildren(node === this.root ? null : node, children);
if (node !== this.root) {
this.tree.setCollapsible(node, node.hasChildren);
}
this._onDidRender.fire();
}
@@ -231,6 +231,11 @@ export class CompressedTreeModel<T extends NonNullable<any>, TFilterData extends
return this.model.isCollapsible(compressedNode);
}
setCollapsible(location: T | null, collapsible?: boolean): boolean {
const compressedNode = this.getCompressedNode(location);
return this.model.setCollapsible(compressedNode, collapsible);
}
isCollapsed(location: T | null): boolean {
const compressedNode = this.getCompressedNode(location);
return this.model.isCollapsed(compressedNode);
@@ -397,6 +402,10 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
return this.model.isCollapsible(location);
}
setCollapsible(location: T | null, collapsed?: boolean): boolean {
return this.model.setCollapsible(location, collapsed);
}
isCollapsed(location: T | null): boolean {
return this.model.isCollapsed(location);
}
+50 -15
View File
@@ -46,6 +46,21 @@ export interface IIndexTreeModelOptions<T, TFilterData> {
readonly autoExpandSingleChildren?: boolean;
}
interface CollapsibleStateUpdate {
readonly collapsible: boolean;
}
interface CollapsedStateUpdate {
readonly collapsed: boolean;
readonly recursive: boolean;
}
type CollapseStateUpdate = CollapsibleStateUpdate | CollapsedStateUpdate;
function isCollapsibleStateUpdate(update: CollapseStateUpdate): update is CollapsibleStateUpdate {
return typeof (update as any).collapsible === 'boolean';
}
export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = void> implements ITreeModel<T, TFilterData, number[]> {
readonly rootRef = [];
@@ -205,6 +220,17 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
return this.getTreeNode(location).collapsible;
}
setCollapsible(location: number[], collapsible?: boolean): boolean {
const node = this.getTreeNode(location);
if (typeof collapsible === 'undefined') {
collapsible = !node.collapsible;
}
const update: CollapsibleStateUpdate = { collapsible };
return this.eventBufferer.bufferEvents(() => this._setCollapseState(location, update));
}
isCollapsed(location: number[]): boolean {
return this.getTreeNode(location).collapsed;
}
@@ -216,15 +242,16 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
collapsed = !node.collapsed;
}
return this.eventBufferer.bufferEvents(() => this._setCollapsed(location, collapsed!, recursive));
const update: CollapsedStateUpdate = { collapsed, recursive: recursive || false };
return this.eventBufferer.bufferEvents(() => this._setCollapseState(location, update));
}
private _setCollapsed(location: number[], collapsed: boolean, recursive?: boolean): boolean {
private _setCollapseState(location: number[], update: CollapseStateUpdate): boolean {
const { node, listIndex, revealed } = this.getTreeNodeWithListIndex(location);
const result = this._setListNodeCollapsed(node, listIndex, revealed, collapsed!, recursive || false);
const result = this._setListNodeCollapseState(node, listIndex, revealed, update);
if (node !== this.root && this.autoExpandSingleChildren && !collapsed! && !recursive) {
if (node !== this.root && this.autoExpandSingleChildren && result && !isCollapsibleStateUpdate(update) && node.collapsible && !node.collapsed && !update.recursive) {
let onlyVisibleChildIndex = -1;
for (let i = 0; i < node.children.length; i++) {
@@ -241,17 +268,17 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
}
if (onlyVisibleChildIndex > -1) {
this._setCollapsed([...location, onlyVisibleChildIndex], false, false);
this._setCollapseState([...location, onlyVisibleChildIndex], update);
}
}
return result;
}
private _setListNodeCollapsed(node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean, collapsed: boolean, recursive: boolean): boolean {
const result = this._setNodeCollapsed(node, collapsed, recursive, false);
private _setListNodeCollapseState(node: IMutableTreeNode<T, TFilterData>, listIndex: number, revealed: boolean, update: CollapseStateUpdate): boolean {
const result = this._setNodeCollapseState(node, update, false);
if (!revealed || !node.visible) {
if (!revealed || !node.visible || !result) {
return result;
}
@@ -263,20 +290,28 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
return result;
}
private _setNodeCollapsed(node: IMutableTreeNode<T, TFilterData>, collapsed: boolean, recursive: boolean, deep: boolean): boolean {
let result = node.collapsible && node.collapsed !== collapsed;
private _setNodeCollapseState(node: IMutableTreeNode<T, TFilterData>, update: CollapseStateUpdate, deep: boolean): boolean {
let result: boolean;
if (node.collapsible) {
node.collapsed = collapsed;
if (node === this.root) {
result = false;
} else {
if (isCollapsibleStateUpdate(update)) {
result = node.collapsible !== update.collapsible;
node.collapsible = update.collapsible;
} else {
result = node.collapsed !== update.collapsed;
node.collapsed = update.collapsed;
}
if (result) {
this._onDidChangeCollapseState.fire({ node, deep });
}
}
if (recursive) {
if (!isCollapsibleStateUpdate(update) && update.recursive) {
for (const child of node.children) {
result = this._setNodeCollapsed(child, collapsed, true, true) || result;
result = this._setNodeCollapseState(child, update, true) || result;
}
}
@@ -292,7 +327,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
location = location.slice(0, location.length - 1);
if (node.collapsed) {
this._setCollapsed(location, false);
this._setCollapseState(location, { collapsed: false, recursive: false });
}
}
});
@@ -216,6 +216,11 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
return this.model.isCollapsible(location);
}
setCollapsible(element: T | null, collapsible?: boolean): boolean {
const location = this.getElementLocation(element);
return this.model.setCollapsible(location, collapsible);
}
isCollapsed(element: T | null): boolean {
const location = this.getElementLocation(element);
return this.model.isCollapsed(location);
+1
View File
@@ -120,6 +120,7 @@ export interface ITreeModel<T, TFilterData, TRef> {
getLastElementAncestor(location?: TRef): T | undefined;
isCollapsible(location: TRef): boolean;
setCollapsible(location: TRef, collapsible?: boolean): boolean;
isCollapsed(location: TRef): boolean;
setCollapsed(location: TRef, collapsed?: boolean, recursive?: boolean): boolean;
expandTo(location: TRef): void;
+8
View File
@@ -8,3 +8,11 @@ import { URI } from 'vs/base/common/uri';
export function getPathFromAmdModule(requirefn: typeof require, relativePath: string): string {
return URI.parse(requirefn.toUrl(relativePath)).fsPath;
}
/**
* Reference a resource that might be inlined.
* Do not rename this method unless you adopt the build scripts.
*/
export function registerAndGetAmdImageURL(absolutePath: string): string {
return require.toUrl(absolutePath);
}
+4 -7
View File
@@ -7,17 +7,14 @@
* An interface for a JavaScript object that
* acts a dictionary. The keys are strings.
*/
export interface IStringDictionary<V> {
[name: string]: V;
}
export type IStringDictionary<V> = Record<string, V>;
/**
* An interface for a JavaScript object that
* acts a dictionary. The keys are numbers.
*/
export interface INumberDictionary<V> {
[idx: number]: V;
}
export type INumberDictionary<V> = Record<number, V>;
const hasOwnProperty = Object.prototype.hasOwnProperty;
@@ -136,4 +133,4 @@ export class SetMap<K, V> {
values.forEach(fn);
}
}
}
+3 -3
View File
@@ -114,9 +114,9 @@ export function log(entry: IRemoteConsoleLog, label: string): void {
// First arg is a string
if (typeof args[0] === 'string') {
if (topFrame && isOneStringArg) {
consoleArgs = [`%c[${label}] %c${args[0]} %c${topFrame}`, color('blue'), color('black'), color('grey')];
consoleArgs = [`%c[${label}] %c${args[0]} %c${topFrame}`, color('blue'), color(''), color('grey')];
} else {
consoleArgs = [`%c[${label}] %c${args[0]}`, color('blue'), color('black'), ...args.slice(1)];
consoleArgs = [`%c[${label}] %c${args[0]}`, color('blue'), color(''), ...args.slice(1)];
}
}
@@ -139,4 +139,4 @@ export function log(entry: IRemoteConsoleLog, label: string): void {
function color(color: string): string {
return `color: ${color}`;
}
}
+13 -13
View File
@@ -207,17 +207,17 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
function scanHexDigits(count: number): number {
let digits = 0;
let value = 0;
let hexValue = 0;
while (digits < count) {
const ch = text.charCodeAt(pos);
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
value = value * 16 + ch - CharacterCodes._0;
hexValue = hexValue * 16 + ch - CharacterCodes._0;
}
else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) {
value = value * 16 + ch - CharacterCodes.A + 10;
hexValue = hexValue * 16 + ch - CharacterCodes.A + 10;
}
else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) {
value = value * 16 + ch - CharacterCodes.a + 10;
hexValue = hexValue * 16 + ch - CharacterCodes.a + 10;
}
else {
break;
@@ -226,9 +226,9 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
digits++;
}
if (digits < count) {
value = -1;
hexValue = -1;
}
return value;
return hexValue;
}
function setPosition(newPosition: number) {
@@ -291,7 +291,7 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
scanError = ScanError.UnexpectedEndOfString;
break;
}
let ch = text.charCodeAt(pos);
const ch = text.charCodeAt(pos);
if (ch === CharacterCodes.doubleQuote) {
result += text.substring(start, pos);
pos++;
@@ -304,8 +304,8 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
scanError = ScanError.UnexpectedEndOfString;
break;
}
ch = text.charCodeAt(pos++);
switch (ch) {
const ch2 = text.charCodeAt(pos++);
switch (ch2) {
case CharacterCodes.doubleQuote:
result += '\"';
break;
@@ -331,9 +331,9 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON
result += '\t';
break;
case CharacterCodes.u:
const ch = scanHexDigits(4);
if (ch >= 0) {
result += String.fromCharCode(ch);
const ch3 = scanHexDigits(4);
if (ch3 >= 0) {
result += String.fromCharCode(ch3);
} else {
scanError = ScanError.InvalidUnicode;
}
@@ -1340,4 +1340,4 @@ function getLiteralNodeType(value: any): NodeType {
case 'string': return 'string';
default: return 'null';
}
}
}
+6 -6
View File
@@ -144,11 +144,11 @@ function withFormatting(text: string, edit: Edit, formattingOptions: FormattingO
// apply the formatting edits and track the begin and end offsets of the changes
for (let i = edits.length - 1; i >= 0; i--) {
const edit = edits[i];
newText = applyEdit(newText, edit);
begin = Math.min(begin, edit.offset);
end = Math.max(end, edit.offset + edit.length);
end += edit.content.length - edit.length;
const curr = edits[i];
newText = applyEdit(newText, curr);
begin = Math.min(begin, curr.offset);
end = Math.max(end, curr.offset + curr.length);
end += curr.content.length - curr.length;
}
// create a single edit with all changes
const editLength = text.length - (newText.length - end) - begin;
@@ -182,4 +182,4 @@ export function applyEdits(text: string, edits: Edit[]): string {
export function isWS(text: string, offset: number) {
return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
}
}
+1 -3
View File
@@ -18,7 +18,7 @@ export function values<V>(forEachable: { forEach(callback: (value: V, ...more: a
export function keys<K, V>(map: Map<K, V>): K[] {
const result: K[] = [];
map.forEach((value, key) => result.push(key));
map.forEach((_value, key) => result.push(key));
return result;
}
@@ -482,8 +482,6 @@ export class ResourceMap<T> {
}
}
// We should fold BoundedMap and LinkedMap. See https://github.com/Microsoft/vscode/issues/28496
interface Item<K, V> {
previous: Item<K, V> | undefined;
next: Item<K, V> | undefined;
+3 -8
View File
@@ -5,11 +5,6 @@
import { CharCode } from 'vs/base/common/charCode';
/**
* The empty string.
*/
export const empty = '';
export function isFalsyOrWhitespace(str: string | undefined): boolean {
if (!str || typeof str !== 'string') {
return true;
@@ -70,7 +65,7 @@ export function escape(html: string): string {
* Escapes regular expression characters in a given string
*/
export function escapeRegExpCharacters(value: string): string {
return value.replace(/[\-\\\{\}\*\+\?\|\^\$\.\[\]\(\)\#]/g, '\\$&');
return value.replace(/[\\\{\}\*\+\?\|\^\$\.\[\]\(\)]/g, '\\$&');
}
/**
@@ -608,7 +603,7 @@ export function lcut(text: string, n: number) {
re.lastIndex += 1;
}
return text.substring(i).replace(/^\s/, empty);
return text.substring(i).replace(/^\s/, '');
}
// Escape codes
@@ -636,7 +631,7 @@ export const removeAccents: (str: string) => string = (function () {
// see: https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript/37511463#37511463
const regex = /[\u0300-\u036f]/g;
return function (str: string) {
return (str as any).normalize('NFD').replace(regex, empty);
return (str as any).normalize('NFD').replace(regex, '');
};
}
})();
@@ -8,6 +8,7 @@ import { ITreeNode, ITreeRenderer, IAsyncDataSource } from 'vs/base/browser/ui/t
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { hasClass } from 'vs/base/browser/dom';
import { timeout } from 'vs/base/common/async';
interface Element {
id: string;
@@ -26,104 +27,89 @@ function find(elements: Element[] | undefined, id: string): Element {
throw new Error('element not found');
}
class Renderer implements ITreeRenderer<Element, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
}
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = element.element.id;
}
disposeTemplate(templateData: HTMLElement): void {
// noop
}
}
class IdentityProvider implements IIdentityProvider<Element> {
getId(element: Element) {
return element.id;
}
}
class VirtualDelegate implements IListVirtualDelegate<Element> {
getHeight() { return 20; }
getTemplateId(element: Element): string { return 'default'; }
}
class DataSource implements IAsyncDataSource<Element, Element> {
hasChildren(element: Element): boolean {
return !!element.children && element.children.length > 0;
}
getChildren(element: Element): Promise<Element[]> {
return Promise.resolve(element.children || []);
}
}
class Model {
constructor(readonly root: Element) { }
get(id: string): Element {
return find(this.root.children, id);
}
}
suite('AsyncDataTree', function () {
test('Collapse state should be preserved across refresh calls', async () => {
const container = document.createElement('div');
container.style.width = '200px';
container.style.height = '200px';
const delegate = new class implements IListVirtualDelegate<Element> {
getHeight() { return 20; }
getTemplateId(element: Element): string { return 'default'; }
};
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
}
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = element.element.id;
}
disposeTemplate(templateData: HTMLElement): void {
// noop
}
};
const dataSource = new class implements IAsyncDataSource<Element, Element> {
hasChildren(element: Element): boolean {
return !!element.children && element.children.length > 0;
}
getChildren(element: Element): Promise<Element[]> {
return Promise.resolve(element.children || []);
}
};
const identityProvider = new class implements IIdentityProvider<Element> {
getId(element: Element) {
return element.id;
}
};
const root: Element = {
const model = new Model({
id: 'root',
children: [{
id: 'a'
}]
};
});
const _: (id: string) => Element = find.bind(null, root.children);
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, { identityProvider });
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], new DataSource(), { identityProvider: new IdentityProvider() });
tree.layout(200);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 0);
await tree.setInput(root);
await tree.setInput(model.root);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
assert(!hasClass(twistie, 'collapsible'));
assert(!hasClass(twistie, 'collapsed'));
_('a').children = [
model.get('a').children = [
{ id: 'aa' },
{ id: 'ab' },
{ id: 'ac' }
];
await tree.updateChildren(root);
await tree.updateChildren(model.root);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
await tree.expand(_('a'));
await tree.expand(model.get('a'));
assert.equal(container.querySelectorAll('.monaco-list-row').length, 4);
_('a').children = [];
await tree.updateChildren(root);
model.get('a').children = [];
await tree.updateChildren(model.root);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
});
test('issue #68648', async () => {
const container = document.createElement('div');
container.style.width = '200px';
container.style.height = '200px';
const delegate = new class implements IListVirtualDelegate<Element> {
getHeight() { return 20; }
getTemplateId(element: Element): string { return 'default'; }
};
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
}
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = element.element.id;
}
disposeTemplate(templateData: HTMLElement): void {
// noop
}
};
const getChildrenCalls: string[] = [];
const dataSource = new class implements IAsyncDataSource<Element, Element> {
@@ -136,25 +122,17 @@ suite('AsyncDataTree', function () {
}
};
const identityProvider = new class implements IIdentityProvider<Element> {
getId(element: Element) {
return element.id;
}
};
const root: Element = {
const model = new Model({
id: 'root',
children: [{
id: 'a'
}]
};
});
const _: (id: string) => Element = find.bind(null, root.children);
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, { identityProvider });
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() });
tree.layout(200);
await tree.setInput(root);
await tree.setInput(model.root);
assert.deepStrictEqual(getChildrenCalls, ['root']);
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
@@ -162,8 +140,8 @@ suite('AsyncDataTree', function () {
assert(!hasClass(twistie, 'collapsed'));
assert(tree.getNode().children[0].collapsed);
_('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
await tree.updateChildren(root);
model.get('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
await tree.updateChildren(model.root);
assert.deepStrictEqual(getChildrenCalls, ['root', 'root']);
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
@@ -171,8 +149,8 @@ suite('AsyncDataTree', function () {
assert(hasClass(twistie, 'collapsed'));
assert(tree.getNode().children[0].collapsed);
_('a').children = [];
await tree.updateChildren(root);
model.get('a').children = [];
await tree.updateChildren(model.root);
assert.deepStrictEqual(getChildrenCalls, ['root', 'root', 'root']);
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
@@ -180,8 +158,8 @@ suite('AsyncDataTree', function () {
assert(!hasClass(twistie, 'collapsed'));
assert(tree.getNode().children[0].collapsed);
_('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
await tree.updateChildren(root);
model.get('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
await tree.updateChildren(model.root);
assert.deepStrictEqual(getChildrenCalls, ['root', 'root', 'root', 'root']);
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
@@ -192,26 +170,6 @@ suite('AsyncDataTree', function () {
test('issue #67722 - once resolved, refreshed collapsed nodes should only get children when expanded', async () => {
const container = document.createElement('div');
container.style.width = '200px';
container.style.height = '200px';
const delegate = new class implements IListVirtualDelegate<Element> {
getHeight() { return 20; }
getTemplateId(element: Element): string { return 'default'; }
};
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
}
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = element.element.id;
}
disposeTemplate(templateData: HTMLElement): void {
// noop
}
};
const getChildrenCalls: string[] = [];
const dataSource = new class implements IAsyncDataSource<Element, Element> {
@@ -224,131 +182,66 @@ suite('AsyncDataTree', function () {
}
};
const identityProvider = new class implements IIdentityProvider<Element> {
getId(element: Element) {
return element.id;
}
};
const root: Element = {
const model = new Model({
id: 'root',
children: [{
id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }]
}]
};
});
const _: (id: string) => Element = find.bind(null, root.children);
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, { identityProvider });
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() });
tree.layout(200);
await tree.setInput(root);
assert(tree.getNode(_('a')).collapsed);
await tree.setInput(model.root);
assert(tree.getNode(model.get('a')).collapsed);
assert.deepStrictEqual(getChildrenCalls, ['root']);
await tree.expand(_('a'));
assert(!tree.getNode(_('a')).collapsed);
await tree.expand(model.get('a'));
assert(!tree.getNode(model.get('a')).collapsed);
assert.deepStrictEqual(getChildrenCalls, ['root', 'a']);
tree.collapse(_('a'));
assert(tree.getNode(_('a')).collapsed);
tree.collapse(model.get('a'));
assert(tree.getNode(model.get('a')).collapsed);
assert.deepStrictEqual(getChildrenCalls, ['root', 'a']);
await tree.updateChildren();
assert(tree.getNode(_('a')).collapsed);
assert(tree.getNode(model.get('a')).collapsed);
assert.deepStrictEqual(getChildrenCalls, ['root', 'a', 'root'], 'a should not be refreshed, since it\' collapsed');
});
test('resolved collapsed nodes which lose children should lose twistie as well', async () => {
const container = document.createElement('div');
container.style.width = '200px';
container.style.height = '200px';
const delegate = new class implements IListVirtualDelegate<Element> {
getHeight() { return 20; }
getTemplateId(element: Element): string { return 'default'; }
};
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
}
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = element.element.id;
}
disposeTemplate(templateData: HTMLElement): void {
// noop
}
};
const dataSource = new class implements IAsyncDataSource<Element, Element> {
hasChildren(element: Element): boolean {
return !!element.children && element.children.length > 0;
}
getChildren(element: Element): Promise<Element[]> {
return Promise.resolve(element.children || []);
}
};
const identityProvider = new class implements IIdentityProvider<Element> {
getId(element: Element) {
return element.id;
}
};
const root: Element = {
const model = new Model({
id: 'root',
children: [{
id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }]
}]
};
});
const _: (id: string) => Element = find.bind(null, root.children);
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, { identityProvider });
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], new DataSource(), { identityProvider: new IdentityProvider() });
tree.layout(200);
await tree.setInput(root);
await tree.expand(_('a'));
await tree.setInput(model.root);
await tree.expand(model.get('a'));
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
assert(hasClass(twistie, 'collapsible'));
assert(!hasClass(twistie, 'collapsed'));
assert(!tree.getNode(_('a')).collapsed);
assert(!tree.getNode(model.get('a')).collapsed);
tree.collapse(_('a'));
_('a').children = [];
await tree.updateChildren(root);
tree.collapse(model.get('a'));
model.get('a').children = [];
await tree.updateChildren(model.root);
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
assert(!hasClass(twistie, 'collapsible'));
assert(!hasClass(twistie, 'collapsed'));
assert(tree.getNode(_('a')).collapsed);
assert(tree.getNode(model.get('a')).collapsed);
});
test('support default collapse state per element', async () => {
const container = document.createElement('div');
container.style.width = '200px';
container.style.height = '200px';
const delegate = new class implements IListVirtualDelegate<Element> {
getHeight() { return 20; }
getTemplateId(element: Element): string { return 'default'; }
};
const renderer = new class implements ITreeRenderer<Element, void, HTMLElement> {
readonly templateId = 'default';
renderTemplate(container: HTMLElement): HTMLElement {
return container;
}
renderElement(element: ITreeNode<Element, void>, index: number, templateData: HTMLElement): void {
templateData.textContent = element.element.id;
}
disposeTemplate(templateData: HTMLElement): void {
// noop
}
};
const getChildrenCalls: string[] = [];
const dataSource = new class implements IAsyncDataSource<Element, Element> {
@@ -361,22 +254,139 @@ suite('AsyncDataTree', function () {
}
};
const root: Element = {
const model = new Model({
id: 'root',
children: [{
id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }]
}]
};
});
const _: (id: string) => Element = find.bind(null, root.children);
const tree = new AsyncDataTree<Element, Element>('test', container, delegate, [renderer], dataSource, {
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, {
collapseByDefault: el => el.id !== 'a'
});
tree.layout(200);
await tree.setInput(root);
assert(!tree.getNode(_('a')).collapsed);
await tree.setInput(model.root);
assert(!tree.getNode(model.get('a')).collapsed);
assert.deepStrictEqual(getChildrenCalls, ['root', 'a']);
});
test('issue #80098 - concurrent refresh and expand', async () => {
const container = document.createElement('div');
const calls: Function[] = [];
const dataSource = new class implements IAsyncDataSource<Element, Element> {
hasChildren(element: Element): boolean {
return !!element.children && element.children.length > 0;
}
getChildren(element: Element): Promise<Element[]> {
return new Promise(c => calls.push(() => c(element.children)));
}
};
const model = new Model({
id: 'root',
children: [{
id: 'a', children: [{
id: 'aa'
}]
}]
});
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() });
tree.layout(200);
const pSetInput = tree.setInput(model.root);
calls.pop()!(); // resolve getChildren(root)
await pSetInput;
const pUpdateChildrenA = tree.updateChildren(model.get('a'));
const pExpandA = tree.expand(model.get('a'));
assert.equal(calls.length, 1, 'expand(a) still hasn\'t called getChildren(a)');
calls.pop()!();
assert.equal(calls.length, 0, 'no pending getChildren calls');
await pUpdateChildrenA;
assert.equal(calls.length, 0, 'expand(a) should not have forced a second refresh');
const result = await pExpandA;
assert.equal(result, true, 'expand(a) should be done');
});
test('issue #80098 - first expand should call getChildren', async () => {
const container = document.createElement('div');
const calls: Function[] = [];
const dataSource = new class implements IAsyncDataSource<Element, Element> {
hasChildren(element: Element): boolean {
return !!element.children && element.children.length > 0;
}
getChildren(element: Element): Promise<Element[]> {
return new Promise(c => calls.push(() => c(element.children)));
}
};
const model = new Model({
id: 'root',
children: [{
id: 'a', children: [{
id: 'aa'
}]
}]
});
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() });
tree.layout(200);
const pSetInput = tree.setInput(model.root);
calls.pop()!(); // resolve getChildren(root)
await pSetInput;
const pExpandA = tree.expand(model.get('a'));
assert.equal(calls.length, 1, 'expand(a) should\'ve called getChildren(a)');
let race = await Promise.race([pExpandA.then(() => 'expand'), timeout(1).then(() => 'timeout')]);
assert.equal(race, 'timeout', 'expand(a) should not be yet done');
calls.pop()!();
assert.equal(calls.length, 0, 'no pending getChildren calls');
race = await Promise.race([pExpandA.then(() => 'expand'), timeout(1).then(() => 'timeout')]);
assert.equal(race, 'expand', 'expand(a) should now be done');
});
test('issue #78388 - tree should react to hasChildren toggles', async () => {
const container = document.createElement('div');
const model = new Model({
id: 'root',
children: [{
id: 'a'
}]
});
const tree = new AsyncDataTree<Element, Element>('test', container, new VirtualDelegate(), [new Renderer()], new DataSource(), { identityProvider: new IdentityProvider() });
tree.layout(200);
await tree.setInput(model.root);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
assert(!hasClass(twistie, 'collapsible'));
assert(!hasClass(twistie, 'collapsed'));
model.get('a').children = [{ id: 'aa' }];
await tree.updateChildren(model.get('a'), false);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
assert(hasClass(twistie, 'collapsible'));
assert(hasClass(twistie, 'collapsed'));
model.get('a').children = [];
await tree.updateChildren(model.get('a'), false);
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
assert(!hasClass(twistie, 'collapsible'));
assert(!hasClass(twistie, 'collapsed'));
});
});
@@ -333,6 +333,67 @@ suite('IndexTreeModel', function () {
assert.deepEqual(toArray(list), [1, 11, 2]);
});
test('setCollapsible', () => {
const list: ITreeNode<number>[] = [];
const model = new IndexTreeModel<number>('test', toSpliceable(list), -1);
model.splice([0], 0, Iterator.fromArray([
{
element: 0, children: Iterator.fromArray([
{ element: 10 }
])
}
]));
assert.deepEqual(list.length, 2);
model.setCollapsible([0], false);
assert.deepEqual(list.length, 2);
assert.deepEqual(list[0].element, 0);
assert.deepEqual(list[0].collapsible, false);
assert.deepEqual(list[0].collapsed, false);
assert.deepEqual(list[1].element, 10);
assert.deepEqual(list[1].collapsible, false);
assert.deepEqual(list[1].collapsed, false);
model.setCollapsed([0], true);
assert.deepEqual(list.length, 1);
assert.deepEqual(list[0].element, 0);
assert.deepEqual(list[0].collapsible, false);
assert.deepEqual(list[0].collapsed, true);
model.setCollapsed([0], false);
assert.deepEqual(list[0].element, 0);
assert.deepEqual(list[0].collapsible, false);
assert.deepEqual(list[0].collapsed, false);
assert.deepEqual(list[1].element, 10);
assert.deepEqual(list[1].collapsible, false);
assert.deepEqual(list[1].collapsed, false);
model.setCollapsible([0], true);
assert.deepEqual(list.length, 2);
assert.deepEqual(list[0].element, 0);
assert.deepEqual(list[0].collapsible, true);
assert.deepEqual(list[0].collapsed, false);
assert.deepEqual(list[1].element, 10);
assert.deepEqual(list[1].collapsible, false);
assert.deepEqual(list[1].collapsed, false);
model.setCollapsed([0], true);
assert.deepEqual(list.length, 1);
assert.deepEqual(list[0].element, 0);
assert.deepEqual(list[0].collapsible, true);
assert.deepEqual(list[0].collapsed, true);
model.setCollapsed([0], false);
assert.deepEqual(list[0].element, 0);
assert.deepEqual(list[0].collapsible, true);
assert.deepEqual(list[0].collapsed, false);
assert.deepEqual(list[1].element, 10);
assert.deepEqual(list[1].collapsible, false);
assert.deepEqual(list[1].collapsed, false);
});
test('simple filter', function () {
const list: ITreeNode<number>[] = [];
const filter = new class implements ITreeFilter<number> {
+210
View File
@@ -0,0 +1,210 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWorkbenchConstructionOptions, create } from 'vs/workbench/workbench.web.api';
import { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
import { Event, Emitter } from 'vs/base/common/event';
import { URI, UriComponents } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { CancellationToken } from 'vs/base/common/cancellation';
import { streamToBuffer } from 'vs/base/common/buffer';
import { Disposable } from 'vs/base/common/lifecycle';
import { request } from 'vs/base/parts/request/browser/request';
import { ICredentialsProvider } from 'vs/workbench/services/credentials/browser/credentialsService';
export function main(): void {
const options: IWorkbenchConstructionOptions = JSON.parse(document.getElementById('vscode-workbench-web-configuration')!.getAttribute('data-settings')!);
options.urlCallbackProvider = new PollingURLCallbackProvider();
options.credentialsProvider = new LocalStorageCredentialsProvider();
create(document.body, options);
}
interface ICredential {
service: string;
account: string;
password: string;
}
class LocalStorageCredentialsProvider implements ICredentialsProvider {
static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider';
private _credentials: ICredential[];
private get credentials(): ICredential[] {
if (!this._credentials) {
try {
const serializedCredentials = window.localStorage.getItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY);
if (serializedCredentials) {
this._credentials = JSON.parse(serializedCredentials);
}
} catch (error) {
// ignore
}
if (!Array.isArray(this._credentials)) {
this._credentials = [];
}
}
return this._credentials;
}
private save(): void {
window.localStorage.setItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY, JSON.stringify(this.credentials));
}
async getPassword(service: string, account: string): Promise<string | null> {
return this.doGetPassword(service, account);
}
private async doGetPassword(service: string, account?: string): Promise<string | null> {
for (const credential of this.credentials) {
if (credential.service === service) {
if (typeof account !== 'string' || account === credential.account) {
return credential.password;
}
}
}
return null;
}
async setPassword(service: string, account: string, password: string): Promise<void> {
this.deletePassword(service, account);
this.credentials.push({ service, account, password });
this.save();
}
async deletePassword(service: string, account: string): Promise<boolean> {
let found = false;
this._credentials = this.credentials.filter(credential => {
if (credential.service === service && credential.account === account) {
found = true;
return false;
}
return true;
});
if (found) {
this.save();
}
return found;
}
async findPassword(service: string): Promise<string | null> {
return this.doGetPassword(service);
}
async findCredentials(service: string): Promise<Array<{ account: string, password: string }>> {
return this.credentials
.filter(credential => credential.service === service)
.map(({ account, password }) => ({ account, password }));
}
}
class PollingURLCallbackProvider extends Disposable implements IURLCallbackProvider {
static FETCH_INTERVAL = 500; // fetch every 500ms
static FETCH_TIMEOUT = 5 * 60 * 1000; // ...but stop after 5min
static QUERY_KEYS = {
REQUEST_ID: 'vscode-requestId',
SCHEME: 'vscode-scheme',
AUTHORITY: 'vscode-authority',
PATH: 'vscode-path',
QUERY: 'vscode-query',
FRAGMENT: 'vscode-fragment'
};
private readonly _onCallback: Emitter<URI> = this._register(new Emitter<URI>());
readonly onCallback: Event<URI> = this._onCallback.event;
create(options?: Partial<UriComponents>): URI {
const queryValues: Map<string, string> = new Map();
const requestId = generateUuid();
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.REQUEST_ID, requestId);
const { scheme, authority, path, query, fragment } = options ? options : { scheme: undefined, authority: undefined, path: undefined, query: undefined, fragment: undefined };
if (scheme) {
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.SCHEME, scheme);
}
if (authority) {
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.AUTHORITY, authority);
}
if (path) {
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.PATH, path);
}
if (query) {
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.QUERY, query);
}
if (fragment) {
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.FRAGMENT, fragment);
}
// Start to poll on the callback being fired
this.periodicFetchCallback(requestId, Date.now());
return this.doCreateUri('/callback', queryValues);
}
private async periodicFetchCallback(requestId: string, startTime: number): Promise<void> {
// Ask server for callback results
const queryValues: Map<string, string> = new Map();
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.REQUEST_ID, requestId);
const result = await request({
url: this.doCreateUri('/fetch-callback', queryValues).toString(true)
}, CancellationToken.None);
// Check for callback results
const content = await streamToBuffer(result.stream);
if (content.byteLength > 0) {
try {
this._onCallback.fire(URI.revive(JSON.parse(content.toString())));
} catch (error) {
console.error(error);
}
return; // done
}
// Continue fetching unless we hit the timeout
if (Date.now() - startTime < PollingURLCallbackProvider.FETCH_TIMEOUT) {
setTimeout(() => this.periodicFetchCallback(requestId, startTime), PollingURLCallbackProvider.FETCH_INTERVAL);
}
}
private doCreateUri(path: string, queryValues: Map<string, string>): URI {
let query: string | undefined = undefined;
if (queryValues) {
let index = 0;
queryValues.forEach((value, key) => {
if (!query) {
query = '';
}
const prefix = (index++ === 0) ? '' : '&';
query += `${prefix}${key}=${encodeURIComponent(value)}`;
});
}
return URI.parse(window.location.href).with({ path, query });
}
}
@@ -0,0 +1,65 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- Disable pinch zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<!-- Content Security Policy -->
<meta
http-equiv="Content-Security-Policy"
content="
default-src 'self';
img-src 'self' https: data: blob:;
media-src 'none';
script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-4DqvCTjCHj2KW4QxC/Yt6uBwMRyYiEg7kOoykSEkonQ=' 'sha256-g94DXzh59qc37AZjL7sV1lYN7OX4K1fgKl4ts5tAQDw=';
child-src 'self';
frame-src 'self' {{WEBVIEW_ENDPOINT}} https://*.vscode-webview-test.com;
worker-src 'self';
style-src 'self' 'unsafe-inline';
connect-src 'self' ws: wss: https:;
font-src 'self' blob:;
manifest-src 'self';
">
<!-- Workbench Configuration -->
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONGIGURATION}}">
<!-- Workarounds/Hacks (remote user data uri) -->
<meta id="vscode-remote-user-data-uri" data-settings="{{REMOTE_USER_DATA_URI}}">
<!-- Workbench Icon/Manifest/CSS -->
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<link rel="manifest" href="/manifest.json">
<link data-name="vs/workbench/workbench.web.api" rel="stylesheet" href="./static/out/vs/workbench/workbench.web.api.css">
</head>
<body aria-label="">
</body>
<!-- Startup (do not modify order of script tags!) -->
<script>
// NOTE: Changes to inline scripts require update of content security policy
self.require = {
baseUrl: `${window.location.origin}/static/out`,
paths: {
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
}
};
</script>
<script src="./static/out/vs/loader.js"></script>
<script>
// NOTE: Changes to inline scripts require update of content security policy
require(['vs/code/browser/workbench/web.main'], function (web) {
web.main();
});
</script>
</html>
+33 -5
View File
@@ -10,18 +10,19 @@
<!-- Content Security Policy -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none';
content="
default-src 'self';
img-src 'self' https: data: blob:;
media-src 'none';
script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https:;
script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-4DqvCTjCHj2KW4QxC/Yt6uBwMRyYiEg7kOoykSEkonQ=' 'sha256-kXwJWoOluR7vyWhuqykdzYEHvOuOu2ZZhnBm0EBbYvU=';
child-src 'self';
frame-src 'self' {{WEBVIEW_ENDPOINT}} https://*.vscode-webview-test.com;
worker-src 'self';
style-src 'self' 'unsafe-inline';
connect-src 'self' ws: wss: https:;
font-src 'self' blob:;
manifest-src 'self';"
>
manifest-src 'self';
">
<!-- Workbench Configuration -->
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONGIGURATION}}">
@@ -33,13 +34,40 @@
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<link rel="manifest" href="/manifest.json">
<link data-name="vs/workbench/workbench.web.api" rel="stylesheet" href="./static/out/vs/workbench/workbench.web.api.css">
<!-- Prefetch to avoid waterfall -->
<link rel="prefetch" href="./static/node_modules/semver-umd/lib/semver-umd.js">
<link rel="prefetch" href="./static/node_modules/onigasm-umd/release/main.js"> <!-- TODO@ben TODO@alex: should be lazy -->
<link rel="prefetch" href="./static/out/vs/code/browser/workbench/web.main.js"> <!--TODO@ben: Why is it not built -->
<link rel="prefetch" href="./static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js">
</head>
<body aria-label="">
</body>
<!-- Startup (do not modify order of script tags!) -->
<script>
// NOTE: Changes to inline scripts require update of content security policy
self.require = {
baseUrl: `${window.location.origin}/static/out`,
paths: {
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
}
};
</script>
<script src="./static/out/vs/loader.js"></script>
<script src="./static/out/vs/workbench/workbench.web.api.nls.js"></script>
<script src="./static/out/vs/code/browser/workbench/workbench.js"></script>
<script src="./static/out/vs/workbench/workbench.web.api.js"></script>
<!-- <script src="./static/out/vs/code/browser/workbench/web.main.js"></script> TODO@ben: Why is it not built-->
<script>
require(['vs/code/browser/workbench/web.main'], function (web) {
web.main();
});
</script>
</html>
@@ -1,31 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
(function () {
/** @type any */
const amdLoader = require;
amdLoader.config({
baseUrl: `${window.location.origin}/static/out`,
paths: {
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
}
});
amdLoader(['vs/workbench/workbench.web.api'], function (api) {
const options = JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings'));
api.create(document.body, options);
});
})();
@@ -49,7 +49,7 @@ bootstrapWindow.load([
* @param {{
* partsSplashPath?: string,
* highContrast?: boolean,
* extensionDevelopmentPath?: string | string[],
* extensionDevelopmentPath?: string[],
* folderUri?: object,
* workspace?: object
* }} configuration
+6 -6
View File
@@ -26,7 +26,7 @@ import { IStateService } from 'vs/platform/state/common/state';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IURLService } from 'vs/platform/url/common/url';
import { URLHandlerChannelClient, URLServiceChannel } from 'vs/platform/url/node/urlIpc';
import { URLHandlerChannelClient, URLServiceChannel, URLHandlerRouter } from 'vs/platform/url/common/urlIpc';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc';
@@ -56,7 +56,6 @@ import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
import { IMenubarService } from 'vs/platform/menubar/node/menubar';
import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService';
import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc';
import { hasArgs } from 'vs/platform/environment/node/argv';
import { RunOnceScheduler } from 'vs/base/common/async';
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
import { homedir } from 'os';
@@ -580,7 +579,8 @@ export class CodeApplication extends Disposable {
// Create a URL handler which forwards to the last active window
const activeWindowManager = new ActiveWindowManager(windowsService);
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
const urlHandlerChannel = electronIpcServer.getChannel('urlHandler', activeWindowRouter);
const urlHandlerRouter = new URLHandlerRouter(activeWindowRouter);
const urlHandlerChannel = electronIpcServer.getChannel('urlHandler', urlHandlerRouter);
const multiplexURLHandler = new URLHandlerChannelClient(urlHandlerChannel);
// On Mac, Code can be running without any open windows, so we must create a window to handle urls,
@@ -616,9 +616,9 @@ export class CodeApplication extends Disposable {
// Open our first window
const macOpenFiles: string[] = (<any>global).macOpenFiles;
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
const hasCliArgs = hasArgs(args._);
const hasFolderURIs = hasArgs(args['folder-uri']);
const hasFileURIs = hasArgs(args['file-uri']);
const hasCliArgs = args._.length;
const hasFolderURIs = !!args['folder-uri'];
const hasFileURIs = !!args['file-uri'];
const noRecentEntry = args['skip-add-to-recently-opened'] === true;
const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined;
+3 -3
View File
@@ -11,7 +11,7 @@ import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, R
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { parseArgs } from 'vs/platform/environment/node/argv';
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
import product from 'vs/platform/product/node/product';
import { IWindowSettings, MenuBarVisibility, IWindowConfiguration, ReadyState, getTitleBarStyle } from 'vs/platform/windows/common/windows';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
@@ -32,7 +32,7 @@ const RUN_TEXTMATE_IN_WORKER = false;
export interface IWindowCreationOptions {
state: IWindowState;
extensionDevelopmentPath?: string | string[];
extensionDevelopmentPath?: string[];
isExtensionTestHost?: boolean;
}
@@ -574,7 +574,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
windowConfiguration.partsSplashPath = path.join(this.environmentService.userDataPath, 'rapid_render.json');
// Config (combination of process.argv and window configuration)
const environment = parseArgs(process.argv);
const environment = parseArgs(process.argv, OPTIONS);
const config = objects.assign(environment, windowConfiguration);
for (const key in config) {
const configValue = (config as any)[key];
+25 -25
View File
@@ -12,7 +12,6 @@ import { IBackupMainService, IEmptyWindowBackupInfo } from 'vs/platform/backup/c
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { IStateService } from 'vs/platform/state/common/state';
import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
import { hasArgs, asArray } from 'vs/platform/environment/node/argv';
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter } from 'electron';
import { parseLineAndColumnAware } from 'vs/code/node/paths';
import { ILifecycleService, UnloadReason, LifecycleService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
@@ -450,7 +449,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
// Make sure to pass focus to the most relevant of the windows if we open multiple
if (usedWindows.length > 1) {
const focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !hasArgs(openConfig.cli._) && !hasArgs(openConfig.cli['file-uri']) && !hasArgs(openConfig.cli['folder-uri']) && !(openConfig.urisToOpen && openConfig.urisToOpen.length);
const focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && openConfig.cli._.length && !openConfig.cli['file-uri'] && !openConfig.cli['folder-uri'] && !(openConfig.urisToOpen && openConfig.urisToOpen.length);
let focusLastOpened = true;
let focusLastWindow = true;
@@ -811,7 +810,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
}
// Extract paths: from CLI
else if (hasArgs(openConfig.cli._) || hasArgs(openConfig.cli['folder-uri']) || hasArgs(openConfig.cli['file-uri'])) {
else if (openConfig.cli._.length || openConfig.cli['folder-uri'] || openConfig.cli['file-uri']) {
windowsToOpen = this.doExtractPathsFromCLI(openConfig.cli);
isCommandLineOrAPICall = true;
}
@@ -885,31 +884,36 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
const parseOptions: IPathParseOptions = { ignoreFileNotFound: true, gotoLineMode: cli.goto, remoteAuthority: cli.remote || undefined };
// folder uris
const folderUris = asArray(cli['folder-uri']);
for (let f of folderUris) {
const folderUri = this.argToUri(f);
if (folderUri) {
const path = this.parseUri({ folderUri }, parseOptions);
if (path) {
pathsToOpen.push(path);
const folderUris = cli['folder-uri'];
if (folderUris) {
for (let f of folderUris) {
const folderUri = this.argToUri(f);
if (folderUri) {
const path = this.parseUri({ folderUri }, parseOptions);
if (path) {
pathsToOpen.push(path);
}
}
}
}
// file uris
const fileUris = asArray(cli['file-uri']);
for (let f of fileUris) {
const fileUri = this.argToUri(f);
if (fileUri) {
const path = this.parseUri(hasWorkspaceFileExtension(f) ? { workspaceUri: fileUri } : { fileUri }, parseOptions);
if (path) {
pathsToOpen.push(path);
const fileUris = cli['file-uri'];
if (fileUris) {
for (let f of fileUris) {
const fileUri = this.argToUri(f);
if (fileUri) {
const path = this.parseUri(hasWorkspaceFileExtension(f) ? { workspaceUri: fileUri } : { fileUri }, parseOptions);
if (path) {
pathsToOpen.push(path);
}
}
}
}
// folder or file paths
const cliArgs = asArray(cli._);
const cliArgs = cli._;
for (let cliArg of cliArgs) {
const path = this.parsePath(cliArg, parseOptions);
if (path) {
@@ -1166,7 +1170,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
return { openFolderInNewWindow: !!openFolderInNewWindow, openFilesInNewWindow };
}
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string | string[], openConfig: IOpenConfiguration): void {
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string[], openConfig: IOpenConfiguration): void {
// Reload an existing extension development host window on the same path
// We currently do not allow more than one extension development window
@@ -1178,8 +1182,8 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
return;
}
let folderUris = asArray(openConfig.cli['folder-uri']);
let fileUris = asArray(openConfig.cli['file-uri']);
let folderUris = openConfig.cli['folder-uri'] || [];
let fileUris = openConfig.cli['file-uri'] || [];
let cliArgs = openConfig.cli._;
// Fill in previously opened workspace unless an explicit path is provided and we are not unit testing
@@ -1203,10 +1207,6 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
}
}
if (!Array.isArray(extensionDevelopmentPath)) {
extensionDevelopmentPath = [extensionDevelopmentPath];
}
let authority = '';
for (let p of extensionDevelopmentPath) {
if (p.match(/^[a-zA-Z][a-zA-Z0-9\+\-\.]+:/)) {
+2 -2
View File
@@ -5,7 +5,7 @@
import { spawn, ChildProcess, SpawnOptions } from 'child_process';
import { assign } from 'vs/base/common/objects';
import { buildHelpMessage, buildVersionMessage, addArg, createWaitMarkerFile } from 'vs/platform/environment/node/argv';
import { buildHelpMessage, buildVersionMessage, addArg, createWaitMarkerFile, OPTIONS } from 'vs/platform/environment/node/argv';
import { parseCLIProcessArgv } from 'vs/platform/environment/node/argvHelper';
import { ParsedArgs } from 'vs/platform/environment/common/environment';
import product from 'vs/platform/product/node/product';
@@ -47,7 +47,7 @@ export async function main(argv: string[]): Promise<any> {
// Help
if (args.help) {
const executable = `${product.applicationName}${os.platform() === 'win32' ? '.exe' : ''}`;
console.log(buildHelpMessage(product.nameLong, executable, pkg.version));
console.log(buildHelpMessage(product.nameLong, executable, pkg.version, OPTIONS));
}
// Version Info
+3 -12
View File
@@ -83,23 +83,14 @@ export class Main {
async run(argv: ParsedArgs): Promise<void> {
if (argv['install-source']) {
await this.setInstallSource(argv['install-source']);
} else if (argv['list-extensions']) {
await this.listExtensions(!!argv['show-versions'], argv['category']);
} else if (argv['install-extension']) {
const arg = argv['install-extension'];
const args: string[] = typeof arg === 'string' ? [arg] : arg;
await this.installExtensions(args, !!argv['force']);
await this.installExtensions(argv['install-extension'], !!argv['force']);
} else if (argv['uninstall-extension']) {
const arg = argv['uninstall-extension'];
const ids: string[] = typeof arg === 'string' ? [arg] : arg;
await this.uninstallExtension(ids);
await this.uninstallExtension(argv['uninstall-extension']);
} else if (argv['locate-extension']) {
const arg = argv['locate-extension'];
const ids: string[] = typeof arg === 'string' ? [arg] : arg;
await this.locateExtension(ids);
await this.locateExtension(argv['locate-extension']);
} else if (argv['telemetry']) {
console.log(buildTelemetryMessage(this.environmentService.appRoot, this.environmentService.extensionsPath ? this.environmentService.extensionsPath : undefined));
}
+6 -19
View File
@@ -14,7 +14,7 @@ export interface ISimpleWindow {
openedWorkspace?: IWorkspaceIdentifier;
openedFolderUri?: URI;
extensionDevelopmentPath?: string | string[];
extensionDevelopmentPath?: string[];
lastFocusTime: number;
}
@@ -95,30 +95,17 @@ export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], wor
return null;
}
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPath: string | string[]): W | null {
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPaths: string[]): W | null {
const matches = (uriString: string): boolean => {
if (Array.isArray(extensionDevelopmentPath)) {
return extensionDevelopmentPath.some(p => extpath.isEqual(p, uriString, !platform.isLinux /* ignorecase */));
} else if (extensionDevelopmentPath) {
return extpath.isEqual(extensionDevelopmentPath, uriString, !platform.isLinux /* ignorecase */);
}
return false;
return extensionDevelopmentPaths.some(p => extpath.isEqual(p, uriString, !platform.isLinux /* ignorecase */));
};
for (const window of windows) {
// match on extension development path. The path can be one or more paths or uri strings, using paths.isEqual is not 100% correct but good enough
if (window.extensionDevelopmentPath) {
if (Array.isArray(window.extensionDevelopmentPath)) {
if (window.extensionDevelopmentPath.some(p => matches(p))) {
return window;
}
} else if (window.extensionDevelopmentPath) {
if (matches(window.extensionDevelopmentPath)) {
return window;
}
}
const currPaths = window.extensionDevelopmentPath;
if (currPaths && currPaths.some(p => matches(p))) {
return window;
}
}
+16 -17
View File
@@ -4,29 +4,28 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { formatOptions, Option, addArg } from 'vs/platform/environment/node/argv';
import { ParsedArgs } from 'vs/platform/environment/common/environment';
suite('formatOptions', () => {
function o(id: keyof ParsedArgs, description: string): Option {
function o(description: string): Option<any> {
return {
id, description, type: 'string'
description, type: 'string'
};
}
test('Text should display small columns correctly', () => {
assert.deepEqual(
formatOptions([
o('add', 'bar')
], 80),
formatOptions({
'add': o('bar')
}, 80),
[' --add bar']
);
assert.deepEqual(
formatOptions([
o('add', 'bar'),
o('wait', 'ba'),
o('trace', 'b')
], 80),
formatOptions({
'add': o('bar'),
'wait': o('ba'),
'trace': o('b')
}, 80),
[
' --add bar',
' --wait ba',
@@ -36,9 +35,9 @@ suite('formatOptions', () => {
test('Text should wrap', () => {
assert.deepEqual(
formatOptions([
o('add', (<any>'bar ').repeat(9))
], 40),
formatOptions({
'add': o((<any>'bar ').repeat(9))
}, 40),
[
' --add bar bar bar bar bar bar bar bar',
' bar'
@@ -47,9 +46,9 @@ suite('formatOptions', () => {
test('Text should revert to the condensed view when the terminal is too narrow', () => {
assert.deepEqual(
formatOptions([
o('add', (<any>'bar ').repeat(9))
], 30),
formatOptions({
'add': o((<any>'bar ').repeat(9))
}, 30),
[
' --add',
' bar bar bar bar bar bar bar bar bar '
@@ -11,7 +11,7 @@ import * as platform from 'vs/base/common/platform';
import { CharWidthRequest, CharWidthRequestType, readCharWidths } from 'vs/editor/browser/config/charWidthReader';
import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver';
import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/config/commonEditorConfig';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IEditorOptions, EditorOption } from 'vs/editor/common/config/editorOptions';
import { BareFontInfo, FontInfo } from 'vs/editor/common/config/fontInfo';
import { IDimension } from 'vs/editor/common/editorCommon';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
@@ -320,7 +320,7 @@ export class Configuration extends CommonEditorConfiguration {
this._register(CSSBasedConfiguration.INSTANCE.onDidChange(() => this._onCSSBasedConfigurationChanged()));
if (this._validatedOptions.automaticLayout) {
if (this._validatedOptions.get(EditorOption.automaticLayout)) {
this._elementSizeObserver.startObserving();
}
@@ -294,7 +294,7 @@ export namespace CoreNavigationCommands {
CursorMoveCommands.moveTo(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position, args.viewPosition)
]
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
}
@@ -322,7 +322,7 @@ export namespace CoreNavigationCommands {
toViewLineNumber: result.toLineNumber,
toViewVisualColumn: result.toVisualColumn
});
cursors.reveal(true, (result.reversed ? RevealTarget.TopMost : RevealTarget.BottomMost), ScrollType.Smooth);
cursors.reveal(args.source, true, (result.reversed ? RevealTarget.TopMost : RevealTarget.BottomMost), ScrollType.Smooth);
}
protected abstract _getColumnSelectResult(context: CursorContext, primary: CursorState, prevColumnSelectData: IColumnSelectData, args: any): IColumnSelectResult;
@@ -343,12 +343,8 @@ export namespace CoreNavigationCommands {
const validatedPosition = context.model.validatePosition(args.position);
const validatedViewPosition = context.validateViewPosition(new Position(args.viewPosition.lineNumber, args.viewPosition.column), validatedPosition);
let fromViewLineNumber = prevColumnSelectData.fromViewLineNumber;
let fromViewVisualColumn = prevColumnSelectData.fromViewVisualColumn;
if (!prevColumnSelectData.isReal && args.setAnchorIfNotSet) {
fromViewLineNumber = validatedViewPosition.lineNumber;
fromViewVisualColumn = args.mouseColumn - 1;
}
let fromViewLineNumber = args.doColumnSelect ? prevColumnSelectData.fromViewLineNumber : validatedViewPosition.lineNumber;
let fromViewVisualColumn = args.doColumnSelect ? prevColumnSelectData.fromViewVisualColumn : args.mouseColumn - 1;
return ColumnSelection.columnSelect(context.config, context.viewModel, fromViewLineNumber, fromViewVisualColumn, validatedViewPosition.lineNumber, args.mouseColumn - 1);
}
});
@@ -492,7 +488,7 @@ export namespace CoreNavigationCommands {
CursorChangeReason.Explicit,
CursorMoveCommands.move(cursors.context, cursors.getAll(), args)
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(source, true, RevealTarget.Primary, ScrollType.Smooth);
}
}
@@ -831,7 +827,7 @@ export namespace CoreNavigationCommands {
CursorChangeReason.Explicit,
CursorMoveCommands.moveToBeginningOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
}
@@ -880,7 +876,7 @@ export namespace CoreNavigationCommands {
CursorChangeReason.Explicit,
this._exec(cursors.context, cursors.getAll())
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
private _exec(context: CursorContext, cursors: CursorState[]): PartialCursorState[] {
@@ -910,7 +906,7 @@ export namespace CoreNavigationCommands {
CursorChangeReason.Explicit,
CursorMoveCommands.moveToEndOfLine(cursors.context, cursors.getAll(), this._inSelectionMode)
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
}
@@ -959,7 +955,7 @@ export namespace CoreNavigationCommands {
CursorChangeReason.Explicit,
this._exec(cursors.context, cursors.getAll())
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
private _exec(context: CursorContext, cursors: CursorState[]): PartialCursorState[] {
@@ -990,7 +986,7 @@ export namespace CoreNavigationCommands {
CursorChangeReason.Explicit,
CursorMoveCommands.moveToBeginningOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
}
@@ -1034,7 +1030,7 @@ export namespace CoreNavigationCommands {
CursorChangeReason.Explicit,
CursorMoveCommands.moveToEndOfBuffer(cursors.context, cursors.getAll(), this._inSelectionMode)
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
}
@@ -1253,7 +1249,7 @@ export namespace CoreNavigationCommands {
CursorMoveCommands.word(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position)
]
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
}
@@ -1313,7 +1309,7 @@ export namespace CoreNavigationCommands {
CursorMoveCommands.line(cursors.context, cursors.getPrimaryCursor(), this._inSelectionMode, args.position, args.viewPosition)
]
);
cursors.reveal(false, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, false, RevealTarget.Primary, ScrollType.Smooth);
}
}
@@ -1385,7 +1381,7 @@ export namespace CoreNavigationCommands {
CursorChangeReason.Explicit,
CursorMoveCommands.expandLineSelection(cursors.context, cursors.getAll())
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
});
@@ -1413,7 +1409,7 @@ export namespace CoreNavigationCommands {
CursorMoveCommands.cancelSelection(cursors.context, cursors.getPrimaryCursor())
]
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
});
@@ -1440,7 +1436,7 @@ export namespace CoreNavigationCommands {
cursors.getPrimaryCursor()
]
);
cursors.reveal(true, RevealTarget.Primary, ScrollType.Smooth);
cursors.reveal(args.source, true, RevealTarget.Primary, ScrollType.Smooth);
}
});
@@ -1488,7 +1484,7 @@ export namespace CoreNavigationCommands {
const viewRange = cursors.context.convertModelRangeToViewRange(range);
cursors.revealRange(false, viewRange, revealAt, ScrollType.Smooth);
cursors.revealRange(args.source, false, viewRange, revealAt, ScrollType.Smooth);
}
});
@@ -21,6 +21,8 @@ import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
import { ViewContext } from 'vs/editor/common/view/viewContext';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
/**
* Merges mouse events when mouse move events are throttled
@@ -111,7 +113,7 @@ export class MouseHandler extends ViewEventHandler {
const onMouseWheel = (browserEvent: IMouseWheelEvent) => {
this.viewController.emitMouseWheel(browserEvent);
if (!this._context.configuration.editor.viewInfo.mouseWheelZoom) {
if (!this._context.configuration.options.get(EditorOption.mouseWheelZoom)) {
return;
}
const e = new StandardWheelEvent(browserEvent);
@@ -216,7 +218,7 @@ export class MouseHandler extends ViewEventHandler {
const targetIsContent = (t.type === editorBrowser.MouseTargetType.CONTENT_TEXT || t.type === editorBrowser.MouseTargetType.CONTENT_EMPTY);
const targetIsGutter = (t.type === editorBrowser.MouseTargetType.GUTTER_GLYPH_MARGIN || t.type === editorBrowser.MouseTargetType.GUTTER_LINE_NUMBERS || t.type === editorBrowser.MouseTargetType.GUTTER_LINE_DECORATIONS);
const targetIsLineNumbers = (t.type === editorBrowser.MouseTargetType.GUTTER_LINE_NUMBERS);
const selectOnLineNumbers = this._context.configuration.editor.viewInfo.selectOnLineNumbers;
const selectOnLineNumbers = this._context.configuration.options.get(EditorOption.selectOnLineNumbers);
const targetIsViewZone = (t.type === editorBrowser.MouseTargetType.CONTENT_VIEW_ZONE || t.type === editorBrowser.MouseTargetType.GUTTER_VIEW_ZONE);
const targetIsWidget = (t.type === editorBrowser.MouseTargetType.CONTENT_WIDGET);
@@ -351,8 +353,10 @@ class MouseDownOperation extends Disposable {
// Overwrite the detail of the MouseEvent, as it will be sent out in an event and contributions might rely on it.
e.detail = this._mouseState.count;
if (!this._context.configuration.editor.readOnly
&& this._context.configuration.editor.dragAndDrop
const options = this._context.configuration.options;
if (!options.get(EditorOption.readOnly)
&& options.get(EditorOption.dragAndDrop)
&& !this._mouseState.altKey // we don't support multiple mouse
&& e.detail < 2 // only single click on a selection can work
&& !this._isActive // the mouse is not down yet
@@ -10,7 +10,7 @@ import { ClientCoordinates, EditorMouseEvent, EditorPagePosition, PageCoordinate
import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
import { ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions';
import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions';
import { Position } from 'vs/editor/common/core/position';
import { Range as EditorRange } from 'vs/editor/common/core/range';
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
@@ -239,10 +239,11 @@ export class HitTestContext {
constructor(context: ViewContext, viewHelper: IPointerHandlerHelper, lastViewCursorsRenderData: IViewCursorRenderData[]) {
this.model = context.model;
this.layoutInfo = context.configuration.editor.layoutInfo;
const options = context.configuration.options;
this.layoutInfo = options.get(EditorOption.layoutInfo);
this.viewDomNode = viewHelper.viewDomNode;
this.lineHeight = context.configuration.editor.lineHeight;
this.typicalHalfwidthCharacterWidth = context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth;
this.lineHeight = options.get(EditorOption.lineHeight);
this.typicalHalfwidthCharacterWidth = options.get(EditorOption.fontInfo).typicalHalfwidthCharacterWidth;
this.lastViewCursorsRenderData = lastViewCursorsRenderData;
this._context = context;
this._viewHelper = viewHelper;
@@ -713,9 +714,10 @@ export class MouseTargetFactory {
}
public getMouseColumn(editorPos: EditorPagePosition, pos: PageCoordinates): number {
const layoutInfo = this._context.configuration.editor.layoutInfo;
const options = this._context.configuration.options;
const layoutInfo = options.get(EditorOption.layoutInfo);
const mouseContentHorizontalOffset = this._context.viewLayout.getCurrentScrollLeft() + pos.x - editorPos.x - layoutInfo.contentLeft;
return MouseTargetFactory._getMouseColumn(mouseContentHorizontalOffset, this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth);
return MouseTargetFactory._getMouseColumn(mouseContentHorizontalOffset, options.get(EditorOption.fontInfo).typicalHalfwidthCharacterWidth);
}
public static _getMouseColumn(mouseContentHorizontalOffset: number, typicalHalfwidthCharacterWidth: number): number {
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./textAreaHandler';
import * as nls from 'vs/nls';
import * as browser from 'vs/base/browser/browser';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
@@ -16,7 +17,7 @@ import { ViewController } from 'vs/editor/browser/view/viewController';
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
import { RenderLineNumbersType, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions';
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
import { WordCharacterClass, getMapForWordSeparators } from 'vs/editor/common/controller/wordCharacterClassifier';
import { Position } from 'vs/editor/common/core/position';
@@ -91,12 +92,13 @@ export class TextAreaHandler extends ViewPart {
private readonly _viewController: ViewController;
private readonly _viewHelper: ITextAreaHandlerHelper;
private _scrollLeft: number;
private _scrollTop: number;
private _accessibilitySupport: AccessibilitySupport;
private _contentLeft: number;
private _contentWidth: number;
private _contentHeight: number;
private _scrollLeft: number;
private _scrollTop: number;
private _fontInfo: BareFontInfo;
private _lineHeight: number;
private _emptySelectionClipboard: boolean;
@@ -117,19 +119,20 @@ export class TextAreaHandler extends ViewPart {
this._viewController = viewController;
this._viewHelper = viewHelper;
const conf = this._context.configuration.editor;
this._accessibilitySupport = conf.accessibilitySupport;
this._contentLeft = conf.layoutInfo.contentLeft;
this._contentWidth = conf.layoutInfo.contentWidth;
this._contentHeight = conf.layoutInfo.contentHeight;
this._scrollLeft = 0;
this._scrollTop = 0;
this._fontInfo = conf.fontInfo;
this._lineHeight = conf.lineHeight;
this._emptySelectionClipboard = conf.emptySelectionClipboard;
this._copyWithSyntaxHighlighting = conf.copyWithSyntaxHighlighting;
const options = this._context.configuration.options;
const layoutInfo = options.get(EditorOption.layoutInfo);
this._accessibilitySupport = options.get(EditorOption.accessibilitySupport);
this._contentLeft = layoutInfo.contentLeft;
this._contentWidth = layoutInfo.contentWidth;
this._contentHeight = layoutInfo.contentHeight;
this._fontInfo = options.get(EditorOption.fontInfo);
this._lineHeight = options.get(EditorOption.lineHeight);
this._emptySelectionClipboard = options.get(EditorOption.emptySelectionClipboard);
this._copyWithSyntaxHighlighting = options.get(EditorOption.copyWithSyntaxHighlighting);
this._visibleTextArea = null;
this._selections = [new Selection(1, 1, 1, 1)];
@@ -143,7 +146,7 @@ export class TextAreaHandler extends ViewPart {
this.textArea.setAttribute('autocapitalize', 'off');
this.textArea.setAttribute('autocomplete', 'off');
this.textArea.setAttribute('spellcheck', 'false');
this.textArea.setAttribute('aria-label', conf.viewInfo.ariaLabel);
this.textArea.setAttribute('aria-label', this._getAriaLabel(options));
this.textArea.setAttribute('role', 'textbox');
this.textArea.setAttribute('aria-multiline', 'true');
this.textArea.setAttribute('aria-haspopup', 'false');
@@ -280,6 +283,7 @@ export class TextAreaHandler extends ViewPart {
const column = this._selections[0].startColumn;
this._context.privateViewEventBus.emit(new viewEvents.ViewRevealRangeRequestEvent(
'keyboard',
new Range(lineNumber, column, lineNumber, column),
viewEvents.VerticalRevealType.Simple,
true,
@@ -340,7 +344,7 @@ export class TextAreaHandler extends ViewPart {
private _getWordBeforePosition(position: Position): string {
const lineContent = this._context.model.getLineContent(position.lineNumber);
const wordSeparators = getMapForWordSeparators(this._context.configuration.editor.wordSeparators);
const wordSeparators = getMapForWordSeparators(this._context.configuration.options.get(EditorOption.wordSeparators));
let column = position.column;
let distance = 0;
@@ -367,35 +371,33 @@ export class TextAreaHandler extends ViewPart {
return '';
}
private _getAriaLabel(options: IComputedEditorOptions): string {
const accessibilitySupport = options.get(EditorOption.accessibilitySupport);
if (accessibilitySupport === AccessibilitySupport.Disabled) {
return nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press Alt+F1 for options.");
}
return options.get(EditorOption.ariaLabel);
}
// --- begin event handlers
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
const conf = this._context.configuration.editor;
const options = this._context.configuration.options;
const layoutInfo = options.get(EditorOption.layoutInfo);
if (e.fontInfo) {
this._fontInfo = conf.fontInfo;
}
if (e.viewInfo) {
this.textArea.setAttribute('aria-label', conf.viewInfo.ariaLabel);
}
if (e.layoutInfo) {
this._contentLeft = conf.layoutInfo.contentLeft;
this._contentWidth = conf.layoutInfo.contentWidth;
this._contentHeight = conf.layoutInfo.contentHeight;
}
if (e.lineHeight) {
this._lineHeight = conf.lineHeight;
}
if (e.accessibilitySupport) {
this._accessibilitySupport = conf.accessibilitySupport;
this._accessibilitySupport = options.get(EditorOption.accessibilitySupport);
this._contentLeft = layoutInfo.contentLeft;
this._contentWidth = layoutInfo.contentWidth;
this._contentHeight = layoutInfo.contentHeight;
this._fontInfo = options.get(EditorOption.fontInfo);
this._lineHeight = options.get(EditorOption.lineHeight);
this._emptySelectionClipboard = options.get(EditorOption.emptySelectionClipboard);
this._copyWithSyntaxHighlighting = options.get(EditorOption.copyWithSyntaxHighlighting);
this.textArea.setAttribute('aria-label', this._getAriaLabel(options));
if (e.hasChanged(EditorOption.accessibilitySupport)) {
this._textAreaInput.writeScreenReaderContent('strategy changed');
}
if (e.emptySelectionClipboard) {
this._emptySelectionClipboard = conf.emptySelectionClipboard;
}
if (e.copyWithSyntaxHighlighting) {
this._copyWithSyntaxHighlighting = conf.copyWithSyntaxHighlighting;
}
return true;
}
@@ -544,10 +546,12 @@ export class TextAreaHandler extends ViewPart {
tac.setWidth(1);
tac.setHeight(1);
if (this._context.configuration.editor.viewInfo.glyphMargin) {
const options = this._context.configuration.options;
if (options.get(EditorOption.glyphMargin)) {
tac.setClassName('monaco-editor-background textAreaCover ' + Margin.OUTER_CLASS_NAME);
} else {
if (this._context.configuration.editor.viewInfo.renderLineNumbers !== RenderLineNumbersType.Off) {
if (options.get(EditorOption.lineNumbers).renderType !== RenderLineNumbersType.Off) {
tac.setClassName('monaco-editor-background textAreaCover ' + LineNumbersOverlay.CLASS_NAME);
} else {
tac.setClassName('monaco-editor-background textAreaCover');
+16 -12
View File
@@ -6,7 +6,7 @@
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { IMouseEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as editorOptions from 'vs/editor/common/config/editorOptions';
import { OverviewRulerPosition, ConfigurationChangedEvent, EditorLayoutInfo, IComputedEditorOptions, EditorOption, FindComputedEditorOptionValueById, IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { ICursors } from 'vs/editor/common/controller/cursorCommon';
import { ICursorPositionChangedEvent, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { IPosition, Position } from 'vs/editor/common/core/position';
@@ -315,7 +315,7 @@ export interface IOverviewRuler {
getDomNode(): HTMLElement;
dispose(): void;
setZones(zones: OverviewRulerZone[]): void;
setLayout(position: editorOptions.OverviewRulerPosition): void;
setLayout(position: OverviewRulerPosition): void;
}
/**
@@ -351,7 +351,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
* An event emitted when the configuration of the editor has changed. (e.g. `editor.updateOptions()`)
* @event
*/
onDidChangeConfiguration(listener: (e: editorOptions.IConfigurationChangedEvent) => void): IDisposable;
onDidChangeConfiguration(listener: (e: ConfigurationChangedEvent) => void): IDisposable;
/**
* An event emitted when the cursor position has changed.
* @event
@@ -481,7 +481,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
* An event emitted when the layout of the editor has changed.
* @event
*/
onDidLayoutChange(listener: (e: editorOptions.EditorLayoutInfo) => void): IDisposable;
onDidLayoutChange(listener: (e: EditorLayoutInfo) => void): IDisposable;
/**
* An event emitted when the scroll in the editor has changed.
* @event
@@ -532,15 +532,19 @@ export interface ICodeEditor extends editorCommon.IEditor {
setModel(model: ITextModel | null): void;
/**
* Returns the current editor's configuration
*/
getConfiguration(): editorOptions.InternalEditorOptions;
/**
* Returns the 'raw' editor's configuration (without any validation or defaults).
* @internal
*/
getRawConfiguration(): editorOptions.IEditorOptions;
getOptions(): IComputedEditorOptions;
/**
* @internal
*/
getOption<T extends EditorOption>(id: T): FindComputedEditorOptionValueById<T>;
/**
* Returns the editor's configuration (without any validation or defaults).
*/
getRawOptions(): IEditorOptions;
/**
* Get value of the current model attached to this editor.
@@ -655,7 +659,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
/**
* Get the layout info for the editor.
*/
getLayoutInfo(): editorOptions.EditorLayoutInfo;
getLayoutInfo(): EditorLayoutInfo;
/**
* Returns the ranges that are currently visible.
+7 -10
View File
@@ -12,6 +12,7 @@ import { Selection } from 'vs/editor/common/core/selection';
import { IConfiguration } from 'vs/editor/common/editorCommon';
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
export interface IMouseDispatchData {
position: Position;
@@ -107,7 +108,7 @@ export class ViewController {
}
private _hasMulticursorModifier(data: IMouseDispatchData): boolean {
switch (this.configuration.editor.multiCursorModifier) {
switch (this.configuration.options.get(EditorOption.multiCursorModifier)) {
case 'altKey':
return data.altKey;
case 'ctrlKey':
@@ -119,7 +120,7 @@ export class ViewController {
}
private _hasNonMulticursorModifier(data: IMouseDispatchData): boolean {
switch (this.configuration.editor.multiCursorModifier) {
switch (this.configuration.options.get(EditorOption.multiCursorModifier)) {
case 'altKey':
return data.ctrlKey || data.metaKey;
case 'ctrlKey':
@@ -132,11 +133,7 @@ export class ViewController {
public dispatchMouse(data: IMouseDispatchData): void {
if (data.middleButton) {
if (data.inSelectionMode) {
this._columnSelect(data.position, data.mouseColumn, true);
} else {
this.moveTo(data.position);
}
this._columnSelect(data.position, data.mouseColumn, data.inSelectionMode);
} else if (data.startedOnLineNumbers) {
// If the dragging started on the gutter, then have operations work on the entire line
if (this._hasMulticursorModifier(data)) {
@@ -182,7 +179,7 @@ export class ViewController {
if (this._hasMulticursorModifier(data)) {
if (!this._hasNonMulticursorModifier(data)) {
if (data.shiftKey) {
this._columnSelect(data.position, data.mouseColumn, false);
this._columnSelect(data.position, data.mouseColumn, true);
} else {
// Do multi-cursor operations only when purely alt is pressed
if (data.inSelectionMode) {
@@ -222,13 +219,13 @@ export class ViewController {
this._execMouseCommand(CoreNavigationCommands.MoveToSelect, this._usualArgs(viewPosition));
}
private _columnSelect(viewPosition: Position, mouseColumn: number, setAnchorIfNotSet: boolean): void {
private _columnSelect(viewPosition: Position, mouseColumn: number, doColumnSelect: boolean): void {
viewPosition = this._validateViewColumn(viewPosition);
this._execMouseCommand(CoreNavigationCommands.ColumnSelect, {
position: this._convertViewToModelPosition(viewPosition),
viewPosition: viewPosition,
mouseColumn: mouseColumn,
setAnchorIfNotSet: setAnchorIfNotSet
doColumnSelect: doColumnSelect
});
}

Some files were not shown because too many files have changed in this diff Show More