Merge branch 'master' into aeschli/html-extension

This commit is contained in:
Martin Aeschlimann 2016-09-13 16:59:01 +02:00
commit 0aefa275cb
277 changed files with 6693 additions and 4149 deletions

View file

@ -19,7 +19,7 @@
"lcov.path": ["./.build/coverage/lcov.info", "./.build/coverage-single/lcov.info"],
"lcov.watch": [{
"pattern": "**/*.test.js",
"command": "${workspaceRoot}\\scripts\\test.sh --coverage --run ${file}",
"command": "${workspaceRoot}/scripts/test.sh --coverage --run ${file}",
"windows": {
"command": "${workspaceRoot}\\scripts\\test.bat --coverage --run ${file}"
}

View file

@ -23,9 +23,6 @@ function log(prefix, message) {
gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message);
}
const root = path.dirname(__dirname);
const commit = util.getVersion(root);
exports.loaderConfig = function (emptyPaths) {
const result = {
paths: {
@ -236,19 +233,16 @@ function uglifyWithCopyrights() {
const uglifyStream = uglify({ preserveComments });
return es.through(function (data) {
const _this = this;
onNewFile();
uglifyStream.once('data', function(data) {
_this.emit('data', data);
})
uglifyStream.once('data', data => this.emit('data', data));
uglifyStream.write(data);
},
function () { this.emit('end'); });
}
exports.minifyTask = function (src, addSourceMapsComment) {
exports.minifyTask = function (src, sourceMapBaseUrl) {
const sourceMappingURL = sourceMapBaseUrl && (f => `${ sourceMapBaseUrl }/${ f.relative }.map`);
return function() {
const jsFilter = filter('**/*.js', { restore: true });
const cssFilter = filter('**/*.css', { restore: true });
@ -262,12 +256,10 @@ exports.minifyTask = function (src, addSourceMapsComment) {
.pipe(minifyCSS({ reduceIdents: false }))
.pipe(cssFilter.restore)
.pipe(sourcemaps.write('./', {
sourceMappingURL: function (file) {
return 'https://ticino.blob.core.windows.net/sourcemaps/' + commit + '/' + file.relative + '.map';
},
sourceMappingURL,
sourceRoot: null,
includeContent: true,
addComment: addSourceMapsComment
addComment: true
}))
.pipe(gulp.dest(src + '-min'));
};

View file

@ -10,7 +10,6 @@ var buildfile = require('../src/buildfile');
var util = require('./lib/util');
var common = require('./gulpfile.common');
var es = require('event-stream');
var fs = require('fs');
var File = require('vinyl');
var root = path.dirname(__dirname);
@ -78,7 +77,7 @@ gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-build'], common
}));
gulp.task('clean-minified-editor', util.rimraf('out-editor-min'));
gulp.task('minify-editor', ['clean-minified-editor', 'optimize-editor'], common.minifyTask('out-editor', true));
gulp.task('minify-editor', ['clean-minified-editor', 'optimize-editor'], common.minifyTask('out-editor'));
gulp.task('clean-editor-distro', util.rimraf('out-monaco-editor-core'));
gulp.task('editor-distro', ['clean-editor-distro', 'minify-editor', 'optimize-editor'], function() {

View file

@ -6,59 +6,63 @@
// Increase max listeners for event emitters
require('events').EventEmitter.defaultMaxListeners = 100;
var gulp = require('gulp');
var path = require('path');
var tsb = require('gulp-tsb');
var es = require('event-stream');
var filter = require('gulp-filter');
var rimraf = require('rimraf');
var util = require('./lib/util');
var watcher = require('./lib/watch');
var createReporter = require('./lib/reporter');
var glob = require('glob');
var sourcemaps = require('gulp-sourcemaps');
var nlsDev = require('vscode-nls-dev');
const gulp = require('gulp');
const path = require('path');
const tsb = require('gulp-tsb');
const es = require('event-stream');
const filter = require('gulp-filter');
const rimraf = require('rimraf');
const util = require('./lib/util');
const watcher = require('./lib/watch');
const createReporter = require('./lib/reporter');
const glob = require('glob');
const sourcemaps = require('gulp-sourcemaps');
const nlsDev = require('vscode-nls-dev');
const root = path.dirname(__dirname);
const commit = util.getVersion(root);
var extensionsPath = path.join(path.dirname(__dirname), 'extensions');
const extensionsPath = path.join(path.dirname(__dirname), 'extensions');
var compilations = glob.sync('**/tsconfig.json', {
const compilations = glob.sync('**/tsconfig.json', {
cwd: extensionsPath,
ignore: ['**/out/**', '**/node_modules/**']
});
var languages = ['chs', 'cht', 'jpn', 'kor', 'deu', 'fra', 'esn', 'rus', 'ita'];
const getBaseUrl = out => `https://ticino.blob.core.windows.net/sourcemaps/${ commit }/${ out }`;
const languages = ['chs', 'cht', 'jpn', 'kor', 'deu', 'fra', 'esn', 'rus', 'ita'];
var tasks = compilations.map(function(tsconfigFile) {
var absolutePath = path.join(extensionsPath, tsconfigFile);
var relativeDirname = path.dirname(tsconfigFile);
const tasks = compilations.map(function(tsconfigFile) {
const absolutePath = path.join(extensionsPath, tsconfigFile);
const relativeDirname = path.dirname(tsconfigFile);
var tsOptions = require(absolutePath).compilerOptions;
const tsOptions = require(absolutePath).compilerOptions;
tsOptions.verbose = false;
tsOptions.sourceMap = true;
var name = relativeDirname.replace(/\//g, '-');
const name = relativeDirname.replace(/\//g, '-');
// Tasks
var clean = 'clean-extension:' + name;
var compile = 'compile-extension:' + name;
var watch = 'watch-extension:' + name;
const clean = 'clean-extension:' + name;
const compile = 'compile-extension:' + name;
const watch = 'watch-extension:' + name;
// Build Tasks
var cleanBuild = 'clean-extension-build:' + name;
var compileBuild = 'compile-extension-build:' + name;
var watchBuild = 'watch-extension-build:' + name;
const cleanBuild = 'clean-extension-build:' + name;
const compileBuild = 'compile-extension-build:' + name;
const watchBuild = 'watch-extension-build:' + name;
var root = path.join('extensions', relativeDirname);
var srcBase = path.join(root, 'src');
var src = path.join(srcBase, '**');
var out = path.join(root, 'out');
var i18n = path.join(__dirname, '..', 'i18n');
const root = path.join('extensions', relativeDirname);
const srcBase = path.join(root, 'src');
const src = path.join(srcBase, '**');
const out = path.join(root, 'out');
const i18n = path.join(__dirname, '..', 'i18n');
const baseUrl = getBaseUrl(out);
function createPipeline(build) {
var reporter = createReporter();
const reporter = createReporter();
tsOptions.inlineSources = !!build;
var compilation = tsb.create(tsOptions, null, null, err => reporter(err.toString()));
const compilation = tsb.create(tsOptions, null, null, err => reporter(err.toString()));
return function () {
const input = es.through();
@ -68,13 +72,12 @@ var tasks = compilations.map(function(tsconfigFile) {
.pipe(util.loadSourcemaps())
.pipe(compilation())
.pipe(build ? nlsDev.rewriteLocalizeCalls() : es.through())
.pipe(build ? util.stripSourceMappingURL() : es.through())
.pipe(sourcemaps.write('.', {
addComment: false,
sourceMappingURL: !build ? null : f => `${ baseUrl }/${ f.relative }.map`,
addComment: !!build,
includeContent: !!build,
sourceRoot: function(file) {
const levels = file.relative.split(path.sep).length;
return '../'.repeat(levels) + 'src';
}
sourceRoot: file => '../'.repeat(file.relative.split(path.sep).length) + 'src'
}))
.pipe(tsFilter.restore)
.pipe(build ? nlsDev.createAdditionalLanguageFiles(languages, i18n, out) : es.through())
@ -86,11 +89,9 @@ var tasks = compilations.map(function(tsconfigFile) {
const srcOpts = { cwd: path.dirname(__dirname), base: srcBase };
gulp.task(clean, function (cb) {
rimraf(out, cb);
});
gulp.task(clean, cb => rimraf(out, cb));
gulp.task(compile, [clean], function () {
gulp.task(compile, [clean], () => {
const pipeline = createPipeline(false);
const input = gulp.src(src, srcOpts);
@ -99,7 +100,7 @@ var tasks = compilations.map(function(tsconfigFile) {
.pipe(gulp.dest(out));
});
gulp.task(watch, [clean], function () {
gulp.task(watch, [clean], () => {
const pipeline = createPipeline(false);
const input = gulp.src(src, srcOpts);
const watchInput = watcher(src, srcOpts);
@ -109,11 +110,9 @@ var tasks = compilations.map(function(tsconfigFile) {
.pipe(gulp.dest(out));
});
gulp.task(cleanBuild, function (cb) {
rimraf(out, cb);
});
gulp.task(cleanBuild, cb => rimraf(out, cb));
gulp.task(compileBuild, [clean], function () {
gulp.task(compileBuild, [clean], () => {
const pipeline = createPipeline(true);
const input = gulp.src(src, srcOpts);
@ -122,13 +121,13 @@ var tasks = compilations.map(function(tsconfigFile) {
.pipe(gulp.dest(out));
});
gulp.task(watchBuild, [clean], function () {
gulp.task(watchBuild, [clean], () => {
const pipeline = createPipeline(true);
const input = gulp.src(src, srcOpts);
const watchInput = watcher(src, srcOpts);
return watchInput
.pipe(util.incremental(function () { return pipeline(true); }, input))
.pipe(util.incremental(() => pipeline(true), input))
.pipe(gulp.dest(out));
});
@ -142,10 +141,10 @@ var tasks = compilations.map(function(tsconfigFile) {
};
});
gulp.task('clean-extensions', tasks.map(function (t) { return t.clean; }));
gulp.task('compile-extensions', tasks.map(function (t) { return t.compile; }));
gulp.task('watch-extensions', tasks.map(function (t) { return t.watch; }));
gulp.task('clean-extensions', tasks.map(t => t.clean));
gulp.task('compile-extensions', tasks.map(t => t.compile));
gulp.task('watch-extensions', tasks.map(t => t.watch));
gulp.task('clean-extensions-build', tasks.map(function (t) { return t.cleanBuild; }));
gulp.task('compile-extensions-build', tasks.map(function (t) { return t.compileBuild; }));
gulp.task('watch-extensions-build', tasks.map(function (t) { return t.watchBuild; }));
gulp.task('clean-extensions-build', tasks.map(t => t.cleanBuild));
gulp.task('compile-extensions-build', tasks.map(t => t.compileBuild));
gulp.task('watch-extensions-build', tasks.map(t => t.watchBuild));

View file

@ -86,8 +86,9 @@ gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compil
out: 'out-vscode'
}));
const baseUrl = `https://ticino.blob.core.windows.net/sourcemaps/${ commit }/core`;
gulp.task('clean-minified-vscode', util.rimraf('out-vscode-min'));
gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-vscode'], common.minifyTask('out-vscode', true));
gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-vscode'], common.minifyTask('out-vscode', baseUrl));
// Package
const darwinCreditsTemplate = product.darwinCredits && _.template(fs.readFileSync(path.join(root, product.darwinCredits), 'utf8'));
@ -269,8 +270,16 @@ gulp.task('vscode-linux-arm-min', ['minify-vscode', 'clean-vscode-linux-arm'], p
// Sourcemaps
gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], function () {
return gulp.src('out-vscode-min/**/*.map')
gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => {
const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' })
.pipe(es.mapSync(f => {
f.path = `${ f.base }/core/${ f.relative }`;
return f;
}));
const extensions = gulp.src('extensions/**/out/**/*.map', { base: '.' });
return es.merge(vs, extensions)
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,

View file

@ -154,18 +154,6 @@ exports.toFileUri = filePath => {
return 'file://' + filePath.replace(/\\/g, '/');
};
exports.rebase = (base, append) => {
return es.mapSync(f => {
if (append) {
f.base = path.join(f.base, base);
} else {
f.base = base;
}
return f;
});
};
exports.skipDirectories = () => {
return es.mapSync(f => {
if (!f.isDirectory()) {
@ -241,6 +229,19 @@ exports.loadSourcemaps = () => {
return es.duplex(input, output);
};
exports.stripSourceMappingURL = () => {
const input = es.through();
const output = input
.pipe(es.mapSync(f => {
const contents = f.contents.toString('utf8');
f.contents = new Buffer(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
return f;
}));
return es.duplex(input, output);
};
exports.rimraf = dir => {
let retries = 0;

View file

@ -39,7 +39,7 @@ declare module monaco {
#include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, TPromise
#include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken
#include(vs/base/common/uri): URI
#include(vs/base/common/keyCodes): KeyCode, KeyMod
#include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod
#include(vs/base/common/htmlContent): MarkedString
#include(vs/base/browser/keyboardEvent): IKeyboardEvent
#include(vs/base/browser/mouseEvent): IMouseEvent

View file

@ -3,11 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var win = "Please run '.\\scripts\\npm.bat install' instead."
var nix = "Please run './scripts/npm.sh install' instead."
var win = "Please run '.\\scripts\\npm.bat install' instead.";
var nix = "Please run './scripts/npm.sh install' instead.";
if (process.env['npm_config_disturl'] !== 'https://atom.io/download/atom-shell') {
console.error("You can't use plain npm to install Code's dependencies.");
console.error(/^win/.test(process.platform) ? win : nix);
process.exit(1);
}
}

View file

@ -758,9 +758,9 @@ Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "Path"; Value
Root: HKCU; Subkey: "SOFTWARE\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "Open with {#NameShort}"; Tasks: addcontextmenufiles; Flags: uninsdeletekey
Root: HKCU; Subkey: "SOFTWARE\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufiles
Root: HKCU; Subkey: "SOFTWARE\Classes\*\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: addcontextmenufiles
Root: HKCU; Subkey: "SOFTWARE\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "Open with {#NameShort}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey
Root: HKCU; Subkey: "SOFTWARE\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders
Root: HKCU; Subkey: "SOFTWARE\Classes\directory\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders
Root: HKCU; Subkey: "SOFTWARE\Classes\Folder\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "Open with {#NameShort}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey
Root: HKCU; Subkey: "SOFTWARE\Classes\Folder\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders
Root: HKCU; Subkey: "SOFTWARE\Classes\Folder\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders
Root: HKCU; Subkey: "SOFTWARE\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "Open with {#NameShort}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey
Root: HKCU; Subkey: "SOFTWARE\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders
Root: HKCU; Subkey: "SOFTWARE\Classes\directory\background\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders

View file

@ -6,6 +6,8 @@
import {window, workspace, DecorationOptions, DecorationRenderOptions, Disposable, Range, TextDocument, TextEditor} from 'vscode';
const MAX_DECORATORS = 500;
let decorationType: DecorationRenderOptions = {
before: {
contentText: ' ',
@ -76,7 +78,7 @@ export function activateColorDecorations(decoratorProvider: (uri: string) => The
let document = editor.document;
if (supportedLanguages[document.languageId]) {
decoratorProvider(document.uri.toString()).then(ranges => {
let decorations = ranges.map(range => {
let decorations = ranges.slice(0, MAX_DECORATORS).map(range => {
let color = document.getText(range);
return <DecorationOptions>{
range: range,

View file

@ -1,7 +1,7 @@
{
"comments": {
"lineComment": "//",
"blockComment": [ "/*", "*/" ]
"lineComment": "#",
"blockComment": [ "#", " " ]
},
"brackets": [
["{", "}"],

View file

@ -1,7 +1,7 @@
{
"comments": {
"lineComment": "//",
"blockComment": [ "/*", "*/" ]
"lineComment": "#",
"blockComment": [ "#", " " ]
},
"brackets": [
["{", "}"],

View file

@ -1,6 +1,6 @@
{
"account": "monacobuild",
"container": "debuggers",
"zip": "864e0bd/node-debug.zip",
"zip": "d643199/node-debug.zip",
"output": ""
}

View file

@ -54,6 +54,35 @@ function invertColor(color) {
return res;
}
function getLanguageMappings() {
var langToExt = {
'csharp': ['cs', 'csx']
};
var allExtensions = fs.readdirSync('..');
for (var i= 0; i < allExtensions.length; i++) {
let dirPath = path.join('..', allExtensions[i], 'package.json');
if (!fs.lstatSync(path.join('..', allExtensions[i])).isDirectory() || !fs.lstatSync(dirPath).isFile()) {
continue;
}
let content = fs.readFileSync(dirPath).toString();
let jsonContent = JSON.parse(content);
let languages = jsonContent.contributes && jsonContent.contributes.languages;
if (Array.isArray(languages)) {
for (var k = 0; k < languages.length; k++) {
var extensions = languages[k].extensions;
var languageId = languages[k].id;
if (Array.isArray(extensions) && languageId) {
langToExt[languageId] = extensions.map(function (e) { return e.substr(1); });
}
}
}
}
return langToExt;
}
exports.update = function () {
var fontMappings = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/_fonts/seti.less';
@ -63,6 +92,7 @@ exports.update = function () {
var fileName2Def = {};
var def2ColorId = {};
var colorId2Value = {};
var lang2Def = {};
function writeFileIconContent(info) {
var iconDefinitions = {};
@ -106,14 +136,16 @@ exports.update = function () {
file: "_default",
fileExtensions: ext2Def,
fileNames: fileName2Def,
languageIds: lang2Def,
light: {
file: "_default_light",
fileExtensions: getInvertSet(ext2Def),
languageIds: getInvertSet(lang2Def),
fileNames: getInvertSet(fileName2Def)
},
version: 'https://github.com/jesseweed/seti-ui/commit/' + info.commitSha,
};
fs.writeFileSync('./icons/seti-icon-theme.json', JSON.stringify(res, null, '\t'));
fs.writeFileSync('./icons/vs-seti-icon-theme.json', JSON.stringify(res, null, '\t'));
}
@ -140,6 +172,26 @@ exports.update = function () {
}
def2ColorId[def] = colorId;
}
// replace extensions for languageId
var langToExt = getLanguageMappings();
for (var lang in langToExt) {
var exts = langToExt[lang];
var preferredDef = null;
// use the first file association for the preferred definition
for (var i1 = 0; i1 < exts.length && !preferredDef; i1++) {
preferredDef = ext2Def[exts[i1]];
}
if (preferredDef) {
lang2Def[lang] = preferredDef;
for (var i1 = 0; i1 < exts.length; i1++) {
// remove the extention association, unless it is different from the preferred
if (ext2Def[exts[i1]] === preferredDef) {
delete ext2Def[exts[i1]];
}
}
}
}
var colors = 'https://raw.githubusercontent.com/jesseweed/seti-ui/master/styles/ui-variables.less';
return download(colors).then(function (content) {
var regex3 = /(@[\w-]+):\s*(#[0-9a-z]+)/g;
@ -156,7 +208,7 @@ exports.update = function () {
console.error(e);
}
});
});
});
});
}, console.error);
}

View file

@ -701,16 +701,9 @@
},
"file": "_default",
"fileExtensions": {
"cpp": "_cpp",
"c": "_c",
"cs": "_c-sharp",
"cc": "_cpp",
"cfc": "_coldfusion",
"cfm": "_coldfusion",
"coffee": "_coffee",
"config": "_config",
"cson": "_json",
"css": "_css",
"css.map": "_css",
"sss": "_css",
"csv": "_csv",
@ -719,14 +712,11 @@
"elm": "_elm",
"ico": "_favicon",
"gitignore": "_github",
"gitconfig": "_github",
"gitkeep": "_github",
"gitattributes": "_github",
"go": "_go2",
"slide": "_go",
"article": "_go",
"gradle": "_gradle",
"groovy": "_grails",
"gsp": "_grails",
"hh": "_hacklang",
"haml": "_haml",
@ -735,57 +725,37 @@
"hjs": "_mustache",
"hs": "_haskell",
"lhs": "_haskell",
"html": "_html",
"jade": "_jade",
"java": "_java",
"class": "_java",
"classpath": "_java",
"js": "_javascript",
"js.map": "_javascript",
"es": "_javascript",
"es5": "_javascript",
"es6": "_javascript",
"es7": "_javascript",
"json": "_json",
"jl": "_julia",
"less": "_less",
"liquid": "_liquid",
"ls": "_livescript",
"lua": "_lua",
"markdown": "_markdown",
"md": "_markdown",
"mustache": "_mustache",
"stache": "_mustache",
"npm-debug.log": "_npm",
"npmignore": "_npm",
"h": "_c",
"m": "_c",
"ml": "_ocaml",
"mli": "_ocaml",
"cmx": "_ocaml",
"cmxa": "_ocaml",
"pl": "_perl",
"php": "_php",
"php.inc": "_php",
"pug": "_pug",
"pp": "_puppet",
"py": "_python",
"jsx": "_react",
"cjsx": "_react",
"tsx": "_react",
"rb": "_ruby",
"erb": "_ruby",
"erb.html": "_ruby",
"html.erb": "_ruby",
"rs": "_rust",
"sass": "_sass",
"scss": "_sass",
"slim": "_slim",
"smarty.tpl": "_smarty",
"sbt": "_sbt",
"scala": "_scala",
"styl": "_stylus",
"swift": "_swift",
"tf": "_terraform",
"tf.json": "_terraform",
"tex": "_tex",
@ -795,12 +765,9 @@
"ins": "_tex",
"txt": "_default",
"twig": "_twig",
"ts": "_typescript",
"vala": "_vala",
"vapi": "_vala",
"xml": "_xml",
"yml": "_yml",
"yaml": "_yml",
"ai": "_illustrator",
"psd": "_photoshop",
"pdf": "_pdf",
@ -814,11 +781,7 @@
"jpeg": "_image",
"svg": "_svg",
"svgx": "_image",
"cmd": "_shell",
"sh": "_shell",
"zsh": "_shell",
"fish": "_shell",
"zshrc": "_shell",
"mov": "_video",
"ogv": "_video",
"webm": "_video",
@ -865,19 +828,45 @@
"TODO": "_todo",
"npm-debug.log": "_npm_ignored"
},
"languageIds": {
"csharp": "_c-sharp",
"bat": "_shell",
"coffeescript": "_coffee",
"c": "_c",
"cpp": "_cpp",
"css": "_css",
"go": "_go2",
"groovy": "_grails",
"html": "_html",
"ini": "_github",
"jade": "_jade",
"java": "_java",
"javascriptreact": "_react",
"javascript": "_javascript",
"json": "_json",
"less": "_less",
"lua": "_lua",
"markdown": "_markdown",
"objective-c": "_c",
"perl": "_perl",
"php": "_php",
"python": "_python",
"ruby": "_ruby",
"rust": "_rust",
"scss": "_sass",
"shellscript": "_shell",
"swift": "_swift",
"typescript": "_typescript",
"typescriptreact": "_react",
"xml": "_config",
"yaml": "_yml"
},
"light": {
"file": "_default_light",
"fileExtensions": {
"cpp": "_cpp_light",
"c": "_c_light",
"cs": "_c-sharp_light",
"cc": "_cpp_light",
"cfc": "_coldfusion_light",
"cfm": "_coldfusion_light",
"coffee": "_coffee_light",
"config": "_config_light",
"cson": "_json_light",
"css": "_css_light",
"css.map": "_css_light",
"sss": "_css_light",
"csv": "_csv_light",
@ -886,14 +875,11 @@
"elm": "_elm_light",
"ico": "_favicon_light",
"gitignore": "_github_light",
"gitconfig": "_github_light",
"gitkeep": "_github_light",
"gitattributes": "_github_light",
"go": "_go2_light",
"slide": "_go_light",
"article": "_go_light",
"gradle": "_gradle_light",
"groovy": "_grails_light",
"gsp": "_grails_light",
"hh": "_hacklang_light",
"haml": "_haml_light",
@ -902,57 +888,37 @@
"hjs": "_mustache_light",
"hs": "_haskell_light",
"lhs": "_haskell_light",
"html": "_html_light",
"jade": "_jade_light",
"java": "_java_light",
"class": "_java_light",
"classpath": "_java_light",
"js": "_javascript_light",
"js.map": "_javascript_light",
"es": "_javascript_light",
"es5": "_javascript_light",
"es6": "_javascript_light",
"es7": "_javascript_light",
"json": "_json_light",
"jl": "_julia_light",
"less": "_less_light",
"liquid": "_liquid_light",
"ls": "_livescript_light",
"lua": "_lua_light",
"markdown": "_markdown_light",
"md": "_markdown_light",
"mustache": "_mustache_light",
"stache": "_mustache_light",
"npm-debug.log": "_npm_light",
"npmignore": "_npm_light",
"h": "_c_light",
"m": "_c_light",
"ml": "_ocaml_light",
"mli": "_ocaml_light",
"cmx": "_ocaml_light",
"cmxa": "_ocaml_light",
"pl": "_perl_light",
"php": "_php_light",
"php.inc": "_php_light",
"pug": "_pug_light",
"pp": "_puppet_light",
"py": "_python_light",
"jsx": "_react_light",
"cjsx": "_react_light",
"tsx": "_react_light",
"rb": "_ruby_light",
"erb": "_ruby_light",
"erb.html": "_ruby_light",
"html.erb": "_ruby_light",
"rs": "_rust_light",
"sass": "_sass_light",
"scss": "_sass_light",
"slim": "_slim_light",
"smarty.tpl": "_smarty_light",
"sbt": "_sbt_light",
"scala": "_scala_light",
"styl": "_stylus_light",
"swift": "_swift_light",
"tf": "_terraform_light",
"tf.json": "_terraform_light",
"tex": "_tex_light",
@ -962,12 +928,9 @@
"ins": "_tex_light",
"txt": "_default_light",
"twig": "_twig_light",
"ts": "_typescript_light",
"vala": "_vala_light",
"vapi": "_vala_light",
"xml": "_xml_light",
"yml": "_yml_light",
"yaml": "_yml_light",
"ai": "_illustrator_light",
"psd": "_photoshop_light",
"pdf": "_pdf_light",
@ -981,11 +944,7 @@
"jpeg": "_image_light",
"svg": "_svg_light",
"svgx": "_image_light",
"cmd": "_shell_light",
"sh": "_shell_light",
"zsh": "_shell_light",
"fish": "_shell_light",
"zshrc": "_shell_light",
"mov": "_video_light",
"ogv": "_video_light",
"webm": "_video_light",
@ -1006,6 +965,39 @@
"tmp": "_clock_light",
"DS_Store": "_ignored_light"
},
"languageIds": {
"csharp": "_c-sharp_light",
"bat": "_shell_light",
"coffeescript": "_coffee_light",
"c": "_c_light",
"cpp": "_cpp_light",
"css": "_css_light",
"go": "_go2_light",
"groovy": "_grails_light",
"html": "_html_light",
"ini": "_github_light",
"jade": "_jade_light",
"java": "_java_light",
"javascriptreact": "_react_light",
"javascript": "_javascript_light",
"json": "_json_light",
"less": "_less_light",
"lua": "_lua_light",
"markdown": "_markdown_light",
"objective-c": "_c_light",
"perl": "_perl_light",
"php": "_php_light",
"python": "_python_light",
"ruby": "_ruby_light",
"rust": "_rust_light",
"scss": "_sass_light",
"shellscript": "_shell_light",
"swift": "_swift_light",
"typescript": "_typescript_light",
"typescriptreact": "_react_light",
"xml": "_config_light",
"yaml": "_yml_light"
},
"fileNames": {
"karma.conf.js": "_karma_light",
"karma.conf.coffee": "_karma_light",

View file

@ -232,6 +232,20 @@ suite('window namespace tests', () => {
return result;
});
test('showQuickPick, native promise - #11754', function () {
const data = new Promise<string[]>(resolve => {
resolve(['a', 'b', 'c']);
});
const source = new CancellationTokenSource();
const result = window.showQuickPick(data, undefined, source.token);
source.cancel();
return result.then(value => {
assert.equal(value, undefined);
});
});
test('editor, selection change kind', () => {
return workspace.openTextDocument(join(workspace.rootPath, './far.js')).then(doc => window.showTextDocument(doc)).then(editor => {

View file

@ -2,7 +2,7 @@
"name": "code-oss-dev",
"version": "1.6.0",
"electronVersion": "0.37.6",
"distro": "221e07c30a60acb4752cc6ba35e5ac4481d8b9d5",
"distro": "3d44b35db8d394d6d7b2bc224675735a0a8f2704",
"author": {
"name": "Microsoft Corporation"
},
@ -107,6 +107,7 @@
}
},
"optionalDependencies": {
"windows-mutex": "^0.2.0"
"windows-mutex": "^0.2.0",
"fsevents": "0.3.8"
}
}

View file

@ -122,7 +122,7 @@ try {
}
// Set userData path before app 'ready' event
var userData = args['user-data-dir'] || paths.getDefaultUserDataPath(process.platform);
var userData = path.resolve(args['user-data-dir'] || paths.getDefaultUserDataPath(process.platform));
app.setPath('userData', userData);
// Mac: when someone drops a file to the not-yet running VSCode, the open-file event fires even before

21
src/typings/thenable.d.ts vendored Normal file
View file

@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/**
* Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise,
* and others. This API makes no assumption about what promise libary is being used which
* enables reusing existing code without migrating to a specific promise implementation. Still,
* we recommend the use of native promises which are available in VS Code.
*/
interface Thenable<R> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
}

View file

@ -13,6 +13,7 @@ import {isObject} from 'vs/base/common/types';
import {isChrome, isWebKit} from 'vs/base/browser/browser';
import {IKeyboardEvent, StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {IMouseEvent, StandardMouseEvent} from 'vs/base/browser/mouseEvent';
import {CharCode} from 'vs/base/common/charCode';
export function clearNode(node: HTMLElement) {
while (node.firstChild) {
@ -55,7 +56,6 @@ export function isInDOM(node: Node): boolean {
return false;
}
const _blank = ' '.charCodeAt(0);
let lastStart: number, lastEnd: number;
function _findClassName(node: HTMLElement, className: string): void {
@ -95,14 +95,14 @@ function _findClassName(node: HTMLElement, className: string): void {
idxEnd = idx + classLen;
// a class that is followed by another class
if ((idx === 0 || classes.charCodeAt(idx - 1) === _blank) && classes.charCodeAt(idxEnd) === _blank) {
if ((idx === 0 || classes.charCodeAt(idx - 1) === CharCode.Space) && classes.charCodeAt(idxEnd) === CharCode.Space) {
lastStart = idx;
lastEnd = idxEnd + 1;
return;
}
// last class
if (idx > 0 && classes.charCodeAt(idx - 1) === _blank && idxEnd === classesLen) {
if (idx > 0 && classes.charCodeAt(idx - 1) === CharCode.Space && idxEnd === classesLen) {
lastStart = idx - 1;
lastEnd = idxEnd;
return;

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import _Event, { Emitter } from 'vs/base/common/event';
import _Event, { Emitter, mapEvent } from 'vs/base/common/event';
export type EventHandler = HTMLElement | HTMLDocument | Window;
@ -127,3 +127,11 @@ export const domEvent: IDomEvent = (element: EventHandler, type: string, useCapt
return emitter.event;
};
export function stop<T extends Event>(event: _Event<T>): _Event<T> {
return mapEvent(event, e => {
e.preventDefault();
e.stopPropagation();
return e;
});
}

View file

@ -214,7 +214,7 @@ class StringStream {
}
}
enum FormatType {
const enum FormatType {
Invalid,
Root,
Text,

View file

@ -5,7 +5,7 @@
'use strict';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
import {KeyCode, KeyCodeUtils, KeyMod} from 'vs/base/common/keyCodes';
import * as platform from 'vs/base/common/platform';
import * as browser from 'vs/base/browser/browser';
@ -161,7 +161,7 @@ let extractKeyCode = function extractKeyCode(e:KeyboardEvent): KeyCode {
if (e.charCode) {
// "keypress" events mostly
let char = String.fromCharCode(e.charCode).toUpperCase();
return KeyCode.fromString(char);
return KeyCodeUtils.fromString(char);
}
return lookupKeyCode(e);
};

View file

@ -18,7 +18,7 @@ import types = require('vs/base/common/types');
import {IEventEmitter, EventEmitter} from 'vs/base/common/eventEmitter';
import {Gesture, EventType} from 'vs/base/browser/touch';
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
export interface IActionItem extends IEventEmitter {
actionRunner: IActionRunner;
@ -388,13 +388,13 @@ export class ActionBar extends EventEmitter implements IActionRunner {
let event = new StandardKeyboardEvent(e);
let eventHandled = true;
if (event.equals(isVertical ? CommonKeybindings.UP_ARROW : CommonKeybindings.LEFT_ARROW)) {
if (event.equals(isVertical ? KeyCode.UpArrow : KeyCode.LeftArrow)) {
this.focusPrevious();
} else if (event.equals(isVertical ? CommonKeybindings.DOWN_ARROW : CommonKeybindings.RIGHT_ARROW)) {
} else if (event.equals(isVertical ? KeyCode.DownArrow : KeyCode.RightArrow)) {
this.focusNext();
} else if (event.equals(CommonKeybindings.ESCAPE)) {
} else if (event.equals(KeyCode.Escape)) {
this.cancel();
} else if (event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE)) {
} else if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
// Nothing, just staying out of the else branch
} else {
eventHandled = false;
@ -416,14 +416,14 @@ export class ActionBar extends EventEmitter implements IActionRunner {
let event = new StandardKeyboardEvent(e);
// Run action on Enter/Space
if (event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE)) {
if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
this.doTrigger(event);
event.preventDefault();
event.stopPropagation();
}
// Recompute focused item
else if (event.equals(CommonKeybindings.TAB) || event.equals(CommonKeybindings.SHIFT_TAB)) {
else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab)) {
this.updateFocusedItem();
}
});
@ -706,6 +706,10 @@ export class SelectActionItem extends BaseActionItem {
}
}
public set enabled(value: boolean) {
this.select.disabled = !value;
}
public blur(): void {
if (this.select) {
this.select.blur();

View file

@ -10,7 +10,7 @@ import {EventEmitter} from 'vs/base/common/eventEmitter';
import DOM = require('vs/base/browser/dom');
import {Builder, $} from 'vs/base/browser/builder';
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {KeyCode} from 'vs/base/common/keyCodes';
export class Button extends EventEmitter {
@ -38,10 +38,10 @@ export class Button extends EventEmitter {
this.$el.on(DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
let event = new StandardKeyboardEvent(e);
let eventHandled = false;
if (this.enabled && event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE)) {
if (this.enabled && event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
this.emit(DOM.EventType.CLICK, e);
eventHandled = true;
} else if (event.equals(CommonKeybindings.ESCAPE)) {
} else if (event.equals(KeyCode.Escape)) {
this.$el.domBlur();
eventHandled = true;
}

View file

@ -14,7 +14,7 @@ import {IContextViewProvider} from 'vs/base/browser/ui/contextview/contextview';
import {Widget} from 'vs/base/browser/ui/widget';
import Event, {Emitter} from 'vs/base/common/event';
import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {KeyCode} from 'vs/base/common/keyCodes';
export interface IFindInputOptions {
placeholder?:string;
@ -239,13 +239,13 @@ export class FindInput extends Widget {
// Arrow-Key support to navigate between options
let indexes = [this.caseSensitive.domNode, this.wholeWords.domNode, this.regex.domNode];
this.onkeydown(this.domNode, (event: IKeyboardEvent) => {
if (event.equals(CommonKeybindings.LEFT_ARROW) || event.equals(CommonKeybindings.RIGHT_ARROW) || event.equals(CommonKeybindings.ESCAPE)) {
if (event.equals(KeyCode.LeftArrow) || event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Escape)) {
let index = indexes.indexOf(<HTMLElement>document.activeElement);
if (index >= 0) {
let newIndex: number;
if (event.equals(CommonKeybindings.RIGHT_ARROW)) {
if (event.equals(KeyCode.RightArrow)) {
newIndex = (index + 1) % indexes.length;
} else if (event.equals(CommonKeybindings.LEFT_ARROW)) {
} else if (event.equals(KeyCode.LeftArrow)) {
if (index === 0) {
newIndex = indexes.length - 1;
} else {
@ -253,7 +253,7 @@ export class FindInput extends Widget {
}
}
if (event.equals(CommonKeybindings.ESCAPE)) {
if (event.equals(KeyCode.Escape)) {
indexes[index].blur();
} else if (newIndex >= 0) {
indexes[newIndex].focus();

View file

@ -10,7 +10,7 @@ import * as DOM from 'vs/base/browser/dom';
import { EventType as TouchEventType } from 'vs/base/browser/touch';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import Event, { Emitter, mapEvent, EventBufferer, filterEvent } from 'vs/base/common/event';
import Event, { Emitter, EventBufferer, chain, mapEvent } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IDelegate, IRenderer, IListMouseEvent, IFocusChangeEvent, ISelectionChangeEvent } from './list';
import { ListView, IListViewOptions } from './listView';
@ -134,13 +134,14 @@ class Controller<T> implements IDisposable {
this.disposables.push(view.addListener('click', e => this.onPointer(e)));
this.disposables.push(view.addListener(TouchEventType.Tap, e => this.onPointer(e)));
const onRawKeyDown = domEvent(view.domNode, 'keydown');
const onKeyDown = mapEvent(onRawKeyDown, e => new StandardKeyboardEvent(e));
filterEvent(onKeyDown, e => e.keyCode === KeyCode.Enter)(this.onEnter, this, this.disposables);
filterEvent(onKeyDown, e => e.keyCode === KeyCode.UpArrow)(this.onUpArrow, this, this.disposables);
filterEvent(onKeyDown, e => e.keyCode === KeyCode.DownArrow)(this.onDownArrow, this, this.disposables);
filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageUp)(this.onPageUpArrow, this, this.disposables);
filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageDown)(this.onPageDownArrow, this, this.disposables);
const onKeyDown = chain(domEvent(view.domNode, 'keydown'))
.map(e => new StandardKeyboardEvent(e));
onKeyDown.filter(e => e.keyCode === KeyCode.Enter).on(this.onEnter, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.UpArrow).on(this.onUpArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.DownArrow).on(this.onDownArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.PageUp).on(this.onPageUpArrow, this, this.disposables);
onKeyDown.filter(e => e.keyCode === KeyCode.PageDown).on(this.onPageDownArrow, this, this.disposables);
}
private onMouseDown(e: IListMouseEvent<T>) {

View file

@ -14,7 +14,7 @@ import dom = require('vs/base/browser/dom');
import numbers = require('vs/base/common/numbers');
import sash = require('vs/base/browser/ui/sash/sash');
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {KeyCode} from 'vs/base/common/keyCodes';
import Event, {Emitter} from 'vs/base/common/event';
export enum Orientation {
@ -113,7 +113,7 @@ export abstract class HeaderView extends View {
constructor(opts: IHeaderViewOptions) {
super(opts);
this.headerSize = types.isUndefined(opts.headerSize) ? 22 : opts.headerSize;
}
@ -214,16 +214,16 @@ export abstract class AbstractCollapsibleView extends HeaderView {
this.headerKeyListener = dom.addDisposableListener(this.header, dom.EventType.KEY_DOWN, (e) => {
let event = new StandardKeyboardEvent(e);
let eventHandled = false;
if (event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE) || (event.equals(CommonKeybindings.LEFT_ARROW) && this.state === CollapsibleState.EXPANDED) || (event.equals(CommonKeybindings.RIGHT_ARROW) && this.state === CollapsibleState.COLLAPSED)) {
if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space) || (event.equals(KeyCode.LeftArrow) && this.state === CollapsibleState.EXPANDED) || (event.equals(KeyCode.RightArrow) && this.state === CollapsibleState.COLLAPSED)) {
this.toggleExpansion();
eventHandled = true;
} else if (event.equals(CommonKeybindings.ESCAPE)) {
} else if (event.equals(KeyCode.Escape)) {
this.header.blur();
eventHandled = true;
} else if (event.equals(CommonKeybindings.UP_ARROW)) {
} else if (event.equals(KeyCode.UpArrow)) {
this.emit('focusPrevious');
eventHandled = true;
} else if (event.equals(CommonKeybindings.DOWN_ARROW)) {
} else if (event.equals(KeyCode.DownArrow)) {
this.emit('focusNext');
eventHandled = true;
}

View file

@ -27,7 +27,7 @@ export function asWinJsPromise<T>(callback: (token: CancellationToken) => T | TP
let source = new CancellationTokenSource();
return new TPromise<T>((resolve, reject, progress) => {
let item = callback(source.token);
if (TPromise.is(item)) {
if (item instanceof TPromise) {
item.then(resolve, reject, progress);
} else if (isThenable<T>(item)) {
item.then(resolve, reject);

View file

@ -0,0 +1,237 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
// Names from https://blog.codinghorror.com/ascii-pronunciation-rules-for-programmers/
/**
* An inlined enum containing useful character codes (to be used with String.charCodeAt).
* Please leave the const keyword such that it gets inlined when compiled to JavaScript!
*/
export const enum CharCode {
Null = 0,
/**
* The `\t` character.
*/
Tab = 9,
/**
* The `\n` character.
*/
LineFeed = 10,
/**
* The `\r` character.
*/
CarriageReturn = 13,
Space = 32,
/**
* The `!` character.
*/
ExclamationMark = 33,
/**
* The `"` character.
*/
DoubleQuote = 34,
/**
* The `#` character.
*/
Hash = 35,
/**
* The `$` character.
*/
DollarSign = 36,
/**
* The `%` character.
*/
PercentSign = 37,
/**
* The `&` character.
*/
Ampersand = 38,
/**
* The `'` character.
*/
SingleQuote = 39,
/**
* The `(` character.
*/
OpenParen = 40,
/**
* The `)` character.
*/
CloseParen = 41,
/**
* The `*` character.
*/
Asterisk = 42,
/**
* The `+` character.
*/
Plus = 43,
/**
* The `,` character.
*/
Comma = 44,
/**
* The `-` character.
*/
Dash = 45,
/**
* The `.` character.
*/
Period = 46,
/**
* The `/` character.
*/
Slash = 47,
Digit0 = 48,
Digit1 = 49,
Digit2 = 50,
Digit3 = 51,
Digit4 = 52,
Digit5 = 53,
Digit6 = 54,
Digit7 = 55,
Digit8 = 56,
Digit9 = 57,
/**
* The `:` character.
*/
Colon = 58,
/**
* The `;` character.
*/
Semicolon = 59,
/**
* The `<` character.
*/
LessThan = 60,
/**
* The `=` character.
*/
Equals = 61,
/**
* The `>` character.
*/
GreaterThan = 62,
/**
* The `?` character.
*/
QuestionMark = 63,
/**
* The `@` character.
*/
AtSign = 64,
A = 65,
B = 66,
C = 67,
D = 68,
E = 69,
F = 70,
G = 71,
H = 72,
I = 73,
J = 74,
K = 75,
L = 76,
M = 77,
N = 78,
O = 79,
P = 80,
Q = 81,
R = 82,
S = 83,
T = 84,
U = 85,
V = 86,
W = 87,
X = 88,
Y = 89,
Z = 90,
/**
* The `[` character.
*/
OpenSquareBracket = 91,
/**
* The `\` character.
*/
Backslash = 92,
/**
* The `]` character.
*/
CloseSquareBracket = 93,
/**
* The `^` character.
*/
Caret = 94,
/**
* The `_` character.
*/
Underline = 95,
/**
* The ``(`)`` character.
*/
BackTick = 96,
a = 97,
b = 98,
c = 99,
d = 100,
e = 101,
f = 102,
g = 103,
h = 104,
i = 105,
j = 106,
k = 107,
l = 108,
m = 109,
n = 110,
o = 111,
p = 112,
q = 113,
r = 114,
s = 115,
t = 116,
u = 117,
v = 118,
w = 119,
x = 120,
y = 121,
z = 122,
/**
* The `{` character.
*/
OpenCurlyBrace = 123,
/**
* The `|` character.
*/
Pipe = 124,
/**
* The `}` character.
*/
CloseCurlyBrace = 125,
/**
* The `~` character.
*/
Tilde = 126,
/**
* Unicode Character 'LINE SEPARATOR' (U+2028)
* http://www.fileformat.info/info/unicode/char/2028/index.htm
*/
LINE_SEPARATOR_2028 = 8232,
/**
* UTF-8 BOM
* Unicode Character 'ZERO WIDTH NO-BREAK SPACE' (U+FEFF)
* http://www.fileformat.info/info/unicode/char/feff/index.htm
*/
UTF8_BOM = 65279
}

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {IDisposable} from 'vs/base/common/lifecycle';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import CallbackList from 'vs/base/common/callbackList';
import {EventEmitter} from 'vs/base/common/eventEmitter';
import {TPromise} from 'vs/base/common/winjs.base';
@ -152,7 +152,25 @@ export function fromEventEmitter<T>(emitter: EventEmitter, eventType: string): E
};
}
export function fromPromise<T>(promise: TPromise<Event<T>>): Event<T> {
export function fromPromise(promise: TPromise<any>): Event<void> {
const emitter = new Emitter<void>();
let shouldEmit = false;
promise
.then(null, () => null)
.then(() => {
if (!shouldEmit) {
setTimeout(() => emitter.fire(), 0);
} else {
emitter.fire();
}
});
shouldEmit = true;
return emitter.event;
}
export function delayed<T>(promise: TPromise<Event<T>>): Event<T> {
let toCancel: TPromise<any> = null;
let listener: IDisposable = null;
@ -190,12 +208,19 @@ export function once<T>(event: Event<T>): Event<T> {
};
}
export function mapEvent<I,O>(event: Event<I>, map: (i:I)=>O): Event<O> {
return (listener, thisArgs = null, disposables?) => event(i => listener.call(thisArgs, map(i)), null, disposables);
}
export function any(...events: Event<any>[]): Event<void> {
let listeners = [];
export function filterEvent<T>(event: Event<T>, filter: (e:T)=>boolean): Event<T> {
return (listener, thisArgs = null, disposables?) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables);
const emitter = new Emitter<void>({
onFirstListenerAdd() {
listeners = events.map(e => e(() => emitter.fire(), null));
},
onLastListenerRemove() {
listeners = dispose(listeners);
}
});
return emitter.event;
}
export function debounceEvent<I, O>(event: Event<I>, merger: (last: O, event: I) => O, delay: number = 100): Event<O> {
@ -275,3 +300,46 @@ export class EventBufferer {
buffer.forEach(flush => flush());
}
}
export interface IChainableEvent<T> {
event: Event<T>;
map<O>(fn: (i: T) => O): IChainableEvent<O>;
filter(fn: (e: T) => boolean): IChainableEvent<T>;
on(listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable;
}
export function mapEvent<I,O>(event: Event<I>, map: (i:I)=>O): Event<O> {
return (listener, thisArgs = null, disposables?) => event(i => listener.call(thisArgs, map(i)), null, disposables);
}
export function filterEvent<T>(event: Event<T>, filter: (e:T)=>boolean): Event<T> {
return (listener, thisArgs = null, disposables?) => event(e => filter(e) && listener.call(thisArgs, e), null, disposables);
}
class ChainableEvent<T> implements IChainableEvent<T> {
get event(): Event<T> { return this._event; }
constructor(private _event: Event<T>) {}
map(fn) {
return new ChainableEvent(mapEvent(this._event, fn));
}
filter(fn) {
return new ChainableEvent(filterEvent(this._event, fn));
}
on(listener, thisArgs, disposables) {
return this._event(listener, thisArgs, disposables);
}
}
export function chain<T>(event: Event<T>): IChainableEvent<T> {
return new ChainableEvent(event);
}
export function stopwatch<T>(event: Event<T>): Event<number> {
const start = new Date().getTime();
return mapEvent(once(event), _ => new Date().getTime() - start);
}

View file

@ -6,6 +6,7 @@
import strings = require('vs/base/common/strings');
import {BoundedLinkedMap} from 'vs/base/common/map';
import {CharCode} from 'vs/base/common/charCode';
export interface IFilter {
// Returns null if word doesn't match.
@ -114,19 +115,24 @@ function _matchesSubString(word: string, wordToMatchAgainst: string, i: number,
// CamelCase
function isLower(code: number): boolean {
return 97 <= code && code <= 122;
return CharCode.a <= code && code <= CharCode.z;
}
function isUpper(code: number): boolean {
return 65 <= code && code <= 90;
return CharCode.A <= code && code <= CharCode.Z;
}
function isNumber(code: number): boolean {
return 48 <= code && code <= 57;
return CharCode.Digit0 <= code && code <= CharCode.Digit9;
}
function isWhitespace(code: number): boolean {
return [32, 9, 10, 13].indexOf(code) > -1;
return (
code === CharCode.Space
|| code === CharCode.Tab
|| code === CharCode.LineFeed
|| code === CharCode.CarriageReturn
);
}
function isAlphanumeric(code: number): boolean {

View file

@ -7,6 +7,7 @@
import strings = require('vs/base/common/strings');
import paths = require('vs/base/common/paths');
import {BoundedLinkedMap} from 'vs/base/common/map';
import {CharCode} from 'vs/base/common/charCode';
export interface IExpression {
[pattern: string]: boolean | SiblingClause | any;
@ -467,9 +468,6 @@ function parseExpressionPattern(pattern: string, value: any): (ParsedStringPatte
return parsedPattern;
}
const SLASH = '/'.charCodeAt(0);
const BACKSLASH = '\\'.charCodeAt(0);
function aggregateBasenameMatches(parsedPatterns: (ParsedStringPattern | ParsedExpressionPattern)[], result?: string): (ParsedStringPattern | ParsedExpressionPattern)[] {
const basenamePatterns = parsedPatterns.filter(parsedPattern => !!(<ParsedStringPattern>parsedPattern).basenames);
if (basenamePatterns.length < 2) {
@ -494,7 +492,7 @@ function aggregateBasenameMatches(parsedPatterns: (ParsedStringPattern | ParsedE
let i: number;
for (i = path.length; i > 0; i--) {
const ch = path.charCodeAt(i - 1);
if (ch === SLASH || ch === BACKSLASH) {
if (ch === CharCode.Slash || ch === CharCode.Backslash) {
break;
}
}

View file

@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ArraySet } from 'vs/base/common/set';
import { INavigator, ArrayNavigator } from 'vs/base/common/iterator';
export class HistoryNavigator<T> implements INavigator<T> {
private _history: ArraySet<T>;
private _limit: number;
private _navigator: ArrayNavigator<T>;
constructor(history: T[] = [], limit: number = 10) {
this._history = new ArraySet(history);
this._limit = limit;
this._onChange();
}
public add(t: T) {
this._history.set(t);
this._onChange();
}
public next(): T {
if (this._navigator.next()) {
return this._navigator.current();
}
this.last();
return null;
}
public previous(): T {
if (this._navigator.previous()) {
return this._navigator.current();
}
this.first();
return null;
}
public current(): T {
return this._navigator.current();
}
public parent(): T {
return null;
}
public first(): T {
return this._navigator.first();
}
public last(): T {
return this._navigator.last();
}
private _onChange() {
this._reduceToLimit();
this._navigator = new ArrayNavigator(this._history.elements);
this._navigator.last();
}
private _reduceToLimit() {
let data = this._history.elements;
if (data.length > this._limit) {
this._history = new ArraySet<T>(data.slice(data.length - this._limit));
}
}
}

View file

@ -12,9 +12,9 @@ export interface IIterator<T> {
export class ArrayIterator<T> implements IIterator<T> {
private items: T[];
private start: number;
private end: number;
private index: number;
protected start: number;
protected end: number;
protected index: number;
constructor(items: T[], start: number = 0, end: number = items.length) {
this.items = items;
@ -25,8 +25,11 @@ export class ArrayIterator<T> implements IIterator<T> {
public next(): T {
this.index = Math.min(this.index + 1, this.end);
return this.current();
}
if (this.index === this.end) {
protected current(): T {
if (this.index === this.start - 1 || this.index === this.end) {
return null;
}
@ -34,6 +37,37 @@ export class ArrayIterator<T> implements IIterator<T> {
}
}
export class ArrayNavigator<T> extends ArrayIterator<T> implements INavigator<T> {
constructor(items: T[], start: number = 0, end: number = items.length) {
super(items, start, end);
}
public current(): T {
return super.current();
}
public previous(): T {
this.index = Math.max(this.index - 1, this.start - 1);
return this.current();
}
public first(): T {
this.index = this.start;
return this.current();
}
public last(): T {
this.index = this.end - 1;
return this.current();
}
public parent(): T {
return null;
}
}
export class MappedIterator<T, R> implements IIterator<R> {
constructor(protected iterator: IIterator<T>, protected fn: (item:T)=>R) {

View file

@ -443,7 +443,7 @@ function isDigit(ch: number): boolean {
return ch >= CharacterCodes._0 && ch <= CharacterCodes._9;
}
enum CharacterCodes {
const enum CharacterCodes {
nullCharacter = 0,
maxAsciiCharacter = 0x7F,

View file

@ -19,181 +19,182 @@ export interface ISimplifiedPlatform {
* Inspired somewhat from https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
* But these are "more general", as they should work across browsers & OS`s.
*/
export enum KeyCode {
export const enum KeyCode {
/**
* Placed first to cover the 0 value of the enum.
*/
Unknown,
Unknown = 0,
Backspace,
Tab,
Enter,
Shift,
Ctrl,
Alt,
PauseBreak,
CapsLock,
Escape,
Space,
PageUp,
PageDown,
End,
Home,
LeftArrow,
UpArrow,
RightArrow,
DownArrow,
Insert,
Delete,
Backspace = 1,
Tab = 2,
Enter = 3,
Shift = 4,
Ctrl = 5,
Alt = 6,
PauseBreak = 7,
CapsLock = 8,
Escape = 9,
Space = 10,
PageUp = 11,
PageDown = 12,
End = 13,
Home = 14,
LeftArrow = 15,
UpArrow = 16,
RightArrow = 17,
DownArrow = 18,
Insert = 19,
Delete = 20,
KEY_0,
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_0 = 21,
KEY_1 = 22,
KEY_2 = 23,
KEY_3 = 24,
KEY_4 = 25,
KEY_5 = 26,
KEY_6 = 27,
KEY_7 = 28,
KEY_8 = 29,
KEY_9 = 30,
KEY_A,
KEY_B,
KEY_C,
KEY_D,
KEY_E,
KEY_F,
KEY_G,
KEY_H,
KEY_I,
KEY_J,
KEY_K,
KEY_L,
KEY_M,
KEY_N,
KEY_O,
KEY_P,
KEY_Q,
KEY_R,
KEY_S,
KEY_T,
KEY_U,
KEY_V,
KEY_W,
KEY_X,
KEY_Y,
KEY_Z,
KEY_A = 31,
KEY_B = 32,
KEY_C = 33,
KEY_D = 34,
KEY_E = 35,
KEY_F = 36,
KEY_G = 37,
KEY_H = 38,
KEY_I = 39,
KEY_J = 40,
KEY_K = 41,
KEY_L = 42,
KEY_M = 43,
KEY_N = 44,
KEY_O = 45,
KEY_P = 46,
KEY_Q = 47,
KEY_R = 48,
KEY_S = 49,
KEY_T = 50,
KEY_U = 51,
KEY_V = 52,
KEY_W = 53,
KEY_X = 54,
KEY_Y = 55,
KEY_Z = 56,
Meta,
ContextMenu,
Meta = 57,
ContextMenu = 58,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F1 = 59,
F2 = 60,
F3 = 61,
F4 = 62,
F5 = 63,
F6 = 64,
F7 = 65,
F8 = 66,
F9 = 67,
F10 = 68,
F11 = 69,
F12 = 70,
F13 = 71,
F14 = 72,
F15 = 73,
F16 = 74,
F17 = 75,
F18 = 76,
F19 = 77,
NumLock,
ScrollLock,
NumLock = 78,
ScrollLock = 79,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ';:' key
*/
US_SEMICOLON,
US_SEMICOLON = 80,
/**
* For any country/region, the '+' key
* For the US standard keyboard, the '=+' key
*/
US_EQUAL,
US_EQUAL = 81,
/**
* For any country/region, the ',' key
* For the US standard keyboard, the ',<' key
*/
US_COMMA,
US_COMMA = 82,
/**
* For any country/region, the '-' key
* For the US standard keyboard, the '-_' key
*/
US_MINUS,
US_MINUS = 83,
/**
* For any country/region, the '.' key
* For the US standard keyboard, the '.>' key
*/
US_DOT,
US_DOT = 84,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '/?' key
*/
US_SLASH,
US_SLASH = 85,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '`~' key
*/
US_BACKTICK,
US_BACKTICK = 86,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '[{' key
*/
US_OPEN_SQUARE_BRACKET,
US_OPEN_SQUARE_BRACKET = 87,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '\|' key
*/
US_BACKSLASH,
US_BACKSLASH = 88,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ']}' key
*/
US_CLOSE_SQUARE_BRACKET,
US_CLOSE_SQUARE_BRACKET = 89,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ''"' key
*/
US_QUOTE,
US_QUOTE = 90,
/**
* Used for miscellaneous characters; it can vary by keyboard.
*/
OEM_8,
OEM_8 = 91,
/**
* Either the angle bracket key or the backslash key on the RT 102-key keyboard.
*/
OEM_102,
OEM_102 = 92,
NUMPAD_0, // VK_NUMPAD0, 0x60, Numeric keypad 0 key
NUMPAD_1, // VK_NUMPAD1, 0x61, Numeric keypad 1 key
NUMPAD_2, // VK_NUMPAD2, 0x62, Numeric keypad 2 key
NUMPAD_3, // VK_NUMPAD3, 0x63, Numeric keypad 3 key
NUMPAD_4, // VK_NUMPAD4, 0x64, Numeric keypad 4 key
NUMPAD_5, // VK_NUMPAD5, 0x65, Numeric keypad 5 key
NUMPAD_6, // VK_NUMPAD6, 0x66, Numeric keypad 6 key
NUMPAD_7, // VK_NUMPAD7, 0x67, Numeric keypad 7 key
NUMPAD_8, // VK_NUMPAD8, 0x68, Numeric keypad 8 key
NUMPAD_9, // VK_NUMPAD9, 0x69, Numeric keypad 9 key
NUMPAD_0 = 93, // VK_NUMPAD0, 0x60, Numeric keypad 0 key
NUMPAD_1 = 94, // VK_NUMPAD1, 0x61, Numeric keypad 1 key
NUMPAD_2 = 95, // VK_NUMPAD2, 0x62, Numeric keypad 2 key
NUMPAD_3 = 96, // VK_NUMPAD3, 0x63, Numeric keypad 3 key
NUMPAD_4 = 97, // VK_NUMPAD4, 0x64, Numeric keypad 4 key
NUMPAD_5 = 98, // VK_NUMPAD5, 0x65, Numeric keypad 5 key
NUMPAD_6 = 99, // VK_NUMPAD6, 0x66, Numeric keypad 6 key
NUMPAD_7 = 100, // VK_NUMPAD7, 0x67, Numeric keypad 7 key
NUMPAD_8 = 101, // VK_NUMPAD8, 0x68, Numeric keypad 8 key
NUMPAD_9 = 102, // VK_NUMPAD9, 0x69, Numeric keypad 9 key
NUMPAD_MULTIPLY, // VK_MULTIPLY, 0x6A, Multiply key
NUMPAD_ADD, // VK_ADD, 0x6B, Add key
NUMPAD_SEPARATOR, // VK_SEPARATOR, 0x6C, Separator key
NUMPAD_SUBTRACT, // VK_SUBTRACT, 0x6D, Subtract key
NUMPAD_DECIMAL, // VK_DECIMAL, 0x6E, Decimal key
NUMPAD_DIVIDE, // VK_DIVIDE, 0x6F,
NUMPAD_MULTIPLY = 103, // VK_MULTIPLY, 0x6A, Multiply key
NUMPAD_ADD = 104, // VK_ADD, 0x6B, Add key
NUMPAD_SEPARATOR = 105, // VK_SEPARATOR, 0x6C, Separator key
NUMPAD_SUBTRACT = 106, // VK_SUBTRACT, 0x6D, Subtract key
NUMPAD_DECIMAL = 107, // VK_DECIMAL, 0x6E, Decimal key
NUMPAD_DIVIDE = 108, // VK_DIVIDE, 0x6F,
/**
* Placed last to cover the length of the enum.
* Please do not depend on this value!
*/
MAX_VALUE
}
@ -403,7 +404,7 @@ let USER_SETTINGS = createMapping((TO_USER_SETTINGS_MAP) => {
FROM_USER_SETTINGS_MAP['OEM_102'] = KeyCode.OEM_102;
});
export namespace KeyCode {
export namespace KeyCodeUtils {
export function toString(key:KeyCode): string {
return STRING.fromKeyCode(key);
}
@ -418,12 +419,24 @@ export namespace KeyCode {
// 13: 1 bit for alt
// 12: 1 bit for winCtrl
// 0: 12 bits for keyCode (up to a maximum keyCode of 4096. Given we have 83 at this point thats good enough)
const enum BinaryKeybindingsMask {
CtrlCmd = 1 << 15,
Shift = 1 << 14,
Alt = 1 << 13,
WinCtrl = 1 << 12,
KeyCode = 0x00000fff
}
const BIN_CTRLCMD_MASK = 1 << 15;
const BIN_SHIFT_MASK = 1 << 14;
const BIN_ALT_MASK = 1 << 13;
const BIN_WINCTRL_MASK = 1 << 12;
const BIN_KEYCODE_MASK = 0x00000fff;
export const enum KeyMod {
CtrlCmd = 1 << 15,
Shift = 1 << 14,
Alt = 1 << 13,
WinCtrl = 1 << 12,
}
export function KeyChord(firstPart:number, secondPart:number): number {
return firstPart | ((secondPart & 0x0000ffff) << 16);
}
export class BinaryKeybindings {
@ -440,85 +453,26 @@ export class BinaryKeybindings {
}
public static hasCtrlCmd(keybinding:number): boolean {
return (keybinding & BIN_CTRLCMD_MASK ? true : false);
return (keybinding & BinaryKeybindingsMask.CtrlCmd ? true : false);
}
public static hasShift(keybinding:number): boolean {
return (keybinding & BIN_SHIFT_MASK ? true : false);
return (keybinding & BinaryKeybindingsMask.Shift ? true : false);
}
public static hasAlt(keybinding:number): boolean {
return (keybinding & BIN_ALT_MASK ? true : false);
return (keybinding & BinaryKeybindingsMask.Alt ? true : false);
}
public static hasWinCtrl(keybinding:number): boolean {
return (keybinding & BIN_WINCTRL_MASK ? true : false);
return (keybinding & BinaryKeybindingsMask.WinCtrl ? true : false);
}
public static extractKeyCode(keybinding:number): KeyCode {
return (keybinding & BIN_KEYCODE_MASK);
return (keybinding & BinaryKeybindingsMask.KeyCode);
}
}
export class KeyMod {
public static CtrlCmd = BIN_CTRLCMD_MASK;
public static Shift = BIN_SHIFT_MASK;
public static Alt = BIN_ALT_MASK;
public static WinCtrl = BIN_WINCTRL_MASK;
public static chord(firstPart:number, secondPart:number): number {
return firstPart | ((secondPart & 0x0000ffff) << 16);
}
}
/**
* A set of usual keybindings that can be reused in code
*/
export class CommonKeybindings {
public static ENTER: number = KeyCode.Enter;
public static SHIFT_ENTER: number = KeyMod.Shift | KeyCode.Enter;
public static CTRLCMD_ENTER: number = KeyMod.CtrlCmd | KeyCode.Enter;
public static WINCTRL_ENTER: number = KeyMod.WinCtrl | KeyCode.Enter;
public static TAB: number = KeyCode.Tab;
public static SHIFT_TAB: number = KeyMod.Shift | KeyCode.Tab;
public static ESCAPE: number = KeyCode.Escape;
public static SPACE: number = KeyCode.Space;
public static DELETE: number = KeyCode.Delete;
public static SHIFT_DELETE: number = KeyMod.Shift | KeyCode.Delete;
public static CTRLCMD_BACKSPACE: number = KeyMod.CtrlCmd | KeyCode.Backspace;
public static UP_ARROW: number = KeyCode.UpArrow;
public static SHIFT_UP_ARROW: number = KeyMod.Shift | KeyCode.UpArrow;
public static CTRLCMD_UP_ARROW: number = KeyMod.CtrlCmd | KeyCode.UpArrow;
public static DOWN_ARROW: number = KeyCode.DownArrow;
public static SHIFT_DOWN_ARROW: number = KeyMod.Shift | KeyCode.DownArrow;
public static CTRLCMD_DOWN_ARROW: number = KeyMod.CtrlCmd | KeyCode.DownArrow;
public static LEFT_ARROW: number = KeyCode.LeftArrow;
public static RIGHT_ARROW: number = KeyCode.RightArrow;
public static HOME: number = KeyCode.Home;
public static END: number = KeyCode.End;
public static PAGE_UP: number = KeyCode.PageUp;
public static SHIFT_PAGE_UP: number = KeyMod.Shift | KeyCode.PageUp;
public static PAGE_DOWN: number = KeyCode.PageDown;
public static SHIFT_PAGE_DOWN: number = KeyMod.Shift | KeyCode.PageDown;
public static F2: number = KeyCode.F2;
public static CTRLCMD_S: number = KeyMod.CtrlCmd | KeyCode.KEY_S;
public static CTRLCMD_C: number = KeyMod.CtrlCmd | KeyCode.KEY_C;
public static CTRLCMD_V: number = KeyMod.CtrlCmd | KeyCode.KEY_V;
}
export class Keybinding {
/**
@ -681,7 +635,7 @@ export class Keybinding {
result |= KeyMod.WinCtrl;
}
result |= keyCode;
return KeyMod.chord(result, chord);
return KeyChord(result, chord);
}
public value:number;
@ -797,7 +751,7 @@ export class ElectronAcceleratorLabelProvider implements IKeyBindingLabelProvide
return 'Right';
}
return KeyCode.toString(keyCode);
return KeyCodeUtils.toString(keyCode);
}
}
@ -831,7 +785,7 @@ export class MacUIKeyLabelProvider implements IKeyBindingLabelProvider {
return MacUIKeyLabelProvider.downArrowUnicodeLabel;
}
return KeyCode.toString(keyCode);
return KeyCodeUtils.toString(keyCode);
}
}
@ -849,7 +803,7 @@ export class AriaKeyLabelProvider implements IKeyBindingLabelProvider {
public modifierSeparator = '+';
public getLabelForKey(keyCode:KeyCode): string {
return KeyCode.toString(keyCode);
return KeyCodeUtils.toString(keyCode);
}
}
@ -867,7 +821,7 @@ export class ClassicUIKeyLabelProvider implements IKeyBindingLabelProvider {
public modifierSeparator = '+';
public getLabelForKey(keyCode:KeyCode): string {
return KeyCode.toString(keyCode);
return KeyCodeUtils.toString(keyCode);
}
}

View file

@ -111,7 +111,7 @@ export class PagedModel<T> implements IPagedModel<T> {
page.promiseIndexes.unset(index);
if (page.promiseIndexes.elements.length === 0) {
if (page.promiseIndexes.size === 0) {
page.promise.cancel();
}
});

View file

@ -5,6 +5,7 @@
'use strict';
import {isLinux, isWindows} from 'vs/base/common/platform';
import {CharCode} from 'vs/base/common/charCode';
/**
* The forward slash path separator.
@ -113,7 +114,7 @@ export function normalize(path: string, toOSPath?: boolean): string {
for (let end = root.length; end <= len; end++) {
// either at the end or at a path-separator character
if (end === len || path.charCodeAt(end) === _slash || path.charCodeAt(end) === _backslash) {
if (end === len || path.charCodeAt(end) === CharCode.Slash || path.charCodeAt(end) === CharCode.Backslash) {
if (streql(path, start, end, '..')) {
// skip current and remove parent (if there is already something)
@ -160,28 +161,28 @@ export function getRoot(path: string, sep: string = '/'): string {
let len = path.length;
let code = path.charCodeAt(0);
if (code === _slash || code === _backslash) {
if (code === CharCode.Slash || code === CharCode.Backslash) {
code = path.charCodeAt(1);
if (code === _slash || code === _backslash) {
if (code === CharCode.Slash || code === CharCode.Backslash) {
// UNC candidate \\localhost\shares\ddd
// ^^^^^^^^^^^^^^^^^^^
code = path.charCodeAt(2);
if (code !== _slash && code !== _backslash) {
if (code !== CharCode.Slash && code !== CharCode.Backslash) {
let pos = 3;
let start = pos;
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === _slash || code === _backslash) {
if (code === CharCode.Slash || code === CharCode.Backslash) {
break;
}
}
code = path.charCodeAt(pos + 1);
if (start !== pos && code !== _slash && code !== _backslash) {
if (start !== pos && code !== CharCode.Slash && code !== CharCode.Backslash) {
pos += 1;
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === _slash || code === _backslash) {
if (code === CharCode.Slash || code === CharCode.Backslash) {
return path.slice(0, pos + 1) // consume this separator
.replace(/[\\/]/g, sep);
}
@ -194,12 +195,12 @@ export function getRoot(path: string, sep: string = '/'): string {
// ^
return sep;
} else if ((code >= _A && code <= _Z) || (code >= _a && code <= _z)) {
} else if ((code >= CharCode.A && code <= CharCode.Z) || (code >= CharCode.a && code <= CharCode.z)) {
// check for windows drive letter c:\ or c:
if (path.charCodeAt(1) === _colon) {
if (path.charCodeAt(1) === CharCode.Colon) {
code = path.charCodeAt(2);
if (code === _slash || code === _backslash) {
if (code === CharCode.Slash || code === CharCode.Backslash) {
// C:\fff
// ^^^
return path.slice(0, 2) + sep;
@ -219,7 +220,7 @@ export function getRoot(path: string, sep: string = '/'): string {
pos += 3; // 3 -> "://".length
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === _slash || code === _backslash) {
if (code === CharCode.Slash || code === CharCode.Backslash) {
return path.slice(0, pos + 1); // consume this separator
}
}
@ -240,9 +241,9 @@ export const join: (...parts: string[]) => string = function () {
// add the separater between two parts unless
// there already is one
let last = value.charCodeAt(value.length - 1);
if (last !== _slash && last !== _backslash) {
if (last !== CharCode.Slash && last !== CharCode.Backslash) {
let next = part.charCodeAt(0);
if (next !== _slash && next !== _backslash) {
if (next !== CharCode.Slash && next !== CharCode.Backslash) {
value += sep;
}
@ -274,18 +275,18 @@ export function isUNC(path: string): boolean {
}
let code = path.charCodeAt(0);
if (code !== _backslash) {
if (code !== CharCode.Backslash) {
return false;
}
code = path.charCodeAt(1);
if (code !== _backslash) {
if (code !== CharCode.Backslash) {
return false;
}
let pos = 2;
let start = pos;
for (; pos < path.length; pos++) {
code = path.charCodeAt(pos);
if (code === _backslash) {
if (code === CharCode.Backslash) {
break;
}
}
@ -293,7 +294,7 @@ export function isUNC(path: string): boolean {
return false;
}
code = path.charCodeAt(pos + 1);
if (isNaN(code) || code === _backslash) {
if (isNaN(code) || code === CharCode.Backslash) {
return false;
}
return true;
@ -307,15 +308,6 @@ export function makePosixAbsolute(path: string): string {
return isPosixAbsolute(normalize(path)) ? path : sep + path;
}
const _slash = '/'.charCodeAt(0);
const _backslash = '\\'.charCodeAt(0);
const _colon = ':'.charCodeAt(0);
const _a = 'a'.charCodeAt(0);
const _A = 'A'.charCodeAt(0);
const _z = 'z'.charCodeAt(0);
const _Z = 'Z'.charCodeAt(0);
export function isEqualOrParent(path: string, candidate: string): boolean {
if (path === candidate) {
@ -327,7 +319,7 @@ export function isEqualOrParent(path: string, candidate: string): boolean {
let candidateLen = candidate.length;
let lastCandidateChar = candidate.charCodeAt(candidateLen - 1);
if (lastCandidateChar === _slash) {
if (lastCandidateChar === CharCode.Slash) {
candidate = candidate.substring(0, candidateLen - 1);
candidateLen -= 1;
}
@ -351,7 +343,7 @@ export function isEqualOrParent(path: string, candidate: string): boolean {
}
let char = path.charCodeAt(candidateLen);
return char === _slash;
return char === CharCode.Slash;
}
// Reference: https://en.wikipedia.org/wiki/Filename

View file

@ -3,8 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export class ArraySet<T> {
private _elements: T[];
@ -13,6 +11,10 @@ export class ArraySet<T> {
this._elements = elements.slice();
}
get size(): number {
return this._elements.length;
}
set(element: T): void {
this.unset(element);
this._elements.push(element);
@ -31,6 +33,6 @@ export class ArraySet<T> {
}
get elements(): T[] {
return this._elements;
return this._elements.slice();
}
}

View file

@ -5,6 +5,7 @@
'use strict';
import {BoundedLinkedMap} from 'vs/base/common/map';
import {CharCode} from 'vs/base/common/charCode';
/**
* The empty string.
@ -261,7 +262,8 @@ export function normalizeNFC(str: string): string {
*/
export function firstNonWhitespaceIndex(str: string): number {
for (let i = 0, len = str.length; i < len; i++) {
if (str.charAt(i) !== ' ' && str.charAt(i) !== '\t') {
let chCode = str.charCodeAt(i);
if (chCode !== CharCode.Space && chCode !== CharCode.Tab) {
return i;
}
}
@ -274,7 +276,8 @@ export function firstNonWhitespaceIndex(str: string): number {
*/
export function getLeadingWhitespace(str: string): string {
for (let i = 0, len = str.length; i < len; i++) {
if (str.charAt(i) !== ' ' && str.charAt(i) !== '\t') {
let chCode = str.charCodeAt(i);
if (chCode !== CharCode.Space && chCode !== CharCode.Tab) {
return str.substring(0, i);
}
}
@ -287,7 +290,8 @@ export function getLeadingWhitespace(str: string): string {
*/
export function lastNonWhitespaceIndex(str: string, startIndex: number = str.length - 1): number {
for (let i = startIndex; i >= 0; i--) {
if (str.charAt(i) !== ' ' && str.charAt(i) !== '\t') {
let chCode = str.charCodeAt(i);
if (chCode !== CharCode.Space && chCode !== CharCode.Tab) {
return i;
}
}
@ -305,7 +309,7 @@ export function compare(a: string, b: string): number {
}
function isAsciiChar(code: number): boolean {
return (code >= 97 && code <= 122) || (code >= 65 && code <= 90);
return (code >= CharCode.a && code <= CharCode.z) || (code >= CharCode.A && code <= CharCode.Z);
}
export function equalsIgnoreCase(a: string, b: string): boolean {
@ -546,12 +550,10 @@ export function removeAnsiEscapeCodes(str: string): string {
// -- UTF-8 BOM
const __utf8_bom = 65279;
export const UTF8_BOM_CHARACTER = String.fromCharCode(__utf8_bom);
export const UTF8_BOM_CHARACTER = String.fromCharCode(CharCode.UTF8_BOM);
export function startsWithUTF8BOM(str: string): boolean {
return (str && str.length > 0 && str.charCodeAt(0) === __utf8_bom);
return (str && str.length > 0 && str.charCodeAt(0) === CharCode.UTF8_BOM);
}
/**

View file

@ -34,7 +34,7 @@ export declare class Promise {
// static timeout(delay:number):Promise;
static wrapError(error:any):Promise;
static is(value: any): boolean;
static is(value: any): value is Thenable<any>;
static addEventListener(type:string, fn:EventCallback):void;
public then(success?:ValueCallback, error?:ErrorCallback, progress?:ProgressCallback):Promise;
@ -79,12 +79,16 @@ export declare class TPromise<V> {
public cancel():void;
public static as<ValueType>(value:ValueType):TPromise<ValueType>;
public static is(value: any): value is TPromise<any>;
public static is(value: any): value is Thenable<any>;
public static timeout(delay:number):TPromise<void>;
public static join<ValueType>(promises:TPromise<ValueType>[]):TPromise<ValueType[]>;
public static join<ValueType>(promises:Thenable<ValueType>[]):Thenable<ValueType[]>;
public static join<ValueType>(promises: {[n:string]:TPromise<ValueType>}):TPromise<{[n:string]:ValueType}>;
public static any<ValueType>(promises:TPromise<ValueType>[]):TPromise<{ key:string; value:TPromise<ValueType>;}>;
public static wrap<ValueType>(value: Thenable<ValueType>): TPromise<ValueType>;
public static wrap<ValueType>(value: ValueType): TPromise<ValueType>;
public static wrapError<ValueType>(error:any):TPromise<ValueType>;
}

View file

@ -6,6 +6,7 @@
'use strict';
import sd = require('string_decoder');
import {CharCode} from 'vs/base/common/charCode';
/**
* Convenient way to iterate over output line by line. This helper accommodates for the fact that
@ -35,16 +36,16 @@ export class LineDecoder {
}
let start = 0;
let ch: number;
while (start < value.length && ((ch = value.charCodeAt(start)) === 13 || ch === 10)) {
while (start < value.length && ((ch = value.charCodeAt(start)) === CharCode.CarriageReturn || ch === CharCode.LineFeed)) {
start++;
}
let idx = start;
while (idx < value.length) {
ch = value.charCodeAt(idx);
if (ch === 13 || ch === 10) {
if (ch === CharCode.CarriageReturn || ch === CharCode.LineFeed) {
result.push(value.substring(start, idx));
idx++;
while (idx < value.length && ((ch = value.charCodeAt(idx)) === 13 || ch === 10)) {
while (idx < value.length && ((ch = value.charCodeAt(idx)) === CharCode.CarriageReturn || ch === CharCode.LineFeed)) {
idx++;
}
start = idx;

View file

@ -5,7 +5,7 @@
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import Event, { mapEvent, filterEvent } from 'vs/base/common/event';
import Event, { chain } from 'vs/base/common/event';
import { fromEventEmitter } from 'vs/base/node/event';
import { Server as IPCServer, Client as IPCClient, IServer, IClient, IChannel } from 'vs/base/parts/ipc/common/ipc';
@ -73,9 +73,10 @@ export class Server implements IServer, IDisposable {
}
private createScopedEvent(eventName: string, senderId: string) {
const onRawMessageEvent = fromEventEmitter<IIPCEvent>(this.ipc, eventName, (event, message) => ({ event, message }));
const onScopedRawMessageEvent = filterEvent<IIPCEvent>(onRawMessageEvent, ({ event }) => event.sender.getId() === senderId);
return mapEvent<IIPCEvent,string>(onScopedRawMessageEvent, ({ message }) => message);
return chain(fromEventEmitter<IIPCEvent>(this.ipc, eventName, (event, message) => ({ event, message })))
.filter(({ event }) => event.sender.getId() === senderId)
.map(({ message }) => message)
.event;
}
dispose(): void {

View file

@ -335,59 +335,55 @@ export class QuickOpenWidget implements IModelProvider {
private navigateInTree(keyCode: KeyCode, isShift?: boolean): void {
const model: IModel<any> = this.tree.getInput();
const entries = model ? model.entries : [];
let focus = this.tree.getFocus();
let cycled = false;
let revealToTop = false;
const oldFocus = this.tree.getFocus();
// Support cycle-through navigation
if (entries.length > 1) {
// Normal Navigation
switch (keyCode) {
case KeyCode.DownArrow:
this.tree.focusNext();
break;
case KeyCode.UpArrow:
this.tree.focusPrevious();
break;
case KeyCode.PageDown:
this.tree.focusNextPage();
break;
case KeyCode.PageUp:
this.tree.focusPreviousPage();
break;
case KeyCode.Tab:
if (isShift) {
this.tree.focusPrevious();
} else {
this.tree.focusNext();
}
break;
}
let newFocus = this.tree.getFocus();
// Support cycle-through navigation if focus did not change
if (entries.length > 1 && oldFocus === newFocus) {
// Up from no entry or first entry goes down to last
if ((keyCode === KeyCode.UpArrow || (keyCode === KeyCode.Tab && isShift)) && (focus === entries[0] || !focus)) { // TODO@Ben should not make ordering assumptions
if (keyCode === KeyCode.UpArrow || (keyCode === KeyCode.Tab && isShift)) {
this.tree.focusLast();
cycled = true;
}
// Down from last entry goes to up to first
else if ((keyCode === KeyCode.DownArrow || keyCode === KeyCode.Tab && !isShift) && focus === entries[entries.length - 1]) { // TODO@Ben should not make ordering assumptions
else if (keyCode === KeyCode.DownArrow || keyCode === KeyCode.Tab && !isShift) {
this.tree.focusFirst();
cycled = true;
}
}
// Normal Navigation
if (!cycled) {
switch (keyCode) {
case KeyCode.DownArrow:
this.tree.focusNext();
break;
case KeyCode.UpArrow:
this.tree.focusPrevious();
break;
case KeyCode.PageDown:
this.tree.focusNextPage();
break;
case KeyCode.PageUp:
this.tree.focusPreviousPage();
break;
case KeyCode.Tab:
if (isShift) {
this.tree.focusPrevious();
} else {
this.tree.focusNext();
}
break;
}
}
// Reveal
focus = this.tree.getFocus();
if (focus) {
revealToTop ? this.tree.reveal(focus, 0).done(null, errors.onUnexpectedError) : this.tree.reveal(focus).done(null, errors.onUnexpectedError);
newFocus = this.tree.getFocus();
if (newFocus) {
this.tree.reveal(newFocus).done(null, errors.onUnexpectedError);
}
}

View file

@ -43,12 +43,6 @@
height: 16px;
}
/* Bare Style */
.monaco-tree.bare .monaco-tree-row > .content.actions > .primary-action-bar {
color: inherit !important;
background-color: inherit !important;
}
/* Default theme */
.monaco-tree.focused .monaco-tree-row.focused:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #DCEBFC; }
.monaco-tree.focused .monaco-tree-row.selected:not(.highlighted) > .content.actions > .primary-action-bar { background-color: #4FA7FF; color: white; }

View file

@ -1,29 +1,31 @@
<?xml version='1.0' standalone='no' ?>
<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='10px' height='10px'>
<style>
circle {
animation: ball 0.6s linear infinite;
}
circle:nth-child(2) { animation-delay: 0.075s; }
circle:nth-child(3) { animation-delay: 0.15s; }
circle:nth-child(4) { animation-delay: 0.225s; }
circle:nth-child(5) { animation-delay: 0.3s; }
circle:nth-child(6) { animation-delay: 0.375s; }
circle:nth-child(7) { animation-delay: 0.45s; }
circle:nth-child(8) { animation-delay: 0.525s; }
@keyframes ball {
from { opacity: 1; }
to { opacity: 0.3; }
}
</style>
<g style="fill:grey;">
<circle cx='5' cy='1' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0s' />
</circle>
<circle cx='7.8284' cy='2.1716' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.075s' />
</circle>
<circle cx='9' cy='5' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.15s' />
</circle>
<circle cx='7.8284' cy='7.8284' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.225s' />
</circle>
<circle cx='5' cy='9' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.3s' />
</circle>
<circle cx='2.1716' cy='7.8284' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.375s' />
</circle>
<circle cx='1' cy='5' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.45s' />
</circle>
<circle cx='2.1716' cy='2.1716' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.525s' />
</circle>
<circle cx='5' cy='1' r='1' style='opacity:0.3;' />
<circle cx='7.8284' cy='2.1716' r='1' style='opacity:0.3;' />
<circle cx='9' cy='5' r='1' style='opacity:0.3;' />
<circle cx='7.8284' cy='7.8284' r='1' style='opacity:0.3;' />
<circle cx='5' cy='9' r='1' style='opacity:0.3;' />
<circle cx='2.1716' cy='7.8284' r='1' style='opacity:0.3;' />
<circle cx='1' cy='5' r='1' style='opacity:0.3;' />
<circle cx='2.1716' cy='2.1716' r='1' style='opacity:0.3;' />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,29 +1,31 @@
<?xml version='1.0' standalone='no' ?>
<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='10px' height='10px'>
<g style="fill:#fff;">
<circle cx='5' cy='1' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0s' />
</circle>
<circle cx='7.8284' cy='2.1716' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.075s' />
</circle>
<circle cx='9' cy='5' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.15s' />
</circle>
<circle cx='7.8284' cy='7.8284' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.225s' />
</circle>
<circle cx='5' cy='9' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.3s' />
</circle>
<circle cx='2.1716' cy='7.8284' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.375s' />
</circle>
<circle cx='1' cy='5' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.45s' />
</circle>
<circle cx='2.1716' cy='2.1716' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.525s' />
</circle>
<style>
circle {
animation: ball 0.6s linear infinite;
}
circle:nth-child(2) { animation-delay: 0.075s; }
circle:nth-child(3) { animation-delay: 0.15s; }
circle:nth-child(4) { animation-delay: 0.225s; }
circle:nth-child(5) { animation-delay: 0.3s; }
circle:nth-child(6) { animation-delay: 0.375s; }
circle:nth-child(7) { animation-delay: 0.45s; }
circle:nth-child(8) { animation-delay: 0.525s; }
@keyframes ball {
from { opacity: 1; }
to { opacity: 0.3; }
}
</style>
<g style="fill:white;">
<circle cx='5' cy='1' r='1' style='opacity:0.3;' />
<circle cx='7.8284' cy='2.1716' r='1' style='opacity:0.3;' />
<circle cx='9' cy='5' r='1' style='opacity:0.3;' />
<circle cx='7.8284' cy='7.8284' r='1' style='opacity:0.3;' />
<circle cx='5' cy='9' r='1' style='opacity:0.3;' />
<circle cx='2.1716' cy='7.8284' r='1' style='opacity:0.3;' />
<circle cx='1' cy='5' r='1' style='opacity:0.3;' />
<circle cx='2.1716' cy='2.1716' r='1' style='opacity:0.3;' />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,29 +1,31 @@
<?xml version='1.0' standalone='no' ?>
<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='10px' height='10px'>
<style>
circle {
animation: ball 0.6s linear infinite;
}
circle:nth-child(2) { animation-delay: 0.075s; }
circle:nth-child(3) { animation-delay: 0.15s; }
circle:nth-child(4) { animation-delay: 0.225s; }
circle:nth-child(5) { animation-delay: 0.3s; }
circle:nth-child(6) { animation-delay: 0.375s; }
circle:nth-child(7) { animation-delay: 0.45s; }
circle:nth-child(8) { animation-delay: 0.525s; }
@keyframes ball {
from { opacity: 1; }
to { opacity: 0.3; }
}
</style>
<g>
<circle cx='5' cy='1' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0s' />
</circle>
<circle cx='7.8284' cy='2.1716' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.075s' />
</circle>
<circle cx='9' cy='5' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.15s' />
</circle>
<circle cx='7.8284' cy='7.8284' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.225s' />
</circle>
<circle cx='5' cy='9' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.3s' />
</circle>
<circle cx='2.1716' cy='7.8284' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.375s' />
</circle>
<circle cx='1' cy='5' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.45s' />
</circle>
<circle cx='2.1716' cy='2.1716' r='1' style='opacity:0.3;'>
<animate attributeType='CSS' attributeName='opacity' from='1' to='0.3' dur='0.6s' repeatCount='indefinite' begin='0.525s' />
</circle>
<circle cx='5' cy='1' r='1' style='opacity:0.3;' />
<circle cx='7.8284' cy='2.1716' r='1' style='opacity:0.3;' />
<circle cx='9' cy='5' r='1' style='opacity:0.3;' />
<circle cx='7.8284' cy='7.8284' r='1' style='opacity:0.3;' />
<circle cx='5' cy='9' r='1' style='opacity:0.3;' />
<circle cx='2.1716' cy='7.8284' r='1' style='opacity:0.3;' />
<circle cx='1' cy='5' r='1' style='opacity:0.3;' />
<circle cx='2.1716' cy='2.1716' r='1' style='opacity:0.3;' />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -91,14 +91,6 @@
opacity: 0.3;
}
/* Bare row */
.monaco-tree.bare .monaco-tree-wrapper.drop-target,
.monaco-tree.bare .monaco-tree-row {
color: inherit !important;
background-color: inherit !important;
}
/* Default style */
.monaco-tree.focused .monaco-tree-rows > .monaco-tree-row.focused:not(.highlighted) { background-color: #DCEBFC; }

View file

@ -632,7 +632,6 @@ export interface ITreeOptions {
verticalScrollMode?: ScrollbarVisibility;
alwaysFocused?: boolean;
autoExpandSingleChildren?: boolean;
bare?:boolean;
useShadows?:boolean;
paddingOnRow?:boolean;
ariaLabel?:string;

View file

@ -14,7 +14,7 @@ import dom = require('vs/base/browser/dom');
import mouse = require('vs/base/browser/mouseEvent');
import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import _ = require('vs/base/parts/tree/browser/tree');
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
export interface ILegacyTemplateData {
root: HTMLElement;
@ -138,18 +138,18 @@ export class DefaultController implements _.IController {
this.options = options;
this.downKeyBindingDispatcher = new KeybindingDispatcher();
this.downKeyBindingDispatcher.set(CommonKeybindings.SPACE, (t, e) => this.onSpace(t, e));
this.downKeyBindingDispatcher.set(CommonKeybindings.UP_ARROW, (t, e) => this.onUp(t, e));
this.downKeyBindingDispatcher.set(CommonKeybindings.PAGE_UP, (t, e) => this.onPageUp(t, e));
this.downKeyBindingDispatcher.set(CommonKeybindings.DOWN_ARROW, (t, e) => this.onDown(t, e));
this.downKeyBindingDispatcher.set(CommonKeybindings.PAGE_DOWN, (t, e) => this.onPageDown(t, e));
this.downKeyBindingDispatcher.set(CommonKeybindings.LEFT_ARROW, (t, e) => this.onLeft(t, e));
this.downKeyBindingDispatcher.set(CommonKeybindings.RIGHT_ARROW, (t, e) => this.onRight(t, e));
this.downKeyBindingDispatcher.set(CommonKeybindings.ESCAPE, (t, e) => this.onEscape(t, e));
this.downKeyBindingDispatcher.set(KeyCode.Space, (t, e) => this.onSpace(t, e));
this.downKeyBindingDispatcher.set(KeyCode.UpArrow, (t, e) => this.onUp(t, e));
this.downKeyBindingDispatcher.set(KeyCode.PageUp, (t, e) => this.onPageUp(t, e));
this.downKeyBindingDispatcher.set(KeyCode.DownArrow, (t, e) => this.onDown(t, e));
this.downKeyBindingDispatcher.set(KeyCode.PageDown, (t, e) => this.onPageDown(t, e));
this.downKeyBindingDispatcher.set(KeyCode.LeftArrow, (t, e) => this.onLeft(t, e));
this.downKeyBindingDispatcher.set(KeyCode.RightArrow, (t, e) => this.onRight(t, e));
this.downKeyBindingDispatcher.set(KeyCode.Escape, (t, e) => this.onEscape(t, e));
this.upKeyBindingDispatcher = new KeybindingDispatcher();
this.upKeyBindingDispatcher.set(CommonKeybindings.ENTER, this.onEnter.bind(this));
this.upKeyBindingDispatcher.set(CommonKeybindings.CTRLCMD_ENTER, this.onEnter.bind(this));
this.upKeyBindingDispatcher.set(KeyCode.Enter, this.onEnter.bind(this));
this.upKeyBindingDispatcher.set(KeyMod.CtrlCmd | KeyCode.Enter, this.onEnter.bind(this));
}
public onMouseDown(tree:_.ITree, element: any, event:mouse.IMouseEvent, origin: string = 'mouse'):boolean {

View file

@ -66,7 +66,6 @@ export class Tree extends Events.EventEmitter implements _.ITree {
this.options.twistiePixels = typeof this.options.twistiePixels === 'number' ? this.options.twistiePixels : 32;
this.options.indentPixels = typeof this.options.indentPixels === 'number' ? this.options.indentPixels : 12;
this.options.alwaysFocused = this.options.alwaysFocused === true ? true : false;
this.options.bare = this.options.bare === true ? true : false;
this.options.useShadows = this.options.useShadows === false ? false : true;
this.options.paddingOnRow = this.options.paddingOnRow === false ? false : true;

View file

@ -477,10 +477,6 @@ export class TreeView extends HeightMap {
DOM.addClass(this.domNode, 'focused');
}
if (this.context.options.bare) {
DOM.addClass(this.domNode, 'bare');
}
if (!this.context.options.paddingOnRow) {
DOM.addClass(this.domNode, 'no-row-padding');
}

View file

@ -810,7 +810,7 @@ suite('Builder', () => {
b.showDelayed(20);
assert(b.hasClass('hidden'));
TPromise.timeout(30).then(function () {
TPromise.timeout(30).then(() => {
assert(!b.hasClass('hidden'));
done();
});
@ -825,7 +825,7 @@ suite('Builder', () => {
b.hide(); // Should cancel the visibility promise
TPromise.timeout(30).then(function () {
TPromise.timeout(30).then(() => {
assert(b.hasClass('hidden'));
done();
});

View file

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import {CharCode} from 'vs/base/common/charCode';
suite('CharCode', () => {
test('has good values', () => {
function assertValue(actual:CharCode, expected:string): void {
assert.equal(actual, expected.charCodeAt(0), 'char code ok for <<' + expected + '>>');
}
assertValue(CharCode.Tab, '\t');
assertValue(CharCode.LineFeed, '\n');
assertValue(CharCode.CarriageReturn, '\r');
assertValue(CharCode.Space, ' ');
assertValue(CharCode.ExclamationMark, '!');
assertValue(CharCode.DoubleQuote, '"');
assertValue(CharCode.Hash, '#');
assertValue(CharCode.DollarSign, '$');
assertValue(CharCode.PercentSign, '%');
assertValue(CharCode.Ampersand, '&');
assertValue(CharCode.SingleQuote, '\'');
assertValue(CharCode.OpenParen, '(');
assertValue(CharCode.CloseParen, ')');
assertValue(CharCode.Asterisk, '*');
assertValue(CharCode.Plus, '+');
assertValue(CharCode.Comma, ',');
assertValue(CharCode.Dash, '-');
assertValue(CharCode.Period, '.');
assertValue(CharCode.Slash, '/');
assertValue(CharCode.Digit0, '0');
assertValue(CharCode.Digit1, '1');
assertValue(CharCode.Digit2, '2');
assertValue(CharCode.Digit3, '3');
assertValue(CharCode.Digit4, '4');
assertValue(CharCode.Digit5, '5');
assertValue(CharCode.Digit6, '6');
assertValue(CharCode.Digit7, '7');
assertValue(CharCode.Digit8, '8');
assertValue(CharCode.Digit9, '9');
assertValue(CharCode.Colon, ':');
assertValue(CharCode.Semicolon, ';');
assertValue(CharCode.LessThan, '<');
assertValue(CharCode.Equals, '=');
assertValue(CharCode.GreaterThan, '>');
assertValue(CharCode.QuestionMark, '?');
assertValue(CharCode.AtSign, '@');
assertValue(CharCode.A, 'A');
assertValue(CharCode.B, 'B');
assertValue(CharCode.C, 'C');
assertValue(CharCode.D, 'D');
assertValue(CharCode.E, 'E');
assertValue(CharCode.F, 'F');
assertValue(CharCode.G, 'G');
assertValue(CharCode.H, 'H');
assertValue(CharCode.I, 'I');
assertValue(CharCode.J, 'J');
assertValue(CharCode.K, 'K');
assertValue(CharCode.L, 'L');
assertValue(CharCode.M, 'M');
assertValue(CharCode.N, 'N');
assertValue(CharCode.O, 'O');
assertValue(CharCode.P, 'P');
assertValue(CharCode.Q, 'Q');
assertValue(CharCode.R, 'R');
assertValue(CharCode.S, 'S');
assertValue(CharCode.T, 'T');
assertValue(CharCode.U, 'U');
assertValue(CharCode.V, 'V');
assertValue(CharCode.W, 'W');
assertValue(CharCode.X, 'X');
assertValue(CharCode.Y, 'Y');
assertValue(CharCode.Z, 'Z');
assertValue(CharCode.OpenSquareBracket, '[');
assertValue(CharCode.Backslash, '\\');
assertValue(CharCode.CloseSquareBracket, ']');
assertValue(CharCode.Caret, '^');
assertValue(CharCode.Underline, '_');
assertValue(CharCode.BackTick, '`');
assertValue(CharCode.a, 'a');
assertValue(CharCode.b, 'b');
assertValue(CharCode.c, 'c');
assertValue(CharCode.d, 'd');
assertValue(CharCode.e, 'e');
assertValue(CharCode.f, 'f');
assertValue(CharCode.g, 'g');
assertValue(CharCode.h, 'h');
assertValue(CharCode.i, 'i');
assertValue(CharCode.j, 'j');
assertValue(CharCode.k, 'k');
assertValue(CharCode.l, 'l');
assertValue(CharCode.m, 'm');
assertValue(CharCode.n, 'n');
assertValue(CharCode.o, 'o');
assertValue(CharCode.p, 'p');
assertValue(CharCode.q, 'q');
assertValue(CharCode.r, 'r');
assertValue(CharCode.s, 's');
assertValue(CharCode.t, 't');
assertValue(CharCode.u, 'u');
assertValue(CharCode.v, 'v');
assertValue(CharCode.w, 'w');
assertValue(CharCode.x, 'x');
assertValue(CharCode.y, 'y');
assertValue(CharCode.z, 'z');
assertValue(CharCode.OpenCurlyBrace, '{');
assertValue(CharCode.Pipe, '|');
assertValue(CharCode.CloseCurlyBrace, '}');
assertValue(CharCode.Tilde, '~');
});
});

View file

@ -5,10 +5,11 @@
'use strict';
import * as assert from 'assert';
import Event, {Emitter, fromEventEmitter, debounceEvent, EventBufferer, once} from 'vs/base/common/event';
import Event, {Emitter, fromEventEmitter, debounceEvent, EventBufferer, once, fromPromise, stopwatch} from 'vs/base/common/event';
import {IDisposable} from 'vs/base/common/lifecycle';
import {EventEmitter} from 'vs/base/common/eventEmitter';
import Errors = require('vs/base/common/errors');
import {TPromise} from 'vs/base/common/winjs.base';
namespace Samples {
@ -282,4 +283,72 @@ suite('EventBufferer', () => {
listener1.dispose();
listener2.dispose();
});
});
suite('fromPromise', () => {
test('should emit when done', () => {
let count = 0;
const event = fromPromise(TPromise.as(null));
event(() => count++);
assert.equal(count, 0);
return TPromise.timeout(10).then(() => {
assert.equal(count, 1);
});
});
test('should emit when done - setTimeout', () => {
let count = 0;
const event = fromPromise(TPromise.timeout(5));
event(() => count++);
assert.equal(count, 0);
return TPromise.timeout(10).then(() => {
assert.equal(count, 1);
});
});
test('should emit when done - setTimeout', () => {
let count = 0;
const event = fromPromise(TPromise.timeout(10));
event(() => count++);
assert.equal(count, 0);
return TPromise.timeout(0).then(() => {
assert.equal(count, 0);
return TPromise.timeout(10).then(() => {
assert.equal(count, 1);
});
});
});
});
suite('stopwatch', () => {
test('should emit', () => {
const emitter = new Emitter<void>();
const event = stopwatch(emitter.event);
return new TPromise((c, e) => {
event(duration => {
try {
assert(duration > 0);
} catch (err) {
e(err);
}
c(null);
});
setTimeout(() => emitter.fire(), 10);
});
});
});

View file

@ -0,0 +1,114 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import {HistoryNavigator} from 'vs/base/common/history';
suite('History Navigator', () => {
test('create reduces the input to limit', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
assert.deepEqual(['3', '4'], toArray(testObject));
});
test('create sets the position to last', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
assert.equal('4', testObject.current());
assert.equal(null, testObject.next());
assert.equal('3', testObject.previous());
});
test('last returns last element', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
assert.equal('4', testObject.last());
});
test('first returns first element', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
assert.equal('2', testObject.first());
});
test('next returns next element', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
assert.equal('3', testObject.next());
assert.equal('4', testObject.next());
assert.equal(null, testObject.next());
});
test('previous returns previous element', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
assert.equal('3', testObject.previous());
assert.equal('2', testObject.previous());
assert.equal(null, testObject.previous());
});
test('next on last element returs null and remains on last', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
testObject.last();
assert.equal('4', testObject.current());
assert.equal(null, testObject.next());
});
test('previous on first element returs null and remains on first', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
assert.equal('2', testObject.current());
assert.equal(null, testObject.previous());
});
test('add reduces the input to limit', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
testObject.add('5');
assert.deepEqual(['4', '5'], toArray(testObject));
});
test('adding existing element changes the position', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 2);
testObject.add('2');
assert.deepEqual(['4', '2'], toArray(testObject));
});
test('add resets the navigator to last', function () {
let testObject = new HistoryNavigator(['1', '2', '3', '4'], 3);
testObject.first();
testObject.add('5');
assert.equal('5', testObject.current());
assert.equal(null, testObject.next());
});
function toArray(historyNavigator: HistoryNavigator<string>): string[] {
let result = [];
historyNavigator.first();
if (historyNavigator.current()) {
do {
result.push(historyNavigator.current());
} while (historyNavigator.next());
}
return result;
}
});

View file

@ -5,7 +5,7 @@
'use strict';
import * as assert from 'assert';
import {KeyCode, KeyMod, BinaryKeybindings, Keybinding} from 'vs/base/common/keyCodes';
import {KeyCode, KeyMod, KeyChord, BinaryKeybindings} from 'vs/base/common/keyCodes';
interface ITestKeybinding {
ctrlCmd?: boolean;
@ -39,7 +39,7 @@ suite('keyCodes', () => {
test(null, 0);
test({ key: KeyCode.Enter }, KeyCode.Enter);
test({ key: KeyCode.Enter, chord: { key: KeyCode.Tab } }, KeyMod.chord(KeyCode.Enter, KeyCode.Tab));
test({ key: KeyCode.Enter, chord: { key: KeyCode.Tab } }, KeyChord(KeyCode.Enter, KeyCode.Tab));
test({ ctrlCmd: false, shift: false, alt: false, winCtrl: false, key: KeyCode.Enter }, KeyCode.Enter);
test({ ctrlCmd: false, shift: false, alt: false, winCtrl: true, key: KeyCode.Enter }, KeyMod.WinCtrl | KeyCode.Enter);
test({ ctrlCmd: false, shift: false, alt: true, winCtrl: false, key: KeyCode.Enter }, KeyMod.Alt | KeyCode.Enter);
@ -57,7 +57,7 @@ suite('keyCodes', () => {
test({ ctrlCmd: true, shift: true, alt: true, winCtrl: false, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test({ ctrlCmd: true, shift: true, alt: true, winCtrl: true, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
let encoded = KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z);
let encoded = KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z);
let encodedFirstPart = BinaryKeybindings.extractFirstPart(encoded);
let encodedSecondPart = BinaryKeybindings.extractChordPart(encoded);
@ -65,44 +65,4 @@ suite('keyCodes', () => {
assert.equal(encodedFirstPart, KeyMod.CtrlCmd | KeyCode.KEY_Y, 'first part');
assert.equal(encodedSecondPart, encodedSecondPart, 'chord part');
});
test('getUserSettingsKeybindingRegex', () => {
let regex = new RegExp(Keybinding.getUserSettingsKeybindingRegex());
function testIsGood(userSettingsLabel:string, message:string = userSettingsLabel): void {
let userSettings = '"' + userSettingsLabel.replace(/\\/g, '\\\\') + '"';
let isGood = regex.test(userSettings);
assert.ok(isGood, message);
}
// check that all key codes are covered by the regex
let ignore: boolean[] = [];
ignore[KeyCode.Shift] = true;
ignore[KeyCode.Ctrl] = true;
ignore[KeyCode.Alt] = true;
ignore[KeyCode.Meta] = true;
for (let keyCode = KeyCode.Unknown + 1; keyCode < KeyCode.MAX_VALUE; keyCode++) {
if (ignore[keyCode]) {
continue;
}
let userSettings = Keybinding.toUserSettingsLabel(keyCode);
testIsGood(userSettings, keyCode + ' - ' + KeyCode[keyCode] + ' - ' + userSettings);
}
// one modifier
testIsGood('ctrl+a');
testIsGood('shift+a');
testIsGood('alt+a');
testIsGood('cmd+a');
testIsGood('meta+a');
testIsGood('win+a');
// more modifiers
testIsGood('ctrl+shift+a');
testIsGood('shift+alt+a');
testIsGood('ctrl+shift+alt+a');
// chords
testIsGood('ctrl+a ctrl+a');
});
});

View file

@ -486,7 +486,6 @@ export class VSCodeMenu {
const toggleStatusbar = this.createMenuItem(nls.localize({ key: 'miToggleStatusbar', comment: ['&& denotes a mnemonic'] }, "&&Toggle Status Bar"), 'workbench.action.toggleStatusbarVisibility');
const toggleWordWrap = this.createMenuItem(nls.localize({ key: 'miToggleWordWrap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Word Wrap"), 'editor.action.toggleWordWrap');
const toggleRenderWhitespace = this.createMenuItem(nls.localize({ key: 'miToggleRenderWhitespace', comment: ['&& denotes a mnemonic'] }, "Toggle &&Render Whitespace"), 'editor.action.toggleRenderWhitespace');
const toggleRenderControlCharacters = this.createMenuItem(nls.localize({ key: 'miToggleRenderControlCharacters', comment: ['&& denotes a mnemonic'] }, "Toggle &&Control Characters"), 'editor.action.toggleRenderControlCharacter');
@ -518,7 +517,6 @@ export class VSCodeMenu {
toggleStatusbar,
__separator__(),
toggleWordWrap,
toggleRenderWhitespace,
toggleRenderControlCharacters,
__separator__(),
zoomIn,

View file

@ -166,7 +166,7 @@ export class VSCodeWindow {
height: this.windowState.height,
x: this.windowState.x,
y: this.windowState.y,
backgroundColor: usesLightTheme ? '#FFFFFF' : platform.isMacintosh ? '#131313' : '#1E1E1E', // https://github.com/electron/electron/issues/5150
backgroundColor: usesLightTheme ? '#FFFFFF' : platform.isMacintosh ? '#171717' : '#1E1E1E', // https://github.com/electron/electron/issues/5150
minWidth: VSCodeWindow.MIN_WIDTH,
minHeight: VSCodeWindow.MIN_HEIGHT,
show: !isFullscreenOrMaximized,
@ -430,7 +430,12 @@ export class VSCodeWindow {
public serializeWindowState(): IWindowState {
if (this.win.isFullScreen()) {
return {
mode: WindowMode.Fullscreen
mode: WindowMode.Fullscreen,
// still carry over window dimensions from previous sessions!
width: this.windowState.width,
height: this.windowState.height,
x: this.windowState.x,
y: this.windowState.y
};
}
@ -494,7 +499,7 @@ export class VSCodeWindow {
return state;
}
return null;
state.mode = WindowMode.Normal; // if we do not allow fullscreen, treat this state as normal window state
}
if ([state.x, state.y, state.width, state.height].some(n => typeof n !== 'number')) {

View file

@ -100,9 +100,11 @@ class Main {
const response = JSON.parse(err.responseText);
return TPromise.wrapError(response.message);
} catch (e) {
return TPromise.wrapError(err);
// noop
}
}
return TPromise.wrapError(err);
})
.then(result => {
const [extension] = result.firstPage;

View file

@ -383,12 +383,12 @@ class DecorationRenderHelper {
}
}
enum ThemeType {
const enum ThemeType {
Light = 0,
Dark = 1,
HighContrastBlack = 2
}
enum ModelDecorationCSSRuleType {
const enum ModelDecorationCSSRuleType {
ClassName = 0,
InlineClassName = 1,
GlyphMarginClassName = 2,

View file

@ -126,7 +126,7 @@ export class Colorizer {
tabSize,
0,
-1,
false,
'none',
false,
tokens
));
@ -171,7 +171,7 @@ function actualColorize(lines:string[], mode:IMode, tabSize:number): IActualColo
tabSize,
0,
-1,
false,
'none',
false,
tokenizeResult.tokens.map(t => new ViewLineToken(t.startIndex, t.type))
));

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {EventEmitter} from 'vs/base/common/eventEmitter';
import {Schemas} from 'vs/base/common/network';
import Severity from 'vs/base/common/severity';
import {TPromise} from 'vs/base/common/winjs.base';
@ -56,13 +55,18 @@ export class SimpleEditor implements IEditor {
}
}
export class SimpleModel extends EventEmitter implements ITextEditorModel {
export class SimpleModel implements ITextEditorModel {
private model:editorCommon.IModel;
private _onDispose: Emitter<void>;
constructor(model:editorCommon.IModel) {
super();
this.model = model;
this._onDispose = new Emitter<void>();
}
public get onDispose(): Event<void> {
return this._onDispose.event;
}
public load(): TPromise<SimpleModel> {
@ -72,6 +76,10 @@ export class SimpleModel extends EventEmitter implements ITextEditorModel {
public get textEditorModel():editorCommon.IModel {
return this.model;
}
public dispose(): void {
this._onDispose.fire();
}
}
export interface IOpenEditorDelegate {

View file

@ -243,7 +243,7 @@ export function colorizeModelLine(model:IModel, lineNumber:number, tabSize:numbe
export function createMonacoEditorAPI(): typeof monaco.editor {
return {
// methods
create: create,
create: <any>create,
createDiffEditor: createDiffEditor,
createDiffNavigator: createDiffNavigator,

View file

@ -19,7 +19,7 @@ import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
export class ViewLine implements IVisibleLineData {
protected _context:ViewContext;
private _renderWhitespace: boolean;
private _renderWhitespace: 'none' | 'boundary' | 'all';
private _renderControlCharacters: boolean;
private _spaceWidth: number;
private _lineHeight: number;

View file

@ -13,7 +13,7 @@ import {HorizontalRange, LineVisibleRanges} from 'vs/editor/common/view/renderin
import {IRenderingContext} from 'vs/editor/common/view/renderingContext';
import {Range} from 'vs/editor/common/core/range';
enum CornerStyle {
const enum CornerStyle {
EXTERN,
INTERN,
FLAT

View file

@ -10,6 +10,7 @@ import {Range} from 'vs/editor/common/core/range';
import {Selection} from 'vs/editor/common/core/selection';
import {ICommand, ICursorStateComputerData, IEditOperationBuilder, ITokenizedModel} from 'vs/editor/common/editorCommon';
import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {CharCode} from 'vs/base/common/charCode';
export interface IShiftCommandOpts {
isUnshift: boolean;
@ -53,7 +54,6 @@ export class ShiftCommand implements ICommand {
public getEditOperations(model: ITokenizedModel, builder: IEditOperationBuilder): void {
let startLine = this._selection.startLineNumber;
let endLine = this._selection.endLineNumber;
let _SPACE = ' '.charCodeAt(0);
if (this._selection.endColumn === 1 && startLine !== endLine) {
endLine = endLine - 1;
@ -106,7 +106,7 @@ export class ShiftCommand implements ICommand {
extraSpaces = previousLineExtraSpaces;
if (enterAction.appendText) {
for (let j = 0, lenJ = enterAction.appendText.length; j < lenJ && extraSpaces < tabSize; j++) {
if (enterAction.appendText.charCodeAt(j) === _SPACE) {
if (enterAction.appendText.charCodeAt(j) === CharCode.Space) {
extraSpaces++;
} else {
break;
@ -119,7 +119,7 @@ export class ShiftCommand implements ICommand {
// Act as if `prefixSpaces` is not part of the indentation
for (let j = 0; j < extraSpaces; j++) {
if (indentationEndIndex === 0 || lineText.charCodeAt(indentationEndIndex - 1) !== _SPACE) {
if (indentationEndIndex === 0 || lineText.charCodeAt(indentationEndIndex - 1) !== CharCode.Space) {
break;
}
indentationEndIndex--;

View file

@ -251,7 +251,7 @@ class InternalEditorOptionsHelper {
scrollBeyondLastLine: toBoolean(opts.scrollBeyondLastLine),
editorClassName: editorClassName,
stopRenderingLineAfter: stopRenderingLineAfter,
renderWhitespace: toBoolean(opts.renderWhitespace),
renderWhitespace: opts.renderWhitespace,
renderControlCharacters: toBoolean(opts.renderControlCharacters),
renderIndentGuides: toBoolean(opts.renderIndentGuides),
renderLineHighlight: toBoolean(opts.renderLineHighlight),
@ -478,6 +478,9 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed
let fontSize = toFloat(opts.fontSize, DefaultConfig.editor.fontSize);
fontSize = Math.max(0, fontSize);
fontSize = Math.min(100, fontSize);
if (fontSize === 0) {
fontSize = DefaultConfig.editor.fontSize;
}
let lineHeight = toInteger(opts.lineHeight, 0, 150);
if (lineHeight === 0) {
@ -769,9 +772,10 @@ let editorConfiguration:IConfigurationNode = {
'description': nls.localize('hideCursorInOverviewRuler', "Controls if the cursor should be hidden in the overview ruler.")
},
'editor.renderWhitespace': {
'type': 'boolean',
'type': 'string',
'enum': ['none', 'boundary', 'all'],
default: DefaultConfig.editor.renderWhitespace,
description: nls.localize('renderWhitespace', "Controls whether the editor should render whitespace characters")
description: nls.localize('renderWhitespace', "Controls how the editor should render whitespace characters, posibilties are 'none', 'boundary', and 'all'. The 'boundary' option does not render single spaces between words.")
},
'editor.renderControlCharacters': {
'type': 'boolean',

View file

@ -91,7 +91,7 @@ class ConfigClass implements IConfiguration {
codeLens: true,
referenceInfos: true,
folding: true,
renderWhitespace: false,
renderWhitespace: 'none',
renderControlCharacters: false,
renderIndentGuides: false,
renderLineHighlight: true,

View file

@ -22,7 +22,7 @@ export interface ITypingListener {
(): void;
}
enum RevealTarget {
const enum RevealTarget {
Primary = 0,
TopMost = 1,
BottomMost = 2

View file

@ -50,13 +50,13 @@ export interface IConfiguration {
getIndentationOptions(): IInternalIndentationOptions;
}
function isHighSurrogate(model, lineNumber, column) {
var code = model.getLineContent(lineNumber).charCodeAt(column - 1);
function isHighSurrogate(model:ICursorMoveHelperModel, lineNumber:number, column:number) {
let code = model.getLineContent(lineNumber).charCodeAt(column - 1);
return 0xD800 <= code && code <= 0xDBFF;
}
function isLowSurrogate(model, lineNumber, column) {
var code = model.getLineContent(lineNumber).charCodeAt(column - 1);
function isLowSurrogate(model:ICursorMoveHelperModel, lineNumber:number, column:number) {
let code = model.getLineContent(lineNumber).charCodeAt(column - 1);
return 0xDC00 <= code && code <= 0xDFFF;
}

View file

@ -16,6 +16,8 @@ import {Selection, SelectionDirection} from 'vs/editor/common/core/selection';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {IElectricAction, IndentAction} from 'vs/editor/common/modes';
import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {CharCode} from 'vs/base/common/charCode';
import {CharacterClassifier} from 'vs/editor/common/core/characterClassifier';
export interface IPostOperationRunnable {
(ctx: IOneCursorOperationContext): void;
@ -99,31 +101,23 @@ export interface IFindWordResult {
wordType: WordType;
}
export enum WordType {
export const enum WordType {
None = 0,
Regular = 1,
Separator = 2
};
enum CharacterClass {
const enum CharacterClass {
Regular = 0,
Whitespace = 1,
WordSeparator = 2
};
export enum WordNavigationType {
export const enum WordNavigationType {
WordStart = 0,
WordEnd = 1
}
const CH_REGULAR = CharacterClass.Regular;
const CH_WHITESPACE = CharacterClass.Whitespace;
const CH_WORD_SEPARATOR = CharacterClass.WordSeparator;
const W_NONE = WordType.None;
const W_REGULAR = WordType.Regular;
const W_SEPARATOR = WordType.Separator;
export class OneCursor {
// --- contextual state
@ -1528,8 +1522,6 @@ export class OneCursorOp {
}
let selectionContainsOnlyWhitespace = true;
let _tab = '\t'.charCodeAt(0);
let _space = ' '.charCodeAt(0);
for (let lineNumber = selection.startLineNumber; lineNumber <= selection.endLineNumber; lineNumber++) {
let lineText = cursor.model.getLineContent(lineNumber);
@ -1537,7 +1529,7 @@ export class OneCursorOp {
let endIndex = (lineNumber === selection.endLineNumber ? selection.endColumn - 1 : lineText.length);
for (let charIndex = startIndex; charIndex < endIndex; charIndex++) {
let charCode = lineText.charCodeAt(charIndex);
if (charCode !== _tab && charCode !== _space) {
if (charCode !== CharCode.Tab && charCode !== CharCode.Space) {
selectionContainsOnlyWhitespace = false;
// Break outer loop
@ -2261,7 +2253,7 @@ class CursorHelper {
return this.moveHelper.columnFromVisibleColumn(model, lineNumber, column);
}
private _createWord(lineContent: string, wordType:WordType, start: number, end: number): IFindWordResult {
private static _createWord(lineContent: string, wordType:WordType, start: number, end: number): IFindWordResult {
// console.log('WORD ==> ' + start + ' => ' + end + ':::: <<<' + lineContent.substring(start, end) + '>>>');
return { start: start, end: end, wordType: wordType };
}
@ -2270,48 +2262,52 @@ class CursorHelper {
let position = this.model.validatePosition(_position);
let wordSeparators = getMapForWordSeparators(this.configuration.editor.wordSeparators);
let lineContent = this.model.getLineContent(position.lineNumber);
let wordType = W_NONE;
return CursorHelper._findPreviousWordOnLine(lineContent, wordSeparators, position);
}
private static _findPreviousWordOnLine(lineContent:string, wordSeparators:WordCharacterClassifier, position:Position): IFindWordResult {
let wordType = WordType.None;
for (let chIndex = position.column - 2; chIndex >= 0; chIndex--) {
let chCode = lineContent.charCodeAt(chIndex);
let chClass:CharacterClass = (wordSeparators[chCode] || CharacterClass.Regular);
let chClass = wordSeparators.get(chCode);
if (chClass === CH_REGULAR) {
if (wordType === W_SEPARATOR) {
return this._createWord(lineContent, wordType, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
if (chClass === CharacterClass.Regular) {
if (wordType === WordType.Separator) {
return CursorHelper._createWord(lineContent, wordType, chIndex + 1, CursorHelper._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
}
wordType = W_REGULAR;
} else if (chClass === CH_WORD_SEPARATOR) {
if (wordType === W_REGULAR) {
return this._createWord(lineContent, wordType, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
wordType = WordType.Regular;
} else if (chClass === CharacterClass.WordSeparator) {
if (wordType === WordType.Regular) {
return CursorHelper._createWord(lineContent, wordType, chIndex + 1, CursorHelper._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
}
wordType = W_SEPARATOR;
} else if (chClass === CH_WHITESPACE) {
if (wordType !== W_NONE) {
return this._createWord(lineContent, wordType, chIndex + 1, this._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
wordType = WordType.Separator;
} else if (chClass === CharacterClass.Whitespace) {
if (wordType !== WordType.None) {
return CursorHelper._createWord(lineContent, wordType, chIndex + 1, CursorHelper._findEndOfWord(lineContent, wordSeparators, wordType, chIndex + 1));
}
}
}
if (wordType !== W_NONE) {
return this._createWord(lineContent, wordType, 0, this._findEndOfWord(lineContent, wordSeparators, wordType, 0));
if (wordType !== WordType.None) {
return CursorHelper._createWord(lineContent, wordType, 0, CursorHelper._findEndOfWord(lineContent, wordSeparators, wordType, 0));
}
return null;
}
private _findEndOfWord(lineContent:string, wordSeparators:CharacterClass[], wordType:WordType, startIndex:number): number {
private static _findEndOfWord(lineContent:string, wordSeparators:WordCharacterClassifier, wordType:WordType, startIndex:number): number {
let len = lineContent.length;
for (let chIndex = startIndex; chIndex < len; chIndex++) {
let chCode = lineContent.charCodeAt(chIndex);
let chClass:CharacterClass = (wordSeparators[chCode] || CharacterClass.Regular);
let chClass = wordSeparators.get(chCode);
if (chClass === CH_WHITESPACE) {
if (chClass === CharacterClass.Whitespace) {
return chIndex;
}
if (wordType === W_REGULAR && chClass === CH_WORD_SEPARATOR) {
if (wordType === WordType.Regular && chClass === CharacterClass.WordSeparator) {
return chIndex;
}
if (wordType === W_SEPARATOR && chClass === CH_REGULAR) {
if (wordType === WordType.Separator && chClass === CharacterClass.Regular) {
return chIndex;
}
}
@ -2322,49 +2318,53 @@ class CursorHelper {
let position = this.model.validatePosition(_position);
let wordSeparators = getMapForWordSeparators(this.configuration.editor.wordSeparators);
let lineContent = this.model.getLineContent(position.lineNumber);
let wordType = W_NONE;
return CursorHelper._findNextWordOnLine(lineContent, wordSeparators, position);
}
private static _findNextWordOnLine(lineContent:string, wordSeparators:WordCharacterClassifier, position:Position): IFindWordResult {
let wordType = WordType.None;
let len = lineContent.length;
for (let chIndex = position.column - 1; chIndex < len; chIndex++) {
let chCode = lineContent.charCodeAt(chIndex);
let chClass:CharacterClass = (wordSeparators[chCode] || CharacterClass.Regular);
let chClass = wordSeparators.get(chCode);
if (chClass === CH_REGULAR) {
if (wordType === W_SEPARATOR) {
return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
if (chClass === CharacterClass.Regular) {
if (wordType === WordType.Separator) {
return CursorHelper._createWord(lineContent, wordType, CursorHelper._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
}
wordType = W_REGULAR;
} else if (chClass === CH_WORD_SEPARATOR) {
if (wordType === W_REGULAR) {
return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
wordType = WordType.Regular;
} else if (chClass === CharacterClass.WordSeparator) {
if (wordType === WordType.Regular) {
return CursorHelper._createWord(lineContent, wordType, CursorHelper._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
}
wordType = W_SEPARATOR;
} else if (chClass === CH_WHITESPACE) {
if (wordType !== W_NONE) {
return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
wordType = WordType.Separator;
} else if (chClass === CharacterClass.Whitespace) {
if (wordType !== WordType.None) {
return CursorHelper._createWord(lineContent, wordType, CursorHelper._findStartOfWord(lineContent, wordSeparators, wordType, chIndex - 1), chIndex);
}
}
}
if (wordType !== W_NONE) {
return this._createWord(lineContent, wordType, this._findStartOfWord(lineContent, wordSeparators, wordType, len - 1), len);
if (wordType !== WordType.None) {
return CursorHelper._createWord(lineContent, wordType, CursorHelper._findStartOfWord(lineContent, wordSeparators, wordType, len - 1), len);
}
return null;
}
private _findStartOfWord(lineContent:string, wordSeparators:CharacterClass[], wordType:WordType, startIndex:number): number {
private static _findStartOfWord(lineContent:string, wordSeparators:WordCharacterClassifier, wordType:WordType, startIndex:number): number {
for (let chIndex = startIndex; chIndex >= 0; chIndex--) {
let chCode = lineContent.charCodeAt(chIndex);
let chClass:CharacterClass = (wordSeparators[chCode] || CharacterClass.Regular);
let chClass = wordSeparators.get(chCode);
if (chClass === CH_WHITESPACE) {
if (chClass === CharacterClass.Whitespace) {
return chIndex + 1;
}
if (wordType === W_REGULAR && chClass === CH_WORD_SEPARATOR) {
if (wordType === WordType.Regular && chClass === CharacterClass.WordSeparator) {
return chIndex + 1;
}
if (wordType === W_SEPARATOR && chClass === CH_REGULAR) {
if (wordType === WordType.Separator && chClass === CharacterClass.Regular) {
return chIndex + 1;
}
}
@ -2372,37 +2372,33 @@ class CursorHelper {
}
}
function once<T, R>(keyFn:(input:T)=>string, computeFn:(input:T)=>R):(input:T)=>R {
let cache: {[key:string]:R;} = {};
return (input:T):R => {
let key = keyFn(input);
if (!cache.hasOwnProperty(key)) {
cache[key] = computeFn(input);
class WordCharacterClassifier extends CharacterClassifier<CharacterClass> {
constructor(wordSeparators:string) {
super(CharacterClass.Regular);
for (let i = 0, len = wordSeparators.length; i < len; i++) {
this.set(wordSeparators.charCodeAt(i), CharacterClass.WordSeparator);
}
return cache[key];
this.set(CharCode.Space, CharacterClass.Whitespace);
this.set(CharCode.Tab, CharacterClass.Whitespace);
}
}
function once<R>(computeFn:(input:string)=>R):(input:string)=>R {
let cache: {[key:string]:R;} = {}; // TODO@Alex unbounded cache
return (input:string):R => {
if (!cache.hasOwnProperty(input)) {
cache[input] = computeFn(input);
}
return cache[input];
};
}
let getMapForWordSeparators = once<string,CharacterClass[]>(
(input) => input,
(input) => {
let r:CharacterClass[] = [];
// Make array fast for ASCII text
for (let chCode = 0; chCode < 256; chCode++) {
r[chCode] = CharacterClass.Regular;
}
for (let i = 0, len = input.length; i < len; i++) {
r[input.charCodeAt(i)] = CharacterClass.WordSeparator;
}
r[' '.charCodeAt(0)] = CharacterClass.Whitespace;
r['\t'.charCodeAt(0)] = CharacterClass.Whitespace;
return r;
}
let getMapForWordSeparators = once<WordCharacterClassifier>(
(input) => new WordCharacterClassifier(input)
);
class Utils {

View file

@ -6,13 +6,13 @@
import {RunOnceScheduler} from 'vs/base/common/async';
import Event, {Emitter} from 'vs/base/common/event';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {KeyCode} from 'vs/base/common/keyCodes';
import {Disposable} from 'vs/base/common/lifecycle';
import {IClipboardEvent, ICompositionEvent, IKeyboardEventWrapper, ISimpleModel, ITextAreaWrapper, ITypeData, TextAreaState, TextAreaStrategy, createTextAreaState} from 'vs/editor/common/controller/textAreaState';
import {Range} from 'vs/editor/common/core/range';
import {EndOfLinePreference} from 'vs/editor/common/editorCommon';
enum ReadFromTextArea {
const enum ReadFromTextArea {
Type,
Paste
}
@ -252,7 +252,7 @@ export class TextAreaHandler extends Disposable {
}
private _onKeyDownHandler(e:IKeyboardEventWrapper): void {
if (e.equals(CommonKeybindings.ESCAPE)) {
if (e.equals(KeyCode.Escape)) {
// Prevent default always for `Esc`, otherwise it will generate a keypress
// See https://msdn.microsoft.com/en-us/library/ie/ms536939(v=vs.85).aspx
e.preventDefault();

View file

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
/**
* A fast character classifier that uses a compact array for ASCII values.
*/
export class CharacterClassifier<T> {
/**
* Maintain a compact (fully initialized ASCII map for quickly classifying ASCII characters - used more often in code).
*/
private _asciiMap: T[];
/**
* The entire map (sparse array).
*/
private _map: T[];
private _defaultValue: T;
constructor(defaultValue:T) {
this._defaultValue = defaultValue;
this._asciiMap = CharacterClassifier._createAsciiMap(defaultValue);
this._map = [];
}
private static _createAsciiMap<T>(defaultValue:T): T[] {
let asciiMap:T[] = [];
for (let i = 0; i < 256; i++) {
asciiMap[i] = defaultValue;
}
return asciiMap;
}
public set(charCode:number, value:T): void {
if (charCode >= 0 && charCode < 256) {
this._asciiMap[charCode] = value;
} else {
this._map[charCode] = value;
}
}
public get(charCode:number): T {
if (charCode >= 0 && charCode < 256) {
return this._asciiMap[charCode];
} else {
return this._map[charCode] || this._defaultValue;
}
}
}

View file

@ -430,10 +430,10 @@ export interface IEditorOptions {
*/
folding?: boolean;
/**
* Enable rendering of leading whitespace.
* Defaults to false.
* Enable rendering of whitespace.
* Defaults to none.
*/
renderWhitespace?: boolean;
renderWhitespace?: 'none' | 'boundary' | 'all';
/**
* Enable rendering of control characters.
* Defaults to false.
@ -644,7 +644,7 @@ export class InternalEditorViewOptions {
scrollBeyondLastLine:boolean;
editorClassName: string;
stopRenderingLineAfter: number;
renderWhitespace: boolean;
renderWhitespace: 'none' | 'boundary' | 'all';
renderControlCharacters: boolean;
renderIndentGuides: boolean;
renderLineHighlight: boolean;
@ -672,7 +672,7 @@ export class InternalEditorViewOptions {
scrollBeyondLastLine:boolean;
editorClassName: string;
stopRenderingLineAfter: number;
renderWhitespace: boolean;
renderWhitespace: 'none' | 'boundary' | 'all';
renderControlCharacters: boolean;
renderIndentGuides: boolean;
renderLineHighlight: boolean;
@ -696,7 +696,7 @@ export class InternalEditorViewOptions {
this.scrollBeyondLastLine = Boolean(source.scrollBeyondLastLine);
this.editorClassName = String(source.editorClassName);
this.stopRenderingLineAfter = source.stopRenderingLineAfter|0;
this.renderWhitespace = Boolean(source.renderWhitespace);
this.renderWhitespace = source.renderWhitespace;
this.renderControlCharacters = Boolean(source.renderControlCharacters);
this.renderIndentGuides = Boolean(source.renderIndentGuides);
this.renderLineHighlight = Boolean(source.renderLineHighlight);

View file

@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
const __space = ' '.charCodeAt(0);
const __tab = '\t'.charCodeAt(0);
import {CharCode} from 'vs/base/common/charCode';
/**
* Compute the diff in spaces between two line's indentation.
@ -31,7 +30,7 @@ function spacesDiff(a:string, aLength:number, b:string, bLength:number): number
let aSpacesCnt = 0, aTabsCount = 0;
for (let j = i; j < aLength; j++) {
let aCharCode = a.charCodeAt(j);
if (aCharCode === __space) {
if (aCharCode === CharCode.Space) {
aSpacesCnt++;
} else {
aTabsCount++;
@ -41,7 +40,7 @@ function spacesDiff(a:string, aLength:number, b:string, bLength:number): number
let bSpacesCnt = 0, bTabsCount = 0;
for (let j = i; j < bLength; j++) {
let bCharCode = b.charCodeAt(j);
if (bCharCode === __space) {
if (bCharCode === CharCode.Space) {
bSpacesCnt++;
} else {
bTabsCount++;
@ -103,9 +102,9 @@ export function guessIndentation(lines:string[], defaultTabSize:number, defaultI
for (let j = 0, lenJ = currentLineText.length; j < lenJ; j++) {
let charCode = currentLineText.charCodeAt(j);
if (charCode === __tab) {
if (charCode === CharCode.Tab) {
currentLineTabsCount++;
} else if (charCode === __space) {
} else if (charCode === CharCode.Space) {
currentLineSpacesCount++;
} else {
// Hit non whitespace character on this line

View file

@ -7,15 +7,11 @@
import * as strings from 'vs/base/common/strings';
import {ILineTokens, IReadOnlyLineMarker} from 'vs/editor/common/editorCommon';
import {IState} from 'vs/editor/common/modes';
import {TokensBinaryEncoding, TokensInflatorMap} from 'vs/editor/common/model/tokensBinaryEncoding';
import {TokensBinaryEncoding, TokensBinaryEncodingValues, TokensInflatorMap} from 'vs/editor/common/model/tokensBinaryEncoding';
import {ModeTransition} from 'vs/editor/common/core/modeTransition';
import {Token} from 'vs/editor/common/core/token';
import {ViewLineToken} from 'vs/editor/common/core/viewLineToken';
const START_INDEX_MASK = TokensBinaryEncoding.START_INDEX_MASK;
const TYPE_MASK = TokensBinaryEncoding.TYPE_MASK;
const START_INDEX_OFFSET = TokensBinaryEncoding.START_INDEX_OFFSET;
const TYPE_OFFSET = TokensBinaryEncoding.TYPE_OFFSET;
import {CharCode} from 'vs/base/common/charCode';
export interface ILineEdit {
startColumn: number;
@ -65,7 +61,7 @@ var NO_OP_MARKERS_ADJUSTER: IMarkersAdjuster = {
finish: () => {}
};
enum MarkerMoveSemantics {
const enum MarkerMoveSemantics {
MarkerDefined = 0,
ForceMove = 1,
ForceStay = 2
@ -83,9 +79,9 @@ function computePlusOneIndentLevel(line: string, tabSize: number): number {
while (i < len) {
let chCode = line.charCodeAt(i);
if (chCode === 32 /*space*/) {
if (chCode === CharCode.Space) {
indent++;
} else if (chCode === 9 /*\t*/) {
} else if (chCode === CharCode.Tab) {
indent = indent - indent % tabSize + tabSize;
} else {
break;
@ -232,14 +228,14 @@ export class ModelLine {
if (currentTokenStartIndex > 0 && delta !== 0) {
// adjust token's `startIndex` by `delta`
let deflatedType = (tokens[tokensIndex] / TYPE_OFFSET) & TYPE_MASK;
let deflatedType = (tokens[tokensIndex] / TokensBinaryEncodingValues.TYPE_OFFSET) & TokensBinaryEncodingValues.TYPE_MASK;
let newStartIndex = Math.max(minimumAllowedIndex, currentTokenStartIndex + delta);
let newToken = deflatedType * TYPE_OFFSET + newStartIndex * START_INDEX_OFFSET;
let newToken = deflatedType * TokensBinaryEncodingValues.TYPE_OFFSET + newStartIndex * TokensBinaryEncodingValues.START_INDEX_OFFSET;
if (delta < 0) {
// pop all previous tokens that have become `collapsed`
while (tokensIndex > 0) {
let prevTokenStartIndex = (tokens[tokensIndex - 1] / START_INDEX_OFFSET) & START_INDEX_MASK;
let prevTokenStartIndex = (tokens[tokensIndex - 1] / TokensBinaryEncodingValues.START_INDEX_OFFSET) & TokensBinaryEncodingValues.START_INDEX_MASK;
if (prevTokenStartIndex >= newStartIndex) {
// Token at `tokensIndex` - 1 is now `collapsed` => pop it
tokens.splice(tokensIndex - 1, 1);
@ -256,7 +252,7 @@ export class ModelLine {
tokensIndex++;
if (tokensIndex < tokensLength) {
currentTokenStartIndex = (tokens[tokensIndex] / START_INDEX_OFFSET) & START_INDEX_MASK;
currentTokenStartIndex = (tokens[tokensIndex] / TokensBinaryEncodingValues.START_INDEX_OFFSET) & TokensBinaryEncodingValues.START_INDEX_MASK;
}
}
// console.log('after call: tokensIndex: ' + tokensIndex + ': ' + String(this.getTokens()));
@ -287,7 +283,7 @@ export class ModelLine {
// Remove overflowing tokens
while (tokens.length > 0) {
let lastTokenStartIndex = (tokens[tokens.length - 1] / START_INDEX_OFFSET) & START_INDEX_MASK;
let lastTokenStartIndex = (tokens[tokens.length - 1] / TokensBinaryEncodingValues.START_INDEX_OFFSET) & TokensBinaryEncodingValues.START_INDEX_MASK;
if (lastTokenStartIndex < lineTextLength) {
// Valid token
break;
@ -533,10 +529,10 @@ export class ModelLine {
for (let i = 0, len = otherTokens.length; i < len; i++) {
let token = otherTokens[i];
let deflatedStartIndex = (token / START_INDEX_OFFSET) & START_INDEX_MASK;
let deflatedType = (token / TYPE_OFFSET) & TYPE_MASK;
let deflatedStartIndex = (token / TokensBinaryEncodingValues.START_INDEX_OFFSET) & TokensBinaryEncodingValues.START_INDEX_MASK;
let deflatedType = (token / TokensBinaryEncodingValues.TYPE_OFFSET) & TokensBinaryEncodingValues.TYPE_MASK;
let newStartIndex = deflatedStartIndex + thisTextLength;
let newToken = deflatedType * TYPE_OFFSET + newStartIndex * START_INDEX_OFFSET;
let newToken = deflatedType * TokensBinaryEncodingValues.TYPE_OFFSET + newStartIndex * TokensBinaryEncodingValues.START_INDEX_OFFSET;
otherTokens[i] = newToken;
}

View file

@ -14,6 +14,7 @@ import {guessIndentation} from 'vs/editor/common/model/indentationGuesser';
import {DEFAULT_INDENTATION, DEFAULT_TRIM_AUTO_WHITESPACE} from 'vs/editor/common/config/defaultConfig';
import {PrefixSumComputer} from 'vs/editor/common/viewModel/prefixSumComputer';
import {IndentRange, computeRanges} from 'vs/editor/common/model/indentRanges';
import {CharCode} from 'vs/base/common/charCode';
const LIMIT_FIND_COUNT = 999;
export const LONG_LINE_BOUNDARY = 1000;
@ -728,10 +729,6 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo
}
private static _isMultiline(searchString:string): boolean {
const BACKSLASH_CHAR_CODE = '\\'.charCodeAt(0);
const n_CHAR_CODE = 'n'.charCodeAt(0);
const r_CHAR_CODE = 'r'.charCodeAt(0);
if (!searchString || searchString.length === 0) {
return false;
}
@ -739,7 +736,7 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo
for (let i = 0, len = searchString.length; i < len; i++) {
let chCode = searchString.charCodeAt(i);
if (chCode === BACKSLASH_CHAR_CODE) {
if (chCode === CharCode.Backslash) {
// move to next char
i++;
@ -750,7 +747,7 @@ export class TextModel extends OrderGuaranteeEventEmitter implements editorCommo
}
let nextChCode = searchString.charCodeAt(i);
if (nextChCode === n_CHAR_CODE || nextChCode === r_CHAR_CODE) {
if (nextChCode === CharCode.n || nextChCode === CharCode.r) {
return true;
}
}

View file

@ -9,10 +9,12 @@ import * as strings from 'vs/base/common/strings';
import {ViewLineToken} from 'vs/editor/common/core/viewLineToken';
import {Token} from 'vs/editor/common/core/token';
const START_INDEX_MASK = 0xffffffff;
const TYPE_MASK = 0xffff;
const START_INDEX_OFFSET = 1;
const TYPE_OFFSET = Math.pow(2, 32);
export const enum TokensBinaryEncodingValues {
START_INDEX_MASK = 0xffffffff,
TYPE_MASK = 0xffff,
START_INDEX_OFFSET = 1,
TYPE_OFFSET = 4294967296 // Math.pow(2, 32)
}
const DEFAULT_VIEW_TOKEN = new ViewLineToken(0, '');
const INFLATED_TOKENS_EMPTY_TEXT:ViewLineToken[] = [];
@ -35,10 +37,6 @@ export class TokensInflatorMap {
}
export class TokensBinaryEncoding {
public static START_INDEX_MASK = START_INDEX_MASK;
public static TYPE_MASK = TYPE_MASK;
public static START_INDEX_OFFSET = START_INDEX_OFFSET;
public static TYPE_OFFSET = TYPE_OFFSET;
public static deflateArr(map:TokensInflatorMap, tokens:Token[]): number[] {
if (tokens.length === 0) {
@ -90,7 +88,7 @@ export class TokensBinaryEncoding {
// 16 bits for token => up to 2^16 = 65,536
// [token][startIndex]
deflated = deflatedToken * TYPE_OFFSET + token.startIndex * START_INDEX_OFFSET;
deflated = deflatedToken * TokensBinaryEncodingValues.TYPE_OFFSET + token.startIndex * TokensBinaryEncodingValues.START_INDEX_OFFSET;
result[i] = deflated;
@ -101,11 +99,11 @@ export class TokensBinaryEncoding {
}
public static getStartIndex(binaryEncodedToken:number): number {
return (binaryEncodedToken / START_INDEX_OFFSET) & START_INDEX_MASK;
return (binaryEncodedToken / TokensBinaryEncodingValues.START_INDEX_OFFSET) & TokensBinaryEncodingValues.START_INDEX_MASK;
}
public static getType(map:TokensInflatorMap, binaryEncodedToken:number): string {
var deflatedType = (binaryEncodedToken / TYPE_OFFSET) & TYPE_MASK;
var deflatedType = (binaryEncodedToken / TokensBinaryEncodingValues.TYPE_OFFSET) & TokensBinaryEncodingValues.TYPE_MASK;
if (deflatedType === 0) {
return strings.empty;
}
@ -126,8 +124,8 @@ export class TokensBinaryEncoding {
for (let i = 0, len = binaryEncodedTokens.length; i < len; i++) {
let deflated = binaryEncodedTokens[i];
let startIndex = (deflated / START_INDEX_OFFSET) & START_INDEX_MASK;
let deflatedType = (deflated / TYPE_OFFSET) & TYPE_MASK;
let startIndex = (deflated / TokensBinaryEncodingValues.START_INDEX_OFFSET) & TokensBinaryEncodingValues.START_INDEX_MASK;
let deflatedType = (deflated / TokensBinaryEncodingValues.TYPE_OFFSET) & TokensBinaryEncodingValues.TYPE_MASK;
result.push(new ViewLineToken(startIndex, inflateMap[deflatedType]));
}
@ -152,19 +150,19 @@ export class TokensBinaryEncoding {
const inflateMap = map._inflate;
let originalToken = binaryEncodedTokens[startIndex];
let deflatedType = (originalToken / TYPE_OFFSET) & TYPE_MASK;
let deflatedType = (originalToken / TokensBinaryEncodingValues.TYPE_OFFSET) & TokensBinaryEncodingValues.TYPE_MASK;
let newStartIndex = 0;
result.push(new ViewLineToken(newStartIndex, inflateMap[deflatedType]));
for (let i = startIndex + 1, len = binaryEncodedTokens.length; i < len; i++) {
originalToken = binaryEncodedTokens[i];
let originalStartIndex = (originalToken / START_INDEX_OFFSET) & START_INDEX_MASK;
let originalStartIndex = (originalToken / TokensBinaryEncodingValues.START_INDEX_OFFSET) & TokensBinaryEncodingValues.START_INDEX_MASK;
if (originalStartIndex >= endOffset) {
break;
}
deflatedType = (originalToken / TYPE_OFFSET) & TYPE_MASK;
deflatedType = (originalToken / TokensBinaryEncodingValues.TYPE_OFFSET) & TokensBinaryEncodingValues.TYPE_MASK;
newStartIndex = originalStartIndex - startOffset + deltaStartIndex;
result.push(new ViewLineToken(newStartIndex, inflateMap[deflatedType]));
}

View file

@ -16,6 +16,7 @@ import {TextualSuggestSupport} from 'vs/editor/common/modes/supports/suggestSupp
import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService';
import * as wordHelper from 'vs/editor/common/model/wordHelper';
import {ICompatWorkerService, ICompatMode} from 'vs/editor/common/services/compatWorkerService';
import {CharCode} from 'vs/base/common/charCode';
export function createWordRegExp(allowInWords:string = ''): RegExp {
return wordHelper.createWordRegExp(allowInWords);
@ -105,7 +106,7 @@ export abstract class AbstractMode implements modes.IMode {
}
public setTokenizationSupport<T>(callback:(mode:modes.IMode) => T) : IDisposable {
var supportImpl = callback(this);
let supportImpl = callback(this);
this['tokenizationSupport'] = supportImpl;
this._eventEmitter.emit('modeSupportChanged', _createModeSupportChangedEvent());
@ -170,69 +171,43 @@ class SimplifiedMode implements modes.IMode {
}
}
export var isDigit:(character:string, base:number)=>boolean = (function () {
var _0 = '0'.charCodeAt(0),
_1 = '1'.charCodeAt(0),
_2 = '2'.charCodeAt(0),
_3 = '3'.charCodeAt(0),
_4 = '4'.charCodeAt(0),
_5 = '5'.charCodeAt(0),
_6 = '6'.charCodeAt(0),
_7 = '7'.charCodeAt(0),
_8 = '8'.charCodeAt(0),
_9 = '9'.charCodeAt(0),
_a = 'a'.charCodeAt(0),
_b = 'b'.charCodeAt(0),
_c = 'c'.charCodeAt(0),
_d = 'd'.charCodeAt(0),
_e = 'e'.charCodeAt(0),
_f = 'f'.charCodeAt(0),
_A = 'A'.charCodeAt(0),
_B = 'B'.charCodeAt(0),
_C = 'C'.charCodeAt(0),
_D = 'D'.charCodeAt(0),
_E = 'E'.charCodeAt(0),
_F = 'F'.charCodeAt(0);
return function isDigit(character:string, base:number):boolean {
var c = character.charCodeAt(0);
switch (base) {
case 1:
return c === _0;
case 2:
return c >= _0 && c <= _1;
case 3:
return c >= _0 && c <= _2;
case 4:
return c >= _0 && c <= _3;
case 5:
return c >= _0 && c <= _4;
case 6:
return c >= _0 && c <= _5;
case 7:
return c >= _0 && c <= _6;
case 8:
return c >= _0 && c <= _7;
case 9:
return c >= _0 && c <= _8;
case 10:
return c >= _0 && c <= _9;
case 11:
return (c >= _0 && c <= _9) || (c === _a) || (c === _A);
case 12:
return (c >= _0 && c <= _9) || (c >= _a && c <= _b) || (c >= _A && c <= _B);
case 13:
return (c >= _0 && c <= _9) || (c >= _a && c <= _c) || (c >= _A && c <= _C);
case 14:
return (c >= _0 && c <= _9) || (c >= _a && c <= _d) || (c >= _A && c <= _D);
case 15:
return (c >= _0 && c <= _9) || (c >= _a && c <= _e) || (c >= _A && c <= _E);
default:
return (c >= _0 && c <= _9) || (c >= _a && c <= _f) || (c >= _A && c <= _F);
}
};
})();
export function isDigit(character:string, base:number): boolean {
let c = character.charCodeAt(0);
switch (base) {
case 1:
return c === CharCode.Digit0;
case 2:
return c >= CharCode.Digit0 && c <= CharCode.Digit1;
case 3:
return c >= CharCode.Digit0 && c <= CharCode.Digit2;
case 4:
return c >= CharCode.Digit0 && c <= CharCode.Digit3;
case 5:
return c >= CharCode.Digit0 && c <= CharCode.Digit4;
case 6:
return c >= CharCode.Digit0 && c <= CharCode.Digit5;
case 7:
return c >= CharCode.Digit0 && c <= CharCode.Digit6;
case 8:
return c >= CharCode.Digit0 && c <= CharCode.Digit7;
case 9:
return c >= CharCode.Digit0 && c <= CharCode.Digit8;
case 10:
return c >= CharCode.Digit0 && c <= CharCode.Digit9;
case 11:
return (c >= CharCode.Digit0 && c <= CharCode.Digit9) || (c === CharCode.a) || (c === CharCode.A);
case 12:
return (c >= CharCode.Digit0 && c <= CharCode.Digit9) || (c >= CharCode.a && c <= CharCode.b) || (c >= CharCode.A && c <= CharCode.B);
case 13:
return (c >= CharCode.Digit0 && c <= CharCode.Digit9) || (c >= CharCode.a && c <= CharCode.c) || (c >= CharCode.A && c <= CharCode.C);
case 14:
return (c >= CharCode.Digit0 && c <= CharCode.Digit9) || (c >= CharCode.a && c <= CharCode.d) || (c >= CharCode.A && c <= CharCode.D);
case 15:
return (c >= CharCode.Digit0 && c <= CharCode.Digit9) || (c >= CharCode.a && c <= CharCode.e) || (c >= CharCode.A && c <= CharCode.E);
default:
return (c >= CharCode.Digit0 && c <= CharCode.Digit9) || (c >= CharCode.a && c <= CharCode.f) || (c >= CharCode.A && c <= CharCode.F);
}
}
export class FrankensteinMode extends AbstractMode {

View file

@ -5,53 +5,55 @@
'use strict';
import {IStream} from 'vs/editor/common/modes';
import {CharacterClassifier} from 'vs/editor/common/core/characterClassifier';
class CharacterSet {
private static _CACHE:{ [key:string]:CharacterSet; } = {}; // TODO@Alex unbounded cache
public static getOrCreate(source:string): CharacterSet {
if (!CharacterSet._CACHE.hasOwnProperty(source)) {
CharacterSet._CACHE[source] = new CharacterSet(source);
}
return CharacterSet._CACHE[source];
}
private _classifier: CharacterClassifier<boolean>;
constructor(source:string) {
this._classifier = new CharacterClassifier<boolean>(false);
for (let i = 0, len = source.length; i < len; i++) {
this._classifier.set(source.charCodeAt(i), true);
}
}
public contains(charCode:number): boolean {
return this._classifier.get(charCode);
}
}
export class LineStream implements IStream {
static STRING_TO_ARRAY_CACHE:{ [key:string]:boolean[]; } = {};
/*protected*/ _source:string;
private sourceLength:number;
/*protected*/ _pos:number;
private whitespace:string;
private whitespaceArr:boolean[];
private separators:string;
private separatorsArr:boolean[];
private tokenStart:number;
private tokenEnd:number;
private _source:string;
private _sourceLength:number;
private _pos:number;
private _whitespace:string;
private _whitespaceArr:CharacterSet;
private _separators:string;
private _separatorsArr:CharacterSet;
private _tokenStart:number;
private _tokenEnd:number;
constructor(source:string) {
this._source = source;
this.sourceLength = source.length;
this._sourceLength = source.length;
this._pos = 0;
this.whitespace = '\t \u00a0';
this.whitespaceArr = this.stringToArray(this.whitespace);
this.separators = '';
this.separatorsArr = this.stringToArray(this.separators);
this.tokenStart = -1;
this.tokenEnd = -1;
}
private stringToArray(str:string):boolean[] {
if (!LineStream.STRING_TO_ARRAY_CACHE.hasOwnProperty(str)) {
LineStream.STRING_TO_ARRAY_CACHE[str] = this.actualStringToArray(str);
}
return LineStream.STRING_TO_ARRAY_CACHE[str];
}
private actualStringToArray(str:string):boolean[] {
let maxCharCode = 0;
for (let i = 0; i < str.length; i++) {
maxCharCode = Math.max(maxCharCode, str.charCodeAt(i));
}
let r:boolean[] = [];
for (let i = 0; i <= maxCharCode; i++) {
r[i] = false;
}
for (let i = 0; i < str.length; i++) {
r[str.charCodeAt(i)] = true;
}
return r;
this._whitespace = '\t \u00a0';
this._whitespaceArr = CharacterSet.getOrCreate(this._whitespace);
this._separators = '';
this._separatorsArr = CharacterSet.getOrCreate(this._separators);
this._tokenStart = -1;
this._tokenEnd = -1;
}
public pos():number {
@ -59,12 +61,12 @@ export class LineStream implements IStream {
}
public eos() {
return this._pos >= this.sourceLength;
return this._pos >= this._sourceLength;
}
public peek():string {
// Check EOS
if (this._pos >= this.sourceLength) {
if (this._pos >= this._sourceLength) {
throw new Error('Stream is at the end');
}
return this._source[this._pos];
@ -72,26 +74,26 @@ export class LineStream implements IStream {
public next():string {
// Check EOS
if (this._pos >= this.sourceLength) {
if (this._pos >= this._sourceLength) {
throw new Error('Stream is at the end');
}
// Reset peeked token
this.tokenStart = -1;
this.tokenEnd = -1;
this._tokenStart = -1;
this._tokenEnd = -1;
return this._source[this._pos++];
}
public next2(): void {
// Check EOS
if (this._pos >= this.sourceLength) {
if (this._pos >= this._sourceLength) {
throw new Error('Stream is at the end');
}
// Reset peeked token
this.tokenStart = -1;
this.tokenEnd = -1;
this._tokenStart = -1;
this._tokenEnd = -1;
this._pos++;
}
@ -100,11 +102,11 @@ export class LineStream implements IStream {
if (n === 0) {
return '';
}
var oldPos = this._pos;
const oldPos = this._pos;
this._pos += n;
// Reset peeked token
this.tokenStart = -1;
this.tokenEnd = -1;
this._tokenStart = -1;
this._tokenEnd = -1;
return this._source.substring(oldPos, this._pos);
}
@ -114,14 +116,14 @@ export class LineStream implements IStream {
}
this._pos += n;
// Reset peeked token
this.tokenStart = -1;
this.tokenEnd = -1;
this._tokenStart = -1;
this._tokenEnd = -1;
return n;
}
public advanceToEOS():string {
var oldPos = this._pos;
this._pos = this.sourceLength;
const oldPos = this._pos;
this._pos = this._sourceLength;
this.resetPeekedToken();
return this._source.substring(oldPos, this._pos);
}
@ -131,10 +133,10 @@ export class LineStream implements IStream {
this.resetPeekedToken();
}
private createPeeker(condition:any):()=>number {
private createPeeker(condition:RegExp|string):()=>number {
if (condition instanceof RegExp) {
return () => {
var result = condition.exec(this._source.substr(this._pos));
let result = condition.exec(this._source.substr(this._pos));
if (result === null) {
return 0;
} else if (result.index !== 0) {
@ -142,13 +144,14 @@ export class LineStream implements IStream {
}
return result[0].length;
};
} else if ((condition instanceof String || (typeof condition) === 'string') && condition) {
} else if ((typeof condition === 'string') && condition) {
return () => {
var len = (<String> condition).length, match = this._pos + len <= this.sourceLength;
for (var i = 0; match && i < len; i++) {
match = this._source.charCodeAt(this._pos + i) === (<String> condition).charCodeAt(i);
const len = condition.length;
let match = (this._pos + len <= this._sourceLength);
for (let i = 0; match && i < len; i++) {
match = this._source.charCodeAt(this._pos + i) === condition.charCodeAt(i);
}
return match ? len : 0;
return (match ? len : 0);
};
}
throw new Error('Condition must be either a regular expression, function or a non-empty string');
@ -156,16 +159,15 @@ export class LineStream implements IStream {
// --- BEGIN `_advanceIfStringCaseInsensitive`
private _advanceIfStringCaseInsensitive(condition:string): number {
var oldPos = this._pos,
source = this._source,
len = condition.length,
i:number;
const oldPos = this._pos;
const source = this._source;
const len = condition.length;
if (len < 1 || oldPos + len > this.sourceLength) {
if (len < 1 || oldPos + len > this._sourceLength) {
return 0;
}
for (i = 0; i < len; i++) {
for (let i = 0; i < len; i++) {
if (source.charAt(oldPos + i).toLowerCase() !== condition.charAt(i).toLowerCase()) {
return 0;
}
@ -183,16 +185,15 @@ export class LineStream implements IStream {
// --- BEGIN `advanceIfString`
private _advanceIfString(condition: string): number {
var oldPos = this._pos,
source = this._source,
len = condition.length,
i:number;
const oldPos = this._pos;
const source = this._source;
const len = condition.length;
if (len < 1 || oldPos + len > this.sourceLength) {
if (len < 1 || oldPos + len > this._sourceLength) {
return 0;
}
for (i = 0; i < len; i++) {
for (let i = 0; i < len; i++) {
if (source.charCodeAt(oldPos + i) !== condition.charCodeAt(i)) {
return 0;
}
@ -210,7 +211,7 @@ export class LineStream implements IStream {
// --- BEGIN `advanceIfString`
private _advanceIfCharCode(charCode:number): number {
if (this._pos < this.sourceLength && this._source.charCodeAt(this._pos) === charCode) {
if (this._pos < this._sourceLength && this._source.charCodeAt(this._pos) === charCode) {
return 1;
}
@ -226,7 +227,7 @@ export class LineStream implements IStream {
// --- BEGIN `advanceIfRegExp`
private _advanceIfRegExp(condition:RegExp): number {
if (this._pos >= this.sourceLength) {
if (this._pos >= this._sourceLength) {
return 0;
}
if (!condition.test(this._source.substr(this._pos))) {
@ -242,14 +243,14 @@ export class LineStream implements IStream {
}
// --- END
private advanceLoop(condition:any, isWhile:boolean, including:boolean):string {
private advanceLoop(condition:RegExp|string, isWhile:boolean, including:boolean):string {
if (this.eos()) {
return '';
}
var peeker = this.createPeeker(condition);
var oldPos = this._pos;
var n = 0;
var f = null;
const peeker = this.createPeeker(condition);
const oldPos = this._pos;
let n = 0;
let f = null;
if (isWhile) {
f = (n) => {
return n > 0;
@ -272,11 +273,11 @@ export class LineStream implements IStream {
return this._source.substring(oldPos, this._pos);
}
public advanceWhile(condition:any):string {
public advanceWhile(condition:RegExp|string):string {
return this.advanceLoop(condition, true, false);
}
public advanceUntil(condition:any, including:boolean):string {
public advanceUntil(condition:RegExp|string, including:boolean):string {
return this.advanceLoop(condition, false, including);
}
@ -286,12 +287,12 @@ export class LineStream implements IStream {
return 0;
}
var oldPos = this._pos;
var index = this._source.indexOf(condition, oldPos);
const oldPos = this._pos;
const index = this._source.indexOf(condition, oldPos);
if (index === -1) {
// String was not found => advanced to `eos`
return (this.sourceLength - oldPos);
return (this._sourceLength - oldPos);
}
if (including) {
@ -311,16 +312,16 @@ export class LineStream implements IStream {
// --- END
private resetPeekedToken() {
this.tokenStart = -1;
this.tokenEnd = -1;
this._tokenStart = -1;
this._tokenEnd = -1;
}
public setTokenRules(separators:string, whitespace:string):void {
if (this.separators !== separators || this.whitespace !== whitespace) {
this.separators = separators;
this.separatorsArr = this.stringToArray(this.separators);
this.whitespace = whitespace;
this.whitespaceArr = this.stringToArray(this.whitespace);
if (this._separators !== separators || this._whitespace !== whitespace) {
this._separators = separators;
this._separatorsArr = CharacterSet.getOrCreate(this._separators);
this._whitespace = whitespace;
this._whitespaceArr = CharacterSet.getOrCreate(this._whitespace);
this.resetPeekedToken();
}
}
@ -328,15 +329,16 @@ export class LineStream implements IStream {
// --- tokens
public peekToken():string {
if (this.tokenStart !== -1) {
return this._source.substring(this.tokenStart, this.tokenEnd);
if (this._tokenStart !== -1) {
return this._source.substring(this._tokenStart, this._tokenEnd);
}
var source = this._source,
sourceLength = this.sourceLength,
whitespaceArr = this.whitespaceArr,
separatorsArr = this.separatorsArr,
tokenStart = this._pos;
const source = this._source;
const sourceLength = this._sourceLength;
const whitespaceArr = this._whitespaceArr;
const separatorsArr = this._separatorsArr;
let tokenStart = this._pos;
// Check EOS
if (tokenStart >= sourceLength) {
@ -344,48 +346,48 @@ export class LineStream implements IStream {
}
// Skip whitespace
while (whitespaceArr[source.charCodeAt(tokenStart)] && tokenStart < sourceLength) {
while (whitespaceArr.contains(source.charCodeAt(tokenStart)) && tokenStart < sourceLength) {
tokenStart++;
}
var tokenEnd = tokenStart;
let tokenEnd = tokenStart;
// If a separator is hit, it is a token
if (separatorsArr[source.charCodeAt(tokenEnd)] && tokenEnd < sourceLength) {
if (separatorsArr.contains(source.charCodeAt(tokenEnd)) && tokenEnd < sourceLength) {
tokenEnd++;
} else {
// Advance until a separator or a whitespace is hit
while (!separatorsArr[source.charCodeAt(tokenEnd)] && !whitespaceArr[source.charCodeAt(tokenEnd)] && tokenEnd < sourceLength) {
while (!separatorsArr.contains(source.charCodeAt(tokenEnd)) && !whitespaceArr.contains(source.charCodeAt(tokenEnd)) && tokenEnd < sourceLength) {
tokenEnd++;
}
}
// Cache peeked token
this.tokenStart = tokenStart;
this.tokenEnd = tokenEnd;
this._tokenStart = tokenStart;
this._tokenEnd = tokenEnd;
return source.substring(tokenStart, tokenEnd);
}
public nextToken():string {
// Check EOS
if (this._pos >= this.sourceLength) {
if (this._pos >= this._sourceLength) {
throw new Error('Stream is at the end');
}
// Peek token if necessary
var result:string;
if (this.tokenStart === -1) {
let result:string;
if (this._tokenStart === -1) {
result = this.peekToken();
} else {
result = this._source.substring(this.tokenStart, this.tokenEnd);
result = this._source.substring(this._tokenStart, this._tokenEnd);
}
// Advance to tokenEnd
this._pos = this.tokenEnd;
this._pos = this._tokenEnd;
// Reset peeked token
this.tokenStart = -1;
this.tokenEnd = -1;
this._tokenStart = -1;
this._tokenEnd = -1;
return result;
}
@ -393,26 +395,26 @@ export class LineStream implements IStream {
// -- whitespace
public peekWhitespace():string {
var source = this._source,
sourceLength = this.sourceLength,
whitespaceArr = this.whitespaceArr,
peek = this._pos;
const source = this._source;
const sourceLength = this._sourceLength;
const whitespaceArr = this._whitespaceArr;
while (whitespaceArr[source.charCodeAt(peek)] && peek < sourceLength) {
let peek = this._pos;
while (whitespaceArr.contains(source.charCodeAt(peek)) && peek < sourceLength) {
peek++;
}
return source.substring(this._pos, peek);
}
// --- BEGIN `advanceIfRegExp`
// --- BEGIN `skipWhitespace`
private _skipWhitespace(): number {
var source = this._source,
sourceLength = this.sourceLength,
whitespaceArr = this.whitespaceArr,
oldPos = this._pos,
peek = this._pos;
const source = this._source;
const sourceLength = this._sourceLength;
const whitespaceArr = this._whitespaceArr;
const oldPos = this._pos;
while (whitespaceArr[source.charCodeAt(peek)] && peek < sourceLength) {
let peek = this._pos;
while (whitespaceArr.contains(source.charCodeAt(peek)) && peek < sourceLength) {
peek++;
}

View file

@ -5,97 +5,137 @@
'use strict';
import {ILink} from 'vs/editor/common/modes';
import {CharCode} from 'vs/base/common/charCode';
import {CharacterClassifier} from 'vs/editor/common/core/characterClassifier';
export interface ILinkComputerTarget {
getLineCount(): number;
getLineContent(lineNumber:number): string;
}
const enum State {
Invalid = 0,
Start = 1,
H = 2,
HT = 3,
HTT = 4,
HTTP = 5,
F = 6,
FI = 7,
FIL = 8,
BeforeColon = 9,
AfterColon = 10,
AlmostThere = 11,
End = 12,
Accept = 13
}
type Edge = [State,number,State];
class StateMachine {
private _states: State[][];
private _maxCharCode: number;
constructor(edges:Edge[]) {
let maxCharCode = 0;
let maxState = State.Invalid;
for (let i = 0, len = edges.length; i < len; i++) {
let [from, chCode, to] = edges[i];
if (chCode > maxCharCode) {
maxCharCode = chCode;
}
if (from > maxState) {
maxState = from;
}
if (to > maxState) {
maxState = to;
}
}
let states:number[][] = [];
for (let i = 0; i <= maxState; i++) {
let tmp:number[] = [];
for (let j = 0; j <= maxCharCode; j++) {
tmp[j] = State.Invalid;
}
states[i] = tmp;
}
for (let i = 0, len = edges.length; i < len; i++) {
let [from, chCode, to] = edges[i];
states[from][chCode] = to;
}
this._states = states;
this._maxCharCode = maxCharCode;
}
public nextState(currentState:State, chCode:number): State {
if (chCode < 0 || chCode > this._maxCharCode) {
return State.Invalid;
}
return this._states[currentState][chCode];
}
}
// State machine for http:// or https:// or file://
const STATE_MAP:{[ch:string]:number}[] = [];
const START_STATE = 1;
const END_STATE = 12;
const ACCEPT_STATE = 13;
let stateMachine = new StateMachine([
[State.Start, CharCode.h, State.H],
[State.Start, CharCode.H, State.H],
[State.Start, CharCode.f, State.F],
[State.Start, CharCode.F, State.F],
STATE_MAP[1] = { 'h': 2, 'H': 2, 'f': 6, 'F': 6 };
STATE_MAP[2] = { 't': 3, 'T': 3 };
STATE_MAP[3] = { 't': 4, 'T': 4 };
STATE_MAP[4] = { 'p': 5, 'P': 5 };
STATE_MAP[5] = { 's': 9, 'S': 9, ':': 10 };
STATE_MAP[6] = { 'i': 7, 'I': 7 };
STATE_MAP[7] = { 'l': 8, 'L': 8 };
STATE_MAP[8] = { 'e': 9, 'E': 9 };
STATE_MAP[9] = { ':': 10 };
STATE_MAP[10] = { '/': 11 };
STATE_MAP[11] = { '/': END_STATE };
[State.H, CharCode.t, State.HT],
[State.H, CharCode.T, State.HT],
enum CharacterClass {
[State.HT, CharCode.t, State.HTT],
[State.HT, CharCode.T, State.HTT],
[State.HTT, CharCode.p, State.HTTP],
[State.HTT, CharCode.P, State.HTTP],
[State.HTTP, CharCode.s, State.BeforeColon],
[State.HTTP, CharCode.S, State.BeforeColon],
[State.HTTP, CharCode.Colon, State.AfterColon],
[State.F, CharCode.i, State.FI],
[State.F, CharCode.I, State.FI],
[State.FI, CharCode.l, State.FIL],
[State.FI, CharCode.L, State.FIL],
[State.FIL, CharCode.e, State.BeforeColon],
[State.FIL, CharCode.E, State.BeforeColon],
[State.BeforeColon, CharCode.Colon, State.AfterColon],
[State.AfterColon, CharCode.Slash, State.AlmostThere],
[State.AlmostThere, CharCode.Slash, State.End],
]);
const enum CharacterClass {
None = 0,
ForceTermination = 1,
CannotEndIn = 2
}
const _openParens = '('.charCodeAt(0);
const _closeParens = ')'.charCodeAt(0);
const _openSquareBracket = '['.charCodeAt(0);
const _closeSquareBracket = ']'.charCodeAt(0);
const _openCurlyBracket = '{'.charCodeAt(0);
const _closeCurlyBracket = '}'.charCodeAt(0);
const classifier = (function() {
let result = new CharacterClassifier(CharacterClass.None);
class CharacterClassifier {
/**
* Maintain a compact (fully initialized ASCII map for quickly classifying ASCII characters - used more often in code).
*/
private _asciiMap: CharacterClass[];
/**
* The entire map (sparse array).
*/
private _map: CharacterClass[];
constructor() {
const FORCE_TERMINATION_CHARACTERS = ' \t<>\'\"、。。、,.:;?!@#$%&*‘“〈《「『【〔([{「」}])〕】』」》〉”’`~…';
const CANNOT_END_WITH_CHARACTERS = '.,;';
this._asciiMap = [];
for (let i = 0; i < 256; i++) {
this._asciiMap[i] = CharacterClass.None;
}
this._map = [];
for (let i = 0; i < FORCE_TERMINATION_CHARACTERS.length; i++) {
this._set(FORCE_TERMINATION_CHARACTERS.charCodeAt(i), CharacterClass.ForceTermination);
}
for (let i = 0; i < CANNOT_END_WITH_CHARACTERS.length; i++) {
this._set(CANNOT_END_WITH_CHARACTERS.charCodeAt(i), CharacterClass.CannotEndIn);
}
const FORCE_TERMINATION_CHARACTERS = ' \t<>\'\"、。。、,.:;?!@#$%&*‘“〈《「『【〔([{「」}])〕】』」》〉”’`~…';
for (let i = 0; i < FORCE_TERMINATION_CHARACTERS.length; i++) {
result.set(FORCE_TERMINATION_CHARACTERS.charCodeAt(i), CharacterClass.ForceTermination);
}
private _set(charCode:number, charClass:CharacterClass): void {
if (charCode < 256) {
this._asciiMap[charCode] = charClass;
}
this._map[charCode] = charClass;
const CANNOT_END_WITH_CHARACTERS = '.,;';
for (let i = 0; i < CANNOT_END_WITH_CHARACTERS.length; i++) {
result.set(CANNOT_END_WITH_CHARACTERS.charCodeAt(i), CharacterClass.CannotEndIn);
}
public classify(charCode:number): CharacterClass {
if (charCode < 256) {
return this._asciiMap[charCode];
}
let charClass = this._map[charCode];
if (charClass) {
return charClass;
}
return CharacterClass.None;
}
}
const characterClassifier = new CharacterClassifier();
return result;
})();
class LinkComputer {
@ -104,7 +144,7 @@ class LinkComputer {
let lastIncludedCharIndex = linkEndIndex - 1;
do {
const chCode = line.charCodeAt(lastIncludedCharIndex);
const chClass = characterClassifier.classify(chCode);
const chClass = classifier.get(chCode);
if (chClass !== CharacterClass.CannotEndIn) {
break;
}
@ -130,7 +170,7 @@ class LinkComputer {
let j = 0;
let linkBeginIndex = 0;
let state = START_STATE;
let state = State.Start;
let hasOpenParens = false;
let hasOpenSquareBracket = false;
let hasOpenCurlyBracket = false;
@ -138,34 +178,34 @@ class LinkComputer {
while (j < len) {
let resetStateMachine = false;
const chCode = line.charCodeAt(j);
if (state === ACCEPT_STATE) {
const chCode = line.charCodeAt(j);
if (state === State.Accept) {
let chClass:CharacterClass;
switch (chCode) {
case _openParens:
case CharCode.OpenParen:
hasOpenParens = true;
chClass = CharacterClass.None;
break;
case _closeParens:
case CharCode.CloseParen:
chClass = (hasOpenParens ? CharacterClass.None : CharacterClass.ForceTermination);
break;
case _openSquareBracket:
case CharCode.OpenSquareBracket:
hasOpenSquareBracket = true;
chClass = CharacterClass.None;
break;
case _closeSquareBracket:
case CharCode.CloseSquareBracket:
chClass = (hasOpenSquareBracket ? CharacterClass.None : CharacterClass.ForceTermination);
break;
case _openCurlyBracket:
case CharCode.OpenCurlyBrace:
hasOpenCurlyBracket = true;
chClass = CharacterClass.None;
break;
case _closeCurlyBracket:
case CharCode.CloseCurlyBrace:
chClass = (hasOpenCurlyBracket ? CharacterClass.None : CharacterClass.ForceTermination);
break;
default:
chClass = characterClassifier.classify(chCode);
chClass = classifier.get(chCode);
}
// Check if character terminates link
@ -173,27 +213,24 @@ class LinkComputer {
result.push(LinkComputer._createLink(line, i, linkBeginIndex, j));
resetStateMachine = true;
}
} else if (state === END_STATE) {
const chCode = line.charCodeAt(j);
const chClass = characterClassifier.classify(chCode);
} else if (state === State.End) {
const chClass = classifier.get(chCode);
// Check if character terminates link
if (chClass === CharacterClass.ForceTermination) {
resetStateMachine = true;
} else {
state = ACCEPT_STATE;
state = State.Accept;
}
} else {
const ch = line.charAt(j);
if (STATE_MAP[state].hasOwnProperty(ch)) {
state = STATE_MAP[state][ch];
} else {
state = stateMachine.nextState(state, chCode);
if (state === State.Invalid) {
resetStateMachine = true;
}
}
if (resetStateMachine) {
state = START_STATE;
state = State.Start;
hasOpenParens = false;
hasOpenSquareBracket = false;
hasOpenCurlyBracket = false;
@ -205,7 +242,7 @@ class LinkComputer {
j++;
}
if (state === ACCEPT_STATE) {
if (state === State.Accept) {
result.push(LinkComputer._createLink(line, i, linkBeginIndex, len));
}

View file

@ -15,7 +15,7 @@
* Inside monarch we use fully typed definitions and compiled versions of the more abstract JSON descriptions.
*/
export enum MonarchBracket {
export const enum MonarchBracket {
None = 0,
Open = 1,
Close = -1

View file

@ -68,7 +68,7 @@ function _tokenizeToString(text: string, tokenizationSupport: ITokenizationSuppo
result += '<br/>';
};
result = '<div style="white-space: pre-wrap;">';
result = `<div class="monaco-tokenized-source">`;
_tokenizeLines(text, tokenizationSupport, emitToken, emitNewLine);
result += '</div>';

View file

@ -8,7 +8,7 @@ import * as nls from 'vs/nls';
import network = require('vs/base/common/network');
import Event, {Emitter} from 'vs/base/common/event';
import {EmitterEvent} from 'vs/base/common/eventEmitter';
import {MarkedString, textToMarkedString} from 'vs/base/common/htmlContent';
import {MarkedString} from 'vs/base/common/htmlContent';
import {IDisposable} from 'vs/base/common/lifecycle';
import Severity from 'vs/base/common/severity';
import URI from 'vs/base/common/uri';
@ -145,9 +145,10 @@ class ModelMarkerHandler {
if (typeof message === 'string') {
if (source) {
message = nls.localize('sourceAndDiagMessage', "[{0}] {1}", source, message);
const indent = new Array(source.length + 1 + 3 /*'[] '.length*/).join(' ');
message = nls.localize('diagAndSource', "[{0}] {1}", source, message.replace(/\n/g, '\n' + indent));
}
hoverMessage = [textToMarkedString(message)];
hoverMessage = [{ language: '_', value: message }];
}
return {

View file

@ -5,7 +5,7 @@
'use strict';
import {Emitter} from 'vs/base/common/event';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
import {KeyMod as ConstKeyMod, KeyChord} from 'vs/base/common/keyCodes';
import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range';
import {Selection, SelectionDirection} from 'vs/editor/common/core/selection';
@ -14,6 +14,198 @@ import {CancellationTokenSource} from 'vs/base/common/cancellation';
import Severity from 'vs/base/common/severity';
import URI from 'vs/base/common/uri';
// --------------------------------------------
// This is repeated here so it can be exported
// --------------------------------------------
export class KeyMod {
public static CtrlCmd:number = ConstKeyMod.CtrlCmd;
public static Shift:number = ConstKeyMod.Shift;
public static Alt:number = ConstKeyMod.Alt;
public static WinCtrl:number = ConstKeyMod.WinCtrl;
public static chord(firstPart:number, secondPart:number): number {
return KeyChord(firstPart, secondPart);
}
}
// --------------------------------------------
// This is repeated here so it can be exported
// --------------------------------------------
/**
* Virtual Key Codes, the value does not hold any inherent meaning.
* Inspired somewhat from https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
* But these are "more general", as they should work across browsers & OS`s.
*/
export enum KeyCode {
/**
* Placed first to cover the 0 value of the enum.
*/
Unknown = 0,
Backspace = 1,
Tab = 2,
Enter = 3,
Shift = 4,
Ctrl = 5,
Alt = 6,
PauseBreak = 7,
CapsLock = 8,
Escape = 9,
Space = 10,
PageUp = 11,
PageDown = 12,
End = 13,
Home = 14,
LeftArrow = 15,
UpArrow = 16,
RightArrow = 17,
DownArrow = 18,
Insert = 19,
Delete = 20,
KEY_0 = 21,
KEY_1 = 22,
KEY_2 = 23,
KEY_3 = 24,
KEY_4 = 25,
KEY_5 = 26,
KEY_6 = 27,
KEY_7 = 28,
KEY_8 = 29,
KEY_9 = 30,
KEY_A = 31,
KEY_B = 32,
KEY_C = 33,
KEY_D = 34,
KEY_E = 35,
KEY_F = 36,
KEY_G = 37,
KEY_H = 38,
KEY_I = 39,
KEY_J = 40,
KEY_K = 41,
KEY_L = 42,
KEY_M = 43,
KEY_N = 44,
KEY_O = 45,
KEY_P = 46,
KEY_Q = 47,
KEY_R = 48,
KEY_S = 49,
KEY_T = 50,
KEY_U = 51,
KEY_V = 52,
KEY_W = 53,
KEY_X = 54,
KEY_Y = 55,
KEY_Z = 56,
Meta = 57,
ContextMenu = 58,
F1 = 59,
F2 = 60,
F3 = 61,
F4 = 62,
F5 = 63,
F6 = 64,
F7 = 65,
F8 = 66,
F9 = 67,
F10 = 68,
F11 = 69,
F12 = 70,
F13 = 71,
F14 = 72,
F15 = 73,
F16 = 74,
F17 = 75,
F18 = 76,
F19 = 77,
NumLock = 78,
ScrollLock = 79,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ';:' key
*/
US_SEMICOLON = 80,
/**
* For any country/region, the '+' key
* For the US standard keyboard, the '=+' key
*/
US_EQUAL = 81,
/**
* For any country/region, the ',' key
* For the US standard keyboard, the ',<' key
*/
US_COMMA = 82,
/**
* For any country/region, the '-' key
* For the US standard keyboard, the '-_' key
*/
US_MINUS = 83,
/**
* For any country/region, the '.' key
* For the US standard keyboard, the '.>' key
*/
US_DOT = 84,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '/?' key
*/
US_SLASH = 85,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '`~' key
*/
US_BACKTICK = 86,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '[{' key
*/
US_OPEN_SQUARE_BRACKET = 87,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '\|' key
*/
US_BACKSLASH = 88,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ']}' key
*/
US_CLOSE_SQUARE_BRACKET = 89,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ''"' key
*/
US_QUOTE = 90,
/**
* Used for miscellaneous characters; it can vary by keyboard.
*/
OEM_8 = 91,
/**
* Either the angle bracket key or the backslash key on the RT 102-key keyboard.
*/
OEM_102 = 92,
NUMPAD_0 = 93,
NUMPAD_1 = 94,
NUMPAD_2 = 95,
NUMPAD_3 = 96,
NUMPAD_4 = 97,
NUMPAD_5 = 98,
NUMPAD_6 = 99,
NUMPAD_7 = 100,
NUMPAD_8 = 101,
NUMPAD_9 = 102,
NUMPAD_MULTIPLY = 103,
NUMPAD_ADD = 104,
NUMPAD_SEPARATOR = 105,
NUMPAD_SUBTRACT = 106,
NUMPAD_DECIMAL = 107,
NUMPAD_DIVIDE = 108,
/**
* Placed last to cover the length of the enum.
* Please do not depend on this value!
*/
MAX_VALUE
}
export function createMonacoBaseAPI(): typeof monaco {
return {
editor: undefined,

View file

@ -9,15 +9,16 @@ import {Arrays} from 'vs/editor/common/core/arrays';
import {Range} from 'vs/editor/common/core/range';
import {ViewLineToken, ViewLineTokens} from 'vs/editor/common/core/viewLineToken';
import {InlineDecoration} from 'vs/editor/common/viewModel/viewModel';
import {CharCode} from 'vs/base/common/charCode';
function cmpLineDecorations(a:InlineDecoration, b:InlineDecoration): number {
return Range.compareRangesUsingStarts(a.range, b.range);
}
export function createLineParts(lineNumber:number, minLineColumn:number, lineContent:string, tabSize:number, lineTokens:ViewLineTokens, rawLineDecorations:InlineDecoration[], renderWhitespace:boolean): LineParts {
if (renderWhitespace) {
export function createLineParts(lineNumber:number, minLineColumn:number, lineContent:string, tabSize:number, lineTokens:ViewLineTokens, rawLineDecorations:InlineDecoration[], renderWhitespace:'none' | 'boundary' | 'all'): LineParts {
if (renderWhitespace !== 'none') {
let oldLength = rawLineDecorations.length;
rawLineDecorations = insertWhitespaceLineDecorations(lineNumber, lineContent, tabSize, lineTokens.getFauxIndentLength(), rawLineDecorations);
rawLineDecorations = insertWhitespaceLineDecorations(lineNumber, lineContent, tabSize, lineTokens.getFauxIndentLength(), renderWhitespace, rawLineDecorations);
if (rawLineDecorations.length !== oldLength) {
rawLineDecorations.sort(cmpLineDecorations);
}
@ -93,27 +94,16 @@ function trimEmptyTrailingPart(parts: ViewLineToken[], lineContent: string): Vie
return parts.slice(0, parts.length - 1);
}
const _tab = '\t'.charCodeAt(0);
const _space = ' '.charCodeAt(0);
function insertOneCustomLineDecoration(dest:InlineDecoration[], lineNumber:number, startColumn:number, endColumn:number, className:string): void {
dest.push(new InlineDecoration(new Range(lineNumber, startColumn, lineNumber, endColumn), className));
}
function insertWhitespaceLineDecorations(lineNumber:number, lineContent: string, tabSize:number, fauxIndentLength: number, rawLineDecorations: InlineDecoration[]): InlineDecoration[] {
function insertWhitespaceLineDecorations(lineNumber:number, lineContent: string, tabSize:number, fauxIndentLength: number, renderWhitespace: 'none' | 'boundary' | 'all', rawLineDecorations: InlineDecoration[]): InlineDecoration[] {
let lineLength = lineContent.length;
if (lineLength === fauxIndentLength) {
return rawLineDecorations;
}
let firstChar = lineContent.charCodeAt(fauxIndentLength);
let lastChar = lineContent.charCodeAt(lineLength - 1);
if (firstChar !== _tab && firstChar !== _space && lastChar !== _tab && lastChar !== _space) {
// This line contains no leading nor trailing whitespace => fast path
return rawLineDecorations;
}
let firstNonWhitespaceIndex = strings.firstNonWhitespaceIndex(lineContent);
let lastNonWhitespaceIndex: number;
if (firstNonWhitespaceIndex === -1) {
@ -138,6 +128,33 @@ function insertWhitespaceLineDecorations(lineNumber:number, lineContent: string,
sm_decoration.push('leading whitespace');
}
let startOfWhitespace = -1;
let hasTab = false;
for (let i = Math.max(firstNonWhitespaceIndex, fauxIndentLength); i <= lastNonWhitespaceIndex; ++i) {
let currentCharIsTab = lineContent.charCodeAt(i) === CharCode.Tab;
if (currentCharIsTab || lineContent.charCodeAt(i) === CharCode.Space) {
if (currentCharIsTab) {
hasTab = true;
}
if (startOfWhitespace === -1) {
startOfWhitespace = i;
}
} else if (startOfWhitespace !== -1) {
if (renderWhitespace === 'all' || renderWhitespace === 'boundary' && (hasTab || i - startOfWhitespace >= 2)) {
sm_endIndex.push(startOfWhitespace - 1);
sm_decoration.push(null);
sm_endIndex.push(i - 1);
sm_decoration.push('embedded whitespace');
}
startOfWhitespace = -1;
hasTab = false;
}
}
// add content state
sm_endIndex.push(lastNonWhitespaceIndex);
sm_decoration.push(null);
@ -166,7 +183,7 @@ function insertCustomLineDecorationsWithStateMachine(lineNumber:number, lineCont
for (let index = 0; index < lineLength; index++) {
let chCode = lineContent.charCodeAt(index);
if (chCode === _tab) {
if (chCode === CharCode.Tab) {
tmpIndent = tabSize;
} else {
tmpIndent++;

View file

@ -5,6 +5,7 @@
'use strict';
import {ViewLineToken} from 'vs/editor/common/core/viewLineToken';
import {CharCode} from 'vs/base/common/charCode';
export class RenderLineInput {
_renderLineInputBrand: void;
@ -13,7 +14,7 @@ export class RenderLineInput {
tabSize: number;
spaceWidth: number;
stopRenderingLineAfter: number;
renderWhitespace: boolean;
renderWhitespace: 'none' | 'boundary' | 'all';
renderControlCharacters: boolean;
parts: ViewLineToken[];
@ -22,7 +23,7 @@ export class RenderLineInput {
tabSize: number,
spaceWidth: number,
stopRenderingLineAfter: number,
renderWhitespace: boolean,
renderWhitespace: 'none' | 'boundary' | 'all',
renderControlCharacters: boolean,
parts: ViewLineToken[]
) {
@ -49,16 +50,6 @@ export class RenderLineOutput {
}
}
const _space = ' '.charCodeAt(0);
const _tab = '\t'.charCodeAt(0);
const _lowerThan = '<'.charCodeAt(0);
const _greaterThan = '>'.charCodeAt(0);
const _ampersand = '&'.charCodeAt(0);
const _carriageReturn = '\r'.charCodeAt(0);
const _controlCharacterSequenceConversionStart = 9216;
const _lineSeparator = '\u2028'.charCodeAt(0); //http://www.fileformat.info/info/unicode/char/2028/index.htm
const _bom = 65279;
export function renderLine(input:RenderLineInput): RenderLineOutput {
const lineText = input.lineContent;
const lineTextLength = lineText.length;
@ -92,11 +83,13 @@ function isWhitespace(type:string): boolean {
function isControlCharacter(characterCode: number): boolean {
return characterCode < 32;
}
const _controlCharacterSequenceConversionStart = 9216;
function controlCharacterToPrintable(characterCode: number): string {
return String.fromCharCode(_controlCharacterSequenceConversionStart + characterCode);
}
function renderLineActual(lineText: string, lineTextLength: number, tabSize: number, spaceWidth: number, actualLineParts: ViewLineToken[], renderWhitespace: boolean, renderControlCharacters: boolean, charBreakIndex: number): RenderLineOutput {
function renderLineActual(lineText: string, lineTextLength: number, tabSize: number, spaceWidth: number, actualLineParts: ViewLineToken[], renderWhitespace: 'none' | 'boundary' | 'all', renderControlCharacters: boolean, charBreakIndex: number): RenderLineOutput {
lineTextLength = +lineTextLength;
tabSize = +tabSize;
charBreakIndex = +charBreakIndex;
@ -111,7 +104,7 @@ function renderLineActual(lineText: string, lineTextLength: number, tabSize: num
for (let partIndex = 0, partIndexLen = actualLineParts.length; partIndex < partIndexLen; partIndex++) {
let part = actualLineParts[partIndex];
let parsRendersWhitespace = (renderWhitespace && isWhitespace(part.type));
let parsRendersWhitespace = (renderWhitespace !== 'none' && isWhitespace(part.type));
let toCharIndex = lineTextLength;
if (partIndex + 1 < partIndexLen) {
@ -128,7 +121,7 @@ function renderLineActual(lineText: string, lineTextLength: number, tabSize: num
charOffsetInPartArr[charIndex] = charOffsetInPart;
let charCode = lineText.charCodeAt(charIndex);
if (charCode === _tab) {
if (charCode === CharCode.Tab) {
let insertSpacesCount = tabSize - (charIndex + tabsCharDelta) % tabSize;
tabsCharDelta += insertSpacesCount - 1;
charOffsetInPart += insertSpacesCount - 1;
@ -143,7 +136,7 @@ function renderLineActual(lineText: string, lineTextLength: number, tabSize: num
insertSpacesCount--;
}
} else {
// must be _space
// must be CharCode.Space
partContent += '&middot;';
partContentCnt++;
}
@ -175,7 +168,7 @@ function renderLineActual(lineText: string, lineTextLength: number, tabSize: num
let charCode = lineText.charCodeAt(charIndex);
switch (charCode) {
case _tab:
case CharCode.Tab:
let insertSpacesCount = tabSize - (charIndex + tabsCharDelta) % tabSize;
tabsCharDelta += insertSpacesCount - 1;
charOffsetInPart += insertSpacesCount - 1;
@ -185,40 +178,39 @@ function renderLineActual(lineText: string, lineTextLength: number, tabSize: num
}
break;
case _space:
case CharCode.Space:
out += '&nbsp;';
break;
case _lowerThan:
case CharCode.LessThan:
out += '&lt;';
break;
case _greaterThan:
case CharCode.GreaterThan:
out += '&gt;';
break;
case _ampersand:
case CharCode.Ampersand:
out += '&amp;';
break;
case 0:
case CharCode.Null:
out += '&#00;';
break;
case _bom:
case _lineSeparator:
case CharCode.UTF8_BOM:
case CharCode.LINE_SEPARATOR_2028:
out += '\ufffd';
break;
case _carriageReturn:
case CharCode.CarriageReturn:
// zero width space, because carriage return would introduce a line break
out += '&#8203';
break;
default:
let characterCode = lineText.charCodeAt(charIndex);
if (renderControlCharacters && isControlCharacter(characterCode)) {
out += controlCharacterToPrintable(characterCode);
if (renderControlCharacters && isControlCharacter(charCode)) {
out += controlCharacterToPrintable(charCode);
} else {
out += lineText.charAt(charIndex);
}

View file

@ -8,8 +8,10 @@ import * as strings from 'vs/base/common/strings';
import {WrappingIndent} from 'vs/editor/common/editorCommon';
import {PrefixSumComputer} from 'vs/editor/common/viewModel/prefixSumComputer';
import {ILineMapperFactory, ILineMapping, OutputPosition} from 'vs/editor/common/viewModel/splitLinesCollection';
import {CharCode} from 'vs/base/common/charCode';
import {CharacterClassifier} from 'vs/editor/common/core/characterClassifier';
enum CharacterClass {
const enum CharacterClass {
NONE = 0,
BREAK_BEFORE = 1,
BREAK_AFTER = 2,
@ -17,57 +19,25 @@ enum CharacterClass {
BREAK_IDEOGRAPHIC = 4 // for Han and Kana.
}
class CharacterClassifier {
/**
* Maintain a compact (fully initialized ASCII map for quickly classifying ASCII characters - used more often in code).
*/
private _asciiMap: CharacterClass[];
/**
* The entire map (sparse array).
*/
private _map: CharacterClass[];
class WrappingCharacterClassifier extends CharacterClassifier<CharacterClass> {
constructor(BREAK_BEFORE:string, BREAK_AFTER:string, BREAK_OBTRUSIVE:string) {
this._asciiMap = [];
for (let i = 0; i < 256; i++) {
this._asciiMap[i] = CharacterClass.NONE;
}
this._map = [];
super(CharacterClass.NONE);
for (let i = 0; i < BREAK_BEFORE.length; i++) {
this._set(BREAK_BEFORE.charCodeAt(i), CharacterClass.BREAK_BEFORE);
this.set(BREAK_BEFORE.charCodeAt(i), CharacterClass.BREAK_BEFORE);
}
for (let i = 0; i < BREAK_AFTER.length; i++) {
this._set(BREAK_AFTER.charCodeAt(i), CharacterClass.BREAK_AFTER);
this.set(BREAK_AFTER.charCodeAt(i), CharacterClass.BREAK_AFTER);
}
for (let i = 0; i < BREAK_OBTRUSIVE.length; i++) {
this._set(BREAK_OBTRUSIVE.charCodeAt(i), CharacterClass.BREAK_OBTRUSIVE);
this.set(BREAK_OBTRUSIVE.charCodeAt(i), CharacterClass.BREAK_OBTRUSIVE);
}
}
private _set(charCode:number, charClass:CharacterClass): void {
if (charCode < 256) {
this._asciiMap[charCode] = charClass;
}
this._map[charCode] = charClass;
}
public classify(charCode:number): CharacterClass {
if (charCode < 256) {
return this._asciiMap[charCode];
}
let charClass = this._map[charCode];
if (charClass) {
return charClass;
}
public get(charCode:number): CharacterClass {
// Initialize CharacterClass.BREAK_IDEOGRAPHIC for these Unicode ranges:
// 1. CJK Unified Ideographs (0x4E00 -- 0x9FFF)
// 2. CJK Unified Ideographs Extension A (0x3400 -- 0x4DBF)
@ -80,16 +50,16 @@ class CharacterClassifier {
return CharacterClass.BREAK_IDEOGRAPHIC;
}
return CharacterClass.NONE;
return super.get(charCode);
}
}
export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactory {
private classifier:CharacterClassifier;
private classifier:WrappingCharacterClassifier;
constructor(breakBeforeChars:string, breakAfterChars:string, breakObtrusiveChars:string) {
this.classifier = new CharacterClassifier(breakBeforeChars, breakAfterChars, breakObtrusiveChars);
this.classifier = new WrappingCharacterClassifier(breakBeforeChars, breakAfterChars, breakObtrusiveChars);
}
// TODO@Alex -> duplicated in lineCommentCommand
@ -116,7 +86,6 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor
let wrappedTextIndentVisibleColumn = 0;
let wrappedTextIndent = '';
const TAB_CHAR_CODE = '\t'.charCodeAt(0);
let firstNonWhitespaceIndex = -1;
if (hardWrappingIndent !== WrappingIndent.None) {
@ -124,7 +93,7 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor
if (firstNonWhitespaceIndex !== -1) {
wrappedTextIndent = lineText.substring(0, firstNonWhitespaceIndex);
for (let i = 0; i < firstNonWhitespaceIndex; i++) {
wrappedTextIndentVisibleColumn = CharacterHardWrappingLineMapperFactory.nextVisibleColumn(wrappedTextIndentVisibleColumn, tabSize, lineText.charCodeAt(i) === TAB_CHAR_CODE, 1);
wrappedTextIndentVisibleColumn = CharacterHardWrappingLineMapperFactory.nextVisibleColumn(wrappedTextIndentVisibleColumn, tabSize, lineText.charCodeAt(i) === CharCode.Tab, 1);
}
if (hardWrappingIndent === WrappingIndent.Indent) {
wrappedTextIndent += '\t';
@ -156,8 +125,8 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor
// but the character at `i` might not fit
let charCode = lineText.charCodeAt(i);
let charCodeIsTab = (charCode === TAB_CHAR_CODE);
let charCodeClass = classifier.classify(charCode);
let charCodeIsTab = (charCode === CharCode.Tab);
let charCodeClass = classifier.get(charCode);
if (charCodeClass === CharacterClass.BREAK_BEFORE) {
// This is a character that indicates that a break should happen before it
@ -170,7 +139,7 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor
// CJK breaking : before break
if (charCodeClass === CharacterClass.BREAK_IDEOGRAPHIC && i > 0) {
let prevCode = lineText.charCodeAt(i - 1);
let prevClass = classifier.classify(prevCode);
let prevClass = classifier.get(prevCode);
if (prevClass !== CharacterClass.BREAK_BEFORE) { // Kinsoku Shori: Don't break after a leading character, like an open bracket
niceBreakOffset = i;
niceBreakVisibleColumn = 0;
@ -245,7 +214,7 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor
// CJK breaking : after break
if (charCodeClass === CharacterClass.BREAK_IDEOGRAPHIC && i < len - 1) {
let nextCode = lineText.charCodeAt(i + 1);
let nextClass = classifier.classify(nextCode);
let nextClass = classifier.get(nextCode);
if (nextClass !== CharacterClass.BREAK_AFTER) { // Kinsoku Shori: Don't break before a trailing character, like a period
niceBreakOffset = i + 1;
niceBreakVisibleColumn = wrappedTextIndentVisibleColumn;

View file

@ -5,7 +5,7 @@
'use strict';
import * as nls from 'vs/nls';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
import {KeyCode, KeyMod, KeyChord} from 'vs/base/common/keyCodes';
import {ICommand, ICommonCodeEditor, EditorContextKeys} from 'vs/editor/common/editorCommon';
import {editorAction, IActionOptions, EditorAction, ServicesAccessor} from 'vs/editor/common/editorCommonExtensions';
import {BlockCommentCommand} from './blockCommentCommand';
@ -65,7 +65,7 @@ class AddLineCommentAction extends CommentLineAction {
precondition: EditorContextKeys.Writable,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_C)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_C)
}
});
}
@ -81,7 +81,7 @@ class RemoveLineCommentAction extends CommentLineAction {
precondition: EditorContextKeys.Writable,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_U)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_U)
}
});
}

View file

@ -13,6 +13,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
import {ICommentsConfiguration} from 'vs/editor/common/modes';
import {BlockCommentCommand} from './blockCommentCommand';
import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry';
import {CharCode} from 'vs/base/common/charCode';
export interface IInsertionPoint {
ignore: boolean;
@ -36,7 +37,7 @@ export interface ISimpleModel {
getLineContent(lineNumber:number): string;
}
export enum Type {
export const enum Type {
Toggle = 0,
ForceAdd = 1,
ForceRemove = 2
@ -114,7 +115,6 @@ export class LineCommentCommand implements editorCommon.ICommand {
lineNumber:number,
shouldRemoveComments:boolean,
lineContent: string,
_space = ' '.charCodeAt(0),
onlyWhitespaceLines = true;
if (type === Type.Toggle) {
@ -162,7 +162,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
if (shouldRemoveComments) {
commentStrEndOffset = lineContentStartOffset + lineData.commentStrLength;
if (commentStrEndOffset < lineContent.length && lineContent.charCodeAt(commentStrEndOffset) === _space) {
if (commentStrEndOffset < lineContent.length && lineContent.charCodeAt(commentStrEndOffset) === CharCode.Space) {
lineData.commentStrLength += 1;
}
}
@ -414,8 +414,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
lineContent: string,
j: number,
lenJ: number,
currentVisibleColumn: number,
_tab = '\t'.charCodeAt(0);
currentVisibleColumn: number;
for (i = 0, len = lines.length; i < len; i++) {
if (lines[i].ignore) {
@ -426,7 +425,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
currentVisibleColumn = 0;
for (j = 0, lenJ = lines[i].commentStrOffset; currentVisibleColumn < minVisibleColumn && j < lenJ; j++) {
currentVisibleColumn = LineCommentCommand.nextVisibleColumn(currentVisibleColumn, tabSize, lineContent.charCodeAt(j) === _tab, 1);
currentVisibleColumn = LineCommentCommand.nextVisibleColumn(currentVisibleColumn, tabSize, lineContent.charCodeAt(j) === CharCode.Tab, 1);
}
if (currentVisibleColumn < minVisibleColumn) {
@ -445,7 +444,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
currentVisibleColumn = 0;
for (j = 0, lenJ = lines[i].commentStrOffset; currentVisibleColumn < minVisibleColumn && j < lenJ; j++) {
currentVisibleColumn = LineCommentCommand.nextVisibleColumn(currentVisibleColumn, tabSize, lineContent.charCodeAt(j) === _tab, 1);
currentVisibleColumn = LineCommentCommand.nextVisibleColumn(currentVisibleColumn, tabSize, lineContent.charCodeAt(j) === CharCode.Tab, 1);
}
if (currentVisibleColumn > minVisibleColumn) {

View file

@ -9,7 +9,7 @@ import 'vs/css!./defineKeybinding';
import * as nls from 'vs/nls';
import {RunOnceScheduler} from 'vs/base/common/async';
import {MarkedString} from 'vs/base/common/htmlContent';
import {CommonKeybindings, KeyCode, KeyMod, Keybinding} from 'vs/base/common/keyCodes';
import {KeyCode, KeyMod, KeyChord, Keybinding} from 'vs/base/common/keyCodes';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import * as dom from 'vs/base/browser/dom';
import {renderHtml} from 'vs/base/browser/htmlContentRenderer';
@ -353,14 +353,14 @@ class DefineKeybindingWidget implements IOverlayWidget {
let kb = new Keybinding(keyEvent.asKeybinding());
switch (kb.value) {
case CommonKeybindings.ENTER:
case KeyCode.Enter:
if (this._lastKeybinding) {
this._onAccepted(this._lastKeybinding.toUserSettingsLabel());
}
this._stop();
return;
case CommonKeybindings.ESCAPE:
case KeyCode.Escape:
this._stop();
return;
}
@ -461,7 +461,7 @@ export class DefineKeybindingAction extends EditorAction {
precondition: ContextKeyExpr.and(EditorContextKeys.Writable, EditorContextKeys.LanguageId.isEqualTo('json')),
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_K)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_K)
}
});
}

View file

@ -8,7 +8,7 @@
import 'vs/css!./findWidget';
import * as nls from 'vs/nls';
import {onUnexpectedError} from 'vs/base/common/errors';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
import * as strings from 'vs/base/common/strings';
import * as dom from 'vs/base/browser/dom';
import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
@ -318,17 +318,17 @@ export class FindWidget extends Widget implements IOverlayWidget {
private _onFindInputKeyDown(e:IKeyboardEvent): void {
switch (e.asKeybinding()) {
case CommonKeybindings.ENTER:
case KeyCode.Enter:
this._codeEditor.getAction(FIND_IDS.NextMatchFindAction).run().done(null, onUnexpectedError);
e.preventDefault();
return;
case CommonKeybindings.SHIFT_ENTER:
case KeyMod.Shift | KeyCode.Enter:
this._codeEditor.getAction(FIND_IDS.PreviousMatchFindAction).run().done(null, onUnexpectedError);
e.preventDefault();
return;
case CommonKeybindings.TAB:
case KeyCode.Tab:
if (this._isReplaceVisible) {
this._replaceInputBox.focus();
} else {
@ -337,7 +337,7 @@ export class FindWidget extends Widget implements IOverlayWidget {
e.preventDefault();
return;
case CommonKeybindings.CTRLCMD_DOWN_ARROW:
case KeyMod.CtrlCmd | KeyCode.DownArrow:
this._codeEditor.focus();
e.preventDefault();
return;
@ -347,27 +347,27 @@ export class FindWidget extends Widget implements IOverlayWidget {
private _onReplaceInputKeyDown(e:IKeyboardEvent): void {
switch (e.asKeybinding()) {
case CommonKeybindings.ENTER:
case KeyCode.Enter:
this._controller.replace();
e.preventDefault();
return;
case CommonKeybindings.CTRLCMD_ENTER:
case KeyMod.CtrlCmd | KeyCode.Enter:
this._controller.replaceAll();
e.preventDefault();
return;
case CommonKeybindings.TAB:
case KeyCode.Tab:
this._findInput.focusOnCaseSensitive();
e.preventDefault();
return;
case CommonKeybindings.SHIFT_TAB:
case KeyMod.Shift | KeyCode.Tab:
this._findInput.focus();
e.preventDefault();
return;
case CommonKeybindings.CTRLCMD_DOWN_ARROW:
case KeyMod.CtrlCmd | KeyCode.DownArrow:
this._codeEditor.focus();
e.preventDefault();
return;
@ -422,7 +422,7 @@ export class FindWidget extends Widget implements IOverlayWidget {
}, true);
}));
this._register(this._findInput.onCaseSensitiveKeyDown((e) => {
if (e.equals(CommonKeybindings.SHIFT_TAB)) {
if (e.equals(KeyMod.Shift | KeyCode.Tab)) {
if (this._isReplaceVisible) {
this._replaceInputBox.focus();
e.preventDefault();
@ -485,7 +485,7 @@ export class FindWidget extends Widget implements IOverlayWidget {
this._state.change({ isRevealed: false }, false);
},
onKeyDown: (e) => {
if (e.equals(CommonKeybindings.TAB)) {
if (e.equals(KeyCode.Tab)) {
if (this._isReplaceVisible) {
if (this._replaceBtn.isEnabled()) {
this._replaceBtn.focus();
@ -526,7 +526,7 @@ export class FindWidget extends Widget implements IOverlayWidget {
this._controller.replace();
},
onKeyDown: (e) => {
if (e.equals(CommonKeybindings.SHIFT_TAB)) {
if (e.equals(KeyMod.Shift | KeyCode.Tab)) {
this._closeBtn.focus();
e.preventDefault();
}
@ -687,7 +687,7 @@ class SimpleButton extends Widget {
e.preventDefault();
});
this.onkeydown(this._domNode, (e) => {
if (e.equals(CommonKeybindings.SPACE) || e.equals(CommonKeybindings.ENTER)) {
if (e.equals(KeyCode.Space) || e.equals(KeyCode.Enter)) {
this._opts.onTrigger();
e.preventDefault();
return;

View file

@ -5,7 +5,8 @@
'use strict';
import * as nls from 'vs/nls';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
import {HistoryNavigator} from 'vs/base/common/history';
import {KeyCode, KeyMod, KeyChord} from 'vs/base/common/keyCodes';
import {Disposable} from 'vs/base/common/lifecycle';
import {ContextKeyExpr, RawContextKey, IContextKey, IContextKeyService} from 'vs/platform/contextkey/common/contextkey';
import {Range} from 'vs/editor/common/core/range';
@ -16,21 +17,21 @@ import {editorAction, commonEditorContribution, ServicesAccessor, EditorAction,
import {FIND_IDS, FindModelBoundToEditorModel} from 'vs/editor/contrib/find/common/findModel';
import {FindReplaceState, FindReplaceStateChangedEvent, INewFindReplaceState} from 'vs/editor/contrib/find/common/findState';
import {DocumentHighlightProviderRegistry} from 'vs/editor/common/modes';
import {RunOnceScheduler} from 'vs/base/common/async';
import {RunOnceScheduler, Delayer} from 'vs/base/common/async';
import EditorContextKeys = editorCommon.EditorContextKeys;
export enum FindStartFocusAction {
export const enum FindStartFocusAction {
NoFocusChange,
FocusFindInput,
FocusReplaceInput
}
export interface IFindStartOptions {
forceRevealReplace:boolean;
seedSearchStringFromSelection:boolean;
shouldFocus:FindStartFocusAction;
shouldAnimate:boolean;
forceRevealReplace: boolean;
seedSearchStringFromSelection: boolean;
shouldFocus: FindStartFocusAction;
shouldAnimate: boolean;
}
export const CONTEXT_FIND_WIDGET_VISIBLE = new RawContextKey<boolean>('findWidgetVisible', false);
@ -43,17 +44,21 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
private _editor: editorCommon.ICommonCodeEditor;
private _findWidgetVisible: IContextKey<boolean>;
protected _state: FindReplaceState;
private _currentHistoryNavigator: HistoryNavigator<string>;
private _updateHistoryDelayer: Delayer<void>;
private _model: FindModelBoundToEditorModel;
public static get(editor:editorCommon.ICommonCodeEditor): CommonFindController {
public static get(editor: editorCommon.ICommonCodeEditor): CommonFindController {
return editor.getContribution<CommonFindController>(CommonFindController.ID);
}
constructor(editor:editorCommon.ICommonCodeEditor, @IContextKeyService contextKeyService: IContextKeyService) {
constructor(editor: editorCommon.ICommonCodeEditor, @IContextKeyService contextKeyService: IContextKeyService) {
super();
this._editor = editor;
this._findWidgetVisible = CONTEXT_FIND_WIDGET_VISIBLE.bindTo(contextKeyService);
this._updateHistoryDelayer = new Delayer<void>(500);
this._currentHistoryNavigator = new HistoryNavigator<string>();
this._state = this._register(new FindReplaceState());
this._register(this._state.addChangeListener((e) => this._onStateChanged(e)));
@ -95,7 +100,10 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
return CommonFindController.ID;
}
private _onStateChanged(e:FindReplaceStateChangedEvent): void {
private _onStateChanged(e: FindReplaceStateChangedEvent): void {
if (e.updateHistory && e.searchString) {
this._delayedUpdateHistory();
}
if (e.isRevealed) {
if (this._state.isRevealed) {
this._findWidgetVisible.set(true);
@ -106,10 +114,24 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
}
}
protected _delayedUpdateHistory() {
this._updateHistoryDelayer.trigger(this._updateHistory.bind(this));
}
protected _updateHistory() {
if (this._state.searchString) {
this._currentHistoryNavigator.add(this._state.searchString);
}
}
public getState(): FindReplaceState {
return this._state;
}
public getHistory(): HistoryNavigator<string> {
return this._currentHistoryNavigator;
}
public closeFindWidget(): void {
this._state.change({
isRevealed: false,
@ -130,7 +152,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
this._state.change({ isRegex: !this._state.isRegex }, false);
}
public setSearchString(searchString:string): void {
public setSearchString(searchString: string): void {
this._state.change({ searchString: searchString }, false);
}
@ -151,7 +173,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
return null;
}
protected _start(opts:IFindStartOptions): void {
protected _start(opts: IFindStartOptions): void {
this.disposeModel();
if (!this._editor.getModel()) {
@ -187,7 +209,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
}
}
public start(opts:IFindStartOptions): void {
public start(opts: IFindStartOptions): void {
this._start(opts);
}
@ -231,6 +253,22 @@ export class CommonFindController extends Disposable implements editorCommon.IEd
}
return false;
}
public showPreviousFindTerm(): boolean {
let previousTerm = this._currentHistoryNavigator.previous();
if (previousTerm) {
this._state.change({ searchString: previousTerm }, false, false);
}
return true;
}
public showNextFindTerm(): boolean {
let nextTerm = this._currentHistoryNavigator.next();
if (nextTerm) {
this._state.change({ searchString: nextTerm }, false, false);
}
return true;
}
}
@editorAction
@ -239,7 +277,7 @@ export class StartFindAction extends EditorAction {
constructor() {
super({
id: FIND_IDS.StartFindAction,
label: nls.localize('startFindAction',"Find"),
label: nls.localize('startFindAction', "Find"),
alias: 'Find',
precondition: null,
kbOpts: {
@ -253,7 +291,7 @@ export class StartFindAction extends EditorAction {
});
}
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
let controller = CommonFindController.get(editor);
if (controller) {
controller.start({
@ -267,7 +305,7 @@ export class StartFindAction extends EditorAction {
}
export abstract class MatchFindAction extends EditorAction {
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
let controller = CommonFindController.get(editor);
if (controller && !this._run(controller)) {
controller.start({
@ -280,7 +318,7 @@ export abstract class MatchFindAction extends EditorAction {
}
}
protected abstract _run(controller:CommonFindController): boolean;
protected abstract _run(controller: CommonFindController): boolean;
}
@editorAction
@ -300,7 +338,7 @@ export class NextMatchFindAction extends MatchFindAction {
});
}
protected _run(controller:CommonFindController): boolean {
protected _run(controller: CommonFindController): boolean {
return controller.moveToNextMatch();
}
}
@ -322,13 +360,13 @@ export class PreviousMatchFindAction extends MatchFindAction {
});
}
protected _run(controller:CommonFindController): boolean {
protected _run(controller: CommonFindController): boolean {
return controller.moveToPrevMatch();
}
}
export abstract class SelectionMatchFindAction extends EditorAction {
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
let controller = CommonFindController.get(editor);
if (!controller) {
return;
@ -348,7 +386,7 @@ export abstract class SelectionMatchFindAction extends EditorAction {
}
}
protected abstract _run(controller:CommonFindController): boolean;
protected abstract _run(controller: CommonFindController): boolean;
}
@editorAction
@ -367,7 +405,7 @@ export class NextSelectionMatchFindAction extends SelectionMatchFindAction {
});
}
protected _run(controller:CommonFindController): boolean {
protected _run(controller: CommonFindController): boolean {
return controller.moveToNextMatch();
}
}
@ -388,7 +426,7 @@ export class PreviousSelectionMatchFindAction extends SelectionMatchFindAction {
});
}
protected _run(controller:CommonFindController): boolean {
protected _run(controller: CommonFindController): boolean {
return controller.moveToPrevMatch();
}
}
@ -410,7 +448,7 @@ export class StartFindReplaceAction extends EditorAction {
});
}
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
if (editor.getConfiguration().readOnly) {
return;
}
@ -428,14 +466,14 @@ export class StartFindReplaceAction extends EditorAction {
}
export interface IMultiCursorFindResult {
searchText:string;
matchCase:boolean;
wholeWord:boolean;
searchText: string;
matchCase: boolean;
wholeWord: boolean;
currentMatch: Selection;
}
function multiCursorFind(editor:editorCommon.ICommonCodeEditor, changeFindSearchString:boolean): IMultiCursorFindResult {
function multiCursorFind(editor: editorCommon.ICommonCodeEditor, changeFindSearchString: boolean): IMultiCursorFindResult {
let controller = CommonFindController.get(editor);
if (!controller) {
return null;
@ -489,7 +527,7 @@ function multiCursorFind(editor:editorCommon.ICommonCodeEditor, changeFindSearch
}
export abstract class SelectNextFindMatchAction extends EditorAction {
protected _getNextMatch(editor:editorCommon.ICommonCodeEditor): Selection {
protected _getNextMatch(editor: editorCommon.ICommonCodeEditor): Selection {
let r = multiCursorFind(editor, true);
if (!r) {
return null;
@ -512,7 +550,7 @@ export abstract class SelectNextFindMatchAction extends EditorAction {
}
export abstract class SelectPreviousFindMatchAction extends EditorAction {
protected _getPreviousMatch(editor:editorCommon.ICommonCodeEditor): Selection {
protected _getPreviousMatch(editor: editorCommon.ICommonCodeEditor): Selection {
let r = multiCursorFind(editor, true);
if (!r) {
return null;
@ -550,7 +588,7 @@ export class AddSelectionToNextFindMatchAction extends SelectNextFindMatchAction
});
}
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
let nextMatch = this._getNextMatch(editor);
if (!nextMatch) {
@ -575,7 +613,7 @@ export class AddSelectionToPreviousFindMatchAction extends SelectPreviousFindMat
});
}
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
let previousMatch = this._getPreviousMatch(editor);
if (!previousMatch) {
@ -599,12 +637,12 @@ export class MoveSelectionToNextFindMatchAction extends SelectNextFindMatchActio
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.Focus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_D)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_D)
}
});
}
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
let nextMatch = this._getNextMatch(editor);
if (!nextMatch) {
@ -629,7 +667,7 @@ export class MoveSelectionToPreviousFindMatchAction extends SelectPreviousFindMa
});
}
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
let previousMatch = this._getPreviousMatch(editor);
if (!previousMatch) {
@ -643,7 +681,7 @@ export class MoveSelectionToPreviousFindMatchAction extends SelectPreviousFindMa
}
export abstract class AbstractSelectHighlightsAction extends EditorAction {
public run(accessor:ServicesAccessor, editor:editorCommon.ICommonCodeEditor): void {
public run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor): void {
let r = multiCursorFind(editor, true);
if (!r) {
return;
@ -713,7 +751,7 @@ export class SelectionHighlighter extends Disposable implements editorCommon.IEd
private updateSoon: RunOnceScheduler;
private lastWordUnderCursor: Range;
constructor(editor:editorCommon.ICommonCodeEditor) {
constructor(editor: editorCommon.ICommonCodeEditor) {
super();
this.editor = editor;
this.decorations = [];
@ -812,7 +850,7 @@ export class SelectionHighlighter extends Disposable implements editorCommon.IEd
// do not overlap with selection (issue #64 and #512)
let matches: Range[] = [];
for (let i = 0, j = 0, len = allMatches.length, lenJ = selections.length; i < len; ) {
for (let i = 0, j = 0, len = allMatches.length, lenJ = selections.length; i < len;) {
let match = allMatches[i];
if (j >= lenJ) {
@ -943,3 +981,25 @@ CommonEditorRegistry.registerEditorCommand(new FindCommand({
primary: KeyMod.Alt | KeyCode.Enter
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
id: FIND_IDS.ShowPreviousFindTermAction,
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
handler: x => x.showPreviousFindTerm(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
kbExpr: EditorContextKeys.Focus,
primary: KeyMod.Alt | KeyCode.UpArrow
}
}));
CommonEditorRegistry.registerEditorCommand(new FindCommand({
id: FIND_IDS.ShowNextFindTermAction,
precondition: CONTEXT_FIND_WIDGET_VISIBLE,
handler: x => x.showNextFindTerm(),
kbOpts: {
weight: CommonEditorRegistry.commandWeight(5),
kbExpr: EditorContextKeys.Focus,
primary: KeyMod.Alt | KeyCode.DownArrow
}
}));

View file

@ -34,7 +34,9 @@ export const FIND_IDS = {
ToggleRegexCommand: 'toggleFindRegex',
ReplaceOneAction: 'editor.action.replaceOne',
ReplaceAllAction: 'editor.action.replaceAll',
SelectAllMatchesAction: 'editor.action.selectAllMatches'
SelectAllMatchesAction: 'editor.action.selectAllMatches',
ShowPreviousFindTermAction: 'find.history.showPrevious',
ShowNextFindTermAction: 'find.history.showNext'
};
export const MATCHES_LIMIT = 999;

View file

@ -10,6 +10,7 @@ import {Range} from 'vs/editor/common/core/range';
export interface FindReplaceStateChangedEvent {
moveCursor: boolean;
updateHistory: boolean;
searchString: boolean;
replaceString: boolean;
@ -90,6 +91,7 @@ export class FindReplaceState implements IDisposable {
public changeMatchInfo(matchesPosition:number, matchesCount:number, currentMatch:Range): void {
let changeEvent:FindReplaceStateChangedEvent = {
moveCursor: false,
updateHistory: false,
searchString: false,
replaceString: false,
isRevealed: false,
@ -135,9 +137,10 @@ export class FindReplaceState implements IDisposable {
}
}
public change(newState:INewFindReplaceState, moveCursor:boolean): void {
public change(newState:INewFindReplaceState, moveCursor:boolean, updateHistory: boolean = true): void {
let changeEvent:FindReplaceStateChangedEvent = {
moveCursor: moveCursor,
updateHistory: updateHistory,
searchString: false,
replaceString: false,
isRevealed: false,

View file

@ -15,10 +15,12 @@ import {
NextMatchFindAction, StartFindAction, SelectHighlightsAction
} from 'vs/editor/contrib/find/common/findController';
import {withMockCodeEditor} from 'vs/editor/test/common/mocks/mockCodeEditor';
import {HistoryNavigator} from 'vs/base/common/history';
class TestFindController extends CommonFindController {
public hasFocus: boolean;
public delayUpdateHistory: boolean = false;
protected _start(opts:IFindStartOptions): void {
super._start(opts);
@ -27,6 +29,14 @@ class TestFindController extends CommonFindController {
this.hasFocus = true;
}
}
protected _delayedUpdateHistory() {
if (this.delayUpdateHistory) {
super._delayedUpdateHistory();
} else {
this._updateHistory();
}
}
}
suite('FindController', () => {
@ -196,4 +206,125 @@ suite('FindController', () => {
assert.equal(findController.getState().searchScope, null);
});
});
test('find term is added to history on state change', () => {
withMockCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], {}, (editor, cursor) => {
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
findController.getState().change({ searchString: '3' }, false);
assert.deepEqual(['1', '2', '3'], toArray(findController.getHistory()));
});
});
test('find term is added with delay', (done) => {
withMockCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], {}, (editor, cursor) => {
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.delayUpdateHistory = true;
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
findController.getState().change({ searchString: '3' }, false);
setTimeout(function() {
assert.deepEqual(['3'], toArray(findController.getHistory()));
done();
}, 500);
});
});
test('show previous find term', () => {
withMockCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], {}, (editor, cursor) => {
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
findController.getState().change({ searchString: '3' }, false);
findController.showPreviousFindTerm();
assert.deepEqual('2', findController.getState().searchString);
});
});
test('show previous find term do not update history', () => {
withMockCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], {}, (editor, cursor) => {
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
findController.getState().change({ searchString: '3' }, false);
findController.showPreviousFindTerm();
assert.deepEqual(['1', '2', '3'], toArray(findController.getHistory()));
});
});
test('show next find term', () => {
withMockCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], {}, (editor, cursor) => {
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
findController.getState().change({ searchString: '3' }, false);
findController.getState().change({ searchString: '4' }, false);
findController.showPreviousFindTerm();
findController.showPreviousFindTerm();
findController.showNextFindTerm();
assert.deepEqual('3', findController.getState().searchString);
});
});
test('show next find term do not update history', () => {
withMockCodeEditor([
'var x = (3 * 5)',
'var y = (3 * 5)',
'var z = (3 * 5)',
], {}, (editor, cursor) => {
let findController = editor.registerAndInstantiateContribution<TestFindController>(TestFindController);
findController.getState().change({ searchString: '1' }, false);
findController.getState().change({ searchString: '2' }, false);
findController.getState().change({ searchString: '3' }, false);
findController.getState().change({ searchString: '4' }, false);
findController.showPreviousFindTerm();
findController.showPreviousFindTerm();
findController.showNextFindTerm();
assert.deepEqual(['1', '2', '3', '4'], toArray(findController.getHistory()));
});
});
function toArray(historyNavigator: HistoryNavigator<string>): string[] {
let result = [];
historyNavigator.first();
if (historyNavigator.current()) {
do {
result.push(historyNavigator.current());
} while (historyNavigator.next());
}
return result;
}
});

View file

@ -9,7 +9,7 @@
import * as nls from 'vs/nls';
import * as types from 'vs/base/common/types';
import {RunOnceScheduler} from 'vs/base/common/async';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
import {KeyCode, KeyMod, KeyChord} from 'vs/base/common/keyCodes';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {TPromise} from 'vs/base/common/winjs.base';
import * as editorCommon from 'vs/editor/common/editorCommon';
@ -585,7 +585,7 @@ class UnFoldRecursivelyAction extends FoldingAction<void> {
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_CLOSE_SQUARE_BRACKET)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_CLOSE_SQUARE_BRACKET)
}
});
}
@ -641,7 +641,7 @@ class FoldRecursivelyAction extends FoldingAction<void> {
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_OPEN_SQUARE_BRACKET)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.US_OPEN_SQUARE_BRACKET)
}
});
}
@ -662,7 +662,7 @@ class FoldAllAction extends FoldingAction<void> {
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_0)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_0)
}
});
}
@ -683,7 +683,7 @@ class UnfoldAllAction extends FoldingAction<void> {
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_J)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_J)
}
});
}
@ -718,7 +718,7 @@ CommonEditorRegistry.registerEditorAction(
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_1)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_1)
}
})
);
@ -730,7 +730,7 @@ CommonEditorRegistry.registerEditorAction(
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_2)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_2)
}
})
);
@ -742,7 +742,7 @@ CommonEditorRegistry.registerEditorAction(
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_3)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_3)
}
})
);
@ -754,7 +754,7 @@ CommonEditorRegistry.registerEditorAction(
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_4)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_4)
}
})
);
@ -766,7 +766,7 @@ CommonEditorRegistry.registerEditorAction(
precondition: null,
kbOpts: {
kbExpr: EditorContextKeys.TextFocus,
primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_5)
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_5)
}
})
);

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