mirror of https://github.com/microsoft/vscode.git
Hello Code
This commit is contained in:
commit
8f35cc4768
|
@ -0,0 +1,13 @@
|
|||
.DS_Store
|
||||
npm-debug.log
|
||||
Thumbs.db
|
||||
node_modules/
|
||||
out/
|
||||
out-build/
|
||||
out-editor/
|
||||
out-editor-min/
|
||||
out-editor-ossfree/
|
||||
out-editor-ossfree-min/
|
||||
out-vscode/
|
||||
out-vscode-min/
|
||||
build/node_modules
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"version": "0.1.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Unit Tests",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "node_modules/mocha/bin/_mocha",
|
||||
"stopOnEntry": false,
|
||||
"args": [
|
||||
"--timeout",
|
||||
"999999",
|
||||
"--colors"
|
||||
],
|
||||
"cwd": ".",
|
||||
"runtimeExecutable": null,
|
||||
"runtimeArgs": [],
|
||||
"env": {},
|
||||
"sourceMaps": true,
|
||||
"outDir": "out"
|
||||
},
|
||||
{
|
||||
"name": "Attach to Extension Host",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 5870,
|
||||
"sourceMaps": true,
|
||||
"outDir": "out"
|
||||
},
|
||||
{
|
||||
"name": "VSCode API Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"${workspaceRoot}/extensions/vscode-api-tests/testWorkspace",
|
||||
"--extensionDevelopmentPath=${workspaceRoot}/extensions/vscode-api-tests",
|
||||
"--extensionTestsPath=${workspaceRoot}/extensions/vscode-api-tests/out"
|
||||
],
|
||||
"stopOnEntry": false,
|
||||
"sourceMaps": true,
|
||||
"outDir": "out"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"editor.insertSpaces": false,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"files.exclude": {
|
||||
".git": true,
|
||||
"**/.DS_Store": true,
|
||||
"**/coverage": true
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/node_modules/**": true,
|
||||
"**/bower_components": true,
|
||||
"out*/**": true,
|
||||
"extensions/**/out/**": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"version": "0.1.0",
|
||||
"command": "gulp",
|
||||
"isShellCommand": true,
|
||||
"tasks": [
|
||||
{
|
||||
"taskName": "watch",
|
||||
"args": [
|
||||
"--no-color"
|
||||
],
|
||||
"isBuildCommand": true,
|
||||
"isWatching": true,
|
||||
"problemMatcher": {
|
||||
"owner": "typescript",
|
||||
"fileLocation": ["absolute"],
|
||||
"pattern": {
|
||||
"regexp": "^\\*\\*\\* Error: ([^(]+)\\((\\d+|\\d+,\\d+|\\d+,\\d+,\\d+,\\d+)\\): (.*)$",
|
||||
"file": 1,
|
||||
"location": 2,
|
||||
"message": 3
|
||||
},
|
||||
"watching": {
|
||||
"beginsPattern": "^\\*\\*\\* Starting\\.\\.\\.$",
|
||||
"endsPattern": "^\\*\\*\\* Finished"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"taskName": "test",
|
||||
"args": [
|
||||
"--no-color"
|
||||
],
|
||||
"showOutput": "always",
|
||||
"isTestCommand": true
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
Copyright (c) Microsoft Corporation
|
||||
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,196 @@
|
|||
// Listing in here platform dependencies that come in at build time
|
||||
|
||||
[{
|
||||
"name": "atom-brightray",
|
||||
"repositoryURL": "https://github.com/atom/brightray",
|
||||
"license": "MIT",
|
||||
"isProd": true
|
||||
},
|
||||
{
|
||||
"name": "chromium",
|
||||
"version": "45.0.2454.85",
|
||||
"repositoryURL": "http://www.chromium.org/Home",
|
||||
"licenseDetail": [
|
||||
"BSD License",
|
||||
"",
|
||||
"Copyright 2014 The Chromium Authors. All rights reserved.",
|
||||
"",
|
||||
"Redistribution and use in source and binary forms, with or without modification,",
|
||||
"are permitted provided that the following conditions are met:",
|
||||
"",
|
||||
" * Redistributions of source code must retain the above copyright notice, this",
|
||||
" list of conditions and the following disclaimer.",
|
||||
"",
|
||||
" * Redistributions in binary form must reproduce the above copyright notice,",
|
||||
" this list of conditions and the following disclaimer in the documentation",
|
||||
" and/or other materials provided with the distribution.",
|
||||
"",
|
||||
" * Neither the name Google Inc. nor the names of its contributors may be used to",
|
||||
" endorse or promote products derived from this software without specific",
|
||||
" prior written permission.",
|
||||
"",
|
||||
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND",
|
||||
"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED",
|
||||
"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE",
|
||||
"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR",
|
||||
"ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES",
|
||||
"(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;",
|
||||
"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON",
|
||||
"ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT",
|
||||
"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS",
|
||||
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
],
|
||||
"isProd": true
|
||||
},
|
||||
{
|
||||
"name": "libchromiumcontent",
|
||||
"version": "45.0.2454.85 ",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/atom/libchromiumcontent",
|
||||
"isProd": true
|
||||
},
|
||||
{
|
||||
"name": "nodejs",
|
||||
"version": "4.1.1",
|
||||
"repositoryURL": "https://github.com/nodejs/node",
|
||||
"isProd": true
|
||||
},
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "0.34.1",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/atom/electron",
|
||||
"isProd": true
|
||||
},
|
||||
{
|
||||
"name": "inno setup",
|
||||
"version": "5.5.6",
|
||||
"repositoryURL": "https://github.com/jrsoftware/issrc",
|
||||
"isProd": true
|
||||
},
|
||||
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// The following definitions are here for the sole purpose of
|
||||
// defining licenses for dependencies where licensing cannot
|
||||
// be inferred by tooling:
|
||||
|
||||
{
|
||||
// Reason: LICENSE file missing in repo
|
||||
// SOURCE: https://github.com/isaacs/core-util-is/blob/master/lib/util.js
|
||||
"name":"core-util-is",
|
||||
"isLicense": true,
|
||||
"licenseDetail": [
|
||||
"Copyright Joyent, Inc. and other Node contributors.",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining a",
|
||||
"copy of this software and associated documentation files (the",
|
||||
"\"Software\"), to deal in the Software without restriction, including",
|
||||
"without limitation the rights to use, copy, modify, merge, publish,",
|
||||
"distribute, sublicense, and/or sell copies of the Software, and to permit",
|
||||
"persons to whom the Software is furnished to do so, subject to the",
|
||||
"following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be included",
|
||||
"in all copies or substantial portions of the Software.",
|
||||
"",
|
||||
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS",
|
||||
"OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
|
||||
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN",
|
||||
"NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,",
|
||||
"DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR",
|
||||
"OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE",
|
||||
"USE OR OTHER DEALINGS IN THE SOFTWARE."
|
||||
]
|
||||
},
|
||||
{
|
||||
// Reason: vscode-textmate is not public yet
|
||||
// TODO: Remove once vscode-textmate visibility is made public
|
||||
"name": "vscode-textmate",
|
||||
"isLicense": true,
|
||||
"licenseDetail": [
|
||||
"The MIT License (MIT)",
|
||||
"",
|
||||
"Copyright (c) Microsoft Corporation",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining a copy",
|
||||
"of this software and associated documentation files (the \"Software\"), to deal",
|
||||
"in the Software without restriction, including without limitation the rights",
|
||||
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
|
||||
"copies of the Software, and to permit persons to whom the Software is",
|
||||
"furnished to do so, subject to the following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be included in all",
|
||||
"copies or substantial portions of the Software.",
|
||||
"",
|
||||
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
|
||||
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
|
||||
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
|
||||
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
|
||||
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
|
||||
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
|
||||
"SOFTWARE."
|
||||
]
|
||||
},
|
||||
{
|
||||
// Reason: LICENSE file missing in repo
|
||||
"name": "winreg",
|
||||
"isLicense": true,
|
||||
"licenseDetail": [
|
||||
"Copyright (c) Paul Bottin",
|
||||
"",
|
||||
"The BSD License",
|
||||
"",
|
||||
"Redistribution and use in source and binary forms, with or without",
|
||||
"modification, are permitted provided that the following conditions",
|
||||
"are met:",
|
||||
"",
|
||||
"1. Redistributions of source code must retain the above copyright",
|
||||
" notice, this list of conditions and the following disclaimer.",
|
||||
"",
|
||||
"2. Redistributions in binary form must reproduce the above copyright",
|
||||
" notice, this list of conditions and the following disclaimer in the",
|
||||
" documentation and/or other materials provided with the distribution.",
|
||||
"",
|
||||
"THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND",
|
||||
"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE",
|
||||
"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR",
|
||||
"PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS",
|
||||
"BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR",
|
||||
"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF",
|
||||
"SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR",
|
||||
"BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,",
|
||||
"WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE",
|
||||
"OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN",
|
||||
"IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
]
|
||||
},
|
||||
{
|
||||
// Reason: LICENSE file doesn't have Copyright statement
|
||||
"name": "readdirp",
|
||||
"isLicense": true,
|
||||
"licenseDetail": [
|
||||
"This software is released under the MIT license:",
|
||||
"",
|
||||
"Copyright (c) Thorsten Lorenz",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining a copy of",
|
||||
"this software and associated documentation files (the \"Software\"), to deal in",
|
||||
"the Software without restriction, including without limitation the rights to",
|
||||
"use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of",
|
||||
"the Software, and to permit persons to whom the Software is furnished to do so,",
|
||||
"subject to the following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be included in all",
|
||||
"copies or substantial portions of the Software.",
|
||||
"",
|
||||
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
|
||||
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS",
|
||||
"FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR",
|
||||
"COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER",
|
||||
"IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN",
|
||||
"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
|
||||
]
|
||||
}
|
||||
|
||||
]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,28 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
var gulp = require('gulp');
|
||||
var tsb = require('gulp-tsb');
|
||||
var util = require('./lib/util');
|
||||
var watcher = require('./lib/watch');
|
||||
var assign = require('object-assign');
|
||||
|
||||
var compilation = tsb.create(assign({ verbose: true }, require('./tsconfig.json').compilerOptions));
|
||||
|
||||
gulp.task('compile', function() {
|
||||
return gulp.src('**/*.ts', { base: '.' })
|
||||
.pipe(compilation())
|
||||
.pipe(gulp.dest(''));
|
||||
});
|
||||
|
||||
gulp.task('watch', function() {
|
||||
var src = gulp.src('**/*.ts', { base: '.' });
|
||||
|
||||
return watcher('**/*.ts', { base: '.' })
|
||||
.pipe(util.incremental(compilation, src))
|
||||
.pipe(gulp.dest(''));
|
||||
});
|
||||
|
||||
gulp.task('default', ['compile']);
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
glob = require('glob');
|
||||
|
||||
var StartState = 0;
|
||||
var BundleRead = 1;
|
||||
var ReadingFiles = 2;
|
||||
|
||||
exports.parse = function (content) {
|
||||
|
||||
var state = StartState,
|
||||
lines = content.split(/\r\n|\n/),
|
||||
bundledModules = {},
|
||||
cssModules = {},
|
||||
toDelete = {};
|
||||
|
||||
lines.forEach(function (line) {
|
||||
line = line.trim();
|
||||
switch (state) {
|
||||
case StartState:
|
||||
if (line.length > 0) {
|
||||
if (/.*\.js$/.test(line)) {
|
||||
bundledModules[line] = true;
|
||||
cssModules[(line.substring(0, line.length - 2) + 'css').toLowerCase()] = true;
|
||||
}
|
||||
state = BundleRead;
|
||||
}
|
||||
break;
|
||||
case BundleRead:
|
||||
if ('----------------' === line) {
|
||||
state = ReadingFiles;
|
||||
}
|
||||
break;
|
||||
case ReadingFiles:
|
||||
if (line.length === 0) {
|
||||
state = StartState;
|
||||
} else {
|
||||
if (!bundledModules[line]) {
|
||||
toDelete[line] = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
bundledModules: bundledModules,
|
||||
cssModules: cssModules,
|
||||
toDelete: toDelete
|
||||
};
|
||||
};
|
||||
|
||||
//exports.cleanEmptyFolders = function (location) {
|
||||
// glob.sync('**/*', {
|
||||
// cwd: location
|
||||
// }).sort(function (a, b) {
|
||||
// if (a === b) {
|
||||
// return 0;
|
||||
// }
|
||||
// if (a > b) {
|
||||
// return -1;
|
||||
// }
|
||||
// return 1;
|
||||
// }).forEach(function (file) {
|
||||
//
|
||||
// });
|
||||
//
|
||||
// console.log(all);
|
||||
//
|
||||
//}
|
|
@ -0,0 +1,260 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var vm = require('vm');
|
||||
/**
|
||||
* Bundle `entryPoints` given config `config`.
|
||||
*/
|
||||
function bundle(entryPoints, config, callback) {
|
||||
var entryPointsMap = {};
|
||||
entryPoints.forEach(function (module) {
|
||||
entryPointsMap[module.name] = module;
|
||||
});
|
||||
var code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
|
||||
var r = vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
|
||||
var loaderModule = { exports: {} };
|
||||
r.call({}, require, loaderModule, loaderModule.exports);
|
||||
var loader = loaderModule.exports;
|
||||
config.isBuild = true;
|
||||
loader.config(config);
|
||||
loader(Object.keys(entryPointsMap), function () {
|
||||
var modules = loader.getBuildInfo();
|
||||
callback(null, emitEntryPoints(modules, entryPointsMap));
|
||||
}, function (err) { return callback(err, null); });
|
||||
}
|
||||
exports.bundle = bundle;
|
||||
function emitEntryPoints(modules, entryPoints) {
|
||||
var modulesMap = {};
|
||||
modules.forEach(function (m) {
|
||||
modulesMap[m.id] = m;
|
||||
});
|
||||
var modulesGraph = {};
|
||||
modules.forEach(function (m) {
|
||||
modulesGraph[m.id] = m.dependencies;
|
||||
});
|
||||
var sortedModules = topologicalSort(modulesGraph);
|
||||
var result = [];
|
||||
var usedPlugins = {};
|
||||
Object.keys(entryPoints).forEach(function (moduleToBundle) {
|
||||
var info = entryPoints[moduleToBundle];
|
||||
var rootNodes = [moduleToBundle].concat(info.include || []);
|
||||
var allDependencies = visit(rootNodes, modulesGraph);
|
||||
var excludes = ['require', 'exports', 'module'].concat(info.exclude || []);
|
||||
excludes.forEach(function (excludeRoot) {
|
||||
var allExcludes = visit([excludeRoot], modulesGraph);
|
||||
Object.keys(allExcludes).forEach(function (exclude) {
|
||||
delete allDependencies[exclude];
|
||||
});
|
||||
});
|
||||
var includedModules = sortedModules.filter(function (module) {
|
||||
return allDependencies[module];
|
||||
});
|
||||
var res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules);
|
||||
result = result.concat(res.files);
|
||||
for (var pluginName in res.usedPlugins) {
|
||||
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
|
||||
}
|
||||
});
|
||||
Object.keys(usedPlugins).forEach(function (pluginName) {
|
||||
var plugin = usedPlugins[pluginName];
|
||||
if (typeof plugin.finishBuild === 'function') {
|
||||
var write = function (filename, contents) {
|
||||
result.push({
|
||||
dest: filename,
|
||||
sources: [{
|
||||
path: null,
|
||||
contents: contents
|
||||
}]
|
||||
});
|
||||
};
|
||||
plugin.finishBuild(write);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
function emitEntryPoint(modulesMap, deps, entryPoint, includedModules) {
|
||||
var mainResult = {
|
||||
sources: [],
|
||||
dest: entryPoint + '.js'
|
||||
}, results = [mainResult];
|
||||
var usedPlugins = {};
|
||||
var getLoaderPlugin = function (pluginName) {
|
||||
if (!usedPlugins[pluginName]) {
|
||||
usedPlugins[pluginName] = modulesMap[pluginName].exports;
|
||||
}
|
||||
return usedPlugins[pluginName];
|
||||
};
|
||||
includedModules.forEach(function (c) {
|
||||
var bangIndex = c.indexOf('!');
|
||||
if (bangIndex >= 0) {
|
||||
var pluginName = c.substr(0, bangIndex);
|
||||
var plugin = getLoaderPlugin(pluginName);
|
||||
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
|
||||
return;
|
||||
}
|
||||
var module = modulesMap[c];
|
||||
if (module.path === 'empty:') {
|
||||
return;
|
||||
}
|
||||
var contents = readFileAndRemoveBOM(module.path);
|
||||
if (module.shim) {
|
||||
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
|
||||
}
|
||||
else {
|
||||
mainResult.sources.push(emitNamedModule(c, deps[c], module.defineLocation, module.path, contents));
|
||||
}
|
||||
});
|
||||
Object.keys(usedPlugins).forEach(function (pluginName) {
|
||||
var plugin = usedPlugins[pluginName];
|
||||
if (typeof plugin.writeFile === 'function') {
|
||||
var req = (function () {
|
||||
throw new Error('no-no!');
|
||||
});
|
||||
req.toUrl = function (something) { return something; };
|
||||
var write = function (filename, contents) {
|
||||
results.push({
|
||||
dest: filename,
|
||||
sources: [{
|
||||
path: null,
|
||||
contents: contents
|
||||
}]
|
||||
});
|
||||
};
|
||||
plugin.writeFile(pluginName, entryPoint, req, write, {});
|
||||
}
|
||||
});
|
||||
return {
|
||||
files: results,
|
||||
usedPlugins: usedPlugins
|
||||
};
|
||||
}
|
||||
function readFileAndRemoveBOM(path) {
|
||||
var BOM_CHAR_CODE = 65279;
|
||||
var contents = fs.readFileSync(path, 'utf8');
|
||||
// Remove BOM
|
||||
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
|
||||
contents = contents.substring(1);
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
function emitPlugin(entryPoint, plugin, pluginName, moduleName) {
|
||||
var result = '';
|
||||
if (typeof plugin.write === 'function') {
|
||||
var write = (function (what) {
|
||||
result += what;
|
||||
});
|
||||
write.getEntryPoint = function () {
|
||||
return entryPoint;
|
||||
};
|
||||
write.asModule = function (moduleId, code) {
|
||||
code = code.replace(/^define\(/, 'define("' + moduleId + '",');
|
||||
result += code;
|
||||
};
|
||||
plugin.write(pluginName, moduleName, write);
|
||||
}
|
||||
return {
|
||||
path: null,
|
||||
contents: result
|
||||
};
|
||||
}
|
||||
function emitNamedModule(moduleId, myDeps, defineCallPosition, path, contents) {
|
||||
// `defineCallPosition` is the position in code: |define()
|
||||
var defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
|
||||
// `parensOffset` is the position in code: define|()
|
||||
var parensOffset = contents.indexOf('(', defineCallOffset);
|
||||
var insertStr = '"' + moduleId + '", ';
|
||||
return {
|
||||
path: path,
|
||||
contents: contents.substr(0, parensOffset + 1) + insertStr + contents.substr(parensOffset + 1)
|
||||
};
|
||||
}
|
||||
function emitShimmedModule(moduleId, myDeps, factory, path, contents) {
|
||||
var strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
|
||||
var strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
|
||||
return {
|
||||
path: path,
|
||||
contents: contents + '\n;\n' + strDefine
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Convert a position (line:col) to (offset) in string `str`
|
||||
*/
|
||||
function positionToOffset(str, desiredLine, desiredCol) {
|
||||
if (desiredLine === 1) {
|
||||
return desiredCol - 1;
|
||||
}
|
||||
var line = 1, lastNewLineOffset = -1;
|
||||
do {
|
||||
if (desiredLine === line) {
|
||||
return lastNewLineOffset + 1 + desiredCol - 1;
|
||||
}
|
||||
lastNewLineOffset = str.indexOf('\n', lastNewLineOffset + 1);
|
||||
line++;
|
||||
} while (lastNewLineOffset >= 0);
|
||||
return -1;
|
||||
}
|
||||
/**
|
||||
* Return a set of reachable nodes in `graph` starting from `rootNodes`
|
||||
*/
|
||||
function visit(rootNodes, graph) {
|
||||
var result = {}, queue = rootNodes;
|
||||
rootNodes.forEach(function (node) {
|
||||
result[node] = true;
|
||||
});
|
||||
while (queue.length > 0) {
|
||||
var el = queue.shift();
|
||||
var myEdges = graph[el] || [];
|
||||
myEdges.forEach(function (toNode) {
|
||||
if (!result[toNode]) {
|
||||
result[toNode] = true;
|
||||
queue.push(toNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Perform a topological sort on `graph`
|
||||
*/
|
||||
function topologicalSort(graph) {
|
||||
var allNodes = {}, outgoingEdgeCount = {}, inverseEdges = {};
|
||||
Object.keys(graph).forEach(function (fromNode) {
|
||||
allNodes[fromNode] = true;
|
||||
outgoingEdgeCount[fromNode] = graph[fromNode].length;
|
||||
graph[fromNode].forEach(function (toNode) {
|
||||
allNodes[toNode] = true;
|
||||
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
|
||||
inverseEdges[toNode] = inverseEdges[toNode] || [];
|
||||
inverseEdges[toNode].push(fromNode);
|
||||
});
|
||||
});
|
||||
// https://en.wikipedia.org/wiki/Topological_sorting
|
||||
var S = [], L = [];
|
||||
Object.keys(allNodes).forEach(function (node) {
|
||||
if (outgoingEdgeCount[node] === 0) {
|
||||
delete outgoingEdgeCount[node];
|
||||
S.push(node);
|
||||
}
|
||||
});
|
||||
while (S.length > 0) {
|
||||
// Ensure the exact same order all the time with the same inputs
|
||||
S.sort();
|
||||
var n = S.shift();
|
||||
L.push(n);
|
||||
var myInverseEdges = inverseEdges[n] || [];
|
||||
myInverseEdges.forEach(function (m) {
|
||||
outgoingEdgeCount[m]--;
|
||||
if (outgoingEdgeCount[m] === 0) {
|
||||
delete outgoingEdgeCount[m];
|
||||
S.push(m);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (Object.keys(outgoingEdgeCount).length > 0) {
|
||||
throw new Error('Cannot do topological sort on cyclic graph, remaining nodes: ' + Object.keys(outgoingEdgeCount));
|
||||
}
|
||||
return L;
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import fs = require('fs');
|
||||
import path = require('path');
|
||||
import vm = require('vm');
|
||||
|
||||
interface IPosition {
|
||||
line: number;
|
||||
col: number;
|
||||
}
|
||||
|
||||
interface IBuildModuleInfo {
|
||||
id: string;
|
||||
path: string;
|
||||
defineLocation: IPosition;
|
||||
dependencies: string[];
|
||||
shim: string;
|
||||
exports: any;
|
||||
}
|
||||
|
||||
interface IBuildModuleInfoMap {
|
||||
[moduleId:string]: IBuildModuleInfo;
|
||||
}
|
||||
|
||||
interface ILoaderPlugin {
|
||||
write(pluginName:string, moduleName:string, write:ILoaderPluginWriteFunc): void;
|
||||
writeFile(pluginName:string, entryPoint:string, req:ILoaderPluginReqFunc, write:(filename:string, contents:string)=>void, config:any): void;
|
||||
finishBuild(write:(filename:string, contents:string)=>void): void;
|
||||
}
|
||||
|
||||
interface ILoaderPluginWriteFunc {
|
||||
(something:string): void;
|
||||
getEntryPoint(): string;
|
||||
asModule(moduleId:string, code:string): void;
|
||||
}
|
||||
|
||||
interface ILoaderPluginReqFunc {
|
||||
(something:string): void;
|
||||
toUrl(something:string): string;
|
||||
}
|
||||
|
||||
export interface IEntryPoint {
|
||||
name: string;
|
||||
include: string[];
|
||||
exclude: string[];
|
||||
}
|
||||
|
||||
interface IEntryPointMap {
|
||||
[moduleId:string]: IEntryPoint;
|
||||
}
|
||||
|
||||
interface IGraph {
|
||||
[node:string]: string[];
|
||||
}
|
||||
|
||||
interface INodeSet {
|
||||
[node:string]: boolean;
|
||||
}
|
||||
|
||||
export interface IFile {
|
||||
path: string;
|
||||
contents: string;
|
||||
}
|
||||
|
||||
export interface IConcatFile {
|
||||
dest: string;
|
||||
sources: IFile[];
|
||||
}
|
||||
|
||||
export interface ILoaderConfig {
|
||||
isBuild?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundle `entryPoints` given config `config`.
|
||||
*/
|
||||
export function bundle(entryPoints:IEntryPoint[], config:ILoaderConfig, callback:(err:any, result:IConcatFile[]) => void): void {
|
||||
let entryPointsMap:IEntryPointMap = {};
|
||||
entryPoints.forEach((module:IEntryPoint) => {
|
||||
entryPointsMap[module.name] = module;
|
||||
});
|
||||
|
||||
|
||||
var code = require('fs').readFileSync(path.join(__dirname, '../../src/vs/loader.js'));
|
||||
var r: Function = <any> vm.runInThisContext('(function(require, module, exports) { ' + code + '\n});');
|
||||
var loaderModule = { exports: {} };
|
||||
r.call({}, require, loaderModule, loaderModule.exports);
|
||||
|
||||
var loader:any = loaderModule.exports;
|
||||
config.isBuild = true;
|
||||
loader.config(config);
|
||||
|
||||
loader(Object.keys(entryPointsMap), () => {
|
||||
let modules = <IBuildModuleInfo[]>loader.getBuildInfo();
|
||||
callback(null, emitEntryPoints(modules, entryPointsMap));
|
||||
}, (err) => callback(err, null))
|
||||
}
|
||||
|
||||
function emitEntryPoints(modules:IBuildModuleInfo[], entryPoints:IEntryPointMap): IConcatFile[] {
|
||||
let modulesMap: IBuildModuleInfoMap = {};
|
||||
modules.forEach((m:IBuildModuleInfo) => {
|
||||
modulesMap[m.id] = m;
|
||||
});
|
||||
|
||||
let modulesGraph:IGraph = {};
|
||||
modules.forEach((m:IBuildModuleInfo) => {
|
||||
modulesGraph[m.id] = m.dependencies;
|
||||
});
|
||||
|
||||
let sortedModules = topologicalSort(modulesGraph);
|
||||
|
||||
let result: IConcatFile[] = [];
|
||||
let usedPlugins: IPluginMap = {};
|
||||
|
||||
Object.keys(entryPoints).forEach((moduleToBundle:string) => {
|
||||
let info = entryPoints[moduleToBundle];
|
||||
let rootNodes = [moduleToBundle].concat(info.include || []);
|
||||
let allDependencies = visit(rootNodes, modulesGraph);
|
||||
let excludes:string[] = ['require', 'exports', 'module'].concat(info.exclude || []);
|
||||
|
||||
excludes.forEach((excludeRoot:string) => {
|
||||
let allExcludes = visit([excludeRoot], modulesGraph);
|
||||
Object.keys(allExcludes).forEach((exclude:string) => {
|
||||
delete allDependencies[exclude];
|
||||
});
|
||||
});
|
||||
|
||||
let includedModules = sortedModules.filter((module:string) => {
|
||||
return allDependencies[module];
|
||||
});
|
||||
|
||||
let res = emitEntryPoint(modulesMap, modulesGraph, moduleToBundle, includedModules);
|
||||
|
||||
result = result.concat(res.files);
|
||||
for (let pluginName in res.usedPlugins) {
|
||||
usedPlugins[pluginName] = usedPlugins[pluginName] || res.usedPlugins[pluginName];
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(usedPlugins).forEach((pluginName:string) => {
|
||||
let plugin = usedPlugins[pluginName];
|
||||
if (typeof plugin.finishBuild === 'function') {
|
||||
let write = (filename:string, contents:string) => {
|
||||
result.push({
|
||||
dest: filename,
|
||||
sources: [{
|
||||
path: null,
|
||||
contents: contents
|
||||
}]
|
||||
});
|
||||
};
|
||||
plugin.finishBuild(write);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
interface IPluginMap {
|
||||
[moduleId:string]:ILoaderPlugin;
|
||||
}
|
||||
|
||||
interface IEmitEntryPointResult {
|
||||
files: IConcatFile[];
|
||||
usedPlugins: IPluginMap;
|
||||
}
|
||||
|
||||
function emitEntryPoint(modulesMap:IBuildModuleInfoMap, deps:IGraph, entryPoint:string, includedModules:string[]): IEmitEntryPointResult {
|
||||
let mainResult: IConcatFile = {
|
||||
sources: [],
|
||||
dest: entryPoint + '.js'
|
||||
},
|
||||
results: IConcatFile[] = [mainResult];
|
||||
|
||||
let usedPlugins: IPluginMap = {};
|
||||
let getLoaderPlugin = (pluginName:string):ILoaderPlugin => {
|
||||
if (!usedPlugins[pluginName]) {
|
||||
usedPlugins[pluginName] = modulesMap[pluginName].exports;
|
||||
}
|
||||
return usedPlugins[pluginName];
|
||||
}
|
||||
|
||||
includedModules.forEach((c:string) => {
|
||||
let bangIndex = c.indexOf('!');
|
||||
|
||||
if (bangIndex >= 0) {
|
||||
let pluginName = c.substr(0, bangIndex);
|
||||
let plugin = getLoaderPlugin(pluginName);
|
||||
mainResult.sources.push(emitPlugin(entryPoint, plugin, pluginName, c.substr(bangIndex + 1)));
|
||||
return;
|
||||
}
|
||||
|
||||
let module = modulesMap[c];
|
||||
|
||||
if (module.path === 'empty:') {
|
||||
return;
|
||||
}
|
||||
|
||||
let contents = readFileAndRemoveBOM(module.path);
|
||||
|
||||
if (module.shim) {
|
||||
mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents));
|
||||
} else {
|
||||
mainResult.sources.push(emitNamedModule(c, deps[c], module.defineLocation, module.path, contents));
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(usedPlugins).forEach((pluginName:string) => {
|
||||
let plugin = usedPlugins[pluginName];
|
||||
if (typeof plugin.writeFile === 'function') {
|
||||
let req:ILoaderPluginReqFunc = <any>(() => {
|
||||
throw new Error('no-no!');
|
||||
});
|
||||
req.toUrl = something => something;
|
||||
|
||||
let write = (filename:string, contents:string) => {
|
||||
results.push({
|
||||
dest: filename,
|
||||
sources: [{
|
||||
path: null,
|
||||
contents: contents
|
||||
}]
|
||||
});
|
||||
};
|
||||
plugin.writeFile(pluginName, entryPoint, req, write, {});
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
files: results,
|
||||
usedPlugins: usedPlugins
|
||||
};
|
||||
}
|
||||
|
||||
function readFileAndRemoveBOM(path:string): string {
|
||||
var BOM_CHAR_CODE = 65279;
|
||||
var contents = fs.readFileSync(path, 'utf8');
|
||||
// Remove BOM
|
||||
if (contents.charCodeAt(0) === BOM_CHAR_CODE) {
|
||||
contents = contents.substring(1);
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
|
||||
function emitPlugin(entryPoint:string, plugin:ILoaderPlugin, pluginName:string, moduleName:string): IFile {
|
||||
let result = '';
|
||||
if (typeof plugin.write === 'function') {
|
||||
let write: ILoaderPluginWriteFunc = <any>((what) => {
|
||||
result += what;
|
||||
});
|
||||
write.getEntryPoint = () => {
|
||||
return entryPoint;
|
||||
};
|
||||
write.asModule = (moduleId:string, code:string) => {
|
||||
code = code.replace(/^define\(/, 'define("'+moduleId+'",');
|
||||
result += code;
|
||||
};
|
||||
plugin.write(pluginName, moduleName, write);
|
||||
}
|
||||
return {
|
||||
path: null,
|
||||
contents: result
|
||||
};
|
||||
}
|
||||
|
||||
function emitNamedModule(moduleId:string, myDeps:string[], defineCallPosition:IPosition, path:string, contents:string): IFile {
|
||||
|
||||
// `defineCallPosition` is the position in code: |define()
|
||||
let defineCallOffset = positionToOffset(contents, defineCallPosition.line, defineCallPosition.col);
|
||||
|
||||
// `parensOffset` is the position in code: define|()
|
||||
let parensOffset = contents.indexOf('(', defineCallOffset);
|
||||
|
||||
let insertStr = '"' + moduleId + '", ';
|
||||
|
||||
return {
|
||||
path: path,
|
||||
contents: contents.substr(0, parensOffset + 1) + insertStr + contents.substr(parensOffset + 1)
|
||||
};
|
||||
}
|
||||
|
||||
function emitShimmedModule(moduleId:string, myDeps:string[], factory:string, path:string, contents:string): IFile {
|
||||
let strDeps = (myDeps.length > 0 ? '"' + myDeps.join('", "') + '"' : '');
|
||||
let strDefine = 'define("' + moduleId + '", [' + strDeps + '], ' + factory + ');';
|
||||
return {
|
||||
path: path,
|
||||
contents: contents + '\n;\n' + strDefine
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a position (line:col) to (offset) in string `str`
|
||||
*/
|
||||
function positionToOffset(str:string, desiredLine:number, desiredCol:number): number {
|
||||
if (desiredLine === 1) {
|
||||
return desiredCol - 1;
|
||||
}
|
||||
|
||||
let line = 1,
|
||||
lastNewLineOffset = -1;
|
||||
|
||||
do {
|
||||
if (desiredLine === line) {
|
||||
return lastNewLineOffset + 1 + desiredCol - 1;
|
||||
}
|
||||
lastNewLineOffset = str.indexOf('\n', lastNewLineOffset + 1);
|
||||
line++;
|
||||
} while (lastNewLineOffset >= 0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a set of reachable nodes in `graph` starting from `rootNodes`
|
||||
*/
|
||||
function visit(rootNodes:string[], graph:IGraph):INodeSet {
|
||||
let result:INodeSet = {},
|
||||
queue = rootNodes;
|
||||
|
||||
rootNodes.forEach((node) => {
|
||||
result[node] = true;
|
||||
});
|
||||
|
||||
while (queue.length > 0) {
|
||||
let el = queue.shift();
|
||||
let myEdges = graph[el] || [];
|
||||
myEdges.forEach((toNode) => {
|
||||
if (!result[toNode]) {
|
||||
result[toNode] = true;
|
||||
queue.push(toNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a topological sort on `graph`
|
||||
*/
|
||||
function topologicalSort(graph:IGraph): string[] {
|
||||
|
||||
let allNodes:INodeSet = {},
|
||||
outgoingEdgeCount:{[node:string]:number;} = {},
|
||||
inverseEdges:IGraph = {};
|
||||
|
||||
Object.keys(graph).forEach((fromNode:string) => {
|
||||
allNodes[fromNode] = true;
|
||||
outgoingEdgeCount[fromNode] = graph[fromNode].length;
|
||||
|
||||
graph[fromNode].forEach((toNode) => {
|
||||
allNodes[toNode] = true;
|
||||
outgoingEdgeCount[toNode] = outgoingEdgeCount[toNode] || 0;
|
||||
|
||||
inverseEdges[toNode] = inverseEdges[toNode] || [];
|
||||
inverseEdges[toNode].push(fromNode);
|
||||
});
|
||||
});
|
||||
|
||||
// https://en.wikipedia.org/wiki/Topological_sorting
|
||||
let S: string[] = [],
|
||||
L: string[] = [];
|
||||
|
||||
Object.keys(allNodes).forEach((node:string) => {
|
||||
if (outgoingEdgeCount[node] === 0) {
|
||||
delete outgoingEdgeCount[node];
|
||||
S.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
while (S.length > 0) {
|
||||
// Ensure the exact same order all the time with the same inputs
|
||||
S.sort();
|
||||
|
||||
let n:string = S.shift();
|
||||
L.push(n);
|
||||
|
||||
let myInverseEdges = inverseEdges[n] || [];
|
||||
myInverseEdges.forEach((m:string) => {
|
||||
outgoingEdgeCount[m]--;
|
||||
if (outgoingEdgeCount[m] === 0) {
|
||||
delete outgoingEdgeCount[m];
|
||||
S.push(m);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (Object.keys(outgoingEdgeCount).length > 0) {
|
||||
throw new Error('Cannot do topological sort on cyclic graph, remaining nodes: ' + Object.keys(outgoingEdgeCount));
|
||||
}
|
||||
|
||||
return L;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
var es = require('event-stream');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var copyright = [
|
||||
'/*---------------------------------------------------------------------------------------------',
|
||||
' * Copyright (c) Microsoft Corporation. All rights reserved.',
|
||||
' * Licensed under the MIT License. See License.txt in the project root for license information.',
|
||||
' *--------------------------------------------------------------------------------------------*/'
|
||||
].join('\n');
|
||||
|
||||
var ignoreList = [
|
||||
'/src/vs/languages/typescript/common/lib/lib.d.ts',
|
||||
'/src/vs/languages/typescript/common/lib/lib.es6.d.ts',
|
||||
'/src/vs/languages/typescript/common/lib/typescriptServices.d.ts',
|
||||
'/src/vs/workbench/parts/emmet/node/emmet.d.ts',
|
||||
'/src/vs/editor/standalone-languages/swift.ts',
|
||||
'/src/vs/workbench/browser/media/octicons/octicons.css',
|
||||
'/src/vs/base/test/node/encoding/fixtures/some_utf16be.css',
|
||||
'/src/vs/base/test/node/encoding/fixtures/some_utf16le.css',
|
||||
'/src/vs/workbench/services/search/test/node/fixtures/site.css',
|
||||
'/src/vs/workbench/services/search/test/node/fixtures/some_utf16be.css',
|
||||
'/src/vs/workbench/services/search/test/node/fixtures/some_utf16le.css',
|
||||
'/src/vs/workbench/services/files/test/node/fixtures/service/some_utf16le.css',
|
||||
'/extensions/lib.core.d.ts',
|
||||
'/extensions/node.d.ts',
|
||||
'/extensions/csharp-o/src/typings/applicationinsights.d.ts',
|
||||
'/extensions/typescript/out/lib/lib.core.d.ts',
|
||||
'/extensions/typescript/out/lib/lib.core.es6.d.ts',
|
||||
'/extensions/typescript/out/lib/lib.d.ts',
|
||||
'/extensions/typescript/out/lib/lib.dom.d.ts',
|
||||
'/extensions/typescript/out/lib/lib.es6.d.ts',
|
||||
'/extensions/typescript/out/lib/lib.scriptHost.d.ts',
|
||||
'/extensions/typescript/out/lib/lib.webworker.d.ts',
|
||||
'/extensions/typescript/src/lib/lib.core.d.ts',
|
||||
'/extensions/typescript/src/lib/lib.core.es6.d.ts',
|
||||
'/extensions/typescript/src/lib/lib.d.ts',
|
||||
'/extensions/typescript/src/lib/lib.dom.d.ts',
|
||||
'/extensions/typescript/src/lib/lib.es6.d.ts',
|
||||
'/extensions/typescript/src/lib/lib.scriptHost.d.ts',
|
||||
'/extensions/typescript/src/lib/lib.webworker.d.ts',
|
||||
'/extensions/csharp-o/src/typings/semver/semver.d.ts'
|
||||
];
|
||||
|
||||
function ignore(filePath) {
|
||||
filePath = path.posix.normalize(filePath);
|
||||
|
||||
return ignoreList.some(function(p) {
|
||||
return filePath.indexOf(p) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
exports.copyrights = function () {
|
||||
return es.mapSync(function (file) {
|
||||
if (file.contents) {
|
||||
var contents = file.contents.toString('utf8');
|
||||
|
||||
if (contents.indexOf(copyright) !== 0 && !ignore(file.path)) {
|
||||
throw new Error('File ' + file.path + ' does not contain copyright statement.');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.insertCopyrights = function() {
|
||||
return es.mapSync(function (file) {
|
||||
if (file.contents) {
|
||||
var contents = file.contents.toString('utf8');
|
||||
|
||||
if (contents.indexOf(copyright) !== 0 && !ignore(file.path)) {
|
||||
contents = copyright + '\n\n' + contents;
|
||||
fs.writeFileSync(file.path, contents, 'utf8');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
exports.getVersion = function (repo) {
|
||||
var git = path.join(repo, '.git');
|
||||
var headPath = path.join(git, 'HEAD');
|
||||
var head;
|
||||
|
||||
try {
|
||||
head = fs.readFileSync(headPath, 'utf8').trim();
|
||||
} catch (e) {
|
||||
return void 0;
|
||||
}
|
||||
|
||||
if (/^[0-9a-f]{40}$/i.test(head)) {
|
||||
return head;
|
||||
}
|
||||
|
||||
var refMatch = /^ref: (.*)$/.exec(head);
|
||||
|
||||
if (!refMatch) {
|
||||
return void 0;
|
||||
}
|
||||
|
||||
var ref = refMatch[1];
|
||||
var refPath = path.join(git, ref);
|
||||
|
||||
try {
|
||||
return fs.readFileSync(refPath, 'utf8').trim();
|
||||
} catch (e) {
|
||||
// noop
|
||||
}
|
||||
|
||||
var packedRefsPath = path.join(git, 'packed-refs');
|
||||
var refsRaw;
|
||||
|
||||
try {
|
||||
refsRaw = fs.readFileSync(packedRefsPath, 'utf8').trim();
|
||||
} catch (e) {
|
||||
return void 0;
|
||||
}
|
||||
|
||||
var refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm;
|
||||
var refsMatch;
|
||||
var refs = {};
|
||||
|
||||
while (refsMatch = refsRegex.exec(refsRaw)) {
|
||||
refs[refsMatch[2]] = refsMatch[1];
|
||||
}
|
||||
|
||||
return refs[ref];
|
||||
};
|
|
@ -0,0 +1,369 @@
|
|||
var ts = require('./typescript/typescriptServices');
|
||||
var lazy = require('lazy.js');
|
||||
var event_stream_1 = require('event-stream');
|
||||
var File = require('vinyl');
|
||||
var sm = require('source-map');
|
||||
var assign = require('object-assign');
|
||||
var clone = require('clone');
|
||||
var path = require('path');
|
||||
var CollectStepResult;
|
||||
(function (CollectStepResult) {
|
||||
CollectStepResult[CollectStepResult["Yes"] = 0] = "Yes";
|
||||
CollectStepResult[CollectStepResult["YesAndRecurse"] = 1] = "YesAndRecurse";
|
||||
CollectStepResult[CollectStepResult["No"] = 2] = "No";
|
||||
CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse";
|
||||
})(CollectStepResult || (CollectStepResult = {}));
|
||||
function collect(node, fn) {
|
||||
var result = [];
|
||||
function loop(node) {
|
||||
var stepResult = fn(node);
|
||||
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
|
||||
result.push(node);
|
||||
}
|
||||
if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) {
|
||||
ts.forEachChild(node, loop);
|
||||
}
|
||||
}
|
||||
loop(node);
|
||||
return result;
|
||||
}
|
||||
function zip(stream, zipper) {
|
||||
if (zipper === void 0) { zipper = function (a, b) { return [a, b]; }; }
|
||||
var pass = event_stream_1.through();
|
||||
var oneBuffer = [];
|
||||
var otherBuffer = [];
|
||||
var result = pass.pipe(event_stream_1.through(function (f) {
|
||||
oneBuffer.push(f);
|
||||
flush();
|
||||
}), function () {
|
||||
flush();
|
||||
result.emit('end');
|
||||
});
|
||||
function flush() {
|
||||
while (oneBuffer.length > 0 && otherBuffer.length > 0) {
|
||||
result.emit('data', zipper(oneBuffer.shift(), otherBuffer.shift()));
|
||||
}
|
||||
}
|
||||
stream.pipe(event_stream_1.through(function (f) { return otherBuffer.push(f); }));
|
||||
return event_stream_1.duplex(pass, result);
|
||||
}
|
||||
function template(lines) {
|
||||
var indent = '', wrap = '';
|
||||
if (lines.length > 1) {
|
||||
indent = '\t';
|
||||
wrap = '\n';
|
||||
}
|
||||
return "/*---------------------------------------------------------\n * Copyright (C) Microsoft Corporation. All rights reserved.\n *--------------------------------------------------------*/\ndefine([], [" + (wrap + lines.map(function (l) { return indent + l; }).join(',\n') + wrap) + "]);";
|
||||
}
|
||||
/**
|
||||
* Returns a stream containing the patched JavaScript and source maps.
|
||||
*/
|
||||
function nls() {
|
||||
var input = event_stream_1.through();
|
||||
var output = input.pipe(event_stream_1.through(function (f) {
|
||||
var _this = this;
|
||||
if (!f.sourceMap) {
|
||||
return this.emit('error', new Error("File " + f.relative + " does not have sourcemaps."));
|
||||
}
|
||||
var source = f.sourceMap.sources[0];
|
||||
if (!source) {
|
||||
return this.emit('error', new Error("File " + f.relative + " does not have a source in the source map."));
|
||||
}
|
||||
var root = f.sourceMap.sourceRoot;
|
||||
if (root) {
|
||||
source = path.join(root, source);
|
||||
}
|
||||
var typescript = f.sourceMap.sourcesContent[0];
|
||||
if (!typescript) {
|
||||
return this.emit('error', new Error("File " + f.relative + " does not have the original content in the source map."));
|
||||
}
|
||||
nls.patchFiles(f, typescript).forEach(function (f) { return _this.emit('data', f); });
|
||||
}));
|
||||
return event_stream_1.duplex(input, output);
|
||||
}
|
||||
function isImportNode(node) {
|
||||
return node.kind === 212 /* ImportDeclaration */ || node.kind === 211 /* ImportEqualsDeclaration */;
|
||||
}
|
||||
var nls;
|
||||
(function (nls_1) {
|
||||
function fileFrom(file, contents, path) {
|
||||
if (path === void 0) { path = file.path; }
|
||||
return new File({
|
||||
contents: new Buffer(contents),
|
||||
base: file.base,
|
||||
cwd: file.cwd,
|
||||
path: path
|
||||
});
|
||||
}
|
||||
nls_1.fileFrom = fileFrom;
|
||||
function mappedPositionFrom(source, lc) {
|
||||
return { source: source, line: lc.line + 1, column: lc.character };
|
||||
}
|
||||
nls_1.mappedPositionFrom = mappedPositionFrom;
|
||||
function lcFrom(position) {
|
||||
return { line: position.line - 1, character: position.column };
|
||||
}
|
||||
nls_1.lcFrom = lcFrom;
|
||||
var SingleFileServiceHost = (function () {
|
||||
function SingleFileServiceHost(options, filename, contents) {
|
||||
var _this = this;
|
||||
this.options = options;
|
||||
this.filename = filename;
|
||||
this.getCompilationSettings = function () { return _this.options; };
|
||||
this.getScriptFileNames = function () { return [_this.filename]; };
|
||||
this.getScriptVersion = function () { return '1'; };
|
||||
this.getScriptSnapshot = function (name) { return name === _this.filename ? _this.file : _this.lib; };
|
||||
this.getCurrentDirectory = function () { return ''; };
|
||||
this.getDefaultLibFileName = function () { return 'lib.d.ts'; };
|
||||
this.file = ts.ScriptSnapshot.fromString(contents);
|
||||
this.lib = ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
return SingleFileServiceHost;
|
||||
})();
|
||||
nls_1.SingleFileServiceHost = SingleFileServiceHost;
|
||||
function isCallExpressionWithinTextSpanCollectStep(textSpan, node) {
|
||||
if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) {
|
||||
return CollectStepResult.No;
|
||||
}
|
||||
return node.kind === 160 /* CallExpression */ ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse;
|
||||
}
|
||||
function analyze(contents, options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var filename = 'file.ts';
|
||||
var serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents);
|
||||
var service = ts.createLanguageService(serviceHost);
|
||||
var sourceFile = service.getSourceFile(filename);
|
||||
// all imports
|
||||
var imports = lazy(collect(sourceFile, function (n) { return isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse; }));
|
||||
// import nls = require('vs/nls');
|
||||
var importEqualsDeclarations = imports
|
||||
.filter(function (n) { return n.kind === 211 /* ImportEqualsDeclaration */; })
|
||||
.map(function (n) { return n; })
|
||||
.filter(function (d) { return d.moduleReference.kind === 222 /* ExternalModuleReference */; })
|
||||
.filter(function (d) { return d.moduleReference.expression.getText() === "'vs/nls'"; });
|
||||
// import ... from 'vs/nls';
|
||||
var importDeclarations = imports
|
||||
.filter(function (n) { return n.kind === 212 /* ImportDeclaration */; })
|
||||
.map(function (n) { return n; })
|
||||
.filter(function (d) { return d.moduleSpecifier.kind === 8 /* StringLiteral */; })
|
||||
.filter(function (d) { return d.moduleSpecifier.getText() === "'vs/nls'"; })
|
||||
.filter(function (d) { return !!d.importClause && !!d.importClause.namedBindings; });
|
||||
var nlsExpressions = importEqualsDeclarations
|
||||
.map(function (d) { return d.moduleReference.expression; })
|
||||
.concat(importDeclarations.map(function (d) { return d.moduleSpecifier; }))
|
||||
.map(function (d) { return ({
|
||||
start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()),
|
||||
end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd())
|
||||
}); });
|
||||
// `nls.localize(...)` calls
|
||||
var nlsLocalizeCallExpressions = importDeclarations
|
||||
.filter(function (d) { return d.importClause.namedBindings.kind === 214 /* NamespaceImport */; })
|
||||
.map(function (d) { return d.importClause.namedBindings.name; })
|
||||
.concat(importEqualsDeclarations.map(function (d) { return d.name; }))
|
||||
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
|
||||
.flatten()
|
||||
.filter(function (r) { return !r.isWriteAccess; })
|
||||
.map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); })
|
||||
.map(function (a) { return lazy(a).last(); })
|
||||
.filter(function (n) { return !!n; })
|
||||
.map(function (n) { return n; })
|
||||
.filter(function (n) { return n.expression.kind === 158 /* PropertyAccessExpression */ && n.expression.name.getText() === 'localize'; });
|
||||
// `localize` named imports
|
||||
var allLocalizeImportDeclarations = importDeclarations
|
||||
.filter(function (d) { return d.importClause.namedBindings.kind === 215 /* NamedImports */; })
|
||||
.map(function (d) { return d.importClause.namedBindings.elements; })
|
||||
.flatten();
|
||||
// `localize` read-only references
|
||||
var localizeReferences = allLocalizeImportDeclarations
|
||||
.filter(function (d) { return d.name.getText() === 'localize'; })
|
||||
.map(function (n) { return service.getReferencesAtPosition(filename, n.pos + 1); })
|
||||
.flatten()
|
||||
.filter(function (r) { return !r.isWriteAccess; });
|
||||
// custom named `localize` read-only references
|
||||
var namedLocalizeReferences = allLocalizeImportDeclarations
|
||||
.filter(function (d) { return d.propertyName && d.propertyName.getText() === 'localize'; })
|
||||
.map(function (n) { return service.getReferencesAtPosition(filename, n.name.pos + 1); })
|
||||
.flatten()
|
||||
.filter(function (r) { return !r.isWriteAccess; });
|
||||
// find the deepest call expressions AST nodes that contain those references
|
||||
var localizeCallExpressions = localizeReferences
|
||||
.concat(namedLocalizeReferences)
|
||||
.map(function (r) { return collect(sourceFile, function (n) { return isCallExpressionWithinTextSpanCollectStep(r.textSpan, n); }); })
|
||||
.map(function (a) { return lazy(a).last(); })
|
||||
.filter(function (n) { return !!n; })
|
||||
.map(function (n) { return n; });
|
||||
// collect everything
|
||||
var localizeCalls = nlsLocalizeCallExpressions
|
||||
.concat(localizeCallExpressions)
|
||||
.map(function (e) { return e.arguments; })
|
||||
.filter(function (a) { return a.length > 1; })
|
||||
.sort(function (a, b) { return a[0].getStart() - b[0].getStart(); })
|
||||
.map(function (a) { return ({
|
||||
keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) },
|
||||
key: a[0].getText(),
|
||||
valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) },
|
||||
value: a[1].getText()
|
||||
}); });
|
||||
return {
|
||||
localizeCalls: localizeCalls.toArray(),
|
||||
nlsExpressions: nlsExpressions.toArray()
|
||||
};
|
||||
}
|
||||
nls_1.analyze = analyze;
|
||||
var TextModel = (function () {
|
||||
function TextModel(contents) {
|
||||
var regex = /\r\n|\r|\n/g;
|
||||
var index = 0;
|
||||
var match;
|
||||
this.lines = [];
|
||||
this.lineEndings = [];
|
||||
while (match = regex.exec(contents)) {
|
||||
this.lines.push(contents.substring(index, match.index));
|
||||
this.lineEndings.push(match[0]);
|
||||
index = regex.lastIndex;
|
||||
}
|
||||
if (contents.length > 0) {
|
||||
this.lines.push(contents.substring(index, contents.length));
|
||||
this.lineEndings.push('');
|
||||
}
|
||||
}
|
||||
TextModel.prototype.get = function (index) {
|
||||
return this.lines[index];
|
||||
};
|
||||
TextModel.prototype.set = function (index, line) {
|
||||
this.lines[index] = line;
|
||||
};
|
||||
Object.defineProperty(TextModel.prototype, "lineCount", {
|
||||
get: function () {
|
||||
return this.lines.length;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
/**
|
||||
* Applies patch(es) to the model.
|
||||
* Multiple patches must be ordered.
|
||||
* Does not support patches spanning multiple lines.
|
||||
*/
|
||||
TextModel.prototype.apply = function (patch) {
|
||||
var startLineNumber = patch.span.start.line;
|
||||
var endLineNumber = patch.span.end.line;
|
||||
var startLine = this.lines[startLineNumber] || '';
|
||||
var endLine = this.lines[endLineNumber] || '';
|
||||
this.lines[startLineNumber] = [
|
||||
startLine.substring(0, patch.span.start.character),
|
||||
patch.content,
|
||||
endLine.substring(patch.span.end.character)
|
||||
].join('');
|
||||
for (var i = startLineNumber + 1; i <= endLineNumber; i++) {
|
||||
this.lines[i] = '';
|
||||
}
|
||||
};
|
||||
TextModel.prototype.toString = function () {
|
||||
return lazy(this.lines).zip(this.lineEndings)
|
||||
.flatten().toArray().join('');
|
||||
};
|
||||
return TextModel;
|
||||
})();
|
||||
nls_1.TextModel = TextModel;
|
||||
function patchJavascript(patches, contents, moduleId) {
|
||||
var model = new nls.TextModel(contents);
|
||||
// patch the localize calls
|
||||
lazy(patches).reverse().each(function (p) { return model.apply(p); });
|
||||
// patch the 'vs/nls' imports
|
||||
var firstLine = model.get(0);
|
||||
var patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1");
|
||||
model.set(0, patchedFirstLine);
|
||||
return model.toString();
|
||||
}
|
||||
nls_1.patchJavascript = patchJavascript;
|
||||
function patchSourcemap(patches, rsm, smc) {
|
||||
var smg = new sm.SourceMapGenerator({
|
||||
file: rsm.file,
|
||||
sourceRoot: rsm.sourceRoot
|
||||
});
|
||||
patches = patches.reverse();
|
||||
var currentLine = -1;
|
||||
var currentLineDiff = 0;
|
||||
var source = null;
|
||||
smc.eachMapping(function (m) {
|
||||
var patch = patches[patches.length - 1];
|
||||
var original = { line: m.originalLine, column: m.originalColumn };
|
||||
var generated = { line: m.generatedLine, column: m.generatedColumn };
|
||||
if (currentLine !== generated.line) {
|
||||
currentLineDiff = 0;
|
||||
}
|
||||
currentLine = generated.line;
|
||||
generated.column += currentLineDiff;
|
||||
if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) {
|
||||
var originalLength = patch.span.end.character - patch.span.start.character;
|
||||
var modifiedLength = patch.content.length;
|
||||
var lengthDiff = modifiedLength - originalLength;
|
||||
currentLineDiff += lengthDiff;
|
||||
generated.column += lengthDiff;
|
||||
patches.pop();
|
||||
}
|
||||
source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source;
|
||||
source = source.replace(/\\/g, '/');
|
||||
smg.addMapping({ source: source, name: m.name, original: original, generated: generated });
|
||||
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
|
||||
if (source) {
|
||||
smg.setSourceContent(source, smc.sourceContentFor(source));
|
||||
}
|
||||
return JSON.parse(smg.toString());
|
||||
}
|
||||
nls_1.patchSourcemap = patchSourcemap;
|
||||
function patch(moduleId, typescript, javascript, sourcemap) {
|
||||
var _a = analyze(typescript), localizeCalls = _a.localizeCalls, nlsExpressions = _a.nlsExpressions;
|
||||
if (localizeCalls.length === 0) {
|
||||
return { javascript: javascript, sourcemap: sourcemap };
|
||||
}
|
||||
var nlsKeys = template(localizeCalls.map(function (lc) { return lc.key; }));
|
||||
var nls = template(localizeCalls.map(function (lc) { return lc.value; }));
|
||||
var smc = new sm.SourceMapConsumer(sourcemap);
|
||||
var positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]);
|
||||
var i = 0;
|
||||
// build patches
|
||||
var patches = lazy(localizeCalls)
|
||||
.map(function (lc) { return ([
|
||||
{ range: lc.keySpan, content: '' + (i++) },
|
||||
{ range: lc.valueSpan, content: 'null' }
|
||||
]); })
|
||||
.flatten()
|
||||
.map(function (c) {
|
||||
var start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start)));
|
||||
var end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end)));
|
||||
return { span: { start: start, end: end }, content: c.content };
|
||||
})
|
||||
.toArray();
|
||||
javascript = patchJavascript(patches, javascript, moduleId);
|
||||
// since imports are not within the sourcemap information,
|
||||
// we must do this MacGyver style
|
||||
if (nlsExpressions.length) {
|
||||
javascript = javascript.replace(/^define\(.*$/m, function (line) {
|
||||
return line.replace(/(['"])vs\/nls\1/g, "$1vs/nls!" + moduleId + "$1");
|
||||
});
|
||||
}
|
||||
sourcemap = patchSourcemap(patches, sourcemap, smc);
|
||||
return { javascript: javascript, sourcemap: sourcemap, nlsKeys: nlsKeys, nls: nls };
|
||||
}
|
||||
nls_1.patch = patch;
|
||||
function patchFiles(javascriptFile, typescript) {
|
||||
// hack?
|
||||
var moduleId = javascriptFile.relative
|
||||
.replace(/\.js$/, '')
|
||||
.replace(/\\/g, '/');
|
||||
var _a = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap), javascript = _a.javascript, sourcemap = _a.sourcemap, nlsKeys = _a.nlsKeys, nls = _a.nls;
|
||||
var result = [fileFrom(javascriptFile, javascript)];
|
||||
result[0].sourceMap = sourcemap;
|
||||
if (nlsKeys) {
|
||||
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));
|
||||
}
|
||||
if (nls) {
|
||||
result.push(fileFrom(javascriptFile, nls, javascriptFile.path.replace(/\.js$/, '.nls.js')));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
nls_1.patchFiles = patchFiles;
|
||||
})(nls || (nls = {}));
|
||||
module.exports = nls;
|
|
@ -0,0 +1,485 @@
|
|||
import * as ts from './typescript/typescriptServices';
|
||||
import * as lazy from 'lazy.js';
|
||||
import { duplex, through, mapSync, readArray, merge } from 'event-stream';
|
||||
import { Stream } from 'stream';
|
||||
import { ThroughStream } from 'through';
|
||||
import File = require('vinyl');
|
||||
import * as sm from 'source-map';
|
||||
import assign = require('object-assign');
|
||||
import clone = require('clone');
|
||||
import filter = require('gulp-filter');
|
||||
import path = require('path');
|
||||
import fs = require('fs');
|
||||
|
||||
declare class FileSourceMap extends File {
|
||||
public sourceMap: sm.RawSourceMap;
|
||||
}
|
||||
|
||||
enum CollectStepResult {
|
||||
Yes,
|
||||
YesAndRecurse,
|
||||
No,
|
||||
NoAndRecurse
|
||||
}
|
||||
|
||||
function collect(node: ts.Node, fn: (node: ts.Node) => CollectStepResult): ts.Node[] {
|
||||
const result: ts.Node[] = [];
|
||||
|
||||
function loop(node: ts.Node) {
|
||||
var stepResult = fn(node);
|
||||
|
||||
if (stepResult === CollectStepResult.Yes || stepResult === CollectStepResult.YesAndRecurse) {
|
||||
result.push(node);
|
||||
}
|
||||
|
||||
if (stepResult === CollectStepResult.YesAndRecurse || stepResult === CollectStepResult.NoAndRecurse) {
|
||||
ts.forEachChild(node, loop);
|
||||
}
|
||||
}
|
||||
|
||||
loop(node);
|
||||
return result;
|
||||
}
|
||||
|
||||
function zip<A,B,R>(stream: Stream, zipper: (a: A, b: B) => R = (a,b) => <any> [a, b]): ThroughStream {
|
||||
const pass = through();
|
||||
const oneBuffer: any[] = [];
|
||||
const otherBuffer: any[] = [];
|
||||
|
||||
const result = pass.pipe(through(f => {
|
||||
oneBuffer.push(f);
|
||||
flush();
|
||||
}), () => {
|
||||
flush();
|
||||
result.emit('end');
|
||||
});
|
||||
|
||||
function flush() {
|
||||
while (oneBuffer.length > 0 && otherBuffer.length > 0) {
|
||||
result.emit('data', zipper(oneBuffer.shift(), otherBuffer.shift()));
|
||||
}
|
||||
}
|
||||
|
||||
stream.pipe(through(f => otherBuffer.push(f)));
|
||||
|
||||
return duplex(pass, result);
|
||||
}
|
||||
|
||||
function template(lines: string[]): string {
|
||||
let indent = '', wrap = '';
|
||||
|
||||
if (lines.length > 1) {
|
||||
indent = '\t';
|
||||
wrap = '\n';
|
||||
}
|
||||
|
||||
return `/*---------------------------------------------------------
|
||||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*--------------------------------------------------------*/
|
||||
define([], [${ wrap + lines.map(l => indent + l).join(',\n') + wrap }]);`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream containing the patched JavaScript and source maps.
|
||||
*/
|
||||
function nls(): Stream {
|
||||
var input = through();
|
||||
var output = input.pipe(through(function (f: FileSourceMap) {
|
||||
if (!f.sourceMap) {
|
||||
return this.emit('error', new Error(`File ${ f.relative } does not have sourcemaps.`));
|
||||
}
|
||||
|
||||
let source = f.sourceMap.sources[0];
|
||||
if (!source) {
|
||||
return this.emit('error', new Error(`File ${ f.relative } does not have a source in the source map.`));
|
||||
}
|
||||
|
||||
const root = f.sourceMap.sourceRoot;
|
||||
if (root) {
|
||||
source = path.join(root, source);
|
||||
}
|
||||
|
||||
const typescript = f.sourceMap.sourcesContent[0];
|
||||
if (!typescript) {
|
||||
return this.emit('error', new Error(`File ${ f.relative } does not have the original content in the source map.`));
|
||||
}
|
||||
|
||||
nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
|
||||
}));
|
||||
|
||||
return duplex(input, output);
|
||||
}
|
||||
|
||||
function isImportNode(node: ts.Node): boolean {
|
||||
return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration;
|
||||
}
|
||||
|
||||
module nls {
|
||||
|
||||
export interface INlsStringResult {
|
||||
javascript: string;
|
||||
sourcemap: sm.RawSourceMap;
|
||||
nls?: string;
|
||||
nlsKeys?: string;
|
||||
}
|
||||
|
||||
export interface ISpan {
|
||||
start: ts.LineAndCharacter;
|
||||
end: ts.LineAndCharacter;
|
||||
}
|
||||
|
||||
export interface ILocalizeCall {
|
||||
keySpan: ISpan;
|
||||
key: string;
|
||||
valueSpan: ISpan;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface ILocalizeAnalysisResult {
|
||||
localizeCalls: ILocalizeCall[];
|
||||
nlsExpressions: ISpan[];
|
||||
}
|
||||
|
||||
export interface IPatch {
|
||||
span: ISpan;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export function fileFrom(file: File, contents: string, path: string = file.path) {
|
||||
return new File({
|
||||
contents: new Buffer(contents),
|
||||
base: file.base,
|
||||
cwd: file.cwd,
|
||||
path: path
|
||||
});
|
||||
}
|
||||
|
||||
export function mappedPositionFrom(source: string, lc: ts.LineAndCharacter): sm.MappedPosition {
|
||||
return { source, line: lc.line + 1, column: lc.character };
|
||||
}
|
||||
|
||||
export function lcFrom(position: sm.Position): ts.LineAndCharacter {
|
||||
return { line: position.line - 1, character: position.column };
|
||||
}
|
||||
|
||||
export class SingleFileServiceHost implements ts.LanguageServiceHost {
|
||||
|
||||
private file: ts.IScriptSnapshot;
|
||||
private lib: ts.IScriptSnapshot;
|
||||
|
||||
constructor(private options: ts.CompilerOptions, private filename: string, contents: string) {
|
||||
this.file = ts.ScriptSnapshot.fromString(contents);
|
||||
this.lib = ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
|
||||
getCompilationSettings = () => this.options;
|
||||
getScriptFileNames = () => [this.filename];
|
||||
getScriptVersion = () => '1';
|
||||
getScriptSnapshot = (name: string) => name === this.filename ? this.file : this.lib;
|
||||
getCurrentDirectory = () => '';
|
||||
getDefaultLibFileName = () => 'lib.d.ts';
|
||||
}
|
||||
|
||||
function isCallExpressionWithinTextSpanCollectStep(textSpan: ts.TextSpan, node: ts.Node): CollectStepResult {
|
||||
if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) {
|
||||
return CollectStepResult.No;
|
||||
}
|
||||
|
||||
return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse;
|
||||
}
|
||||
|
||||
export function analyze(contents: string, options: ts.CompilerOptions = {}): ILocalizeAnalysisResult {
|
||||
const filename = 'file.ts';
|
||||
const serviceHost = new SingleFileServiceHost(assign(clone(options), { noResolve: true }), filename, contents);
|
||||
const service = ts.createLanguageService(serviceHost);
|
||||
const sourceFile = service.getSourceFile(filename);
|
||||
|
||||
// all imports
|
||||
const imports = lazy(collect(sourceFile, n => isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
|
||||
|
||||
// import nls = require('vs/nls');
|
||||
const importEqualsDeclarations = imports
|
||||
.filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration)
|
||||
.map(n => <ts.ImportEqualsDeclaration> n)
|
||||
.filter(d => d.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)
|
||||
.filter(d => (<ts.ExternalModuleReference>d.moduleReference).expression.getText() === "'vs/nls'");
|
||||
|
||||
// import ... from 'vs/nls';
|
||||
const importDeclarations = imports
|
||||
.filter(n => n.kind === ts.SyntaxKind.ImportDeclaration)
|
||||
.map(n => <ts.ImportDeclaration> n)
|
||||
.filter(d => d.moduleSpecifier.kind === ts.SyntaxKind.StringLiteral)
|
||||
.filter(d => d.moduleSpecifier.getText() === "'vs/nls'")
|
||||
.filter(d => !!d.importClause && !!d.importClause.namedBindings);
|
||||
|
||||
const nlsExpressions = importEqualsDeclarations
|
||||
.map(d => (<ts.ExternalModuleReference>d.moduleReference).expression)
|
||||
.concat(importDeclarations.map(d => d.moduleSpecifier))
|
||||
.map<ISpan>(d => ({
|
||||
start: ts.getLineAndCharacterOfPosition(sourceFile, d.getStart()),
|
||||
end: ts.getLineAndCharacterOfPosition(sourceFile, d.getEnd())
|
||||
}));
|
||||
|
||||
// `nls.localize(...)` calls
|
||||
const nlsLocalizeCallExpressions = importDeclarations
|
||||
.filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamespaceImport)
|
||||
.map(d => (<ts.NamespaceImport> d.importClause.namedBindings).name)
|
||||
.concat(importEqualsDeclarations.map(d => d.name))
|
||||
|
||||
// find read-only references to `nls`
|
||||
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
|
||||
.flatten()
|
||||
.filter(r => !r.isWriteAccess)
|
||||
|
||||
// find the deepest call expressions AST nodes that contain those references
|
||||
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
|
||||
.map(a => lazy(a).last())
|
||||
.filter(n => !!n)
|
||||
.map(n => <ts.CallExpression> n)
|
||||
|
||||
// only `localize` calls
|
||||
.filter(n => n.expression.kind === ts.SyntaxKind.PropertyAccessExpression && (<ts.PropertyAccessExpression> n.expression).name.getText() === 'localize');
|
||||
|
||||
// `localize` named imports
|
||||
const allLocalizeImportDeclarations = importDeclarations
|
||||
.filter(d => d.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports)
|
||||
.map(d => (<ts.NamedImports> d.importClause.namedBindings).elements)
|
||||
.flatten()
|
||||
|
||||
// `localize` read-only references
|
||||
const localizeReferences = allLocalizeImportDeclarations
|
||||
.filter(d => d.name.getText() === 'localize')
|
||||
.map(n => service.getReferencesAtPosition(filename, n.pos + 1))
|
||||
.flatten()
|
||||
.filter(r => !r.isWriteAccess);
|
||||
|
||||
// custom named `localize` read-only references
|
||||
const namedLocalizeReferences = allLocalizeImportDeclarations
|
||||
.filter(d => d.propertyName && d.propertyName.getText() === 'localize')
|
||||
.map(n => service.getReferencesAtPosition(filename, n.name.pos + 1))
|
||||
.flatten()
|
||||
.filter(r => !r.isWriteAccess);
|
||||
|
||||
// find the deepest call expressions AST nodes that contain those references
|
||||
const localizeCallExpressions = localizeReferences
|
||||
.concat(namedLocalizeReferences)
|
||||
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
|
||||
.map(a => lazy(a).last())
|
||||
.filter(n => !!n)
|
||||
.map(n => <ts.CallExpression> n);
|
||||
|
||||
// collect everything
|
||||
const localizeCalls = nlsLocalizeCallExpressions
|
||||
.concat(localizeCallExpressions)
|
||||
.map(e => e.arguments)
|
||||
.filter(a => a.length > 1)
|
||||
.sort((a, b) => a[0].getStart() - b[0].getStart())
|
||||
.map<ILocalizeCall>(a => ({
|
||||
keySpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[0].getEnd()) },
|
||||
key: a[0].getText(),
|
||||
valueSpan: { start: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getStart()), end: ts.getLineAndCharacterOfPosition(sourceFile, a[1].getEnd()) },
|
||||
value: a[1].getText()
|
||||
}));
|
||||
|
||||
return {
|
||||
localizeCalls: localizeCalls.toArray(),
|
||||
nlsExpressions: nlsExpressions.toArray()
|
||||
};
|
||||
}
|
||||
|
||||
export class TextModel {
|
||||
|
||||
private lines: string[];
|
||||
private lineEndings: string[];
|
||||
|
||||
constructor(contents: string) {
|
||||
const regex = /\r\n|\r|\n/g;
|
||||
let index = 0;
|
||||
let match: RegExpExecArray;
|
||||
|
||||
this.lines = [];
|
||||
this.lineEndings = [];
|
||||
|
||||
while (match = regex.exec(contents)) {
|
||||
this.lines.push(contents.substring(index, match.index));
|
||||
this.lineEndings.push(match[0]);
|
||||
index = regex.lastIndex;
|
||||
}
|
||||
|
||||
if (contents.length > 0) {
|
||||
this.lines.push(contents.substring(index, contents.length));
|
||||
this.lineEndings.push('');
|
||||
}
|
||||
}
|
||||
|
||||
public get(index: number): string {
|
||||
return this.lines[index];
|
||||
}
|
||||
|
||||
public set(index: number, line: string): void {
|
||||
this.lines[index] = line;
|
||||
}
|
||||
|
||||
public get lineCount(): number {
|
||||
return this.lines.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies patch(es) to the model.
|
||||
* Multiple patches must be ordered.
|
||||
* Does not support patches spanning multiple lines.
|
||||
*/
|
||||
public apply(patch: IPatch): void {
|
||||
const startLineNumber = patch.span.start.line;
|
||||
const endLineNumber = patch.span.end.line;
|
||||
|
||||
const startLine = this.lines[startLineNumber] || '';
|
||||
const endLine = this.lines[endLineNumber] || '';
|
||||
|
||||
this.lines[startLineNumber] = [
|
||||
startLine.substring(0, patch.span.start.character),
|
||||
patch.content,
|
||||
endLine.substring(patch.span.end.character)
|
||||
].join('');
|
||||
|
||||
for (let i = startLineNumber + 1; i <= endLineNumber; i++) {
|
||||
this.lines[i] = '';
|
||||
}
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return lazy(this.lines).zip(this.lineEndings)
|
||||
.flatten().toArray().join('');
|
||||
}
|
||||
}
|
||||
|
||||
export function patchJavascript(patches: IPatch[], contents: string, moduleId: string): string {
|
||||
const model = new nls.TextModel(contents);
|
||||
|
||||
// patch the localize calls
|
||||
lazy(patches).reverse().each(p => model.apply(p));
|
||||
|
||||
// patch the 'vs/nls' imports
|
||||
const firstLine = model.get(0);
|
||||
const patchedFirstLine = firstLine.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${ moduleId }$1`);
|
||||
model.set(0, patchedFirstLine);
|
||||
|
||||
return model.toString();
|
||||
}
|
||||
|
||||
export function patchSourcemap(patches: IPatch[], rsm: sm.RawSourceMap, smc: sm.SourceMapConsumer): sm.RawSourceMap {
|
||||
const smg = new sm.SourceMapGenerator({
|
||||
file: rsm.file,
|
||||
sourceRoot: rsm.sourceRoot
|
||||
});
|
||||
|
||||
patches = patches.reverse();
|
||||
let currentLine = -1;
|
||||
let currentLineDiff = 0;
|
||||
let source = null;
|
||||
|
||||
smc.eachMapping(m => {
|
||||
const patch = patches[patches.length - 1];
|
||||
const original = { line: m.originalLine, column: m.originalColumn };
|
||||
const generated = { line: m.generatedLine, column: m.generatedColumn };
|
||||
|
||||
if (currentLine !== generated.line) {
|
||||
currentLineDiff = 0;
|
||||
}
|
||||
|
||||
currentLine = generated.line;
|
||||
generated.column += currentLineDiff;
|
||||
|
||||
if (patch && m.generatedLine - 1 === patch.span.end.line && m.generatedColumn === patch.span.end.character) {
|
||||
const originalLength = patch.span.end.character - patch.span.start.character;
|
||||
const modifiedLength = patch.content.length;
|
||||
const lengthDiff = modifiedLength - originalLength;
|
||||
currentLineDiff += lengthDiff;
|
||||
generated.column += lengthDiff;
|
||||
|
||||
patches.pop();
|
||||
}
|
||||
|
||||
source = rsm.sourceRoot ? path.relative(rsm.sourceRoot, m.source) : m.source;
|
||||
source = source.replace(/\\/g, '/');
|
||||
smg.addMapping({ source, name: m.name, original, generated});
|
||||
}, null, sm.SourceMapConsumer.GENERATED_ORDER);
|
||||
|
||||
if (source) {
|
||||
smg.setSourceContent(source, smc.sourceContentFor(source));
|
||||
}
|
||||
|
||||
return JSON.parse(smg.toString());
|
||||
}
|
||||
|
||||
export function patch(moduleId: string, typescript: string, javascript: string, sourcemap: sm.RawSourceMap): INlsStringResult {
|
||||
const { localizeCalls, nlsExpressions } = analyze(typescript);
|
||||
|
||||
if (localizeCalls.length === 0) {
|
||||
return { javascript, sourcemap };
|
||||
}
|
||||
|
||||
const nlsKeys = template(localizeCalls.map(lc => lc.key));
|
||||
const nls = template(localizeCalls.map(lc => lc.value));
|
||||
const smc = new sm.SourceMapConsumer(sourcemap);
|
||||
const positionFrom = mappedPositionFrom.bind(null, sourcemap.sources[0]);
|
||||
let i = 0;
|
||||
|
||||
// build patches
|
||||
const patches = lazy(localizeCalls)
|
||||
.map(lc => ([
|
||||
{ range: lc.keySpan, content: '' + (i++) },
|
||||
{ range: lc.valueSpan, content: 'null' }
|
||||
]))
|
||||
.flatten()
|
||||
.map<IPatch>(c => {
|
||||
const start = lcFrom(smc.generatedPositionFor(positionFrom(c.range.start)));
|
||||
const end = lcFrom(smc.generatedPositionFor(positionFrom(c.range.end)));
|
||||
return { span: { start, end }, content: c.content };
|
||||
})
|
||||
.toArray();
|
||||
|
||||
javascript = patchJavascript(patches, javascript, moduleId);
|
||||
|
||||
// since imports are not within the sourcemap information,
|
||||
// we must do this MacGyver style
|
||||
if (nlsExpressions.length) {
|
||||
javascript = javascript.replace(/^define\(.*$/m, line => {
|
||||
return line.replace(/(['"])vs\/nls\1/g, `$1vs/nls!${ moduleId }$1`);
|
||||
});
|
||||
}
|
||||
|
||||
sourcemap = patchSourcemap(patches, sourcemap, smc);
|
||||
|
||||
return { javascript, sourcemap, nlsKeys, nls };
|
||||
}
|
||||
|
||||
export function patchFiles(javascriptFile: File, typescript: string): File[] {
|
||||
// hack?
|
||||
const moduleId = javascriptFile.relative
|
||||
.replace(/\.js$/, '')
|
||||
.replace(/\\/g, '/');
|
||||
|
||||
const { javascript, sourcemap, nlsKeys, nls } = patch(
|
||||
moduleId,
|
||||
typescript,
|
||||
javascriptFile.contents.toString(),
|
||||
(<any>javascriptFile).sourceMap
|
||||
);
|
||||
|
||||
const result: File[] = [fileFrom(javascriptFile, javascript)];
|
||||
(<any>result[0]).sourceMap = sourcemap;
|
||||
|
||||
if (nlsKeys) {
|
||||
result.push(fileFrom(javascriptFile, nlsKeys, javascriptFile.path.replace(/\.js$/, '.nls.keys.js')));
|
||||
}
|
||||
|
||||
if (nls) {
|
||||
result.push(fileFrom(javascriptFile, nls, javascriptFile.path.replace(/\.js$/, '.nls.js')));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export = nls;
|
|
@ -0,0 +1,42 @@
|
|||
var es = require('event-stream');
|
||||
var _ = require('underscore');
|
||||
|
||||
var allErrors = [];
|
||||
var count = 0;
|
||||
|
||||
function onStart() {
|
||||
if (count++ > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('*** Starting...');
|
||||
}
|
||||
|
||||
function onEnd() {
|
||||
if (--count > 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
var errors = _.flatten(allErrors);
|
||||
errors.map(function (err) { console.log('*** Error:', err); });
|
||||
console.log('*** Finished with', errors.length, 'errors.');
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
var errors = [];
|
||||
allErrors.push(errors);
|
||||
|
||||
return function (err) {
|
||||
if (err) {
|
||||
errors.push(err);
|
||||
return;
|
||||
}
|
||||
|
||||
errors.length = 0;
|
||||
onStart();
|
||||
return es.through(null, function () {
|
||||
onEnd();
|
||||
this.emit('end');
|
||||
});
|
||||
};
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
var es = require('event-stream');
|
||||
var path = require('path');
|
||||
|
||||
module.exports = function (opts) {
|
||||
return es.mapSync(function (file) {
|
||||
if (file.stat.isDirectory()) {
|
||||
return file;
|
||||
}
|
||||
var contents = file.contents.toString('utf8');
|
||||
|
||||
if (opts.complain) {
|
||||
if (contents.indexOf('\r\n') >= 0) {
|
||||
console.log(file.path + ' uses \\r\\n');
|
||||
}
|
||||
|
||||
if (opts.whitespace) {
|
||||
var lines = contents.split(/\r\n|\r|\n/);
|
||||
var hadErrorLineNumber = 0;
|
||||
for (var i = 0, len = lines.length; i < len; i++) {
|
||||
var line = lines[i];
|
||||
if (line.length === 0) {
|
||||
// empty lines are OK
|
||||
continue;
|
||||
}
|
||||
|
||||
if (/^[\t]*[^\s]/.test(line)) {
|
||||
// good indent
|
||||
continue;
|
||||
} else if (/^[\t]* \*/.test(line)) {
|
||||
// block comment using an extra space
|
||||
continue;
|
||||
} else if (/^[\t]+$/.test(line)) {
|
||||
// empty line
|
||||
continue;
|
||||
} else {
|
||||
// console.log(file.path + '(' + hadErrorLineNumber + ',1): Mixed whitespace indentation');
|
||||
hadErrorLineNumber = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hadErrorLineNumber) {
|
||||
console.log(file.path + '(' + hadErrorLineNumber + ',1): Mixed whitespace indentation');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var lines = contents.split(/\r\n|\r|\n/);
|
||||
|
||||
if (opts.whitespace) {
|
||||
for (var i = 0, len = lines.length; i < len; i++) {
|
||||
var line = lines[i];
|
||||
line = line.replace(/^\ {28}/, '\t\t\t\t\t\t\t');
|
||||
line = line.replace(/^\ {24}/, '\t\t\t\t\t\t');
|
||||
line = line.replace(/^\ {20}/, '\t\t\t\t\t');
|
||||
line = line.replace(/^\ {16}/, '\t\t\t\t');
|
||||
line = line.replace(/^\ {12}/, '\t\t\t');
|
||||
line = line.replace(/^\ {8}/, '\t\t');
|
||||
line = line.replace(/^\ {4}/, '\t');
|
||||
lines[i] = line;
|
||||
}
|
||||
}
|
||||
|
||||
file.contents = new Buffer(lines.join('\n'), 'utf8');
|
||||
}
|
||||
return file;
|
||||
});
|
||||
};
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,4 @@
|
|||
declare module 'clone' {
|
||||
function fn<T>(obj: T): T;
|
||||
export = fn;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
declare module "event-stream" {
|
||||
import { Stream } from 'stream';
|
||||
import { ThroughStream } from 'through';
|
||||
|
||||
function merge(...stream: Stream[]): ThroughStream;
|
||||
function concat(...stream: Stream[]): ThroughStream;
|
||||
function duplex(istream: Stream, ostream: Stream): ThroughStream;
|
||||
|
||||
function through(write?: (data: any) => void, end?: () => void,
|
||||
opts?: {autoDestroy: boolean; }): ThroughStream;
|
||||
|
||||
function readArray<T>(array: T[]): ThroughStream;
|
||||
function writeArray<T>(cb: (err:Error, array:T[]) => void): ThroughStream;
|
||||
|
||||
function mapSync<I,O>(cb: (data:I) => O): ThroughStream;
|
||||
function map<I,O>(cb: (data:I, cb:(err?:Error, data?: O)=>void) => O): ThroughStream;
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
declare module 'gulp-filter' {
|
||||
import { ThroughStream } from 'through';
|
||||
|
||||
function fn(pattern: string): ThroughStream;
|
||||
function fn(patterns: string[]): ThroughStream;
|
||||
|
||||
export = fn;
|
||||
}
|
|
@ -0,0 +1,273 @@
|
|||
// Type definitions for Lazy.js 0.3.2
|
||||
// Project: https://github.com/dtao/lazy.js/
|
||||
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
|
||||
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||
|
||||
declare function Lazy(value: string): Lazy.StringLikeSequence;
|
||||
declare function Lazy<T>(value: T[]): Lazy.ArrayLikeSequence<T>;
|
||||
declare function Lazy(value: any[]): Lazy.ArrayLikeSequence<any>;
|
||||
declare function Lazy<T>(value: Object): Lazy.ObjectLikeSequence<T>;
|
||||
declare function Lazy(value: Object): Lazy.ObjectLikeSequence<any>;
|
||||
|
||||
declare module Lazy {
|
||||
function strict(): StrictLazy;
|
||||
function generate<T>(generatorFn: GeneratorCallback<T>, length?: number): GeneratedSequence<T>;
|
||||
function range(to: number): GeneratedSequence<number>;
|
||||
function range(from: number, to: number, step?: number): GeneratedSequence<number>;
|
||||
function repeat<T>(value: T, count?: number): GeneratedSequence<T>;
|
||||
function on<T>(eventType: string): Sequence<T>;
|
||||
function readFile(path: string): StringLikeSequence;
|
||||
function makeHttpRequest(path: string): StringLikeSequence;
|
||||
|
||||
interface StrictLazy {
|
||||
(value: string): StringLikeSequence;
|
||||
<T>(value: T[]): ArrayLikeSequence<T>;
|
||||
(value: any[]): ArrayLikeSequence<any>;
|
||||
<T>(value: Object): ObjectLikeSequence<T>;
|
||||
(value: Object): ObjectLikeSequence<any>;
|
||||
strict(): StrictLazy;
|
||||
generate<T>(generatorFn: GeneratorCallback<T>, length?: number): GeneratedSequence<T>;
|
||||
range(to: number): GeneratedSequence<number>;
|
||||
range(from: number, to: number, step?: number): GeneratedSequence<number>;
|
||||
repeat<T>(value: T, count?: number): GeneratedSequence<T>;
|
||||
on<T>(eventType: string): Sequence<T>;
|
||||
readFile(path: string): StringLikeSequence;
|
||||
makeHttpRequest(path: string): StringLikeSequence;
|
||||
}
|
||||
|
||||
interface ArrayLike<T> {
|
||||
length: number;
|
||||
[index: number]: T;
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
(): void;
|
||||
}
|
||||
|
||||
interface ErrorCallback {
|
||||
(error: any): void;
|
||||
}
|
||||
|
||||
interface ValueCallback<T> {
|
||||
(value: T): void;
|
||||
}
|
||||
|
||||
interface GetKeyCallback<T> {
|
||||
(value: T): string;
|
||||
}
|
||||
|
||||
interface TestCallback<T> {
|
||||
(value: T): boolean;
|
||||
}
|
||||
|
||||
interface MapCallback<T, U> {
|
||||
(value: T): U;
|
||||
}
|
||||
|
||||
interface MapStringCallback {
|
||||
(value: string): string;
|
||||
}
|
||||
|
||||
interface NumberCallback<T> {
|
||||
(value: T): number;
|
||||
}
|
||||
|
||||
interface MemoCallback<T, U> {
|
||||
(memo: U, value: T): U;
|
||||
}
|
||||
|
||||
interface GeneratorCallback<T> {
|
||||
(index: number): T;
|
||||
}
|
||||
|
||||
interface CompareCallback {
|
||||
(x: any, y: any): number;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
interface Iterator<T> {
|
||||
new (sequence: Sequence<T>): Iterator<T>;
|
||||
current(): T;
|
||||
moveNext(): boolean;
|
||||
}
|
||||
|
||||
interface GeneratedSequence<T> extends Sequence<T> {
|
||||
new(generatorFn: GeneratorCallback<T>, length: number): GeneratedSequence<T>;
|
||||
length(): number;
|
||||
}
|
||||
|
||||
interface AsyncSequence<T> extends SequenceBase<T> {
|
||||
each(callback: ValueCallback<T>): AsyncHandle<T>;
|
||||
}
|
||||
|
||||
interface AsyncHandle<T> {
|
||||
cancel(): void;
|
||||
onComplete(callback: Callback): void;
|
||||
onError(callback: ErrorCallback): void;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
module Sequence {
|
||||
function define(methodName: string[], overrides: Object): Function;
|
||||
}
|
||||
|
||||
interface Sequence<T> extends SequenceBase<T> {
|
||||
each(eachFn: ValueCallback<T>): Sequence<T>;
|
||||
}
|
||||
|
||||
interface ArraySequence<T> extends SequenceBase<T[]> {
|
||||
flatten(): Sequence<T>;
|
||||
}
|
||||
|
||||
interface SequenceBase<T> extends SequenceBaser<T> {
|
||||
first(): any;
|
||||
first(count: number): Sequence<T>;
|
||||
indexOf(value: any, startIndex?: number): Sequence<T>;
|
||||
|
||||
last(): any;
|
||||
last(count: number): Sequence<T>;
|
||||
lastIndexOf(value: any): Sequence<T>;
|
||||
|
||||
reverse(): Sequence<T>;
|
||||
}
|
||||
|
||||
interface SequenceBaser<T> {
|
||||
// TODO improve define() (needs ugly overload)
|
||||
async(interval: number): AsyncSequence<T>;
|
||||
chunk(size: number): Sequence<T>;
|
||||
compact(): Sequence<T>;
|
||||
concat(var_args: T[]): Sequence<T>;
|
||||
concat(sequence: Sequence<T>): Sequence<T>;
|
||||
consecutive(length: number): Sequence<T>;
|
||||
contains(value: T): boolean;
|
||||
countBy(keyFn: GetKeyCallback<T>): ObjectLikeSequence<T>;
|
||||
countBy(propertyName: string): ObjectLikeSequence<T>;
|
||||
dropWhile(predicateFn: TestCallback<T>): Sequence<T>;
|
||||
every(predicateFn: TestCallback<T>): boolean;
|
||||
filter(predicateFn: TestCallback<T>): Sequence<T>;
|
||||
find(predicateFn: TestCallback<T>): Sequence<T>;
|
||||
findWhere(properties: Object): Sequence<T>;
|
||||
|
||||
groupBy(keyFn: GetKeyCallback<T>): ObjectLikeSequence<T>;
|
||||
initial(count?: number): Sequence<T>;
|
||||
intersection(var_args: T[]): Sequence<T>;
|
||||
invoke(methodName: string): Sequence<T>;
|
||||
isEmpty(): boolean;
|
||||
join(delimiter?: string): string;
|
||||
map<U>(mapFn: MapCallback<T, U[]>): ArraySequence<U>;
|
||||
map<U>(mapFn: MapCallback<T, U>): Sequence<U>;
|
||||
|
||||
max(valueFn?: NumberCallback<T>): T;
|
||||
min(valueFn?: NumberCallback<T>): T;
|
||||
none(valueFn?: TestCallback<T>): boolean;
|
||||
pluck(propertyName: string): Sequence<T>;
|
||||
reduce<U>(aggregatorFn: MemoCallback<T, U>, memo?: U): U;
|
||||
reduceRight<U>(aggregatorFn: MemoCallback<T, U>, memo: U): U;
|
||||
reject(predicateFn: TestCallback<T>): Sequence<T>;
|
||||
rest(count?: number): Sequence<T>;
|
||||
shuffle(): Sequence<T>;
|
||||
some(predicateFn?: TestCallback<T>): boolean;
|
||||
sort(sortFn?: CompareCallback, descending?: boolean): Sequence<T>;
|
||||
sortBy(sortFn: string, descending?: boolean): Sequence<T>;
|
||||
sortBy(sortFn: NumberCallback<T>, descending?: boolean): Sequence<T>;
|
||||
sortedIndex(value: T): Sequence<T>;
|
||||
size(): number;
|
||||
sum(valueFn?: NumberCallback<T>): Sequence<T>;
|
||||
takeWhile(predicateFn: TestCallback<T>): Sequence<T>;
|
||||
union(var_args: T[]): Sequence<T>;
|
||||
uniq(): Sequence<T>;
|
||||
where(properties: Object): Sequence<T>;
|
||||
without(...var_args: T[]): Sequence<T>;
|
||||
without(var_args: T[]): Sequence<T>;
|
||||
zip(var_args: T[]): ArraySequence<T>;
|
||||
|
||||
toArray(): T[];
|
||||
toObject(): Object;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
module ArrayLikeSequence {
|
||||
function define(methodName: string[], overrides: Object): Function;
|
||||
}
|
||||
|
||||
interface ArrayLikeSequence<T> extends Sequence<T> {
|
||||
// define()X;
|
||||
concat(var_args: T[]): ArrayLikeSequence<T>;
|
||||
concat(sequence: Sequence<T>): Sequence<T>;
|
||||
first(count?: number): ArrayLikeSequence<T>;
|
||||
get(index: number): T;
|
||||
length(): number;
|
||||
map<U>(mapFn: MapCallback<T, U[]>): ArraySequence<U>;
|
||||
map<U>(mapFn: MapCallback<T, U>): ArrayLikeSequence<U>;
|
||||
pop(): ArrayLikeSequence<T>;
|
||||
rest(count?: number): ArrayLikeSequence<T>;
|
||||
reverse(): ArrayLikeSequence<T>;
|
||||
shift(): ArrayLikeSequence<T>;
|
||||
slice(begin: number, end?: number): ArrayLikeSequence<T>;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
module ObjectLikeSequence {
|
||||
function define(methodName: string[], overrides: Object): Function;
|
||||
}
|
||||
|
||||
interface ObjectLikeSequence<T> extends Sequence<T> {
|
||||
assign(other: Object): ObjectLikeSequence<T>;
|
||||
// throws error
|
||||
//async(): X;
|
||||
defaults(defaults: Object): ObjectLikeSequence<T>;
|
||||
functions(): Sequence<T>;
|
||||
get(property: string): ObjectLikeSequence<T>;
|
||||
invert(): ObjectLikeSequence<T>;
|
||||
keys(): Sequence<string>;
|
||||
omit(properties: string[]): ObjectLikeSequence<T>;
|
||||
pairs(): Sequence<T>;
|
||||
pick(properties: string[]): ObjectLikeSequence<T>;
|
||||
toArray(): T[];
|
||||
toObject(): Object;
|
||||
values(): Sequence<T>;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
module StringLikeSequence {
|
||||
function define(methodName: string[], overrides: Object): Function;
|
||||
}
|
||||
|
||||
interface StringLikeSequence extends SequenceBaser<string> {
|
||||
charAt(index: number): string;
|
||||
charCodeAt(index: number): number;
|
||||
contains(value: string): boolean;
|
||||
endsWith(suffix: string): boolean;
|
||||
|
||||
first(): string;
|
||||
first(count: number): StringLikeSequence;
|
||||
|
||||
indexOf(substring: string, startIndex?: number): number;
|
||||
|
||||
last(): string;
|
||||
last(count: number): StringLikeSequence;
|
||||
|
||||
lastIndexOf(substring: string, startIndex?: number): number;
|
||||
mapString(mapFn: MapStringCallback): StringLikeSequence;
|
||||
match(pattern: RegExp): StringLikeSequence;
|
||||
reverse(): StringLikeSequence;
|
||||
|
||||
split(delimiter: string): StringLikeSequence;
|
||||
split(delimiter: RegExp): StringLikeSequence;
|
||||
|
||||
startsWith(prefix: string): boolean;
|
||||
substring(start: number, stop?: number): StringLikeSequence;
|
||||
toLowerCase(): StringLikeSequence;
|
||||
toUpperCase(): StringLikeSequence;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'lazy.js' {
|
||||
export = Lazy;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,4 @@
|
|||
declare module 'object-assign' {
|
||||
function fn(target: any, ...sources: any[]): any;
|
||||
export = fn;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
// Type definitions for source-map v0.1.38
|
||||
// Project: https://github.com/mozilla/source-map
|
||||
// Definitions by: Morten Houston Ludvigsen <https://github.com/MortenHoustonLudvigsen>
|
||||
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||
|
||||
declare module SourceMap {
|
||||
interface StartOfSourceMap {
|
||||
file?: string;
|
||||
sourceRoot?: string;
|
||||
}
|
||||
|
||||
interface RawSourceMap extends StartOfSourceMap {
|
||||
version: string;
|
||||
sources: Array<string>;
|
||||
names: Array<string>;
|
||||
sourcesContent?: string;
|
||||
mappings: string;
|
||||
}
|
||||
|
||||
interface Position {
|
||||
line: number;
|
||||
column: number;
|
||||
}
|
||||
|
||||
interface MappedPosition extends Position {
|
||||
source: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
interface MappingItem {
|
||||
source: string;
|
||||
generatedLine: number;
|
||||
generatedColumn: number;
|
||||
originalLine: number;
|
||||
originalColumn: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Mapping {
|
||||
generated: Position;
|
||||
original: Position;
|
||||
source: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
interface CodeWithSourceMap {
|
||||
code: string;
|
||||
map: SourceMapGenerator;
|
||||
}
|
||||
|
||||
class SourceMapConsumer {
|
||||
public static GENERATED_ORDER: number;
|
||||
public static ORIGINAL_ORDER: number;
|
||||
|
||||
constructor(rawSourceMap: RawSourceMap);
|
||||
public originalPositionFor(generatedPosition: Position): MappedPosition;
|
||||
public generatedPositionFor(originalPosition: MappedPosition): Position;
|
||||
public sourceContentFor(source: string): string;
|
||||
public eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void;
|
||||
}
|
||||
|
||||
class SourceMapGenerator {
|
||||
constructor(startOfSourceMap?: StartOfSourceMap);
|
||||
public static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
|
||||
public addMapping(mapping: Mapping): void;
|
||||
public setSourceContent(sourceFile: string, sourceContent: string): void;
|
||||
public applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void;
|
||||
public toString(): string;
|
||||
}
|
||||
|
||||
class SourceNode {
|
||||
constructor();
|
||||
constructor(line: number, column: number, source: string);
|
||||
constructor(line: number, column: number, source: string, chunk?: string, name?: string);
|
||||
public static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode;
|
||||
public add(chunk: string): void;
|
||||
public prepend(chunk: string): void;
|
||||
public setSourceContent(sourceFile: string, sourceContent: string): void;
|
||||
public walk(fn: (chunk: string, mapping: MappedPosition) => void): void;
|
||||
public walkSourceContents(fn: (file: string, content: string) => void): void;
|
||||
public join(sep: string): SourceNode;
|
||||
public replaceRight(pattern: string, replacement: string): SourceNode;
|
||||
public toString(): string;
|
||||
public toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'source-map' {
|
||||
export = SourceMap;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Type definitions for through
|
||||
// Project: https://github.com/dominictarr/through
|
||||
// Definitions by: Andrew Gaspar <https://github.com/AndrewGaspar/>
|
||||
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||
|
||||
declare module "through" {
|
||||
import stream = require("stream");
|
||||
|
||||
function through(write?: (data:any) => void,
|
||||
end?: () => void,
|
||||
opts?: {
|
||||
autoDestroy: boolean;
|
||||
}): through.ThroughStream;
|
||||
|
||||
module through {
|
||||
export interface ThroughStream extends stream.Transform {
|
||||
autoDestroy: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export = through;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
// Type definitions for vinyl 0.4.3
|
||||
// Project: https://github.com/wearefractal/vinyl
|
||||
// Definitions by: vvakame <https://github.com/vvakame/>, jedmao <https://github.com/jedmao>
|
||||
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||
|
||||
declare module 'vinyl' {
|
||||
|
||||
import fs = require('fs');
|
||||
|
||||
/**
|
||||
* A virtual file format.
|
||||
*/
|
||||
class File {
|
||||
constructor(options?: {
|
||||
/**
|
||||
* Default: process.cwd()
|
||||
*/
|
||||
cwd?: string;
|
||||
/**
|
||||
* Used for relative pathing. Typically where a glob starts.
|
||||
*/
|
||||
base?: string;
|
||||
/**
|
||||
* Full path to the file.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* Type: Buffer|Stream|null (Default: null)
|
||||
*/
|
||||
contents?: any;
|
||||
});
|
||||
|
||||
/**
|
||||
* Default: process.cwd()
|
||||
*/
|
||||
public cwd: string;
|
||||
/**
|
||||
* Used for relative pathing. Typically where a glob starts.
|
||||
*/
|
||||
public base: string;
|
||||
/**
|
||||
* Full path to the file.
|
||||
*/
|
||||
public path: string;
|
||||
public stat: fs.Stats;
|
||||
/**
|
||||
* Type: Buffer|Stream|null (Default: null)
|
||||
*/
|
||||
public contents: any;
|
||||
/**
|
||||
* Returns path.relative for the file base and file path.
|
||||
* Example:
|
||||
* var file = new File({
|
||||
* cwd: "/",
|
||||
* base: "/test/",
|
||||
* path: "/test/file.js"
|
||||
* });
|
||||
* console.log(file.relative); // file.js
|
||||
*/
|
||||
public relative: string;
|
||||
|
||||
public isBuffer(): boolean;
|
||||
|
||||
public isStream(): boolean;
|
||||
|
||||
public isNull(): boolean;
|
||||
|
||||
public isDirectory(): boolean;
|
||||
|
||||
/**
|
||||
* Returns a new File object with all attributes cloned. Custom attributes are deep-cloned.
|
||||
*/
|
||||
public clone(opts?: { contents?: boolean }): File;
|
||||
|
||||
/**
|
||||
* If file.contents is a Buffer, it will write it to the stream.
|
||||
* If file.contents is a Stream, it will pipe it to the stream.
|
||||
* If file.contents is null, it will do nothing.
|
||||
*/
|
||||
public pipe<T extends NodeJS.ReadWriteStream>(
|
||||
stream: T,
|
||||
opts?: {
|
||||
/**
|
||||
* If false, the destination stream will not be ended (same as node core).
|
||||
*/
|
||||
end?: boolean;
|
||||
}
|
||||
): T;
|
||||
|
||||
/**
|
||||
* Returns a pretty String interpretation of the File. Useful for console.log.
|
||||
*/
|
||||
public inspect(): string;
|
||||
}
|
||||
|
||||
export = File;
|
||||
|
||||
}
|
|
@ -0,0 +1,278 @@
|
|||
var es = require('event-stream');
|
||||
var debounce = require('debounce');
|
||||
var filter = require('gulp-filter');
|
||||
var azure = require('gulp-azure-storage');
|
||||
var rename = require('gulp-rename');
|
||||
var vzip = require('gulp-vinyl-zip');
|
||||
var util = require('gulp-util');
|
||||
var remote = require('gulp-remote-src');
|
||||
var _ = require('underscore');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var rimraf = require('rimraf');
|
||||
|
||||
var NoCancellationToken = {
|
||||
isCancellationRequested: function () {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
exports.incremental = function (streamProvider, initial, supportsCancellation) {
|
||||
var state = 'idle';
|
||||
var input = es.through();
|
||||
var output = es.through();
|
||||
var buffer = Object.create(null);
|
||||
|
||||
var token = !supportsCancellation ? null : {
|
||||
isCancellationRequested: function () {
|
||||
// console.log('isCancellationRequested', Object.keys(buffer).length, new Date());
|
||||
return Object.keys(buffer).length > 0;
|
||||
}
|
||||
};
|
||||
|
||||
var run = function (input, isCancellable) {
|
||||
state = 'running';
|
||||
|
||||
var stream = !supportsCancellation ? streamProvider() : streamProvider(isCancellable ? token : NoCancellationToken);
|
||||
|
||||
input
|
||||
.pipe(stream)
|
||||
.pipe(es.through(null, function () {
|
||||
state = 'idle';
|
||||
eventuallyRun();
|
||||
}))
|
||||
.pipe(output);
|
||||
};
|
||||
|
||||
if (initial) {
|
||||
run(initial, false);
|
||||
}
|
||||
|
||||
var eventuallyRun = debounce(function () {
|
||||
var paths = Object.keys(buffer);
|
||||
|
||||
if (paths.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = paths.map(function (path) {
|
||||
return buffer[path];
|
||||
});
|
||||
|
||||
buffer = Object.create(null);
|
||||
run(es.readArray(data), true);
|
||||
}, 500);
|
||||
|
||||
input.on('data', function (f) {
|
||||
buffer[f.path] = f;
|
||||
|
||||
if (state === 'idle') {
|
||||
eventuallyRun();
|
||||
}
|
||||
});
|
||||
|
||||
return es.duplex(input, output);
|
||||
};
|
||||
|
||||
exports.fixWin32DirectoryPermissions = function () {
|
||||
if (!/win32/.test(process.platform)) {
|
||||
return es.through();
|
||||
}
|
||||
|
||||
return es.mapSync(function (f) {
|
||||
if (f.stat && f.stat.isDirectory && f.stat.isDirectory()) {
|
||||
f.stat.mode = 16877;
|
||||
}
|
||||
|
||||
return f;
|
||||
});
|
||||
};
|
||||
|
||||
exports.setExecutableBit = function (pattern) {
|
||||
var setBit = es.mapSync(function (f) {
|
||||
f.stat.mode = /* 100755 */ 33261;
|
||||
return f;
|
||||
});
|
||||
|
||||
if (!pattern) {
|
||||
return setBit;
|
||||
}
|
||||
|
||||
var input = es.through();
|
||||
var _filter = filter(pattern, { restore: true });
|
||||
var output = input
|
||||
.pipe(_filter)
|
||||
.pipe(setBit)
|
||||
.pipe(_filter.restore);
|
||||
|
||||
return es.duplex(input, output);
|
||||
};
|
||||
|
||||
exports.handleAzureJson = function (env) {
|
||||
var input = es.through();
|
||||
var azureJsonFilter = filter('**/*.azure.json', { restore: true });
|
||||
|
||||
var allOpts = [];
|
||||
var result = es.through();
|
||||
|
||||
var output = input
|
||||
.pipe(azureJsonFilter)
|
||||
.pipe(es.through(function (f) {
|
||||
util.log('Downloading binaries from Azure:', util.colors.yellow(f.relative), '...');
|
||||
var opts = JSON.parse(f.contents.toString());
|
||||
opts.prefix = _.template(opts.zip || opts.prefix)(env);
|
||||
opts.output = path.join(path.dirname(f.relative), opts.output);
|
||||
allOpts.push(opts);
|
||||
}, function () {
|
||||
var streams = allOpts.map(function (opts) {
|
||||
var result = azure.download(_.extend(opts, { buffer: true, quiet: true }));
|
||||
|
||||
if (opts.zip) {
|
||||
result = result.pipe(vzip.src());
|
||||
}
|
||||
|
||||
return result.pipe(rename(function (p) {
|
||||
p.dirname = path.join(opts.output, p.dirname);
|
||||
}));
|
||||
});
|
||||
|
||||
es.merge(streams)
|
||||
.pipe(result)
|
||||
.pipe(es.through(null, function() {
|
||||
util.log('Finished downloading from Azure');
|
||||
this.emit('end');
|
||||
}));
|
||||
this.emit('end');
|
||||
}))
|
||||
.pipe(azureJsonFilter.restore);
|
||||
|
||||
return es.duplex(input, es.merge(output, result));
|
||||
};
|
||||
|
||||
exports.toFileUri = function (filePath) {
|
||||
var match = filePath.match(/^([a-z])\:(.*)$/i);
|
||||
|
||||
if (match) {
|
||||
filePath = '/' + match[1].toUpperCase() + ':' + match[2];
|
||||
}
|
||||
|
||||
return 'file://' + filePath.replace(/\\/g, '/');
|
||||
};
|
||||
|
||||
exports.rebase = function (base, append) {
|
||||
return es.mapSync(function (f) {
|
||||
if (append) {
|
||||
f.base = path.join(f.base, base);
|
||||
} else {
|
||||
f.base = base;
|
||||
}
|
||||
return f;
|
||||
});
|
||||
};
|
||||
|
||||
exports.skipDirectories = function () {
|
||||
return es.mapSync(function (f) {
|
||||
if (!f.isDirectory()) {
|
||||
return f;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.cleanNodeModule = function (name, excludes, isNative) {
|
||||
var glob = function (path) { return '**/node_modules/' + name + (path ? '/' + path : ''); };
|
||||
var negate = function (str) { return '!' + str; };
|
||||
|
||||
var allFilter = filter(glob('**'), { restore: true });
|
||||
var globs = [glob('**')].concat(excludes.map(_.compose(negate, glob)));
|
||||
|
||||
var input = es.through();
|
||||
var nodeModuleInput = input.pipe(allFilter);
|
||||
var output = nodeModuleInput.pipe(filter(globs));
|
||||
|
||||
if (isNative) {
|
||||
output = es.merge(output, nodeModuleInput.pipe(filter(glob('**/*.node'))));
|
||||
}
|
||||
|
||||
output = output.pipe(allFilter.restore);
|
||||
return es.duplex(input, output);
|
||||
};
|
||||
|
||||
exports.loadSourcemaps = function () {
|
||||
var input = es.through();
|
||||
|
||||
var output = input
|
||||
.pipe(es.map(function (f, cb) {
|
||||
if (f.sourceMap) {
|
||||
return cb(null, f);
|
||||
}
|
||||
|
||||
if (!f.contents) {
|
||||
return cb(new Error('empty file'));
|
||||
}
|
||||
|
||||
var contents = f.contents.toString('utf8');
|
||||
|
||||
var reg = /\/\/# sourceMappingURL=(.*)$/g;
|
||||
var lastMatch = null;
|
||||
var match = null;
|
||||
|
||||
while (match = reg.exec(contents)) {
|
||||
lastMatch = match;
|
||||
}
|
||||
|
||||
if (!lastMatch) {
|
||||
f.sourceMap = {
|
||||
version : 3,
|
||||
names: [],
|
||||
mappings: '',
|
||||
sources: [f.relative.replace(/\//g, '/')],
|
||||
sourcesContent: [contents]
|
||||
};
|
||||
|
||||
return cb(null, f);
|
||||
}
|
||||
|
||||
f.contents = new Buffer(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
|
||||
|
||||
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
|
||||
if (err) { return cb(err); }
|
||||
|
||||
f.sourceMap = JSON.parse(contents);
|
||||
cb(null, f);
|
||||
});
|
||||
}));
|
||||
|
||||
return es.duplex(input, output);
|
||||
};
|
||||
|
||||
exports.rimraf = function(dir) {
|
||||
return function (cb) {
|
||||
rimraf(dir, cb);
|
||||
};
|
||||
};
|
||||
|
||||
exports.downloadExtensions = function(extensions) {
|
||||
var streams = Object.keys(extensions).map(function (fullName) {
|
||||
var version = extensions[fullName];
|
||||
var match = /^([^.]+)\.([^.]+)$/.exec(fullName);
|
||||
|
||||
if (!match) {
|
||||
throw new Error('Bad extension: ' + fullName);
|
||||
}
|
||||
|
||||
var publisher = match[1];
|
||||
var name = match[2];
|
||||
var url = 'https://' + publisher + '.gallery.vsassets.io/_apis/public/gallery/publisher/'
|
||||
+ publisher + '/extension/' + name + '/' + version
|
||||
+ '/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage';
|
||||
|
||||
return remote(url, { base: '' })
|
||||
.pipe(vzip.src())
|
||||
.pipe(filter('extension/**'))
|
||||
.pipe(rename(function (p) {
|
||||
p.dirname = path.posix.join(fullName, p.dirname.replace(/^extension[/\\]?/, ''));
|
||||
}));
|
||||
});
|
||||
|
||||
return es.merge(streams);
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
var es = require('event-stream');
|
||||
|
||||
function handleDeletions() {
|
||||
return es.mapSync(function (f) {
|
||||
if (!f.contents) {
|
||||
f.contents = new Buffer('');
|
||||
f.stat = { mtime: new Date() };
|
||||
}
|
||||
|
||||
return f;
|
||||
});
|
||||
}
|
||||
|
||||
var watch = process.platform === 'win32' ? require('./watch-win32') : require('gulp-watch');
|
||||
|
||||
module.exports = function () {
|
||||
return watch.apply(null, arguments)
|
||||
.pipe(handleDeletions());
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "watch",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"author": "Microsoft ",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"gulp-watch": "^4.3.5"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
var path = require('path');
|
||||
var cp = require('child_process');
|
||||
var fs = require('fs');
|
||||
var File = require('vinyl');
|
||||
var es = require('event-stream');
|
||||
var filter = require('gulp-filter');
|
||||
|
||||
var watcherPath = path.join(__dirname, 'watcher.exe');
|
||||
|
||||
function toChangeType(type) {
|
||||
switch (type) {
|
||||
case '0': return 'change';
|
||||
case '1': return 'add';
|
||||
default: return 'unlink';
|
||||
}
|
||||
}
|
||||
|
||||
function watch(root) {
|
||||
var result = es.through();
|
||||
var child = cp.spawn(watcherPath, [root]);
|
||||
|
||||
child.stdout.on('data', function(data) {
|
||||
var lines = data.toString('utf8').split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i].trim();
|
||||
if (line.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var changeType = line[0];
|
||||
var changePath = line.substr(2);
|
||||
var changePathFull = path.join(root, changePath);
|
||||
|
||||
var file = new File({
|
||||
path: changePathFull,
|
||||
base: root
|
||||
});
|
||||
|
||||
file.event = toChangeType(changeType);
|
||||
result.emit('data', file);
|
||||
}
|
||||
});
|
||||
|
||||
child.stderr.on('data', function(data) {
|
||||
result.emit('error', data);
|
||||
});
|
||||
|
||||
child.on('exit', function(code) {
|
||||
result.emit('error', 'Watcher died with code ' + code);
|
||||
child = null;
|
||||
});
|
||||
|
||||
process.once('SIGTERM', function () { process.exit(0); });
|
||||
process.once('SIGTERM', function () { process.exit(0); });
|
||||
process.once('exit', function () { child && child.kill(); });
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var cache = Object.create(null);
|
||||
|
||||
module.exports = function(pattern, options) {
|
||||
options = options || {};
|
||||
|
||||
var cwd = path.normalize(options.cwd || process.cwd());
|
||||
var watcher = cache[cwd];
|
||||
|
||||
if (!watcher) {
|
||||
watcher = cache[cwd] = watch(cwd);
|
||||
}
|
||||
|
||||
var rebase = !options.base ? es.through() : es.mapSync(function (f) {
|
||||
f.base = options.base;
|
||||
return f;
|
||||
});
|
||||
|
||||
return watcher
|
||||
.pipe(filter(['**', '!.git{,/**}'])) // ignore all things git
|
||||
.pipe(filter(pattern))
|
||||
.pipe(es.map(function (file, cb) {
|
||||
fs.stat(file.path, function (err, stat) {
|
||||
if (err && err.code === 'ENOENT') { return cb(null, file); }
|
||||
if (err) { return cb(); }
|
||||
if (!stat.isFile()) { return cb(); }
|
||||
|
||||
fs.readFile(file.path, function (err, contents) {
|
||||
if (err && err.code === 'ENOENT') { return cb(null, file); }
|
||||
if (err) { return cb(); }
|
||||
|
||||
file.contents = contents;
|
||||
file.stat = stat;
|
||||
cb(null, file);
|
||||
});
|
||||
});
|
||||
}))
|
||||
.pipe(rebase);
|
||||
};
|
Binary file not shown.
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"noImplicitAny": false,
|
||||
"removeComments": false,
|
||||
"preserveConstEnums": true,
|
||||
"target": "ES5",
|
||||
"sourceMap": false,
|
||||
"experimentalDecorators": true,
|
||||
"noLib": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "sublimehq/Packages",
|
||||
"version": "0.0.0",
|
||||
"license": "TextMate Bundle License",
|
||||
"repositoryURL": "https://github.com/sublimehq/Packages",
|
||||
"licenseDetail": [
|
||||
"Copyright (c) Sublime Packages project authors",
|
||||
"",
|
||||
"If not otherwise specified (see below), files in this folder fall under the following license: ",
|
||||
"",
|
||||
"Permission to copy, use, modify, sell and distribute this",
|
||||
"software is granted. This software is provided \"as is\" without",
|
||||
"express or implied warranty, and with no claim as to its",
|
||||
"suitability for any purpose.",
|
||||
"",
|
||||
"An exception is made for files in readable text which contain their own license information, ",
|
||||
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added ",
|
||||
"to the base-name name of the original file, and an extension of txt, html, or similar. For example ",
|
||||
"\"tidy\" is accompanied by \"tidy-license.txt\"."
|
||||
]
|
||||
}]
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": "REM"
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "bat",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": { "vscode": "*" },
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "bat",
|
||||
"extensions": [ ".bat", ".cmd"],
|
||||
"aliases": [ "Batch", "bat" ],
|
||||
"configuration": "./bat.configuration.json"
|
||||
}],
|
||||
"grammars": [{
|
||||
"language": "bat",
|
||||
"scopeName": "source.dosbatch",
|
||||
"path": "./syntaxes/Batch File.tmLanguage"
|
||||
}]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>uuid</key>
|
||||
<string>E07EC438-7B75-4437-8AA1-DA94C1E6EACC</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.command.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>\b(?i)(?:append|assoc|at|attrib|break|cacls|cd|chcp|chdir|chkdsk|chkntfs|cls|cmd|color|comp|compact|convert|copy|date|del|dir|diskcomp|diskcopy|doskey|echo|endlocal|erase|fc|find|findstr|format|ftype|graftabl|help|keyb|label|md|mkdir|mode|more|move|path|pause|popd|print|prompt|pushd|rd|recover|rem|ren|rename|replace|restore|rmdir|set|setlocal|shift|sort|start|subst|time|title|tree|type|ver|verify|vol|xcopy)\b</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.statement.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>\b(?i)(?:goto|call|exit)\b</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.conditional.if.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>\b(?i)if\s+((not)\s+)(exist|defined|errorlevel|cmdextversion)\b</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.conditional.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>\b(?i)(?:if|else)\b</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.repeat.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>\b(?i)for\b</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>\b(?:EQU|NEQ|LSS|LEQ|GTR|GEQ)\b</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.command.rem.dosbatch</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>comment.line.rem.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>(?:^|\s)((?i)rem)(?:$|\s.*$)</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>comment.line.colons.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>\s*:\s*:.*$</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>"</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.end.shell</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.begin.shell</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>string.quoted.double.dosbatch</string>
|
||||
<key>end</key>
|
||||
<string>"</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.pipe.dosbatch</string>
|
||||
<key>match</key>
|
||||
<string>[|]</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.redirect.shell</string>
|
||||
<key>match</key>
|
||||
<string>&>|\d*>&\d*|\d*(>>|>|<)|\d*<&|\d*<></string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>name</key>
|
||||
<string>Batch File</string>
|
||||
<key>scopeName</key>
|
||||
<string>source.dosbatch</string>
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>bat</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,7 @@
|
|||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "mmcgrana/textmate-clojure",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/mmcgrana/textmate-clojure"
|
||||
}]
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": ";",
|
||||
"blockComment": [ "(comment", ")" ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "clojure",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": { "vscode": "*" },
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "clojure",
|
||||
"aliases": ["Clojure", "clojure"],
|
||||
"extensions": [".clj", ".cljs", ".cljx", ".clojure", ".edn"],
|
||||
"configuration": "./clojure.configuration.json"
|
||||
}],
|
||||
"grammars": [{
|
||||
"language": "clojure",
|
||||
"scopeName": "source.clojure",
|
||||
"path": "./syntaxes/Clojure.tmLanguage"
|
||||
}]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,440 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>clj</string>
|
||||
<string>cljs</string>
|
||||
<string>clojure</string>
|
||||
</array>
|
||||
<key>foldingStartMarker</key>
|
||||
<string>\(\s*$</string>
|
||||
<key>foldingStopMarker</key>
|
||||
<string>^\s*\)</string>
|
||||
<key>keyEquivalent</key>
|
||||
<string>^~C</string>
|
||||
<key>name</key>
|
||||
<string>Clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#comment</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#shebang-comment</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#qouted-sexp</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#sexp</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#keyfn</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#vector</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#set</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#map</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#regexp</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#var</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#constants</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#symbol</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#whitespace</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>repository</key>
|
||||
<dict>
|
||||
<key>comment</key>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.comment.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(;).*$\n?</string>
|
||||
<key>name</key>
|
||||
<string>comment.line.semicolon.clojure</string>
|
||||
</dict>
|
||||
<key>constants</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(nil)(?=(\s|\)|\]|\}))</string>
|
||||
<key>name</key>
|
||||
<string>constant.language.nil.clojure</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(true|false)</string>
|
||||
<key>name</key>
|
||||
<string>constant.language.boolean.clojure</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(\d+/\d+)</string>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.ratio.clojure</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(\d+r\d+)</string>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.arbitrary-radix.clojure</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(0x\d+)</string>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.hexidecimal.clojure</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(0\d+)</string>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.octal.clojure</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(\d+)</string>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.decimal.clojure</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(?<=(\s|\(|\[|\{)):[a-zA-Z0-9\#\.\-\_\:\+\=\>\<\/\!\?\*]+(?=(\s|\)|\]|\}))</string>
|
||||
<key>name</key>
|
||||
<string>constant.keyword.clojure</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>keyfn</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(?<=(\s|\(|\[|\{))(if(-[-a-z\?]*)?|when(-[-a-z]*)?|for(-[-a-z]*)?|cond|do|let(-[-a-z\?]*)?|binding|loop|recur|fn|throw[a-z\-]*|try|catch|finally|([a-z]*case))(?=(\s|\)|\]|\}))</string>
|
||||
<key>name</key>
|
||||
<string>storage.control.clojure</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(?<=(\s|\(|\[|\{))(declare-?|(in-)?ns|import|use|require|load|compile|(def[a-z\-]*))(?=(\s|\)|\]|\}))</string>
|
||||
<key>name</key>
|
||||
<string>keyword.control.clojure</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>map</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(\{)</string>
|
||||
<key>end</key>
|
||||
<string>(\})</string>
|
||||
<key>name</key>
|
||||
<string>meta.map.clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$self</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>qouted-sexp</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(['``]\()</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.expression.begin.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(\))(\n)?</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.expression.end.clojure</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>meta.after-expression.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>meta.qouted-expression.clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$self</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>regexp</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>#\"</string>
|
||||
<key>end</key>
|
||||
<string>\"</string>
|
||||
<key>name</key>
|
||||
<string>string.regexp.clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#regexp_escaped_char</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>regexp_escaped_char</key>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\\(\")</string>
|
||||
<key>name</key>
|
||||
<string>string.regexp.clojure</string>
|
||||
</dict>
|
||||
<key>set</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(\#\{)</string>
|
||||
<key>end</key>
|
||||
<string>(\})</string>
|
||||
<key>name</key>
|
||||
<string>meta.set.clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$self</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>sexp</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(\()</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.expression.begin.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(\))(\n)?</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.expression.end.clojure</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>meta.after-expression.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>meta.expression.clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?<=\()(ns|def|def-|defn|defn-|defvar|defvar-|defmacro|defmacro-|deftest)\s+(.+?)(?=\s)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.clojure</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.global.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(?=\))</string>
|
||||
<key>name</key>
|
||||
<string>meta.definition.global.clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$self</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$self</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>shebang-comment</key>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.comment.shebang.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>^(\#!).*$\n?</string>
|
||||
<key>name</key>
|
||||
<string>comment.line.semicolon.clojure</string>
|
||||
</dict>
|
||||
<key>string</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(")</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.begin.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(")</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.end.clojure</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>string.quoted.double.clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\\.</string>
|
||||
<key>name</key>
|
||||
<string>constant.character.escape.clojure</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>symbol</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(\w[\w\d]+)</string>
|
||||
<key>name</key>
|
||||
<string>meta.symbol.clojure</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>var</key>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(?<=(\s|\(|\[|\{)\#)'[a-zA-Z0-9\.\-\_\:\+\=\>\<\/\!\?\*]+(?=(\s|\)|\]|\}))</string>
|
||||
<key>name</key>
|
||||
<string>meta.var.clojure</string>
|
||||
</dict>
|
||||
<key>vector</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(\[)</string>
|
||||
<key>end</key>
|
||||
<string>(\])</string>
|
||||
<key>name</key>
|
||||
<string>meta.vector.clojure</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$self</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>whitespace</key>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\s+$</string>
|
||||
<key>name</key>
|
||||
<string>invalid.trailing-whitespace</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>scopeName</key>
|
||||
<string>source.clojure</string>
|
||||
<key>smartTypingPairs</key>
|
||||
<array>
|
||||
<array>
|
||||
<string>"</string>
|
||||
<string>"</string>
|
||||
</array>
|
||||
<array>
|
||||
<string>(</string>
|
||||
<string>)</string>
|
||||
</array>
|
||||
<array>
|
||||
<string>{</string>
|
||||
<string>}</string>
|
||||
</array>
|
||||
<array>
|
||||
<string>[</string>
|
||||
<string>]</string>
|
||||
</array>
|
||||
</array>
|
||||
<key>uuid</key>
|
||||
<string>6A87759F-F746-4E84-B788-965B46363202</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,7 @@
|
|||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "textmate/coffee-script.tmbundle",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/textmate/coffee-script.tmbundle"
|
||||
}]
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": "#",
|
||||
"blockComment": [ "###", "###" ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "coffeescript",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": { "vscode": "*" },
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "coffeescript",
|
||||
"extensions": [ ".coffee" ],
|
||||
"aliases": [ "CoffeeScript", "coffeescript", "coffee" ],
|
||||
"configuration": "./coffeescript.configuration.json"
|
||||
}],
|
||||
"grammars": [{
|
||||
"language": "coffeescript",
|
||||
"scopeName": "source.coffee",
|
||||
"path": "./syntaxes/CoffeeScript.tmLanguage"
|
||||
}],
|
||||
"debuggers": [{
|
||||
"type": "node",
|
||||
"enableBreakpointsFor": { "languageIds": ["coffeescript"] }
|
||||
}]
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "textmate/c.tmbundle",
|
||||
"version": "0.0.0",
|
||||
"license": "TextMate Bundle License",
|
||||
"repositoryURL": "https://github.com/textmate/c.tmbundle",
|
||||
"licenseDetail": [
|
||||
"Copyright (c) textmate-c.tmbundle authors",
|
||||
"",
|
||||
"If not otherwise specified (see below), files in this repository fall under the following license:",
|
||||
"",
|
||||
"Permission to copy, use, modify, sell and distribute this",
|
||||
"software is granted. This software is provided \"as is\" without",
|
||||
"express or implied warranty, and with no claim as to its",
|
||||
"suitability for any purpose.",
|
||||
"",
|
||||
"An exception is made for files in readable text which contain their own license information,",
|
||||
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
|
||||
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
|
||||
"\"tidy\" is accompanied by \"tidy-license.txt\"."
|
||||
]
|
||||
}]
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": "//",
|
||||
"blockComment": ["/*", "*/"]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "cpp",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": { "vscode": "*" },
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "c",
|
||||
"extensions": [ ".c", ".h" ],
|
||||
"aliases": [ "C", "c" ],
|
||||
"configuration": "./cpp.configuration.json"
|
||||
},
|
||||
{
|
||||
"id": "cpp",
|
||||
"extensions": [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx" ],
|
||||
"aliases": [ "C++", "Cpp", "cpp"],
|
||||
"configuration": "./cpp.configuration.json"
|
||||
}],
|
||||
"grammars": [{
|
||||
"language": "c",
|
||||
"scopeName": "source.c",
|
||||
"path": "./syntaxes/c.plist"
|
||||
},
|
||||
{
|
||||
"language": "cpp",
|
||||
"scopeName": "source.c++",
|
||||
"path": "./syntaxes/c++.plist"
|
||||
}]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,582 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>comment</key>
|
||||
<string>I don't think anyone uses .hp. .cp tends to be paired with .h. (I could be wrong. :) -- chris</string>
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>cc</string>
|
||||
<string>cpp</string>
|
||||
<string>cp</string>
|
||||
<string>cxx</string>
|
||||
<string>c++</string>
|
||||
<string>C</string>
|
||||
<string>h</string>
|
||||
<string>hh</string>
|
||||
<string>hpp</string>
|
||||
<string>h++</string>
|
||||
</array>
|
||||
<key>firstLineMatch</key>
|
||||
<string>-\*- C\+\+ -\*-</string>
|
||||
<key>keyEquivalent</key>
|
||||
<string>^~C</string>
|
||||
<key>name</key>
|
||||
<string>C++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#special_block</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>source.c</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(friend|explicit|virtual)\b</string>
|
||||
<key>name</key>
|
||||
<string>storage.modifier.$1.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(private|protected|public):</string>
|
||||
<key>name</key>
|
||||
<string>storage.modifier.$1.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(catch|operator|try|throw|using)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.control.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\bdelete\b(\s*\[\])?|\bnew\b(?!])</string>
|
||||
<key>name</key>
|
||||
<string>keyword.control.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>comment</key>
|
||||
<string>common C++ instance var naming idiom -- fMemberName</string>
|
||||
<key>match</key>
|
||||
<string>\b(f|m)[A-Z]\w*\b</string>
|
||||
<key>name</key>
|
||||
<string>variable.other.readwrite.member.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(this|nullptr)\b</string>
|
||||
<key>name</key>
|
||||
<string>variable.language.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\btemplate\b\s*</string>
|
||||
<key>name</key>
|
||||
<string>storage.type.template.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(const_cast|dynamic_cast|reinterpret_cast|static_cast)\b\s*</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.cast.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(class|wchar_t)\b</string>
|
||||
<key>name</key>
|
||||
<string>storage.type.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(constexpr|export|mutable|typename|thread_local)\b</string>
|
||||
<key>name</key>
|
||||
<string>storage.modifier.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?x)
|
||||
(?: ^ # begin-of-line
|
||||
| (?: (?<!else|new|=) ) # or word + space before name
|
||||
)
|
||||
((?:[A-Za-z_][A-Za-z0-9_]*::)*+~[A-Za-z_][A-Za-z0-9_]*) # actual name
|
||||
\s*(\() # start bracket or end-of-line
|
||||
</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.function.c++</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.begin.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\)</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.end.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>meta.function.destructor.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?x)
|
||||
(?: ^ # begin-of-line
|
||||
| (?: (?<!else|new|=) ) # or word + space before name
|
||||
)
|
||||
((?:[A-Za-z_][A-Za-z0-9_]*::)*+~[A-Za-z_][A-Za-z0-9_]*) # actual name
|
||||
\s*(\() # terminating semi-colon
|
||||
</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.function.c++</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.begin.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\)</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.end.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>meta.function.destructor.prototype.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>repository</key>
|
||||
<dict>
|
||||
<key>angle_brackets</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string><</string>
|
||||
<key>end</key>
|
||||
<string>></string>
|
||||
<key>name</key>
|
||||
<string>meta.angle-brackets.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#angle_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>block</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\{</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.block.begin.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\}</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.block.end.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>meta.block.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>support.function.any-method.c</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(?x)
|
||||
(
|
||||
(?!while|for|do|if|else|switch|catch|enumerate|return|r?iterate)(?: \b[A-Za-z_][A-Za-z0-9_]*+\b | :: )*+ # actual name
|
||||
)
|
||||
\s*(\()</string>
|
||||
<key>name</key>
|
||||
<string>meta.function-call.c</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>constructor</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?x)
|
||||
(?: ^\s*) # begin-of-line
|
||||
((?!while|for|do|if|else|switch|catch|enumerate|r?iterate)[A-Za-z_][A-Za-z0-9_:]*) # actual name
|
||||
\s*(\() # start bracket or end-of-line
|
||||
</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.function.c++</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.begin.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\)</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.end.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>meta.function.constructor.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?x)
|
||||
(:) # begin-of-line
|
||||
((?=\s*[A-Za-z_][A-Za-z0-9_:]* # actual name
|
||||
\s*(\())) # start bracket or end-of-line
|
||||
</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.parameters.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(?=\{)</string>
|
||||
<key>name</key>
|
||||
<string>meta.function.constructor.initializer-list.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>special_block</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\b(namespace)\b\s*([_A-Za-z][_A-Za-z0-9]*\b)?+</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>storage.type.c++</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.type.c++</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.namespace.$2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(?<=\})|(?=(;|,|\(|\)|>|\[|\]|=))</string>
|
||||
<key>name</key>
|
||||
<string>meta.namespace-block${2:+.$2}.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\{</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.scope.c++</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\}</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.scope.c++</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#special_block</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#constructor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\b(class|struct)\b\s*([_A-Za-z][_A-Za-z0-9]*\b)?+(\s*:\s*(public|protected|private)\s*([_A-Za-z][_A-Za-z0-9]*\b)((\s*,\s*(public|protected|private)\s*[_A-Za-z][_A-Za-z0-9]*\b)*))?</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>storage.type.c++</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.type.c++</string>
|
||||
</dict>
|
||||
<key>4</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>storage.type.modifier.c++</string>
|
||||
</dict>
|
||||
<key>5</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.type.inherited.c++</string>
|
||||
</dict>
|
||||
<key>6</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(public|protected|private)</string>
|
||||
<key>name</key>
|
||||
<string>storage.type.modifier.c++</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>[_A-Za-z][_A-Za-z0-9]*</string>
|
||||
<key>name</key>
|
||||
<string>entity.name.type.inherited.c++</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(?<=\})|(?=(;|\(|\)|>|\[|\]|=))</string>
|
||||
<key>name</key>
|
||||
<string>meta.class-struct-block.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#angle_brackets</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\{</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.block.begin.c++</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(\})(\s*\n)?</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.invalid.c++</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>invalid.illegal.you-forgot-semicolon.c++</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#special_block</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#constructor</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\b(extern)(?=\s*")</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>storage.modifier.c++</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(?<=\})|(?=\w)</string>
|
||||
<key>name</key>
|
||||
<string>meta.extern-block.c++</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\{</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.block.begin.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\}</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.block.end.c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#special_block</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$base</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>scopeName</key>
|
||||
<string>source.c++</string>
|
||||
<key>uuid</key>
|
||||
<string>26251B18-6B1D-11D9-AFDB-000D93589AF6</string>
|
||||
</dict>
|
||||
</plist>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
bin
|
|
@ -0,0 +1,29 @@
|
|||
[
|
||||
{
|
||||
"name": "Omnisharp-roslyn",
|
||||
"repositoryURL": "https://github.com/OmniSharp/omnisharp-roslyn",
|
||||
"version": "1.5.5",
|
||||
"license": "MIT",
|
||||
"isProd": true
|
||||
},
|
||||
{
|
||||
"name": "ScriptCS",
|
||||
"repositoryURL": "https://github.com/scriptcs/scriptcs",
|
||||
"version": "0.16.0",
|
||||
"license": "Apache2",
|
||||
"licenseDetail": [
|
||||
"Copyright 2013 Glenn Block, Justin Rusbatch, Filip Wojcieszyn",
|
||||
"",
|
||||
"Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file ",
|
||||
"except in compliance with the License. You may obtain a copy of the License at",
|
||||
"",
|
||||
"http://www.apache.org/licenses/LICENSE-2.0",
|
||||
"",
|
||||
"Unless required by applicable law or agreed to in writing, software distributed under the ",
|
||||
"License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, ",
|
||||
"either express or implied. See the License for the specific language governing permissions ",
|
||||
"and limitations under the License."
|
||||
],
|
||||
"isProd": true
|
||||
}
|
||||
]
|
|
@ -0,0 +1,55 @@
|
|||
var gulp = require('gulp');
|
||||
var decompress = require('gulp-decompress');
|
||||
var download = require('gulp-download');
|
||||
var del = require('del');
|
||||
var fs = require('fs');
|
||||
var join = require('path').join;
|
||||
|
||||
|
||||
gulp.task('omnisharp:clean', function () {
|
||||
return del('bin');
|
||||
});
|
||||
|
||||
gulp.task('omnisharp:fetch', ['omnisharp:clean'], function () {
|
||||
|
||||
var release = 'https://github.com/OmniSharp/omnisharp-roslyn/releases/download/v1.5.6/omnisharp.tar.gz';
|
||||
|
||||
return download(release)
|
||||
.pipe(decompress({strip: 1}))
|
||||
.pipe(gulp.dest('bin'))
|
||||
});
|
||||
|
||||
gulp.task('omnisharp:fixscripts', ['omnisharp:fetch'], function () {
|
||||
|
||||
var _fixes = Object.create(null);
|
||||
_fixes['./bin/omnisharp.cmd'] = '@"%~dp0packages\\dnx-clr-win-x86.1.0.0-beta4\\bin\\dnx.exe" "%~dp0packages\\OmniSharp\\1.0.0\\root" run %*';
|
||||
_fixes['./bin/omnisharp'] = '#!/bin/bash\n\
|
||||
SOURCE="${BASH_SOURCE[0]}"\n\
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink\n\
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"\n\
|
||||
SOURCE="$(readlink "$SOURCE")"\n\
|
||||
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located\n\
|
||||
done\n\
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"\n\
|
||||
export SET DNX_APPBASE="$DIR/packages/OmniSharp/1.0.0/root"\n\
|
||||
export PATH=/usr/local/bin:/Library/Frameworks/Mono.framework/Commands:$PATH # this is required for the users of the Homebrew Mono package\n\
|
||||
exec "$DIR/packages/dnx-mono.1.0.0-beta4/bin/dnx" "$DNX_APPBASE" run "$@"\n\
|
||||
\n';
|
||||
|
||||
var promises = Object.keys(_fixes).map(function (key) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
fs.writeFile(join(__dirname, key), _fixes[key], function (err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
});
|
||||
|
||||
|
||||
gulp.task('omnisharp', ['omnisharp:fixscripts']);
|
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"name": "csharp-o",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": {
|
||||
"vscode": "*"
|
||||
},
|
||||
"activationEvents": [
|
||||
"onLanguage:csharp",
|
||||
"onCommand:o.restart",
|
||||
"onCommand:o.pickProjectAndStart",
|
||||
"onCommand:o.restore",
|
||||
"onCommand:o.execute",
|
||||
"onCommand:o.showOutput",
|
||||
"onCommand:o.execute",
|
||||
"onCommand:o.execute-last-command"
|
||||
],
|
||||
"main": "./out/omnisharpMain",
|
||||
"scripts": {
|
||||
"postinstall": "gulp omnisharp",
|
||||
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../gulpfile.plugins.js compile-plugin:csharp-o ./tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"applicationinsights": "0.15.6",
|
||||
"run-in-terminal": "*",
|
||||
"semver": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"del": "^2.0.2",
|
||||
"gulp": "^3.8.9",
|
||||
"gulp-decompress": "^1.2.0",
|
||||
"gulp-download": "^0.0.1",
|
||||
"typescript": "^1.6.2"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"vscode.csharp"
|
||||
],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "o.restart",
|
||||
"title": "Restart OmniSharp",
|
||||
"category": "OmniSharp"
|
||||
},
|
||||
{
|
||||
"command": "o.pickProjectAndStart",
|
||||
"title": "Select Project",
|
||||
"category": "OmniSharp"
|
||||
},
|
||||
{
|
||||
"command": "o.restore",
|
||||
"title": "Restore Packages",
|
||||
"category": "dnx"
|
||||
},
|
||||
{
|
||||
"command": "o.execute",
|
||||
"title": "Run Command",
|
||||
"category": "dnx"
|
||||
}
|
||||
],
|
||||
"keybindings": [
|
||||
{
|
||||
"command": "o.showOutput",
|
||||
"key": "Ctrl+L L",
|
||||
"mac": "Cmd+L L"
|
||||
},
|
||||
{
|
||||
"command": "o.execute",
|
||||
"key": "Ctrl+L Shift+R",
|
||||
"mac": "Cmd+L Shift+R"
|
||||
},
|
||||
{
|
||||
"command": "o.execute-last-command",
|
||||
"key": "Ctrl+L R",
|
||||
"mac": "Cmd+L R"
|
||||
},
|
||||
{
|
||||
"key": "shift+0",
|
||||
"command": "^acceptSelectedSuggestion",
|
||||
"when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey"
|
||||
},
|
||||
{
|
||||
"key": "shift+9",
|
||||
"command": "^acceptSelectedSuggestion",
|
||||
"when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey"
|
||||
},
|
||||
{
|
||||
"key": ".",
|
||||
"command": "^acceptSelectedSuggestion",
|
||||
"when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey"
|
||||
}
|
||||
],
|
||||
"snippets": [
|
||||
{
|
||||
"language": "csharp",
|
||||
"path": "./snippets/csharp.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,524 @@
|
|||
{
|
||||
"Attribute using recommended pattern": {
|
||||
|
||||
"prefix": "attribute",
|
||||
"body": [
|
||||
"[System.AttributeUsage(System.AttributeTargets.${All}, Inherited = ${false}, AllowMultiple = ${true})]",
|
||||
"sealed class ${My}Attribute : System.Attribute",
|
||||
"{",
|
||||
" // See the attribute guidelines at",
|
||||
" // http://go.microsoft.com/fwlink/?LinkId=85236",
|
||||
" readonly string positionalString;",
|
||||
" ",
|
||||
" // This is a positional argument",
|
||||
" public ${My}Attribute (string positionalString)",
|
||||
" {",
|
||||
" this.positionalString = positionalString;",
|
||||
" ",
|
||||
" // TODO: Implement code here",
|
||||
" ${throw new System.NotImplementedException();}",
|
||||
" }",
|
||||
" ",
|
||||
" public string PositionalString",
|
||||
" {",
|
||||
" get { return positionalString; }",
|
||||
" }",
|
||||
" ",
|
||||
" // This is a named argument",
|
||||
" public int NamedInt { get; set; }",
|
||||
"}"
|
||||
],
|
||||
"description": "Attribute using recommended pattern"
|
||||
},
|
||||
|
||||
"Checked block": {
|
||||
|
||||
"prefix": "checked",
|
||||
"body": [
|
||||
"checked",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Checked block"
|
||||
},
|
||||
|
||||
"Class": {
|
||||
|
||||
"prefix": "class",
|
||||
"body": [
|
||||
"class ${Name}",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Class"
|
||||
},
|
||||
|
||||
"Console.WriteLine": {
|
||||
|
||||
"prefix": "cw",
|
||||
"body": [
|
||||
"System.Console.WriteLine($0);"
|
||||
],
|
||||
"description": "Console.WriteLine"
|
||||
},
|
||||
|
||||
"do...while loop": {
|
||||
|
||||
"prefix": "do",
|
||||
"body": [
|
||||
"do",
|
||||
"{",
|
||||
" $0",
|
||||
"} while (${true});"
|
||||
],
|
||||
"description": "do...while loop"
|
||||
},
|
||||
|
||||
"Else statement": {
|
||||
|
||||
"prefix": "else",
|
||||
"body": [
|
||||
"else",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Else statement"
|
||||
},
|
||||
|
||||
"Enum": {
|
||||
|
||||
"prefix": "enum",
|
||||
"body": [
|
||||
"enum ${Name}",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Enum"
|
||||
},
|
||||
|
||||
"Implementing Equals() according to guidelines": {
|
||||
|
||||
"prefix": "equals",
|
||||
"body": [
|
||||
"// override object.Equals",
|
||||
"public override bool Equals (object obj)",
|
||||
"{",
|
||||
" //",
|
||||
" // See the full list of guidelines at",
|
||||
" // http://go.microsoft.com/fwlink/?LinkID=85237",
|
||||
" // and also the guidance for operator== at",
|
||||
" // http://go.microsoft.com/fwlink/?LinkId=85238",
|
||||
" //",
|
||||
" ",
|
||||
" if (obj == null || GetType() != obj.GetType())",
|
||||
" {",
|
||||
" return false;",
|
||||
" }",
|
||||
" ",
|
||||
" // TODO: write your implementation of Equals() here",
|
||||
" ${1:throw new System.NotImplementedException();}",
|
||||
" return base.Equals (obj);",
|
||||
"}",
|
||||
"",
|
||||
"// override object.GetHashCode",
|
||||
"public override int GetHashCode()",
|
||||
"{",
|
||||
" // TODO: write your implementation of GetHashCode() here",
|
||||
" ${2:throw new System.NotImplementedException();}",
|
||||
" return base.GetHashCode();",
|
||||
"}"
|
||||
],
|
||||
"description": "Implementing Equals() according to guidelines"
|
||||
},
|
||||
|
||||
"Exception": {
|
||||
|
||||
"prefix": "exception",
|
||||
"body": [
|
||||
"[System.Serializable]",
|
||||
"public class ${My}Exception : ${System.Exception}",
|
||||
"{",
|
||||
" public ${My}Exception() { }",
|
||||
" public ${My}Exception( string message ) : base( message ) { }",
|
||||
" public ${My}Exception( string message, System.Exception inner ) : base( message, inner ) { }",
|
||||
" protected ${My}Exception(",
|
||||
" System.Runtime.Serialization.SerializationInfo info,",
|
||||
" System.Runtime.Serialization.StreamingContext context ) : base( info, context ) { }",
|
||||
"}"
|
||||
],
|
||||
"description": "Exception"
|
||||
},
|
||||
|
||||
"Foreach statement": {
|
||||
|
||||
"prefix": "foreach",
|
||||
"body": [
|
||||
"foreach (${var} ${item} in ${collection})",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Foreach statement"
|
||||
},
|
||||
|
||||
"Reverse for loop": {
|
||||
|
||||
"prefix": "forr",
|
||||
"body": [
|
||||
"for (int ${i} = ${length} - 1; ${i} >= 0 ; ${i}--)",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Reverse for loop"
|
||||
},
|
||||
|
||||
"for loop": {
|
||||
|
||||
"prefix": "for",
|
||||
"body": [
|
||||
"for (int ${i} = 0; ${i} < ${length}; ${i}++)",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "for loop"
|
||||
},
|
||||
|
||||
"if statement": {
|
||||
|
||||
"prefix": "if",
|
||||
"body": [
|
||||
"if (${true})",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "if statement"
|
||||
},
|
||||
|
||||
"Indexer": {
|
||||
|
||||
"prefix": "indexer",
|
||||
"body": [
|
||||
"${public} ${object} this[${int} index]",
|
||||
"{",
|
||||
" get { $0 }",
|
||||
" set { $1 }",
|
||||
"}"
|
||||
],
|
||||
"description": "Indexer"
|
||||
},
|
||||
|
||||
"Interface": {
|
||||
|
||||
"prefix": "interface",
|
||||
"body": [
|
||||
"interface I${Name}",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Interface"
|
||||
},
|
||||
|
||||
"Safely invoking an event": {
|
||||
|
||||
"prefix": "invoke",
|
||||
"body": [
|
||||
"${EventHandler} temp = ${MyEvent};",
|
||||
"if (temp != null)",
|
||||
"{",
|
||||
" temp($0);",
|
||||
"}"
|
||||
],
|
||||
"description": "Safely invoking an event"
|
||||
},
|
||||
|
||||
"Simple iterator": {
|
||||
|
||||
"prefix": "iterator",
|
||||
"body": [
|
||||
"public System.Collections.Generic.IEnumerator<${ElementType}> GetEnumerator()",
|
||||
"{",
|
||||
" $0throw new System.NotImplementedException();",
|
||||
" yield return default(${ElementType});",
|
||||
"}"
|
||||
],
|
||||
"description": "Simple iterator"
|
||||
},
|
||||
|
||||
"Named iterator/indexer pair using a nested class": {
|
||||
|
||||
"prefix": "iterindex",
|
||||
"body": [
|
||||
"public ${Name}Iterator ${Name}",
|
||||
"{",
|
||||
" get",
|
||||
" {",
|
||||
" return new ${Name}Iterator(this);",
|
||||
" }",
|
||||
"}",
|
||||
"",
|
||||
"public class ${Name}Iterator",
|
||||
"{",
|
||||
" readonly ${ClassName} outer;",
|
||||
" ",
|
||||
" internal ${Name}Iterator(${ClassName} outer)",
|
||||
" {",
|
||||
" this.outer = outer;",
|
||||
" }",
|
||||
" ",
|
||||
" // TODO: provide an appropriate implementation here",
|
||||
" public int Length { get { return 1; } }",
|
||||
" ",
|
||||
" public ${ElementType} this[int index]",
|
||||
" {",
|
||||
" get",
|
||||
" {",
|
||||
" //",
|
||||
" // TODO: implement indexer here",
|
||||
" //",
|
||||
" // you have full access to ${ClassName} privates",
|
||||
" //",
|
||||
" ${throw new System.NotImplementedException();}",
|
||||
" return default(${ElementType});",
|
||||
" }",
|
||||
" }",
|
||||
" ",
|
||||
" public System.Collections.Generic.IEnumerator<${ElementType}> GetEnumerator()",
|
||||
" {",
|
||||
" for (int i = 0; i < this.Length; i++)",
|
||||
" {",
|
||||
" yield return this[i];",
|
||||
" }",
|
||||
" }",
|
||||
"}"
|
||||
],
|
||||
"description": "Named iterator/indexer pair using a nested class"
|
||||
},
|
||||
|
||||
"Lock statement": {
|
||||
|
||||
"prefix": "lock",
|
||||
"body": [
|
||||
"lock (${this})",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Lock statement"
|
||||
},
|
||||
|
||||
"MessageBox.Show": {
|
||||
|
||||
"prefix": "mbox",
|
||||
"body": [
|
||||
"System.Windows.Forms.MessageBox.Show(\"${Text}\");$0"
|
||||
],
|
||||
"description": "MessageBox.Show"
|
||||
},
|
||||
|
||||
"Namespace": {
|
||||
|
||||
"prefix": "namespace",
|
||||
"body": [
|
||||
"namespace ${Name}",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Namespace"
|
||||
},
|
||||
|
||||
"#if": {
|
||||
|
||||
"prefix": "ifd",
|
||||
"body": [
|
||||
"#if ${true}",
|
||||
" $0",
|
||||
"#endif"
|
||||
],
|
||||
"description": "#if"
|
||||
},
|
||||
|
||||
"#region": {
|
||||
|
||||
"prefix": "region",
|
||||
"body": [
|
||||
"#region ${Name}",
|
||||
" $0",
|
||||
"#endregion"
|
||||
],
|
||||
"description": "#region"
|
||||
},
|
||||
|
||||
"Property and backing field": {
|
||||
|
||||
"prefix": "propfull",
|
||||
"body": [
|
||||
"private ${int} ${myVar};",
|
||||
|
||||
"public ${int} ${MyProperty}",
|
||||
"{",
|
||||
" get { return ${myVar};}",
|
||||
" set { ${myVar} = value;}",
|
||||
"}",
|
||||
"$0"
|
||||
],
|
||||
"description": "Property and backing field"
|
||||
},
|
||||
|
||||
"propg": {
|
||||
|
||||
"prefix": "propg",
|
||||
"body": [
|
||||
"public ${int} ${MyProperty} { get; private set; }$0"
|
||||
],
|
||||
"description": "An automatically implemented property with a 'get' accessor and a private 'set' accessor. C# 3.0 or higher"
|
||||
},
|
||||
|
||||
"prop": {
|
||||
|
||||
"prefix": "prop",
|
||||
"body": [
|
||||
"public ${int} ${MyProperty} { get; set; }$0"
|
||||
],
|
||||
"description": "An automatically implemented property. C# 3.0 or higher"
|
||||
},
|
||||
|
||||
"sim": {
|
||||
|
||||
"prefix": "sim",
|
||||
"body": [
|
||||
"static int Main(string[] args)",
|
||||
"{",
|
||||
" $0",
|
||||
" return 0;",
|
||||
"}"
|
||||
],
|
||||
"description": "int Main()"
|
||||
},
|
||||
|
||||
"Struct": {
|
||||
|
||||
"prefix": "struct",
|
||||
"body": [
|
||||
"struct ${Name}",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Struct"
|
||||
},
|
||||
|
||||
"svm": {
|
||||
|
||||
"prefix": "svm",
|
||||
"body": [
|
||||
"static void Main(string[] args)",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "void Main()"
|
||||
},
|
||||
|
||||
"Switch statement": {
|
||||
|
||||
"prefix": "switch",
|
||||
"body": [
|
||||
"switch (${switch_on})",
|
||||
"{",
|
||||
" $0",
|
||||
" default:",
|
||||
"}"
|
||||
],
|
||||
"description": "Switch statement"
|
||||
},
|
||||
|
||||
"Try finally": {
|
||||
|
||||
"prefix": "tryf",
|
||||
"body": [
|
||||
"try",
|
||||
"{",
|
||||
" ${_}",
|
||||
"}",
|
||||
"finally",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Try finally"
|
||||
},
|
||||
|
||||
"Try catch": {
|
||||
|
||||
"prefix": "try",
|
||||
"body": [
|
||||
"try",
|
||||
"{",
|
||||
" ${_}",
|
||||
"}",
|
||||
"catch (${System.Exception})",
|
||||
"{",
|
||||
" $0",
|
||||
" throw;",
|
||||
"}"
|
||||
],
|
||||
"description": "Try catch"
|
||||
},
|
||||
|
||||
"Unchecked block": {
|
||||
|
||||
"prefix": "unchecked",
|
||||
"body": [
|
||||
"unchecked",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Unchecked block"
|
||||
},
|
||||
|
||||
"Unsafe statement": {
|
||||
|
||||
"prefix": "unsafe",
|
||||
"body": [
|
||||
"unsafe",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Unsafe statement"
|
||||
},
|
||||
|
||||
"Using statement": {
|
||||
|
||||
"prefix": "using",
|
||||
"body": [
|
||||
"using(${resource})",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Using statement"
|
||||
},
|
||||
|
||||
"While loop": {
|
||||
|
||||
"prefix": "while",
|
||||
"body": [
|
||||
"while (${true})",
|
||||
"{",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "While loop"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {OmnisharpServer} from '../omnisharpServer';
|
||||
import {Disposable} from 'vscode';
|
||||
|
||||
export default class AbstractProvider {
|
||||
|
||||
protected _server: OmnisharpServer;
|
||||
protected _disposables: Disposable[];
|
||||
|
||||
constructor(server: OmnisharpServer) {
|
||||
this._server = server;
|
||||
this._disposables = [];
|
||||
}
|
||||
|
||||
dispose() {
|
||||
while (this._disposables.length) {
|
||||
this._disposables.pop().dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {Disposable, Uri, workspace} from 'vscode';
|
||||
import {OmnisharpServer} from '../omnisharpServer';
|
||||
import * as proto from '../protocol';
|
||||
|
||||
function forwardDocumentChanges(server: OmnisharpServer): Disposable {
|
||||
|
||||
return workspace.onDidChangeTextDocument(event => {
|
||||
|
||||
let {document} = event;
|
||||
if (document.isUntitled || document.languageId !== 'csharp') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!server.isRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
server.makeRequest(proto.UpdateBuffer, <proto.Request>{
|
||||
Buffer: document.getText(),
|
||||
Filename: document.fileName
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
return err;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function forwardFileChanges(server: OmnisharpServer): Disposable {
|
||||
|
||||
function onFileSystemEvent(uri: Uri): void {
|
||||
if (!server.isRunning()) {
|
||||
return;
|
||||
}
|
||||
let req = { Filename: uri.fsPath };
|
||||
server.makeRequest<boolean>(proto.FilesChanged, [req]).catch(err => {
|
||||
console.warn('[o] failed to forward file change event for ' + uri.fsPath, err);
|
||||
return err;
|
||||
});
|
||||
}
|
||||
|
||||
const watcher = workspace.createFileSystemWatcher('**/*.*');
|
||||
let d1 = watcher.onDidCreate(onFileSystemEvent);
|
||||
let d2 = watcher.onDidChange(onFileSystemEvent);
|
||||
let d3 = watcher.onDidDelete(onFileSystemEvent);
|
||||
|
||||
return Disposable.from(watcher, d1, d2, d3);
|
||||
}
|
||||
|
||||
export default function forwardChanges(server: OmnisharpServer): Disposable {
|
||||
|
||||
// combine file watching and text document watching
|
||||
return Disposable.from(
|
||||
forwardDocumentChanges(server),
|
||||
forwardFileChanges(server));
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {CodeActionProvider, CodeActionContext, Command, CancellationToken, TextDocument, WorkspaceEdit, TextEdit, Range, Uri, workspace, commands} from 'vscode';
|
||||
import {OmnisharpServer} from '../omnisharpServer';
|
||||
import AbstractProvider from './abstractProvider';
|
||||
import {TextChange, V2} from '../protocol';
|
||||
import {toRange2} from '../typeConvertion';
|
||||
|
||||
export default class OmnisharpCodeActionProvider extends AbstractProvider implements CodeActionProvider {
|
||||
|
||||
private _disabled: boolean;
|
||||
private _commandId: string;
|
||||
|
||||
constructor(server: OmnisharpServer) {
|
||||
super(server);
|
||||
this._commandId = 'omnisharp.runCodeAction';
|
||||
|
||||
this._updateEnablement();
|
||||
let d1 = workspace.onDidChangeConfiguration(this._updateEnablement, this);
|
||||
let d2 = commands.registerCommand(this._commandId, this._runCodeAction, this);
|
||||
this._disposables.push(d1, d2);
|
||||
}
|
||||
|
||||
private _updateEnablement(): void {
|
||||
let value = workspace.getConfiguration().get('csharp.disableCodeActions', false);
|
||||
this._disabled = value;
|
||||
}
|
||||
|
||||
public provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken): Promise<Command[]> {
|
||||
|
||||
if (this._disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let req: V2.GetCodeActionsRequest = {
|
||||
Filename: document.fileName,
|
||||
Selection: OmnisharpCodeActionProvider._asRange(range)
|
||||
}
|
||||
|
||||
return this._server.makeRequest<V2.GetCodeActionsResponse>(V2.GetCodeActions, req, token).then(response => {
|
||||
return response.CodeActions.map(ca => {
|
||||
return {
|
||||
title: ca.Name,
|
||||
command: this._commandId,
|
||||
arguments: [ca.Identifier, document, range]
|
||||
};
|
||||
});
|
||||
}, (error) => {
|
||||
return Promise.reject('Problem invoking \'GetCodeActions\' on OmniSharp server: ' + error);
|
||||
});
|
||||
}
|
||||
|
||||
private _runCodeAction(id: string, document: TextDocument, range: Range): Promise<any> {
|
||||
|
||||
let req: V2.RunCodeActionRequest = {
|
||||
Filename: document.fileName,
|
||||
Selection: OmnisharpCodeActionProvider._asRange(range),
|
||||
Identifier: id,
|
||||
WantsTextChanges: true
|
||||
};
|
||||
|
||||
return this._server.makeRequest<V2.RunCodeActionResponse>(V2.RunCodeAction, req).then(response => {
|
||||
|
||||
if (response && Array.isArray(response.Changes)) {
|
||||
|
||||
let edit = new WorkspaceEdit();
|
||||
|
||||
for (let change of response.Changes) {
|
||||
let uri = Uri.file(change.FileName);
|
||||
let edits: TextEdit[] = [];
|
||||
for (let textChange of change.Changes) {
|
||||
edits.push(TextEdit.replace(toRange2(textChange), textChange.NewText));
|
||||
}
|
||||
|
||||
edit.set(uri, edits);
|
||||
}
|
||||
|
||||
return workspace.applyEdit(edit);
|
||||
}
|
||||
|
||||
}, (error) => {
|
||||
return Promise.reject('Problem invoking \'RunCodeAction\' on OmniSharp server: ' + error);
|
||||
});
|
||||
}
|
||||
|
||||
private static _asRange(range: Range): V2.Range {
|
||||
let {start, end} = range;
|
||||
return {
|
||||
Start: { Line: start.line + 1, Column: start.character + 1 },
|
||||
End: { Line: end.line + 1, Column: end.character + 1 }
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {CancellationToken, CodeLens, SymbolKind, Range, Uri, TextDocument, CodeLensProvider, Position} from 'vscode';
|
||||
import {createRequest, toRange, toLocation} from '../typeConvertion';
|
||||
import AbstractSupport from './abstractProvider';
|
||||
import * as proto from '../protocol';
|
||||
|
||||
class OmniSharpCodeLens extends CodeLens {
|
||||
|
||||
fileName: string;
|
||||
|
||||
constructor(fileName: string, range: Range) {
|
||||
super(range);
|
||||
this.fileName = fileName;
|
||||
}
|
||||
}
|
||||
|
||||
export default class OmniSharpCodeLensProvider extends AbstractSupport implements CodeLensProvider {
|
||||
|
||||
private static filteredSymbolNames: { [name: string]: boolean } = {
|
||||
'Equals': true,
|
||||
'Finalize': true,
|
||||
'GetHashCode': true,
|
||||
'ToString': true
|
||||
};
|
||||
|
||||
provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]> {
|
||||
|
||||
return this._server.makeRequest<proto.CurrentFileMembersAsTreeResponse>(proto.CurrentFileMembersAsTree, {
|
||||
Filename: document.fileName
|
||||
}, token).then(tree => {
|
||||
var ret: CodeLens[] = [];
|
||||
tree.TopLevelTypeDefinitions.forEach(node => OmniSharpCodeLensProvider._convertQuickFix(ret, document.fileName, node));
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
private static _convertQuickFix(bucket: CodeLens[], fileName:string, node: proto.Node): void {
|
||||
|
||||
if (node.Kind === 'MethodDeclaration' && OmniSharpCodeLensProvider.filteredSymbolNames[node.Location.Text]) {
|
||||
return;
|
||||
}
|
||||
|
||||
let lens = new OmniSharpCodeLens(fileName, toRange(node.Location));
|
||||
bucket.push(lens);
|
||||
|
||||
for (let child of node.ChildNodes) {
|
||||
OmniSharpCodeLensProvider._convertQuickFix(bucket, fileName, child);
|
||||
}
|
||||
}
|
||||
|
||||
resolveCodeLens(codeLens: CodeLens, token: CancellationToken): Thenable<CodeLens> {
|
||||
if (codeLens instanceof OmniSharpCodeLens) {
|
||||
|
||||
let req = <proto.FindUsagesRequest>{
|
||||
Filename: codeLens.fileName,
|
||||
Line: codeLens.range.start.line + 1,
|
||||
Column: codeLens.range.start.character + 1,
|
||||
OnlyThisFile: false,
|
||||
ExcludeDefinition: true
|
||||
};
|
||||
|
||||
return this._server.makeRequest<proto.QuickFixResponse>(proto.FindUsages, req, token).then(res => {
|
||||
if (!res || !Array.isArray(res.QuickFixes)) {
|
||||
return;
|
||||
}
|
||||
let len = res.QuickFixes.length;
|
||||
codeLens.command = {
|
||||
title: len === 1 ? '1 reference' : `${len} references`,
|
||||
command: 'editor.action.showReferences',
|
||||
arguments: [Uri.file(req.Filename), codeLens.range.start, res.QuickFixes.map(toLocation)]
|
||||
};
|
||||
|
||||
return codeLens;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 proto from '../protocol';
|
||||
import {OmnisharpServer} from '../omnisharpServer';
|
||||
import {Disposable, ViewColumn, commands, window} from 'vscode';
|
||||
import {join, dirname, basename} from 'path';
|
||||
import findLaunchTargets from '../launchTargetFinder';
|
||||
import {runInTerminal} from 'run-in-terminal';
|
||||
|
||||
const isWin = /^win/.test(process.platform);
|
||||
|
||||
export default function registerCommands(server: OmnisharpServer) {
|
||||
let d1 = commands.registerCommand('o.restart', () => server.restart());
|
||||
let d2 = commands.registerCommand('o.pickProjectAndStart', () => pickProjectAndStart(server));
|
||||
let d3 = commands.registerCommand('o.restore', () => dnxRestoreForAll(server));
|
||||
let d4 = commands.registerCommand('o.execute', () => dnxExecuteCommand(server));
|
||||
let d5 = commands.registerCommand('o.execute-last-command', () => dnxExecuteLastCommand(server));
|
||||
let d6 = commands.registerCommand('o.showOutput', () => server.getChannel().show(ViewColumn.Three));
|
||||
return Disposable.from(d1, d2, d3, d4, d5, d6);
|
||||
}
|
||||
|
||||
function pickProjectAndStart(server: OmnisharpServer) {
|
||||
|
||||
return findLaunchTargets().then(targets => {
|
||||
|
||||
let currentPath = server.getSolutionPathOrFolder();
|
||||
if (currentPath) {
|
||||
for (let target of targets) {
|
||||
if (target.target.fsPath === currentPath) {
|
||||
target.label = `\u2713 ${target.label}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return window.showQuickPick(targets, {
|
||||
matchOnDescription: true,
|
||||
placeHolder: `Select 1 of ${targets.length} projects`
|
||||
}).then(target => {
|
||||
if (target) {
|
||||
return server.restart(target.target.fsPath);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
interface Command {
|
||||
label: string;
|
||||
description: string;
|
||||
execute(): Thenable<any>;
|
||||
}
|
||||
|
||||
let lastCommand: Command;
|
||||
|
||||
function dnxExecuteLastCommand(server: OmnisharpServer) {
|
||||
if (lastCommand) {
|
||||
lastCommand.execute();
|
||||
} else {
|
||||
dnxExecuteCommand(server);
|
||||
}
|
||||
}
|
||||
|
||||
function dnxExecuteCommand(server: OmnisharpServer) {
|
||||
|
||||
if (!server.isRunning()) {
|
||||
return Promise.reject('OmniSharp server is not running.');
|
||||
}
|
||||
|
||||
return server.makeRequest<proto.WorkspaceInformationResponse>(proto.Projects).then(info => {
|
||||
|
||||
let commands: Command[] = [];
|
||||
|
||||
info.Dnx.Projects.forEach(project => {
|
||||
Object.keys(project.Commands).forEach(key => {
|
||||
|
||||
commands.push({
|
||||
label: `dnx ${key} - (${project.Name || basename(project.Path)})`,
|
||||
description: dirname(project.Path),
|
||||
execute() {
|
||||
lastCommand = this;
|
||||
|
||||
let command = join(info.Dnx.RuntimePath, 'bin/dnx');
|
||||
let args = [key];
|
||||
|
||||
// dnx-beta[1-6] needs a leading dot, like 'dnx . run'
|
||||
if (/-beta[1-6]/.test(info.Dnx.RuntimePath)) {
|
||||
args.unshift('.');
|
||||
}
|
||||
|
||||
if (isWin) {
|
||||
command += '.exe';
|
||||
}
|
||||
|
||||
return runInTerminal(command, args, {
|
||||
cwd: dirname(project.Path),
|
||||
env: {
|
||||
// KRE_COMPILATION_SERVER_PORT: workspace.DesignTimeHostPort
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return window.showQuickPick(commands).then(command => {
|
||||
if (command) {
|
||||
return command.execute();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function dnxRestoreForAll(server: OmnisharpServer) {
|
||||
|
||||
if (!server.isRunning()) {
|
||||
return Promise.reject('OmniSharp server is not running.');
|
||||
}
|
||||
|
||||
return server.makeRequest<proto.WorkspaceInformationResponse>(proto.Projects).then(info => {
|
||||
|
||||
let commands:Command[] = [];
|
||||
|
||||
info.Dnx.Projects.forEach(project => {
|
||||
commands.push({
|
||||
label: `dnu restore - (${project.Name || basename(project.Path)})`,
|
||||
description: dirname(project.Path),
|
||||
execute() {
|
||||
|
||||
let command = join(info.Dnx.RuntimePath, 'bin/dnu');
|
||||
if (isWin) {
|
||||
command += '.cmd';
|
||||
}
|
||||
|
||||
return runInTerminal(command, ['restore'], {
|
||||
cwd: dirname(project.Path)
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return window.showQuickPick(commands).then(command => {
|
||||
if(command) {
|
||||
return command.execute();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function dnxRestoreForProject(server: OmnisharpServer, fileName: string) {
|
||||
|
||||
return server.makeRequest<proto.WorkspaceInformationResponse>(proto.Projects).then((info):Promise<any> => {
|
||||
for(let project of info.Dnx.Projects) {
|
||||
if (project.Path === fileName) {
|
||||
let command = join(info.Dnx.RuntimePath, 'bin/dnu');
|
||||
if (isWin) {
|
||||
command += '.cmd';
|
||||
}
|
||||
|
||||
return runInTerminal(command, ['restore'], {
|
||||
cwd: dirname(project.Path)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(`Failed to execute restore, try to run 'dnu restore' manually for ${fileName}.`)
|
||||
});
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {plain} from './documentation';
|
||||
import AbstractSupport from './abstractProvider';
|
||||
import * as proto from '../protocol';
|
||||
import {createRequest} from '../typeConvertion';
|
||||
import {CompletionItemProvider, CompletionItem, CompletionItemKind, Uri, CancellationToken, TextDocument, Range, Position} from 'vscode';
|
||||
|
||||
export default class OmniSharpCompletionItemProvider extends AbstractSupport implements CompletionItemProvider {
|
||||
|
||||
public provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken): Promise<CompletionItem[]> {
|
||||
|
||||
let wordToComplete = '';
|
||||
let range = document.getWordRangeAtPosition(position);
|
||||
if (range) {
|
||||
wordToComplete = document.getText(new Range(range.start, position));
|
||||
}
|
||||
|
||||
let req = createRequest<proto.AutoCompleteRequest>(document, position);
|
||||
req.WordToComplete = wordToComplete;
|
||||
req.WantDocumentationForEveryCompletionResult = true;
|
||||
req.WantKind = true;
|
||||
|
||||
return this._server.makeRequest<proto.AutoCompleteResponse[]>(proto.AutoComplete, req).then(values => {
|
||||
|
||||
if (!values) {
|
||||
return;
|
||||
}
|
||||
|
||||
let result: CompletionItem[] = [];
|
||||
let completions: { [c: string]: CompletionItem[] } = Object.create(null);
|
||||
|
||||
// transform AutoCompleteResponse to CompletionItem and
|
||||
// group by code snippet
|
||||
for (let value of values) {
|
||||
let completion = new CompletionItem(value.CompletionText.replace(/\(|\)|<|>/g, ''));
|
||||
completion.detail = value.DisplayText;
|
||||
completion.documentation = plain(value.Description);
|
||||
completion.kind = _kinds[value.Kind] || CompletionItemKind.Property;
|
||||
|
||||
let array = completions[completion.label];
|
||||
if (!array) {
|
||||
completions[completion.label] = [completion];
|
||||
} else {
|
||||
array.push(completion);
|
||||
}
|
||||
}
|
||||
|
||||
// per suggestion group, select on and indicate overloads
|
||||
for (let key in completions) {
|
||||
|
||||
let suggestion = completions[key][0],
|
||||
overloadCount = completions[key].length - 1;
|
||||
|
||||
if (overloadCount === 0) {
|
||||
// remove non overloaded items
|
||||
delete completions[key];
|
||||
|
||||
} else {
|
||||
// indicate that there is more
|
||||
suggestion.detail = `${suggestion.detail} (+ ${overloadCount} overload(s))`;
|
||||
}
|
||||
result.push(suggestion);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var _kinds: { [kind: string]: CompletionItemKind; } = Object.create(null);
|
||||
_kinds['Variable'] = CompletionItemKind.Variable;
|
||||
_kinds['Struct'] = CompletionItemKind.Interface;
|
||||
_kinds['Interface'] = CompletionItemKind.Interface;
|
||||
_kinds['Enum'] = CompletionItemKind.Enum;
|
||||
_kinds['EnumMember'] = CompletionItemKind.Property;
|
||||
_kinds['Property'] = CompletionItemKind.Property;
|
||||
_kinds['Class'] = CompletionItemKind.Class;
|
||||
_kinds['Field'] = CompletionItemKind.Field;
|
||||
_kinds['EventField'] = CompletionItemKind.File;
|
||||
_kinds['Method'] = CompletionItemKind.Method;
|
|
@ -0,0 +1,25 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 AbstractSupport from './abstractProvider';
|
||||
import * as Protocol from '../protocol';
|
||||
import {createRequest, toLocation} from '../typeConvertion';
|
||||
import {Uri, TextDocument, Position, Location, CancellationToken, DefinitionProvider} from 'vscode';
|
||||
|
||||
export default class CSharpDefinitionProvider extends AbstractSupport implements DefinitionProvider {
|
||||
|
||||
public provideDefinition(document: TextDocument, position: Position, token: CancellationToken): Promise<Location> {
|
||||
|
||||
let req = createRequest(document, position);
|
||||
|
||||
return this._server.makeRequest<Protocol.ResourceLocation>(Protocol.GoToDefinition, req, token).then(value => {
|
||||
if (value && value.FileName) {
|
||||
return toLocation(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {OmnisharpServer} from '../omnisharpServer';
|
||||
import AbstractSupport from './abstractProvider';
|
||||
import * as proto from '../protocol';
|
||||
import {createRequest, toRange} from '../typeConvertion';
|
||||
import {Disposable, Uri, CancellationTokenSource, TextDocument, TextDocumentChangeEvent, Range, Diagnostic, DiagnosticSeverity, Location, workspace, languages} from 'vscode';
|
||||
|
||||
export class Advisor {
|
||||
|
||||
private _disposable: Disposable;
|
||||
private _server: OmnisharpServer;
|
||||
private _packageRestoreCounter: number = 0;
|
||||
private _projectSourceFileCounts: { [path: string]: number } = Object.create(null);
|
||||
|
||||
constructor(server: OmnisharpServer) {
|
||||
this._server = server;
|
||||
let d1 = server.onProjectChange(this._onProjectChange, this);
|
||||
let d2 = server.onBeforePackageRestore(this._onBeforePackageRestore, this);
|
||||
let d3 = server.onPackageRestore(this._onPackageRestore, this);
|
||||
this._disposable = Disposable.from(d1, d2, d3);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
this._disposable.dispose();
|
||||
}
|
||||
|
||||
public shouldValidateFiles(): boolean {
|
||||
return this._isServerStarted()
|
||||
&& !this._isRestoringPackages();
|
||||
}
|
||||
|
||||
public shouldValidateProject(): boolean {
|
||||
return this._isServerStarted()
|
||||
&& !this._isRestoringPackages()
|
||||
&& !this._isHugeProject();
|
||||
}
|
||||
|
||||
private _onProjectChange(info: proto.ProjectInformationResponse): void {
|
||||
if (info.DnxProject && info.DnxProject.SourceFiles) {
|
||||
this._projectSourceFileCounts[info.DnxProject.Path] = info.DnxProject.SourceFiles.length;
|
||||
}
|
||||
if (info.MsBuildProject && info.MsBuildProject.SourceFiles) {
|
||||
this._projectSourceFileCounts[info.MsBuildProject.Path] = info.MsBuildProject.SourceFiles.length;
|
||||
}
|
||||
}
|
||||
|
||||
private _onBeforePackageRestore(): void {
|
||||
this._packageRestoreCounter += 1;
|
||||
}
|
||||
|
||||
private _onPackageRestore(): void {
|
||||
this._packageRestoreCounter -= 1;
|
||||
}
|
||||
|
||||
private _isServerStarted(): boolean {
|
||||
return this._server.isRunning();
|
||||
}
|
||||
|
||||
private _isRestoringPackages(): boolean {
|
||||
return this._packageRestoreCounter > 0;
|
||||
}
|
||||
|
||||
private _isHugeProject(): boolean {
|
||||
var sourceFileCount = 0;
|
||||
for (var key in this._projectSourceFileCounts) {
|
||||
sourceFileCount += this._projectSourceFileCounts[key];
|
||||
if (sourceFileCount > 1000) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default function reportDiagnostics(server: OmnisharpServer, advisor: Advisor): Disposable {
|
||||
return new DiagnosticsProvider(server, advisor);
|
||||
}
|
||||
|
||||
class DiagnosticsProvider extends AbstractSupport {
|
||||
|
||||
private _validationAdvisor: Advisor;
|
||||
private _disposable: Disposable;
|
||||
private _documentValidations: { [uri: string]: CancellationTokenSource } = Object.create(null);
|
||||
private _projectValidation: CancellationTokenSource;
|
||||
private _diagnostics: vscode.DiagnosticCollection;
|
||||
|
||||
constructor(server: OmnisharpServer, validationAdvisor: Advisor) {
|
||||
super(server);
|
||||
this._validationAdvisor = validationAdvisor;
|
||||
this._diagnostics = languages.createDiagnosticCollection('omnisharp');
|
||||
|
||||
let d1 = this._server.onPackageRestore(this._validateProject, this);
|
||||
let d2 = this._server.onProjectChange(this._validateProject, this);
|
||||
let d4 = workspace.onDidOpenTextDocument(event => this._onDocumentAddOrChange(event), this);
|
||||
let d3 = workspace.onDidChangeTextDocument(event => this._onDocumentAddOrChange(event.document), this);
|
||||
let d5 = workspace.onDidCloseTextDocument(this._onDocumentRemove, this);
|
||||
this._disposable = Disposable.from(this._diagnostics, d1, d2, d3, d4, d5);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._projectValidation) {
|
||||
this._projectValidation.dispose();
|
||||
}
|
||||
for (let key in this._documentValidations) {
|
||||
this._documentValidations[key].dispose();
|
||||
}
|
||||
this._disposable.dispose();
|
||||
}
|
||||
|
||||
private _onDocumentAddOrChange(document: TextDocument): void {
|
||||
if (document.languageId === 'csharp' && document.uri.scheme === 'file') {
|
||||
this._validateDocument(document);
|
||||
this._validateProject();
|
||||
}
|
||||
}
|
||||
|
||||
private _onDocumentRemove(document: TextDocument) {
|
||||
let key = document.uri.toString();
|
||||
let didChange = false;
|
||||
if (this._diagnostics[key]) {
|
||||
didChange = true;
|
||||
this._diagnostics[key].dispose();
|
||||
delete this._diagnostics[key];
|
||||
}
|
||||
if (this._documentValidations[key]) {
|
||||
didChange = true;
|
||||
this._documentValidations[key].cancel();
|
||||
delete this._documentValidations[key];
|
||||
}
|
||||
if (didChange) {
|
||||
this._validateProject();
|
||||
}
|
||||
}
|
||||
|
||||
private _validateDocument(document: TextDocument): void {
|
||||
|
||||
if (!this._validationAdvisor.shouldValidateFiles()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let key = document.uri.toString();
|
||||
if (this._documentValidations[key]) {
|
||||
this._documentValidations[key].cancel();
|
||||
}
|
||||
|
||||
let source = new CancellationTokenSource();
|
||||
let handle = setTimeout(() => {
|
||||
let req: proto.Request = { Filename: document.fileName };
|
||||
this._server.makeRequest<proto.QuickFixResponse>(proto.CodeCheck, req, source.token).then(value => {
|
||||
|
||||
// (re)set new diagnostics for this document
|
||||
let diagnostics = value.QuickFixes.map(DiagnosticsProvider._asDiagnostic);
|
||||
this._diagnostics.set(document.uri, diagnostics);
|
||||
});
|
||||
}, 750);
|
||||
|
||||
source.token.onCancellationRequested(() => clearTimeout(handle));
|
||||
this._documentValidations[key] = source;
|
||||
}
|
||||
|
||||
private _validateProject(): void {
|
||||
|
||||
if (!this._validationAdvisor.shouldValidateProject()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._projectValidation) {
|
||||
this._projectValidation.cancel();
|
||||
}
|
||||
|
||||
this._projectValidation = new CancellationTokenSource();
|
||||
let handle = setTimeout(() => {
|
||||
this._server.makeRequest<proto.QuickFixResponse>(proto.CodeCheck, {}, this._projectValidation.token).then(value => {
|
||||
|
||||
let quickFixes = value.QuickFixes.sort((a, b) => a.FileName.localeCompare(b.FileName));
|
||||
let entries: [Uri, Diagnostic[]][] = [];
|
||||
let lastEntry: [Uri, Diagnostic[]];
|
||||
|
||||
for (let quickFix of quickFixes) {
|
||||
|
||||
let diag = DiagnosticsProvider._asDiagnostic(quickFix);
|
||||
let uri = Uri.file(quickFix.FileName);
|
||||
|
||||
if (lastEntry && lastEntry[0].toString() === uri.toString()) {
|
||||
lastEntry[1].push(diag);
|
||||
} else {
|
||||
lastEntry = [uri, [diag]];
|
||||
entries.push(lastEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// replace all entries
|
||||
this._diagnostics.set(entries);
|
||||
});
|
||||
}, 3000);
|
||||
|
||||
// clear timeout on cancellation
|
||||
this._projectValidation.token.onCancellationRequested(() => {
|
||||
clearTimeout(handle);
|
||||
});
|
||||
}
|
||||
|
||||
// --- data converter
|
||||
|
||||
private static _asDiagnostic(quickFix: proto.QuickFix): Diagnostic {
|
||||
let severity = DiagnosticsProvider._asDiagnosticSeverity(quickFix.LogLevel);
|
||||
let message = `${quickFix.Text} [${quickFix.Projects.map(n => DiagnosticsProvider._asProjectLabel(n)).join(', ') }]`;
|
||||
return new Diagnostic(toRange(quickFix), message, severity);
|
||||
}
|
||||
|
||||
private static _asDiagnosticSeverity(logLevel: string): DiagnosticSeverity {
|
||||
switch (logLevel.toLowerCase()) {
|
||||
case 'hidden':
|
||||
case 'warning':
|
||||
case 'warn':
|
||||
return DiagnosticSeverity.Warning;
|
||||
default:
|
||||
return DiagnosticSeverity.Error;
|
||||
}
|
||||
}
|
||||
|
||||
private static _asProjectLabel(projectName: string): string {
|
||||
var idx = projectName.indexOf('+');
|
||||
return projectName.substr(idx + 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 AbstractSupport from './abstractProvider';
|
||||
import * as proto from '../protocol';
|
||||
import {createRequest, toRange} from '../typeConvertion';
|
||||
import {DocumentHighlightProvider, DocumentHighlight, DocumentHighlightKind, Uri, CancellationToken, TextDocument, Position, Range} from 'vscode';
|
||||
|
||||
export default class OmnisharpDocumentHighlightProvider extends AbstractSupport implements DocumentHighlightProvider {
|
||||
|
||||
public provideDocumentHighlights(resource: TextDocument, position: Position, token: CancellationToken): Promise<DocumentHighlight[]> {
|
||||
|
||||
let req = createRequest<proto.FindUsagesRequest>(resource, position);
|
||||
req.OnlyThisFile = true;
|
||||
req.ExcludeDefinition = false;
|
||||
|
||||
return this._server.makeRequest<proto.QuickFixResponse>(proto.FindUsages, req, token).then(res => {
|
||||
if (res && Array.isArray(res.QuickFixes)) {
|
||||
return res.QuickFixes.map(OmnisharpDocumentHighlightProvider._asDocumentHighlight);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static _asDocumentHighlight(quickFix: proto.QuickFix): DocumentHighlight {
|
||||
return new DocumentHighlight(toRange(quickFix), DocumentHighlightKind.Read);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 AbstractSupport from './abstractProvider';
|
||||
import * as Protocol from '../protocol';
|
||||
import {toDocumentSymbol} from '../typeConvertion';
|
||||
import {DocumentSymbolProvider, SymbolInformation, SymbolKind, Uri, TextDocument, Range, CancellationToken} from 'vscode';
|
||||
|
||||
export default class OmnisharpDocumentSymbolProvider extends AbstractSupport implements DocumentSymbolProvider {
|
||||
|
||||
public provideDocumentSymbols(document: TextDocument, token: CancellationToken): Promise<SymbolInformation[]> {
|
||||
|
||||
return this._server.makeRequest<Protocol.CurrentFileMembersAsTreeResponse>(Protocol.CurrentFileMembersAsTree, {Filename: document.fileName}, token).then(tree => {
|
||||
var ret: SymbolInformation[] = [];
|
||||
for (let node of tree.TopLevelTypeDefinitions) {
|
||||
toDocumentSymbol(ret, node);
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
|
||||
var _regExp = /<(\S*?).*?>((.|\r|\n)*?)<\/\1>/;
|
||||
|
||||
/**
|
||||
* remove xml-tags from string
|
||||
*/
|
||||
export function plain(doc: string): string {
|
||||
|
||||
if (!doc) {
|
||||
return doc;
|
||||
}
|
||||
|
||||
var newDoc: string;
|
||||
|
||||
while (true) {
|
||||
newDoc = doc.replace(_regExp,(m, g1, g2, g3) => g2);
|
||||
if (newDoc === doc) {
|
||||
break;
|
||||
}
|
||||
doc = newDoc;
|
||||
}
|
||||
|
||||
return newDoc;
|
||||
}
|
|
@ -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';
|
||||
|
||||
import AbstractSupport from './abstractProvider';
|
||||
import * as proto from '../protocol';
|
||||
import {Uri, DocumentRangeFormattingEditProvider, OnTypeFormattingEditProvider, FormattingOptions, CancellationToken, TextEdit, TextDocument, Range, Position} from 'vscode';
|
||||
|
||||
export default class FormattingSupport extends AbstractSupport implements DocumentRangeFormattingEditProvider {
|
||||
|
||||
public provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): Promise<TextEdit[]> {
|
||||
|
||||
let request = <proto.FormatRangeRequest>{
|
||||
Filename: document.fileName,
|
||||
Line: range.start.line + 1,
|
||||
Column: range.start.character + 1,
|
||||
EndLine: range.end.line + 1,
|
||||
EndColumn: range.end.character + 1
|
||||
};
|
||||
|
||||
return this._server.makeRequest<proto.FormatRangeResponse>(proto.FormatRange, request, token).then(res => {
|
||||
if (res && Array.isArray(res.Changes)) {
|
||||
return res.Changes.map(FormattingSupport._asEditOptionation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public provideOnTypeFormattingEdits(document: TextDocument, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): Promise<TextEdit[]> {
|
||||
|
||||
let request = <proto.FormatAfterKeystrokeRequest> {
|
||||
Filename: document.fileName,
|
||||
Line: position.line + 1,
|
||||
Column: position.character + 1,
|
||||
Character: ch
|
||||
};
|
||||
|
||||
return this._server.makeRequest<proto.FormatRangeResponse>(proto.FormatAfterKeystroke, request, token).then(res => {
|
||||
if (res && Array.isArray(res.Changes)) {
|
||||
return res.Changes.map(FormattingSupport._asEditOptionation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static _asEditOptionation(change: proto.TextChange): TextEdit {
|
||||
return new TextEdit(
|
||||
new Range(change.StartLine - 1, change.StartColumn - 1, change.EndLine - 1, change.EndColumn - 1),
|
||||
change.NewText);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {plain} from './documentation';
|
||||
import AbstractSupport from './abstractProvider';
|
||||
import * as Protocol from '../protocol';
|
||||
import {createRequest} from '../typeConvertion';
|
||||
import {HoverProvider, Hover, TextDocument, CancellationToken, Range, Position} from 'vscode';
|
||||
|
||||
export default class OmniSharpHoverProvider extends AbstractSupport implements HoverProvider {
|
||||
|
||||
public provideHover(document: TextDocument, position: Position, token: CancellationToken): Promise<Hover> {
|
||||
|
||||
let req = createRequest<Protocol.TypeLookupRequest>(document, position);
|
||||
req.IncludeDocumentation = true;
|
||||
|
||||
return this._server.makeRequest<Protocol.TypeLookupResponse>(Protocol.TypeLookup, req, token).then(value => {
|
||||
if (value && value.Type) {
|
||||
let contents = [plain(value.Documentation), { language: 'csharp', value: value.Type }];
|
||||
return new Hover(contents);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 vscode from 'vscode';
|
||||
import {OmnisharpServer} from '../omnisharpServer';
|
||||
import {dnxRestoreForProject} from './commands';
|
||||
import {basename} from 'path';
|
||||
import * as proto from '../protocol';
|
||||
|
||||
|
||||
export default function reportStatus(server: OmnisharpServer) {
|
||||
return vscode.Disposable.from(
|
||||
reportServerStatus(server),
|
||||
forwardOutput(server),
|
||||
reportDocumentStatus(server));
|
||||
}
|
||||
|
||||
// --- document status
|
||||
|
||||
let defaultSelector: vscode.DocumentSelector = [
|
||||
'csharp', // c#-files OR
|
||||
{ pattern: '**/project.json' }, // project.json-files OR
|
||||
{ pattern: '**/*.sln' }, // any solution file OR
|
||||
{ pattern: '**/*.csproj' } // an csproj file
|
||||
];
|
||||
|
||||
class Status {
|
||||
|
||||
selector: vscode.DocumentSelector;
|
||||
text: string;
|
||||
command: string;
|
||||
color: string;
|
||||
|
||||
constructor(selector: vscode.DocumentSelector) {
|
||||
this.selector = selector;
|
||||
}
|
||||
}
|
||||
|
||||
export function reportDocumentStatus(server: OmnisharpServer): vscode.Disposable {
|
||||
|
||||
let disposables: vscode.Disposable[] = [];
|
||||
|
||||
let entry = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, Number.MIN_VALUE);
|
||||
let defaultStatus = new Status(defaultSelector);
|
||||
let projectStatus: Status;
|
||||
|
||||
function render() {
|
||||
|
||||
if (!vscode.window.activeTextEditor) {
|
||||
entry.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
let document = vscode.window.activeTextEditor.document;
|
||||
let status: Status;
|
||||
|
||||
if (projectStatus && vscode.languages.match(projectStatus.selector, document)) {
|
||||
status = projectStatus;
|
||||
} else if (defaultStatus.text && vscode.languages.match(defaultStatus.selector, document)) {
|
||||
status = defaultStatus;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
entry.text = status.text;
|
||||
entry.command = status.command;
|
||||
entry.color = status.color;
|
||||
entry.show();
|
||||
return;
|
||||
}
|
||||
|
||||
entry.hide();
|
||||
}
|
||||
|
||||
disposables.push(vscode.window.onDidChangeActiveTextEditor(render));
|
||||
|
||||
disposables.push(server.onServerError(err => {
|
||||
defaultStatus.text = '$(flame) Error starting OmniSharp';
|
||||
defaultStatus.command = 'o.showOutput';
|
||||
defaultStatus.color = '';
|
||||
render();
|
||||
}));
|
||||
|
||||
disposables.push(server.onMultipleLaunchTargets(targets => {
|
||||
defaultStatus.text = '$(flame) Select project';
|
||||
defaultStatus.command = 'o.pickProjectAndStart';
|
||||
defaultStatus.color = 'rgb(90, 218, 90)';
|
||||
render();
|
||||
}));
|
||||
|
||||
disposables.push(server.onBeforeServerStart(path => {
|
||||
defaultStatus.text = '$(flame) Starting...';
|
||||
defaultStatus.command = 'o.showOutput';
|
||||
defaultStatus.color = '';
|
||||
render();
|
||||
}));
|
||||
|
||||
disposables.push(server.onServerStop(() => {
|
||||
projectStatus = undefined;
|
||||
defaultStatus.text = undefined;
|
||||
}));
|
||||
|
||||
disposables.push(server.onServerStart(path => {
|
||||
|
||||
defaultStatus.text = '$(flame) Runnning';
|
||||
defaultStatus.command = 'o.pickProjectAndStart';
|
||||
defaultStatus.color = '';
|
||||
render();
|
||||
|
||||
function updateProjectInfo() {
|
||||
server.makeRequest<proto.WorkspaceInformationResponse>(proto.Projects).then(info => {
|
||||
|
||||
let fileNames: vscode.DocumentSelector[] = [];
|
||||
let label: string;
|
||||
|
||||
// show sln-file if applicable
|
||||
if (info.MSBuild.SolutionPath) {
|
||||
label = basename(info.MSBuild.SolutionPath)//workspace.getRelativePath(info.MSBuild.SolutionPath);
|
||||
fileNames.push({ pattern: info.MSBuild.SolutionPath });
|
||||
|
||||
for (let project of info.MSBuild.Projects) {
|
||||
fileNames.push({ pattern: project.Path });
|
||||
for (let sourceFile of project.SourceFiles) {
|
||||
fileNames.push({ pattern: sourceFile });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// show dnx projects if applicable
|
||||
let count = 0;
|
||||
for (let project of info.Dnx.Projects) {
|
||||
count += 1;
|
||||
|
||||
fileNames.push({ pattern: project.Path });
|
||||
for (let sourceFile of project.SourceFiles) {
|
||||
fileNames.push({ pattern: sourceFile });
|
||||
}
|
||||
}
|
||||
if (label) {
|
||||
// we already have a message from a sln-file
|
||||
} else if (count === 1) {
|
||||
label = basename(info.Dnx.Projects[0].Path)//workspace.getRelativePath(info.Dnx.Projects[0].Path);
|
||||
} else {
|
||||
label = `${count} projects`;
|
||||
}
|
||||
|
||||
// set project info
|
||||
projectStatus = new Status(fileNames);
|
||||
projectStatus.text = '$(flame) ' + label;
|
||||
projectStatus.command = 'o.pickProjectAndStart';
|
||||
|
||||
// default is to change project
|
||||
defaultStatus.text = '$(flame) Switch projects';
|
||||
defaultStatus.command = 'o.pickProjectAndStart';
|
||||
render();
|
||||
});
|
||||
}
|
||||
|
||||
disposables.push(server.onProjectAdded(updateProjectInfo));
|
||||
disposables.push(server.onProjectChange(updateProjectInfo));
|
||||
disposables.push(server.onProjectRemoved(updateProjectInfo));
|
||||
}));
|
||||
|
||||
return vscode.Disposable.from(...disposables);
|
||||
}
|
||||
|
||||
|
||||
// ---- server status
|
||||
|
||||
export function reportServerStatus(server: OmnisharpServer): vscode.Disposable{
|
||||
|
||||
function appendLine(value: string = '') {
|
||||
server.getChannel().appendLine(value);
|
||||
}
|
||||
|
||||
let d0 = server.onServerError(err => {
|
||||
appendLine('[ERROR] ' + err);
|
||||
});
|
||||
|
||||
let d1 = server.onError(message => {
|
||||
if (message.FileName) {
|
||||
appendLine(`${message.FileName}(${message.Line},${message.Column})`);
|
||||
}
|
||||
appendLine(message.Text);
|
||||
appendLine();
|
||||
showMessageSoon();
|
||||
});
|
||||
|
||||
let d2 = server.onMsBuildProjectDiagnostics(message => {
|
||||
|
||||
function asErrorMessage(message: proto.MSBuildDiagnosticsMessage) {
|
||||
let value = `${message.FileName}(${message.StartLine},${message.StartColumn}): Error: ${message.Text}`;
|
||||
appendLine(value);
|
||||
}
|
||||
|
||||
function asWarningMessage(message: proto.MSBuildDiagnosticsMessage) {
|
||||
let value = `${message.FileName}(${message.StartLine},${message.StartColumn}): Warning: ${message.Text}`;
|
||||
appendLine(value);
|
||||
}
|
||||
|
||||
if (message.Errors.length > 0 || message.Warnings.length > 0) {
|
||||
appendLine(message.FileName);
|
||||
message.Errors.forEach(error => asErrorMessage);
|
||||
message.Warnings.forEach(warning => asWarningMessage);
|
||||
appendLine();
|
||||
showMessageSoon();
|
||||
}
|
||||
});
|
||||
|
||||
let d3 = server.onUnresolvedDependencies(message => {
|
||||
|
||||
let info = `There are unresolved dependencies from '${vscode.workspace.asRelativePath(message.FileName) }'. Please execute the restore command to continue.`;
|
||||
|
||||
return vscode.window.showInformationMessage(info, 'Restore').then(value => {
|
||||
if (value) {
|
||||
dnxRestoreForProject(server, message.FileName);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return vscode.Disposable.from(d0, d1, d2, d3);
|
||||
}
|
||||
|
||||
// show user message
|
||||
let _messageHandle: number;
|
||||
function showMessageSoon() {
|
||||
clearTimeout(_messageHandle);
|
||||
_messageHandle = setTimeout(function() {
|
||||
|
||||
let message = "Some projects have trouble loading. Please review the output for more details.";
|
||||
vscode.window.showWarningMessage(message, { title: "Show Output", command: 'o.showOutput' }).then(value => {
|
||||
if (value) {
|
||||
vscode.commands.executeCommand(value.command);
|
||||
}
|
||||
});
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
// --- mirror output in channel
|
||||
|
||||
function forwardOutput(server: OmnisharpServer) {
|
||||
|
||||
const logChannel = server.getChannel();
|
||||
const timing200Pattern = /^\[INFORMATION:OmniSharp.Middleware.LoggingMiddleware\] \/\w+: 200 \d+ms/;
|
||||
|
||||
function forward(message: string) {
|
||||
// strip stuff like: /codecheck: 200 339ms
|
||||
if(!timing200Pattern.test(message)) {
|
||||
logChannel.append(message);
|
||||
}
|
||||
}
|
||||
|
||||
return vscode.Disposable.from(
|
||||
server.onStdout(forward),
|
||||
server.onStderr(forward));
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 AbstractSupport from './abstractProvider';
|
||||
import * as Protocol from '../protocol';
|
||||
import {createRequest, toLocation} from '../typeConvertion';
|
||||
import {ReferenceProvider, Location, Range, TextDocument, Uri, CancellationToken, Position} from 'vscode';
|
||||
|
||||
export default class OmnisharpReferenceProvider extends AbstractSupport implements ReferenceProvider {
|
||||
|
||||
public provideReferences(document: TextDocument, position: Position, options: { includeDeclaration: boolean;}, token: CancellationToken): Promise<Location[]> {
|
||||
|
||||
let req = createRequest<Protocol.FindUsagesRequest>(document, position);
|
||||
req.OnlyThisFile = false;
|
||||
req.ExcludeDefinition = false;
|
||||
|
||||
return this._server.makeRequest<Protocol.QuickFixResponse>(Protocol.FindUsages, req, token).then(res => {
|
||||
if (res && Array.isArray(res.QuickFixes)) {
|
||||
return res.QuickFixes.map(toLocation);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import AbstractSupport from './abstractProvider';
|
||||
import * as proto from '../protocol';
|
||||
import {createRequest, toRange} from '../typeConvertion';
|
||||
import {RenameProvider, TextEdit, WorkspaceEdit, TextDocument, Uri, CancellationToken, Position, Range} from 'vscode';
|
||||
|
||||
export default class OmnisharpRenameProvider extends AbstractSupport implements RenameProvider {
|
||||
|
||||
public provideRenameEdits(document: TextDocument, position: Position, newName: string, token: CancellationToken): Promise<WorkspaceEdit> {
|
||||
|
||||
let request = createRequest<proto.RenameRequest>(document, position);
|
||||
request.WantsTextChanges = true,
|
||||
request.RenameTo = newName;
|
||||
|
||||
return this._server.makeRequest<proto.RenameResponse>(proto.Rename, request, token).then(response => {
|
||||
|
||||
if (!response) {
|
||||
return;
|
||||
}
|
||||
|
||||
const edit = new WorkspaceEdit();
|
||||
response.Changes.forEach(change => {
|
||||
const uri = Uri.file(change.FileName);
|
||||
change.Changes.forEach(change => {
|
||||
edit.replace(uri,
|
||||
new Range(change.StartLine - 1, change.StartColumn - 1, change.EndLine - 1, change.EndColumn - 1),
|
||||
change.NewText);
|
||||
});
|
||||
});
|
||||
|
||||
return edit;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import AbstractSupport from './abstractProvider';
|
||||
import * as Protocol from '../protocol';
|
||||
import {createRequest} from '../typeConvertion';
|
||||
import {SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, Uri, CancellationToken, TextDocument, Position} from 'vscode';
|
||||
|
||||
export default class OmniSharpSignatureHelpProvider extends AbstractSupport implements SignatureHelpProvider {
|
||||
|
||||
public provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Promise<SignatureHelp> {
|
||||
|
||||
let req = createRequest(document, position);
|
||||
|
||||
return this._server.makeRequest<Protocol.SignatureHelp>(Protocol.SignatureHelp, req, token).then(res => {
|
||||
|
||||
let ret = new SignatureHelp();
|
||||
ret.activeSignature = res.ActiveSignature;
|
||||
ret.activeParameter = res.ActiveParameter;
|
||||
|
||||
for(let signature of res.Signatures) {
|
||||
|
||||
let signatureInfo = new SignatureInformation(signature.Label, signature.Documentation);
|
||||
ret.signatures.push(signatureInfo);
|
||||
|
||||
for (let parameter of signature.Parameters) {
|
||||
let parameterInfo = new ParameterInformation(
|
||||
parameter.Label,
|
||||
parameter.Documentation);
|
||||
|
||||
signatureInfo.parameters.push(parameterInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 AbstractSupport from './abstractProvider';
|
||||
import * as Protocol from '../protocol';
|
||||
import {createRequest, toRange} from '../typeConvertion';
|
||||
import {CancellationToken, Uri, Range, WorkspaceSymbolProvider, SymbolInformation, SymbolKind} from 'vscode';
|
||||
|
||||
|
||||
export default class OmnisharpWorkspaceSymbolProvider extends AbstractSupport implements WorkspaceSymbolProvider {
|
||||
|
||||
public provideWorkspaceSymbols(search: string, token: CancellationToken): Promise<SymbolInformation[]> {
|
||||
|
||||
return this._server.makeRequest<Protocol.FindSymbolsResponse>(Protocol.FindSymbols, <Protocol.FindSymbolsRequest> {
|
||||
Filter: search,
|
||||
Filename: ''
|
||||
}, token).then(res => {
|
||||
if (res && Array.isArray(res.QuickFixes)) {
|
||||
return res.QuickFixes.map(OmnisharpWorkspaceSymbolProvider._asSymbolInformation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static _asSymbolInformation(symbolInfo: Protocol.SymbolLocation): SymbolInformation {
|
||||
|
||||
return new SymbolInformation(symbolInfo.Text, OmnisharpWorkspaceSymbolProvider._toKind(symbolInfo),
|
||||
toRange(symbolInfo),
|
||||
Uri.file(symbolInfo.FileName));
|
||||
}
|
||||
|
||||
private static _toKind(symbolInfo: Protocol.SymbolLocation): SymbolKind {
|
||||
switch (symbolInfo.Kind) {
|
||||
case 'Method':
|
||||
return SymbolKind.Method;
|
||||
case 'Field':
|
||||
case 'Property':
|
||||
return SymbolKind.Field;
|
||||
}
|
||||
return SymbolKind.Class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 paths from 'path';
|
||||
import {EventEmitter} from 'events';
|
||||
import {Uri, workspace} from 'vscode';
|
||||
|
||||
export interface LaunchTarget {
|
||||
label: string;
|
||||
description: string;
|
||||
directory: Uri;
|
||||
resource: Uri;
|
||||
target: Uri;
|
||||
}
|
||||
|
||||
|
||||
export default function getLaunchTargets(): Thenable<LaunchTarget[]> {
|
||||
return workspace.findFiles('{**/*.sln,**/*.csproj,**/project.json}', '{**/node_modules/**,**/.git/**,**/bower_components/**}', 100).then(resources => {
|
||||
return select(resources, Uri.file(workspace.rootPath));
|
||||
});
|
||||
}
|
||||
|
||||
function select(resources: Uri[], root: Uri): LaunchTarget[] {
|
||||
|
||||
if (!Array.isArray(resources)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var targets: LaunchTarget[] = [],
|
||||
hasCsProjFiles = false,
|
||||
hasProjectJson = false,
|
||||
hasProjectJsonAtRoot = false;
|
||||
|
||||
hasCsProjFiles = resources
|
||||
.some(resource => /\.csproj$/.test(resource.fsPath));
|
||||
|
||||
resources.forEach(resource => {
|
||||
|
||||
// sln files
|
||||
if (hasCsProjFiles && /\.sln$/.test(resource.fsPath)) {
|
||||
targets.push({
|
||||
label: paths.basename(resource.fsPath),
|
||||
description: workspace.asRelativePath(paths.dirname(resource.fsPath)),
|
||||
resource,
|
||||
target: resource,
|
||||
directory: Uri.file(paths.dirname(resource.fsPath))
|
||||
});
|
||||
}
|
||||
|
||||
// project.json files
|
||||
if (/project.json$/.test(resource.fsPath)) {
|
||||
|
||||
var dirname = paths.dirname(resource.fsPath);
|
||||
hasProjectJson = true;
|
||||
hasProjectJsonAtRoot = hasProjectJsonAtRoot || dirname === root.fsPath;
|
||||
|
||||
targets.push({
|
||||
label: paths.basename(resource.fsPath),
|
||||
description: workspace.asRelativePath(paths.dirname(resource.fsPath)),
|
||||
resource,
|
||||
target: Uri.file(dirname),
|
||||
directory: Uri.file(dirname)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (hasProjectJson && !hasProjectJsonAtRoot) {
|
||||
targets.push({
|
||||
label: paths.basename(root.fsPath),
|
||||
description: '',
|
||||
resource: root,
|
||||
target: root,
|
||||
directory: root
|
||||
});
|
||||
}
|
||||
|
||||
return targets.sort((a, b) => a.directory.fsPath.localeCompare(b.directory.fsPath));
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 DefinitionProvider from './features/definitionProvider';
|
||||
import CodeLensProvider from './features/codeLensProvider';
|
||||
import DocumentHighlightProvider from './features/documentHighlightProvider';
|
||||
import DocumentSymbolProvider from './features/documentSymbolProvider';
|
||||
import CodeActionProvider from './features/codeActionProvider';
|
||||
import ReferenceProvider from './features/referenceProvider';
|
||||
import HoverProvider from './features/hoverProvider';
|
||||
import RenameProvider from './features/renameProvider';
|
||||
import FormatProvider from './features/formattingEditProvider';
|
||||
import CompletionItemProvider from './features/completionItemProvider';
|
||||
import WorkspaceSymbolProvider from './features/workspaceSymbolProvider';
|
||||
import reportDiagnostics,{Advisor} from './features/diagnosticsProvider';
|
||||
import SignatureHelpProvider from './features/signatureHelpProvider';
|
||||
import registerCommands from './features/commands';
|
||||
import {StdioOmnisharpServer} from './omnisharpServer';
|
||||
import forwardChanges from './features/changeForwarding';
|
||||
import reportStatus from './features/omnisharpStatus';
|
||||
import findLaunchTargets from './launchTargetFinder';
|
||||
import {Disposable, ExtensionContext, languages, extensions} from 'vscode';
|
||||
|
||||
export function activate(context: ExtensionContext): any {
|
||||
|
||||
const _selector: vscode.DocumentSelector = {
|
||||
language: 'csharp',
|
||||
scheme: 'file' // only files from disk
|
||||
};
|
||||
|
||||
const server = new StdioOmnisharpServer();
|
||||
let advisor = new Advisor(server);
|
||||
|
||||
let disposables: Disposable[] = [];
|
||||
let localDisposables: Disposable[] = [];
|
||||
|
||||
disposables.push(server.onServerStart(() => {
|
||||
// register language feature provider on start
|
||||
localDisposables.push(languages.registerDefinitionProvider(_selector, new DefinitionProvider(server)));
|
||||
localDisposables.push(languages.registerCodeLensProvider(_selector, new CodeLensProvider(server)));
|
||||
localDisposables.push(languages.registerDocumentHighlightProvider(_selector, new DocumentHighlightProvider(server)));
|
||||
localDisposables.push(languages.registerDocumentSymbolProvider(_selector, new DocumentSymbolProvider(server)));
|
||||
localDisposables.push(languages.registerReferenceProvider(_selector, new ReferenceProvider(server)));
|
||||
localDisposables.push(languages.registerHoverProvider(_selector, new HoverProvider(server)));
|
||||
localDisposables.push(languages.registerRenameProvider(_selector, new RenameProvider(server)));
|
||||
localDisposables.push(languages.registerDocumentRangeFormattingEditProvider(_selector, new FormatProvider(server)));
|
||||
localDisposables.push(languages.registerOnTypeFormattingEditProvider(_selector, new FormatProvider(server), '}', ';'));
|
||||
localDisposables.push(languages.registerCompletionItemProvider(_selector, new CompletionItemProvider(server), '.', '<'));
|
||||
localDisposables.push(languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(server)));
|
||||
localDisposables.push(languages.registerSignatureHelpProvider(_selector, new SignatureHelpProvider(server), '(', ','));
|
||||
let codeActionProvider = new CodeActionProvider(server);
|
||||
localDisposables.push(codeActionProvider);
|
||||
localDisposables.push(languages.registerCodeActionsProvider(_selector, codeActionProvider));
|
||||
localDisposables.push(reportDiagnostics(server, advisor));
|
||||
localDisposables.push(forwardChanges(server));
|
||||
}));
|
||||
|
||||
disposables.push(server.onServerStop(() => {
|
||||
// remove language feature providers on stop
|
||||
Disposable.from(...localDisposables).dispose();
|
||||
}));
|
||||
|
||||
disposables.push(registerCommands(server));
|
||||
disposables.push(reportStatus(server));
|
||||
|
||||
// read and store last solution or folder path
|
||||
server.autoStart(context.workspaceState.get<string>('lastSolutionPathOrFolder'));
|
||||
server.onBeforeServerStart(path => context.workspaceState.update('lastSolutionPathOrFolder', path));
|
||||
|
||||
// stop server on deactivate
|
||||
disposables.push(new Disposable(() => {
|
||||
advisor.dispose();
|
||||
server.stop();
|
||||
}));
|
||||
|
||||
context.subscriptions.push(...disposables);
|
||||
}
|
||||
|
|
@ -0,0 +1,507 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {EventEmitter} from 'events';
|
||||
import {ChildProcess, exec} from 'child_process';
|
||||
import {request} from 'http';
|
||||
import {dirname} from 'path';
|
||||
import {ReadLine, createInterface} from 'readline';
|
||||
import omnisharpLauncher from './omnisharpServerLauncher';
|
||||
import {Disposable, CancellationToken, OutputChannel, workspace, window} from 'vscode';
|
||||
import {ErrorMessage, UnresolvedDependenciesMessage, MSBuildProjectDiagnostics, ProjectInformationResponse} from './protocol';
|
||||
import getLaunchTargets, {LaunchTarget} from './launchTargetFinder';
|
||||
|
||||
|
||||
enum ServerState {
|
||||
Starting,
|
||||
Started,
|
||||
Stopped
|
||||
}
|
||||
|
||||
interface Request {
|
||||
path: string;
|
||||
data?: any;
|
||||
onSuccess: Function;
|
||||
onError: Function;
|
||||
_enqueued: number;
|
||||
}
|
||||
|
||||
export abstract class OmnisharpServer {
|
||||
|
||||
private _eventBus = new EventEmitter();
|
||||
private _start: Promise<void>;
|
||||
private _state: ServerState = ServerState.Stopped;
|
||||
private _solutionPath: string;
|
||||
private _queue: Request[] = [];
|
||||
private _isProcessingQueue = false;
|
||||
private _channel: OutputChannel;
|
||||
|
||||
protected _serverProcess: ChildProcess;
|
||||
protected _extraArgv: string[];
|
||||
|
||||
constructor() {
|
||||
this._extraArgv = [];
|
||||
this._channel = window.createOutputChannel('OmniSharp Log');
|
||||
}
|
||||
|
||||
public isRunning(): boolean {
|
||||
return this._state === ServerState.Started;
|
||||
}
|
||||
|
||||
private _getState(): ServerState {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
private _setState(value: ServerState) : void {
|
||||
if (typeof value !== 'undefined' && value !== this._state) {
|
||||
this._state = value;
|
||||
this._fireEvent('stateChanged', this._state);
|
||||
}
|
||||
}
|
||||
|
||||
public getSolutionPathOrFolder(): string {
|
||||
return this._solutionPath;
|
||||
}
|
||||
|
||||
public getChannel(): vscode.OutputChannel {
|
||||
return this._channel;
|
||||
}
|
||||
|
||||
public onStdout(listener: (e: string) => any, thisArg?: any) {
|
||||
return this._addListener('stdout', listener, thisArg);
|
||||
}
|
||||
|
||||
public onStderr(listener: (e: string) => any, thisArg?: any) {
|
||||
return this._addListener('stderr', listener, thisArg);
|
||||
}
|
||||
|
||||
public onError(listener: (e: ErrorMessage) => any, thisArg?: any) {
|
||||
return this._addListener('Error', listener, thisArg);
|
||||
}
|
||||
|
||||
public onServerError(listener: (err: any) => any, thisArg?: any) {
|
||||
return this._addListener('ServerError', listener, thisArg);
|
||||
}
|
||||
|
||||
public onUnresolvedDependencies(listener: (e: UnresolvedDependenciesMessage) => any, thisArg?:any) {
|
||||
return this._addListener('UnresolvedDependencies', listener, thisArg);
|
||||
}
|
||||
|
||||
public onBeforePackageRestore(listener: () => any, thisArg?: any) {
|
||||
return this._addListener('PackageRestoreStarted', listener, thisArg);
|
||||
}
|
||||
|
||||
public onPackageRestore(listener: () => any, thisArg?: any) {
|
||||
return this._addListener('PackageRestoreFinished', listener, thisArg);
|
||||
}
|
||||
|
||||
public onProjectChange(listener: (e: ProjectInformationResponse) => any, thisArg?: any) {
|
||||
return this._addListener('ProjectChanged', listener, thisArg);
|
||||
}
|
||||
|
||||
public onProjectAdded(listener: (e: ProjectInformationResponse) => any, thisArg?: any) {
|
||||
return this._addListener('ProjectAdded', listener, thisArg);
|
||||
}
|
||||
|
||||
public onProjectRemoved(listener: (e: ProjectInformationResponse) => any, thisArg?: any) {
|
||||
return this._addListener('ProjectRemoved', listener, thisArg);
|
||||
}
|
||||
|
||||
public onMsBuildProjectDiagnostics(listener: (e: MSBuildProjectDiagnostics) => any, thisArg?: any) {
|
||||
return this._addListener('MsBuildProjectDiagnostics', listener, thisArg);
|
||||
}
|
||||
|
||||
public onBeforeServerStart(listener: (e:string) => any) {
|
||||
return this._addListener('BeforeServerStart', listener);
|
||||
}
|
||||
|
||||
public onServerStart(listener: (e: string) => any) {
|
||||
return this._addListener('ServerStart', listener);
|
||||
}
|
||||
|
||||
public onServerStop(listener: () => any) {
|
||||
return this._addListener('ServerStop', listener);
|
||||
}
|
||||
|
||||
public onMultipleLaunchTargets(listener: (targets: LaunchTarget[]) => any, thisArg?: any) {
|
||||
return this._addListener('server:MultipleLaunchTargets', listener, thisArg);
|
||||
}
|
||||
|
||||
public onOmnisharpStart(listener: () => any) {
|
||||
return this._addListener('started', listener);
|
||||
}
|
||||
|
||||
private _addListener(event: string, listener: (e: any) => any, thisArg?: any): Disposable {
|
||||
listener = thisArg ? listener.bind(thisArg) : listener;
|
||||
this._eventBus.addListener(event, listener);
|
||||
return new Disposable(() => this._eventBus.removeListener(event, listener));
|
||||
}
|
||||
|
||||
protected _fireEvent(event: string, args: any): void {
|
||||
this._eventBus.emit(event, args);
|
||||
}
|
||||
|
||||
public start(solutionPath: string): Promise<void> {
|
||||
if (!this._start) {
|
||||
this._start = this._doStart(solutionPath);
|
||||
}
|
||||
return this._start;
|
||||
}
|
||||
|
||||
private _doStart(solutionPath: string): Promise<void> {
|
||||
|
||||
this._setState(ServerState.Starting);
|
||||
this._solutionPath = solutionPath;
|
||||
|
||||
var cwd = dirname(solutionPath),
|
||||
argv = ['-s', solutionPath, '--hostPID', process.pid.toString(), 'dnx:enablePackageRestore=false'].concat(this._extraArgv);
|
||||
|
||||
this._fireEvent('stdout', `[INFO] Starting OmniSharp at '${solutionPath}'...\n`);
|
||||
this._fireEvent('BeforeServerStart', solutionPath);
|
||||
|
||||
return omnisharpLauncher(cwd, argv).then(value => {
|
||||
this._serverProcess = value.process;
|
||||
this._fireEvent('stdout', `[INFO] Started OmniSharp from '${value.command}' with process id ${value.process.pid}...\n`);
|
||||
return this._doConnect();
|
||||
}).then(_ => {
|
||||
this._fireEvent('ServerStart', solutionPath);
|
||||
this._setState(ServerState.Started);
|
||||
this._processQueue();
|
||||
}, err => {
|
||||
this._fireEvent('ServerError', err);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract _doConnect(): Promise<OmnisharpServer>;
|
||||
|
||||
public stop(): Promise<void> {
|
||||
|
||||
var ret: Promise<OmnisharpServer>;
|
||||
|
||||
if (!this._serverProcess) {
|
||||
// nothing to kill
|
||||
ret = Promise.resolve(undefined);
|
||||
|
||||
} else if (/^win/.test(process.platform)) {
|
||||
// when killing a process in windows its child
|
||||
// processes are *not* killed but become root
|
||||
// processes. Therefore we use TASKKILL.EXE
|
||||
ret = new Promise<OmnisharpServer>((resolve, reject) => {
|
||||
var killer = exec(`taskkill /F /T /PID ${this._serverProcess.pid}`, function (err, stdout, stderr) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
});
|
||||
killer.on('exit', resolve);
|
||||
killer.on('error', reject);
|
||||
});
|
||||
} else {
|
||||
this._serverProcess.kill('SIGTERM');
|
||||
ret = Promise.resolve(undefined);
|
||||
}
|
||||
return ret.then(_ => {
|
||||
this._start = null;
|
||||
this._serverProcess = null;
|
||||
this._setState(ServerState.Stopped);
|
||||
this._fireEvent('ServerStop', this);
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
public restart(solutionPath: string = this._solutionPath): Promise<void> {
|
||||
if (solutionPath) {
|
||||
return this.stop().then(() => {
|
||||
this.start(solutionPath)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public autoStart(preferredPath:string): Thenable<void> {
|
||||
return getLaunchTargets().then(targets => {
|
||||
if (targets.length === 0) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
// 1st watch for files
|
||||
let watcher = workspace.createFileSystemWatcher('{**/*.sln,**/project.json}', false, true, true);
|
||||
watcher.onDidCreate(uri => {
|
||||
watcher.dispose();
|
||||
resolve();
|
||||
});
|
||||
}).then(() => {
|
||||
// 2nd try again
|
||||
return this.autoStart(preferredPath);
|
||||
});
|
||||
}
|
||||
|
||||
if (targets.length > 1) {
|
||||
|
||||
for (let target of targets) {
|
||||
if (target.target.fsPath === preferredPath) {
|
||||
// start preferred path
|
||||
return this.restart(preferredPath);
|
||||
}
|
||||
}
|
||||
|
||||
this._fireEvent('server:MultipleLaunchTargets', targets);
|
||||
return Promise.reject<void>(undefined);
|
||||
}
|
||||
|
||||
// just start
|
||||
return this.restart(targets[0].target.fsPath);
|
||||
});
|
||||
}
|
||||
|
||||
public makeRequest<R>(path: string, data?: any, token?: CancellationToken): Promise<R> {
|
||||
|
||||
if (this._getState() !== ServerState.Started) {
|
||||
return Promise.reject<R>('server has been stopped or not started');
|
||||
}
|
||||
|
||||
let request: Request;
|
||||
let promise = new Promise<any>((resolve, reject) => {
|
||||
request = {
|
||||
path,
|
||||
data,
|
||||
onSuccess: resolve,
|
||||
onError: reject,
|
||||
_enqueued: Date.now()
|
||||
};
|
||||
this._queue.push(request);
|
||||
// this._statOnRequestStart(request);
|
||||
if (this._getState() === ServerState.Started && !this._isProcessingQueue) {
|
||||
this._processQueue();
|
||||
}
|
||||
});
|
||||
|
||||
if (token) {
|
||||
token.onCancellationRequested(() => {
|
||||
let idx = this._queue.indexOf(request);
|
||||
if (idx !== -1) {
|
||||
this._queue.splice(idx, 1);
|
||||
let err = new Error('Canceled');
|
||||
err.message = 'Canceled';
|
||||
request.onError(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
private _processQueue(): void {
|
||||
|
||||
if (this._queue.length === 0) {
|
||||
// nothing to do
|
||||
this._isProcessingQueue = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// signal that we are working on it
|
||||
this._isProcessingQueue = true;
|
||||
|
||||
// send next request and recurse when done
|
||||
var thisRequest = this._queue.shift();
|
||||
this._makeNextRequest(thisRequest.path, thisRequest.data).then(value => {
|
||||
thisRequest.onSuccess(value);
|
||||
this._processQueue();
|
||||
// this._statOnRequestEnd(thisRequest, true);
|
||||
}, err => {
|
||||
thisRequest.onError(err);
|
||||
this._processQueue();
|
||||
// this._statOnRequestEnd(thisRequest, false);
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
this._processQueue();
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract _makeNextRequest(path: string, data: any): Promise<any>;
|
||||
|
||||
// private _statOnRequestStart(request: Request): void {
|
||||
// console.log(`[DEBUG] *enqueuing* request '${request.path}' (queue size is ${this._queue.length})\n`);
|
||||
// }
|
||||
|
||||
// private _statOnRequestEnd(request: Request, successfully: boolean): void {
|
||||
// var duration = Date.now() - request._enqueued,
|
||||
// state = successfully ? 'successfully' : 'with errors';
|
||||
|
||||
// console.log(`[DEBUG] request '${request.path}' finished *${state}* after ${duration}ms\n`);
|
||||
// }
|
||||
}
|
||||
|
||||
namespace WireProtocol {
|
||||
|
||||
export interface Packet {
|
||||
Type: string;
|
||||
Seq: number;
|
||||
}
|
||||
|
||||
export interface RequestPacket extends Packet {
|
||||
Command: string;
|
||||
Arguments: any;
|
||||
}
|
||||
|
||||
export interface ResponsePacket extends Packet {
|
||||
Command: string;
|
||||
Request_seq: number;
|
||||
Running: boolean;
|
||||
Success: boolean;
|
||||
Message: string;
|
||||
Body: any;
|
||||
}
|
||||
|
||||
export interface EventPacket extends Packet {
|
||||
Event: string;
|
||||
Body: any;
|
||||
}
|
||||
}
|
||||
|
||||
export class StdioOmnisharpServer extends OmnisharpServer {
|
||||
|
||||
private static _seqPool = 1;
|
||||
private static StartupTimeout = 1000 * 60;
|
||||
private static ResponsePacketTimeout = 1000 * 60 * 15; // helps debugging
|
||||
|
||||
private _rl: ReadLine;
|
||||
private _activeRequest: { [seq: number]: { onSuccess: Function; onError: Function; } } = Object.create(null);
|
||||
private _callOnStop: Function[] = [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// extra argv
|
||||
this._extraArgv.push('--stdio');
|
||||
}
|
||||
|
||||
public stop(): Promise<void> {
|
||||
while (this._callOnStop.length) {
|
||||
this._callOnStop.pop()();
|
||||
}
|
||||
return super.stop();
|
||||
}
|
||||
|
||||
protected _doConnect(): Promise<OmnisharpServer> {
|
||||
|
||||
this._serverProcess.stderr.on('data', (data: any) => this._fireEvent('stderr', String(data)));
|
||||
|
||||
this._rl = createInterface({
|
||||
input: this._serverProcess.stdout,
|
||||
output: this._serverProcess.stdin,
|
||||
terminal: false
|
||||
});
|
||||
|
||||
var p = new Promise<OmnisharpServer>((resolve, reject) => {
|
||||
var listener: Disposable;
|
||||
|
||||
// timeout logic
|
||||
var handle = setTimeout(() => {
|
||||
listener && listener.dispose();
|
||||
reject(new Error('Failed to start OmniSharp'));
|
||||
}, StdioOmnisharpServer.StartupTimeout);
|
||||
|
||||
// handle started-event
|
||||
listener = this.onOmnisharpStart(() => {
|
||||
listener && listener.dispose();
|
||||
clearTimeout(handle);
|
||||
resolve(this);
|
||||
});
|
||||
});
|
||||
|
||||
this._startListening();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private _startListening(): void {
|
||||
|
||||
var onLineReceived = (line: string) => {
|
||||
if (line[0] !== '{') {
|
||||
this._fireEvent('stdout', `${line}\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
var packet: WireProtocol.Packet;
|
||||
try {
|
||||
packet = JSON.parse(line);
|
||||
} catch (e) {
|
||||
// not json
|
||||
return;
|
||||
}
|
||||
|
||||
if (!packet.Type) {
|
||||
// bogous packet
|
||||
return;
|
||||
}
|
||||
|
||||
switch (packet.Type) {
|
||||
case 'response':
|
||||
this._handleResponsePacket(<WireProtocol.ResponsePacket> packet);
|
||||
break;
|
||||
case 'event':
|
||||
this._handleEventPacket(<WireProtocol.EventPacket> packet);
|
||||
break;
|
||||
default:
|
||||
console.warn('unknown packet: ', packet);
|
||||
break;
|
||||
}
|
||||
};
|
||||
this._rl.addListener('line', onLineReceived);
|
||||
this._callOnStop.push(() => this._rl.removeListener('line', onLineReceived));
|
||||
}
|
||||
|
||||
private _handleResponsePacket(packet: WireProtocol.ResponsePacket): void {
|
||||
|
||||
var requestSeq = packet.Request_seq,
|
||||
entry = this._activeRequest[requestSeq];
|
||||
|
||||
if (!entry) {
|
||||
console.warn('Received a response WITHOUT a request', packet);
|
||||
return;
|
||||
}
|
||||
|
||||
delete this._activeRequest[requestSeq];
|
||||
|
||||
if (packet.Success) {
|
||||
entry.onSuccess(packet.Body);
|
||||
} else {
|
||||
entry.onError(packet.Message || packet.Body);
|
||||
}
|
||||
}
|
||||
|
||||
private _handleEventPacket(packet: WireProtocol.EventPacket): void {
|
||||
|
||||
if (packet.Event === 'log') {
|
||||
// handle log events
|
||||
var entry = <{ LogLevel: string; Name: string; Message: string; }> packet.Body;
|
||||
this._fireEvent('stdout', `[${entry.LogLevel}:${entry.Name}] ${entry.Message}\n`);
|
||||
return;
|
||||
} else {
|
||||
// fwd all other events
|
||||
this._fireEvent(packet.Event, packet.Body);
|
||||
}
|
||||
}
|
||||
|
||||
protected _makeNextRequest(path: string, data: any): Promise<any> {
|
||||
|
||||
var thisRequestPacket: WireProtocol.RequestPacket = {
|
||||
Type: 'request',
|
||||
Seq: StdioOmnisharpServer._seqPool++,
|
||||
Command: path,
|
||||
Arguments: data
|
||||
};
|
||||
|
||||
return new Promise<any>((c, e) => {
|
||||
|
||||
this._activeRequest[thisRequestPacket.Seq] = {
|
||||
onSuccess: c,
|
||||
onError: e
|
||||
};
|
||||
|
||||
this._serverProcess.stdin.write(JSON.stringify(thisRequestPacket) + '\n');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 {exists as fileExists} from 'fs';
|
||||
import {spawn, ChildProcess} from 'child_process';
|
||||
import {workspace} from 'vscode';
|
||||
import {satisfies} from 'semver';
|
||||
import {join} from 'path';
|
||||
|
||||
var omnisharpEnv = 'OMNISHARP';
|
||||
var isWindows = /^win/.test(process.platform);
|
||||
|
||||
export default function launch(cwd: string, args: string[]):Promise < { process: ChildProcess, command: string } > {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
try {
|
||||
(isWindows ? launchWindows(cwd, args) : launchNix(cwd, args)).then(value => {
|
||||
|
||||
// async error - when target not not ENEOT
|
||||
value.process.on('error', reject);
|
||||
|
||||
// success after a short freeing event loop
|
||||
setTimeout(function () {
|
||||
resolve(value);
|
||||
}, 0);
|
||||
}, err => {
|
||||
reject(err);
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function launchWindows(cwd: string, args: string[]): Promise<{ process: ChildProcess, command: string }> {
|
||||
return getOmnisharpPath().then(command => {
|
||||
|
||||
args = args.slice(0);
|
||||
args.unshift(command);
|
||||
args = [[
|
||||
'/s',
|
||||
'/c',
|
||||
'"' + args.map(arg => /^[^"].* .*[^"]/.test(arg) ? `"${arg}"` : arg).join(' ') + '"'
|
||||
].join(' ')];
|
||||
|
||||
let process = spawn('cmd', args, <any>{
|
||||
windowsVerbatimArguments: true,
|
||||
detached: false,
|
||||
// env: details.env,
|
||||
cwd: cwd
|
||||
});
|
||||
|
||||
return {
|
||||
process,
|
||||
command
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function launchNix(cwd: string, args: string[]): Promise<{ process: ChildProcess, command: string }>{
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
hasMono('>=4.0.1').then(hasIt => {
|
||||
if (!hasIt) {
|
||||
reject(new Error('Cannot start Omnisharp because Mono version >=4.0.1 is required. See http://go.microsoft.com/fwlink/?linkID=534832#_20001'));
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}).then(_ => {
|
||||
return getOmnisharpPath();
|
||||
}).then(command => {
|
||||
let process = spawn(command, args, {
|
||||
detached: false,
|
||||
// env: details.env,
|
||||
cwd
|
||||
});
|
||||
|
||||
return {
|
||||
process,
|
||||
command
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getOmnisharpPath(): Promise<string> {
|
||||
|
||||
let pathCandidate: string;
|
||||
|
||||
let config = workspace.getConfiguration();
|
||||
if (config.has('csharp.omnisharp')) {
|
||||
// form config
|
||||
pathCandidate = config.get<string>('csharp.omnisharp');
|
||||
|
||||
} else if (typeof process.env[omnisharpEnv] === 'string') {
|
||||
// form enviroment variable
|
||||
console.warn('[deprecated] use workspace or user settings with "csharp.omnisharp":"/path/to/omnisharp"');
|
||||
pathCandidate = process.env[omnisharpEnv];
|
||||
|
||||
} else {
|
||||
// bundled version of Omnisharp
|
||||
pathCandidate = join(__dirname, '../bin/omnisharp')
|
||||
if (isWindows) {
|
||||
pathCandidate += '.cmd';
|
||||
}
|
||||
}
|
||||
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
fileExists(pathCandidate, localExists => {
|
||||
if (localExists) {
|
||||
resolve(pathCandidate);
|
||||
} else {
|
||||
reject('OmniSharp does not exist at location: ' + pathCandidate);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const versionRegexp = /(\d+\.\d+\.\d+)/;
|
||||
|
||||
export function hasMono(range?: string): Promise<boolean> {
|
||||
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
let childprocess: ChildProcess;
|
||||
try {
|
||||
childprocess = spawn('mono', ['--version']);
|
||||
} catch (e) {
|
||||
return resolve(false);
|
||||
}
|
||||
|
||||
childprocess.on('error', function (err: any) {
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
let stdout = '';
|
||||
childprocess.stdout.on('data', (data: NodeBuffer) => {
|
||||
stdout += data.toString();
|
||||
});
|
||||
|
||||
childprocess.stdout.on('close', () => {
|
||||
let match = versionRegexp.exec(stdout),
|
||||
ret: boolean;
|
||||
|
||||
if (!match) {
|
||||
ret = false;
|
||||
} else if (!range) {
|
||||
ret = true;
|
||||
} else {
|
||||
ret = satisfies(match[1], range);
|
||||
}
|
||||
|
||||
resolve(ret);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,416 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export var GoToDefinition = '/gotoDefinition';
|
||||
|
||||
export var CodeCheck = '/codecheck';
|
||||
|
||||
export var AutoComplete = '/autocomplete';
|
||||
|
||||
export var CurrentFileMembersAsTree = '/currentfilemembersastree';
|
||||
|
||||
export var TypeLookup = '/typelookup';
|
||||
|
||||
export var AddToProject = '/addtoproject';
|
||||
|
||||
export var RemoveFromProject = '/removefromproject';
|
||||
|
||||
export var FindUsages = '/findusages';
|
||||
|
||||
export var FindSymbols = '/findsymbols';
|
||||
|
||||
export var CodeFormat = '/codeformat';
|
||||
|
||||
export var GetCodeActions = '/getcodeactions';
|
||||
|
||||
export var RunCodeAction = '/runcodeaction';
|
||||
|
||||
export var FormatAfterKeystroke = '/formatAfterKeystroke';
|
||||
|
||||
export var FormatRange = '/formatRange';
|
||||
|
||||
export var UpdateBuffer = '/updatebuffer';
|
||||
|
||||
export var ChangeBuffer = '/changebuffer';
|
||||
|
||||
export var Projects = '/projects';
|
||||
|
||||
export var Rename = '/rename';
|
||||
|
||||
export var FilesChanged = '/filesChanged';
|
||||
|
||||
export var SignatureHelp = '/signatureHelp';
|
||||
|
||||
export interface Request {
|
||||
Filename: string;
|
||||
Line?: number;
|
||||
Column?: number;
|
||||
Buffer?: string;
|
||||
}
|
||||
|
||||
export interface ChangeBufferRequest {
|
||||
FileName: string;
|
||||
StartLine: number;
|
||||
StartColumn: number;
|
||||
EndLine: number;
|
||||
EndColumn: number;
|
||||
NewText: string;
|
||||
}
|
||||
|
||||
export interface AddToProjectRequest extends Request {
|
||||
//?
|
||||
}
|
||||
|
||||
export interface RemoveFromProjectRequest extends Request {
|
||||
//?
|
||||
}
|
||||
|
||||
export interface FindUsagesRequest extends Request {
|
||||
// MaxWidth: number; ?
|
||||
OnlyThisFile: boolean;
|
||||
ExcludeDefinition: boolean;
|
||||
}
|
||||
|
||||
export interface FindSymbolsRequest extends Request {
|
||||
Filter: string;
|
||||
}
|
||||
|
||||
export interface FormatRequest extends Request {
|
||||
ExpandTab: boolean;
|
||||
}
|
||||
|
||||
export interface CodeActionRequest extends Request {
|
||||
CodeAction: number;
|
||||
WantsTextChanges?: boolean;
|
||||
SelectionStartColumn?: number;
|
||||
SelectionStartLine?: number;
|
||||
SelectionEndColumn?: number;
|
||||
SelectionEndLine?: number;
|
||||
}
|
||||
|
||||
export interface FormatResponse {
|
||||
Buffer: string;
|
||||
}
|
||||
|
||||
export interface TextChange {
|
||||
NewText: string;
|
||||
StartLine: number;
|
||||
StartColumn: number;
|
||||
EndLine: number;
|
||||
EndColumn: number;
|
||||
}
|
||||
|
||||
export interface FormatAfterKeystrokeRequest extends Request {
|
||||
Character: string;
|
||||
}
|
||||
|
||||
export interface FormatRangeRequest extends Request {
|
||||
EndLine: number;
|
||||
EndColumn: number;
|
||||
}
|
||||
|
||||
export interface FormatRangeResponse {
|
||||
Changes: TextChange[];
|
||||
}
|
||||
|
||||
export interface ResourceLocation {
|
||||
FileName: string;
|
||||
Line: number;
|
||||
Column: number;
|
||||
}
|
||||
|
||||
export interface Error {
|
||||
Message: string;
|
||||
Line: number;
|
||||
Column: number;
|
||||
EndLine: number;
|
||||
EndColumn: number;
|
||||
FileName: string;
|
||||
}
|
||||
|
||||
export interface ErrorResponse {
|
||||
Errors: Error[];
|
||||
}
|
||||
|
||||
export interface QuickFix {
|
||||
LogLevel: string;
|
||||
FileName: string;
|
||||
Line: number;
|
||||
Column: number;
|
||||
EndLine: number;
|
||||
EndColumn: number;
|
||||
Text: string;
|
||||
Projects: string[];
|
||||
}
|
||||
|
||||
export interface SymbolLocation extends QuickFix {
|
||||
Kind: string;
|
||||
}
|
||||
|
||||
export interface QuickFixResponse {
|
||||
QuickFixes: QuickFix[];
|
||||
}
|
||||
|
||||
export interface FindSymbolsResponse {
|
||||
QuickFixes: SymbolLocation[];
|
||||
}
|
||||
|
||||
export interface TypeLookupRequest extends Request {
|
||||
IncludeDocumentation: boolean;
|
||||
}
|
||||
|
||||
export interface TypeLookupResponse {
|
||||
Type: string;
|
||||
Documentation: string;
|
||||
}
|
||||
|
||||
export interface RunCodeActionResponse {
|
||||
Text: string;
|
||||
Changes: TextChange[];
|
||||
}
|
||||
|
||||
export interface GetCodeActionsResponse {
|
||||
CodeActions: string[];
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
ChildNodes: Node[];
|
||||
Location: QuickFix;
|
||||
Kind: string;
|
||||
}
|
||||
|
||||
export interface CurrentFileMembersAsTreeResponse {
|
||||
TopLevelTypeDefinitions: Node[];
|
||||
}
|
||||
|
||||
export interface AutoCompleteRequest extends Request {
|
||||
WordToComplete: string;
|
||||
WantDocumentationForEveryCompletionResult?: boolean;
|
||||
WantImportableTypes?: boolean;
|
||||
WantMethodHeader?: boolean;
|
||||
WantSnippet?: boolean;
|
||||
WantReturnType?: boolean;
|
||||
WantKind?: boolean;
|
||||
}
|
||||
|
||||
export interface AutoCompleteResponse {
|
||||
CompletionText: string;
|
||||
Description: string;
|
||||
DisplayText: string;
|
||||
RequiredNamespaceImport: string;
|
||||
MethodHeader: string;
|
||||
ReturnType: string;
|
||||
Snippet: string;
|
||||
Kind: string;
|
||||
}
|
||||
|
||||
export interface ProjectInformationResponse {
|
||||
MsBuildProject: MSBuildProject;
|
||||
DnxProject: DnxProject;
|
||||
}
|
||||
|
||||
export interface WorkspaceInformationResponse {
|
||||
MSBuild: MsBuildWorkspaceInformation;
|
||||
Dnx: DnxWorkspaceInformation;
|
||||
ScriptCs: ScriptCsContext;
|
||||
}
|
||||
|
||||
export interface MsBuildWorkspaceInformation {
|
||||
SolutionPath: string;
|
||||
Projects: MSBuildProject[];
|
||||
}
|
||||
|
||||
export interface ScriptCsContext {
|
||||
CsxFiles: { [n: string]: string };
|
||||
References: { [n: string]: string };
|
||||
Usings: { [n: string]: string };
|
||||
ScriptPacks: { [n: string]: string };
|
||||
Path: string;
|
||||
}
|
||||
|
||||
export interface MSBuildProject {
|
||||
ProjectGuid: string;
|
||||
Path: string;
|
||||
AssemblyName: string;
|
||||
TargetPath: string;
|
||||
TargetFramework: string;
|
||||
SourceFiles: string[];
|
||||
}
|
||||
|
||||
export interface DnxWorkspaceInformation {
|
||||
RuntimePath: string;
|
||||
DesignTimeHostPort: number;
|
||||
Projects: DnxProject[];
|
||||
}
|
||||
|
||||
export interface DnxProject {
|
||||
Path: string;
|
||||
Name: string;
|
||||
Commands: { [name: string]: string; };
|
||||
Configurations: string[];
|
||||
ProjectSearchPaths: string[];
|
||||
Frameworks: DnxFramework[];
|
||||
GlobalJsonPath: string;
|
||||
SourceFiles: string[];
|
||||
}
|
||||
|
||||
export interface DnxFramework {
|
||||
Name: string;
|
||||
FriendlyName: string;
|
||||
ShortName: string;
|
||||
}
|
||||
|
||||
export interface RenameRequest extends Request {
|
||||
RenameTo: string;
|
||||
WantsTextChanges?: boolean;
|
||||
}
|
||||
|
||||
export interface ModifiedFileResponse {
|
||||
FileName: string;
|
||||
Buffer: string;
|
||||
Changes: TextChange[];
|
||||
}
|
||||
|
||||
export interface RenameResponse {
|
||||
Changes: ModifiedFileResponse[];
|
||||
}
|
||||
|
||||
export interface SignatureHelp {
|
||||
Signatures: SignatureHelpItem[];
|
||||
ActiveSignature: number;
|
||||
ActiveParameter: number;
|
||||
}
|
||||
|
||||
export interface SignatureHelpItem {
|
||||
Name: string;
|
||||
Label: string;
|
||||
Documentation: string;
|
||||
Parameters: SignatureHelpParameter[];
|
||||
}
|
||||
|
||||
export interface SignatureHelpParameter {
|
||||
Name: string;
|
||||
Label: string;
|
||||
Documentation: string;
|
||||
}
|
||||
|
||||
export interface MSBuildProjectDiagnostics {
|
||||
FileName: string;
|
||||
Warnings: MSBuildDiagnosticsMessage[];
|
||||
Errors: MSBuildDiagnosticsMessage[];
|
||||
}
|
||||
|
||||
export interface MSBuildDiagnosticsMessage {
|
||||
LogLevel: string;
|
||||
FileName: string;
|
||||
Text: string;
|
||||
StartLine: number;
|
||||
StartColumn: number;
|
||||
EndLine: number;
|
||||
EndColumn: number;
|
||||
}
|
||||
|
||||
export interface ErrorMessage {
|
||||
Text: string;
|
||||
FileName: string;
|
||||
Line: number;
|
||||
Column: number;
|
||||
}
|
||||
|
||||
export interface PackageRestoreMessage {
|
||||
FileName: string;
|
||||
Succeeded: boolean;
|
||||
}
|
||||
|
||||
export interface UnresolvedDependenciesMessage {
|
||||
FileName: string;
|
||||
UnresolvedDependencies: PackageDependency[];
|
||||
}
|
||||
|
||||
export interface PackageDependency {
|
||||
Name: string;
|
||||
Version: string;
|
||||
}
|
||||
|
||||
export namespace V2 {
|
||||
|
||||
export var GetCodeActions = '/v2/getcodeactions';
|
||||
export var RunCodeAction = '/v2/runcodeaction';
|
||||
|
||||
export interface Point {
|
||||
Line: number;
|
||||
Column: number;
|
||||
}
|
||||
|
||||
export interface Range {
|
||||
Start: Point;
|
||||
End: Point;
|
||||
}
|
||||
|
||||
export interface GetCodeActionsRequest extends Request {
|
||||
Selection: Range
|
||||
}
|
||||
|
||||
export interface OmniSharpCodeAction {
|
||||
Identifier: string;
|
||||
Name: string;
|
||||
}
|
||||
|
||||
export interface GetCodeActionsResponse {
|
||||
CodeActions: OmniSharpCodeAction[];
|
||||
}
|
||||
|
||||
export interface RunCodeActionRequest extends Request {
|
||||
Identifier: string;
|
||||
Selection: Range;
|
||||
WantsTextChanges: boolean;
|
||||
}
|
||||
|
||||
export interface RunCodeActionResponse {
|
||||
Changes: ModifiedFileResponse[];
|
||||
}
|
||||
|
||||
|
||||
export interface MSBuildProjectDiagnostics {
|
||||
FileName: string;
|
||||
Warnings: MSBuildDiagnosticsMessage[];
|
||||
Errors: MSBuildDiagnosticsMessage[];
|
||||
}
|
||||
|
||||
export interface MSBuildDiagnosticsMessage {
|
||||
LogLevel: string;
|
||||
FileName: string;
|
||||
Text: string;
|
||||
StartLine: number;
|
||||
StartColumn: number;
|
||||
EndLine: number;
|
||||
EndColumn: number;
|
||||
}
|
||||
|
||||
export interface ErrorMessage {
|
||||
Text: string;
|
||||
FileName: string;
|
||||
Line: number;
|
||||
Column: number;
|
||||
}
|
||||
|
||||
export interface PackageRestoreMessage {
|
||||
FileName: string;
|
||||
Succeeded: boolean;
|
||||
}
|
||||
|
||||
export interface UnresolvedDependenciesMessage {
|
||||
FileName: string;
|
||||
UnresolvedDependencies: PackageDependency[];
|
||||
}
|
||||
|
||||
export interface PackageDependency {
|
||||
Name: string;
|
||||
Version: string;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 proto from './protocol';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function toLocation(location: proto.ResourceLocation): vscode.Location {
|
||||
let {FileName, Line, Column} = location;
|
||||
return new vscode.Location(vscode.Uri.file(FileName), new vscode.Position(Line - 1, Column - 1));
|
||||
}
|
||||
|
||||
export function toRange(rangeLike: { Line: number; Column: number; EndLine: number; EndColumn: number;}): vscode.Range {
|
||||
let {Line, Column, EndLine, EndColumn} = rangeLike;
|
||||
return new vscode.Range(Line - 1, Column - 1, EndLine - 1, EndColumn - 1);
|
||||
}
|
||||
|
||||
export function toRange2(rangeLike: { StartLine: number; StartColumn: number; EndLine: number; EndColumn: number;}): vscode.Range {
|
||||
let {StartLine, StartColumn, EndLine, EndColumn} = rangeLike;
|
||||
return new vscode.Range(StartLine - 1, StartColumn - 1, EndLine - 1, EndColumn - 1);
|
||||
}
|
||||
|
||||
export function createRequest<T extends proto.Request>(document: vscode.TextDocument, where: vscode.Position | vscode.Range, includeBuffer:boolean = false): T {
|
||||
|
||||
let Line: number, Column: number;
|
||||
|
||||
if (where instanceof vscode.Position) {
|
||||
Line = where.line + 1;
|
||||
Column = where.character + 1;
|
||||
} else if(where instanceof vscode.Range) {
|
||||
Line = where.start.line + 1;
|
||||
Column = where.start.character + 1
|
||||
}
|
||||
|
||||
let request: proto.Request = {
|
||||
Filename: document.fileName,
|
||||
Buffer: includeBuffer ? document.getText() : undefined,
|
||||
Line,
|
||||
Column
|
||||
};
|
||||
|
||||
return <T>request;
|
||||
}
|
||||
|
||||
export function toDocumentSymbol(bucket: vscode.SymbolInformation[], node: proto.Node, containerLabel?: string): void {
|
||||
|
||||
let ret = new vscode.SymbolInformation(node.Location.Text, kinds[node.Kind],
|
||||
toRange(node.Location),
|
||||
undefined, containerLabel);
|
||||
|
||||
if (node.ChildNodes) {
|
||||
for (let child of node.ChildNodes) {
|
||||
toDocumentSymbol(bucket, child, ret.name)
|
||||
}
|
||||
}
|
||||
bucket.push(ret);
|
||||
}
|
||||
|
||||
var kinds: { [kind: string]: vscode.SymbolKind; } = Object.create(null);
|
||||
kinds['NamespaceDeclaration'] = vscode.SymbolKind.Namespace;
|
||||
kinds['ClassDeclaration'] = vscode.SymbolKind.Class;
|
||||
kinds['FieldDeclaration'] = vscode.SymbolKind.Field;
|
||||
kinds['PropertyDeclaration'] = vscode.SymbolKind.Property;
|
||||
kinds['EventFieldDeclaration'] = vscode.SymbolKind.Property;
|
||||
kinds['MethodDeclaration'] = vscode.SymbolKind.Method;
|
||||
kinds['EnumDeclaration'] = vscode.SymbolKind.Enum;
|
||||
kinds['StructDeclaration'] = vscode.SymbolKind.Enum;
|
||||
kinds['EnumMemberDeclaration'] = vscode.SymbolKind.Property;
|
||||
kinds['InterfaceDeclaration'] = vscode.SymbolKind.Interface;
|
||||
kinds['VariableDeclaration'] = vscode.SymbolKind.Variable;
|
|
@ -0,0 +1,69 @@
|
|||
declare class Client {
|
||||
public context: any;
|
||||
public config: any;
|
||||
public trackEvent(eventName: string, properties: {[key: string]: string}, measures?: {[key: string]: number}): void;
|
||||
}
|
||||
|
||||
declare class ApplicationInsights {
|
||||
static client: Client;
|
||||
/**
|
||||
* Initializes a client with the given instrumentation key, if this is not specified, the value will be
|
||||
* read from the environment variable APPINSIGHTS_INSTRUMENTATIONKEY
|
||||
* @returns {ApplicationInsights/Client} a new client
|
||||
*/
|
||||
static getClient(instrumentationKey?: string): Client;
|
||||
/**
|
||||
* Initializes the default client of the client and sets the default configuration
|
||||
* @param instrumentationKey the instrumentation key to use. Optional, if this is not specified, the value will be
|
||||
* read from the environment variable APPINSIGHTS_INSTRUMENTATIONKEY
|
||||
* @returns {ApplicationInsights} this class
|
||||
*/
|
||||
static setup(instrumentationKey?: string): typeof ApplicationInsights;
|
||||
/**
|
||||
* Starts automatic collection of telemetry. Prior to calling start no telemetry will be collected
|
||||
* @returns {ApplicationInsights} this class
|
||||
*/
|
||||
static start(): typeof ApplicationInsights;
|
||||
/**
|
||||
* Sets the state of console tracking (enabled by default)
|
||||
* @param value if true console activity will be sent to Application Insights
|
||||
* @returns {ApplicationInsights} this class
|
||||
*/
|
||||
static setAutoCollectConsole(value: boolean): typeof ApplicationInsights;
|
||||
/**
|
||||
* Sets the state of exception tracking (enabled by default)
|
||||
* @param value if true uncaught exceptions will be sent to Application Insights
|
||||
* @returns {ApplicationInsights} this class
|
||||
*/
|
||||
static setAutoCollectExceptions(value: boolean): typeof ApplicationInsights;
|
||||
/**
|
||||
* Sets the state of performance tracking (enabled by default)
|
||||
* @param value if true performance counters will be collected every second and sent to Application Insights
|
||||
* @returns {ApplicationInsights} this class
|
||||
*/
|
||||
static setAutoCollectPerformance(value: boolean): typeof ApplicationInsights;
|
||||
/**
|
||||
* Sets the state of request tracking (enabled by default)
|
||||
* @param value if true requests will be sent to Application Insights
|
||||
* @returns {ApplicationInsights} this class
|
||||
*/
|
||||
static setAutoCollectRequests(value: boolean): typeof ApplicationInsights;
|
||||
|
||||
/**
|
||||
* Sets the state of enabling offline mode to cache event when client is offline (disabled by default)
|
||||
* @param value if true events that happen while client is offline will be cahced on disk,
|
||||
* client will retry to send events when back online
|
||||
* @returns {ApplicationInsights} this class
|
||||
*/
|
||||
public static setOfflineMode(value: boolean): typeof ApplicationInsights;
|
||||
/**
|
||||
* Enables verbose debug logging
|
||||
* @returns {ApplicationInsights} this class
|
||||
*/
|
||||
static enableVerboseLogging(): typeof ApplicationInsights;
|
||||
}
|
||||
|
||||
|
||||
declare module 'applicationinsights' {
|
||||
export = ApplicationInsights;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path='../../../../src/typings/mocha.d.ts'/>
|
||||
/// <reference path='../../../../extensions/declares.d.ts'/>
|
||||
/// <reference path='../../../../extensions/node.d.ts'/>
|
||||
/// <reference path='../../../../extensions/lib.core.d.ts'/>
|
|
@ -0,0 +1,125 @@
|
|||
// Type definitions for semver v2.2.1
|
||||
// Project: https://github.com/isaacs/node-semver
|
||||
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
|
||||
// Definitions: https://github.com/borisyankov/DefinitelyTyped
|
||||
|
||||
declare module SemVerModule {
|
||||
/**
|
||||
* Return the parsed version, or null if it's not valid.
|
||||
*/
|
||||
function valid(v: string, loose?: boolean): string;
|
||||
/**
|
||||
* Return the version incremented by the release type (major, minor, patch, or prerelease), or null if it's not valid.
|
||||
*/
|
||||
function inc(v: string, release: string, loose?: boolean): string;
|
||||
|
||||
// Comparison
|
||||
/**
|
||||
* v1 > v2
|
||||
*/
|
||||
function gt(v1: string, v2: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* v1 >= v2
|
||||
*/
|
||||
function gte(v1: string, v2: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* v1 < v2
|
||||
*/
|
||||
function lt(v1: string, v2: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* v1 <= v2
|
||||
*/
|
||||
function lte(v1: string, v2: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* v1 == v2 This is true if they're logically equivalent, even if they're not the exact same string. You already know how to compare strings.
|
||||
*/
|
||||
function eq(v1: string, v2: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* v1 != v2 The opposite of eq.
|
||||
*/
|
||||
function neq(v1: string, v2: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* Pass in a comparison string, and it'll call the corresponding semver comparison function. "===" and "!==" do simple string comparison, but are included for completeness. Throws if an invalid comparison string is provided.
|
||||
*/
|
||||
function cmp(v1: string, comparator: any, v2: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if v2 is greater. Sorts in ascending order if passed to Array.sort().
|
||||
*/
|
||||
function compare(v1: string, v2: string, loose?: boolean): number;
|
||||
/**
|
||||
* The reverse of compare. Sorts an array of versions in descending order when passed to Array.sort().
|
||||
*/
|
||||
function rcompare(v1: string, v2: string, loose?: boolean): number;
|
||||
|
||||
// Ranges
|
||||
/**
|
||||
* Return the valid range or null if it's not valid
|
||||
*/
|
||||
function validRange(range: string, loose?: boolean): string;
|
||||
/**
|
||||
* Return true if the version satisfies the range.
|
||||
*/
|
||||
function satisfies(version: string, range: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* Return the highest version in the list that satisfies the range, or null if none of them do.
|
||||
*/
|
||||
function maxSatisfying(versions: string[], range: string, loose?: boolean): string;
|
||||
/**
|
||||
* Return true if version is greater than all the versions possible in the range.
|
||||
*/
|
||||
function gtr(version: string, range: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* Return true if version is less than all the versions possible in the range.
|
||||
*/
|
||||
function ltr(version: string, range: string, loose?: boolean): boolean;
|
||||
/**
|
||||
* Return true if the version is outside the bounds of the range in either the high or low direction. The hilo argument must be either the string '>' or '<'. (This is the function called by gtr and ltr.)
|
||||
*/
|
||||
function outside(version: string, range: string, hilo: string, loose?: boolean): boolean;
|
||||
|
||||
class SemVerBase {
|
||||
raw: string;
|
||||
loose: boolean;
|
||||
format(): string;
|
||||
inspect(): string;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
class SemVer extends SemVerBase {
|
||||
constructor(version: string, loose?: boolean);
|
||||
|
||||
major: number;
|
||||
minor: number;
|
||||
patch: number;
|
||||
version: string;
|
||||
build: string[];
|
||||
prerelease: string[];
|
||||
|
||||
compare(other:SemVer): number;
|
||||
compareMain(other:SemVer): number;
|
||||
comparePre(other:SemVer): number;
|
||||
inc(release: string): SemVer;
|
||||
}
|
||||
|
||||
class Comparator extends SemVerBase {
|
||||
constructor(comp: string, loose?: boolean);
|
||||
|
||||
semver: SemVer;
|
||||
operator: string;
|
||||
value: boolean;
|
||||
parse(comp: string): void;
|
||||
test(version:SemVer): boolean;
|
||||
}
|
||||
|
||||
class Range extends SemVerBase {
|
||||
constructor(range: string, loose?: boolean);
|
||||
|
||||
set: Comparator[][];
|
||||
parseRange(range: string): Comparator[];
|
||||
test(version: SemVer): boolean;
|
||||
}
|
||||
}
|
||||
|
||||
declare module "semver" {
|
||||
export = SemVerModule;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"noLib": true,
|
||||
"target": "ES5",
|
||||
"module": "commonjs",
|
||||
"outDir": "out",
|
||||
"sourceMap": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "language-csharp",
|
||||
"version": "0.11.0",
|
||||
"license": "Dual-licensed under MIT and GPL",
|
||||
"repositoryURL": "https://github.com/atom/language-csharp"
|
||||
}]
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "csharp",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": { "vscode": "*" },
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "csharp",
|
||||
"extensions": [ ".cs", ".csx" ],
|
||||
"aliases": [ "C#", "csharp" ]
|
||||
}],
|
||||
"grammars": [{
|
||||
"language": "csharp",
|
||||
"scopeName": "source.cs",
|
||||
"path": "./syntaxes/csharp.json"
|
||||
}]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,566 @@
|
|||
{
|
||||
"scopeName": "source.cs",
|
||||
"name": "C#",
|
||||
"fileTypes": [
|
||||
"cs"
|
||||
],
|
||||
"foldingStartMarker": "^\\s*#\\s*region|^\\s*/\\*|^(?![^{]*?//|[^{]*?/\\*(?!.*?\\*/.*?\\{)).*?\\{\\s*($|//|/\\*(?!.*?\\*/.*\\S))",
|
||||
"foldingStopMarker": "^\\s*#\\s*endregion|^\\s*\\*/|^\\s*\\}",
|
||||
"patterns": [
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "keyword.other.using.cs"
|
||||
}
|
||||
},
|
||||
"begin": "^\\s*(using)\\b\\s*",
|
||||
"end": "\\s*(?:$|(;))",
|
||||
"name": "meta.keyword.using.cs"
|
||||
},
|
||||
{
|
||||
"begin": "^\\s*((namespace)\\s+([\\w.]+))",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "meta.namespace.identifier.cs"
|
||||
},
|
||||
"2": {
|
||||
"name": "keyword.other.namespace.cs"
|
||||
},
|
||||
"3": {
|
||||
"name": "entity.name.type.namespace.cs"
|
||||
}
|
||||
},
|
||||
"end": "}",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.namespace.end.cs"
|
||||
}
|
||||
},
|
||||
"name": "meta.namespace.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "{",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.namespace.begin.cs"
|
||||
}
|
||||
},
|
||||
"end": "(?=})",
|
||||
"name": "meta.namespace.body.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#code"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"include": "#code"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"block": {
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "{",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.block.begin.cs"
|
||||
}
|
||||
},
|
||||
"end": "}",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.block.end.cs"
|
||||
}
|
||||
},
|
||||
"name": "meta.block.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#code"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"builtinTypes": {
|
||||
"patterns": [
|
||||
{
|
||||
"match": "\\b(bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|class|struct|enum|interface)\\b",
|
||||
"name": "storage.type.cs"
|
||||
}
|
||||
]
|
||||
},
|
||||
"class": {
|
||||
"begin": "(?=\\w?[\\w\\s]*(?:class|struct|interface|enum)\\s+\\w+)",
|
||||
"end": "}",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.class.end.cs"
|
||||
}
|
||||
},
|
||||
"name": "meta.class.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#storage-modifiers"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "storage.modifier.cs"
|
||||
},
|
||||
"2": {
|
||||
"name": "entity.name.type.class.cs"
|
||||
}
|
||||
},
|
||||
"match": "(class|struct|interface|enum)\\s+(\\w+)",
|
||||
"name": "meta.class.identifier.cs"
|
||||
},
|
||||
{
|
||||
"begin": ":",
|
||||
"end": "(?={)",
|
||||
"patterns": [
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "storage.type.cs"
|
||||
}
|
||||
},
|
||||
"match": "\\s*,?([A-Za-z_]\\w*)\\b"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "{",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.class.begin.cs"
|
||||
}
|
||||
},
|
||||
"end": "(?=})",
|
||||
"name": "meta.class.body.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#method"
|
||||
},
|
||||
{
|
||||
"include": "#code"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"code": {
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#class"
|
||||
},
|
||||
{
|
||||
"include": "#constants"
|
||||
},
|
||||
{
|
||||
"include": "#storage-modifiers"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#preprocessor"
|
||||
},
|
||||
{
|
||||
"include": "#method-call"
|
||||
},
|
||||
{
|
||||
"include": "#builtinTypes"
|
||||
},
|
||||
{
|
||||
"include": "#documentation"
|
||||
}
|
||||
]
|
||||
},
|
||||
"comments": {
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "///",
|
||||
"captures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.comment.cs"
|
||||
}
|
||||
},
|
||||
"end": "$\\n?",
|
||||
"name": "comment.block.documentation.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "text.xml"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "/\\*",
|
||||
"captures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.comment.cs"
|
||||
}
|
||||
},
|
||||
"end": "\\*/\\n?",
|
||||
"name": "comment.block.cs"
|
||||
},
|
||||
{
|
||||
"begin": "//",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.comment.cs"
|
||||
}
|
||||
},
|
||||
"end": "$\\n?",
|
||||
"name": "comment.line.double-slash.cs"
|
||||
}
|
||||
]
|
||||
},
|
||||
"constants": {
|
||||
"patterns": [
|
||||
{
|
||||
"match": "\\b(true|false|null|this|base)\\b",
|
||||
"name": "constant.language.cs"
|
||||
},
|
||||
{
|
||||
"match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b",
|
||||
"name": "constant.numeric.cs"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.string.begin.cs"
|
||||
}
|
||||
},
|
||||
"match": "@\"([^\"]|\"\")*\"",
|
||||
"name": "string.quoted.double.literal.cs"
|
||||
},
|
||||
{
|
||||
"begin": "\"",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.string.begin.cs"
|
||||
}
|
||||
},
|
||||
"end": "\"",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.string.end.cs"
|
||||
}
|
||||
},
|
||||
"name": "string.quoted.double.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"match": "\\\\.",
|
||||
"name": "constant.character.escape.cs"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "'",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.string.begin.cs"
|
||||
}
|
||||
},
|
||||
"end": "'",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.string.end.cs"
|
||||
}
|
||||
},
|
||||
"name": "string.quoted.single.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"match": "\\\\.",
|
||||
"name": "constant.character.escape.cs"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"keywords": {
|
||||
"patterns": [
|
||||
{
|
||||
"match": "\\b(if|else|while|for|foreach|in|do|return|continue|break|switch|case|default|goto|throw|try|catch|finally|lock|yield|await)\\b",
|
||||
"name": "keyword.control.cs"
|
||||
},
|
||||
{
|
||||
"match": "\\b(from|where|select|group|into|orderby|join|let|on|equals|by|ascending|descending)\\b",
|
||||
"name": "keyword.linq.cs"
|
||||
},
|
||||
{
|
||||
"match": "\\b(new|is|as|using|checked|unchecked|typeof|sizeof|override|readonly|stackalloc)\\b",
|
||||
"name": "keyword.operator.cs"
|
||||
},
|
||||
{
|
||||
"match": "\\b(event|delegate|fixed|add|remove|set|get|value)\\b",
|
||||
"name": "keyword.other.cs"
|
||||
},
|
||||
{
|
||||
"match": "\\b(var)\\b",
|
||||
"name": "storage.type.var.cs"
|
||||
},
|
||||
{
|
||||
"match": "[@]\\b(var|event|delegate|add|remove|set|get|value|new|is|as|using|checked|unchecked|typeof|sizeof |override|readonly|stackalloc|from|where|select|group|into|orderby|join|let|on|equals|by|ascending|descending |if|else|while|for|foreach|in|do|return|continue|break|switch|case|default|goto|throw|try|catch|finally|lock|yield|await)\\b",
|
||||
"name": "meta.class.body.cs"
|
||||
}
|
||||
]
|
||||
},
|
||||
"method": {
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "\\[",
|
||||
"end": "\\]",
|
||||
"name": "meta.method.annotation.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#constants"
|
||||
},
|
||||
{
|
||||
"include": "#preprocessor"
|
||||
},
|
||||
{
|
||||
"include": "#builtinTypes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "(?=\\bnew\\s+)(?=[\\w<].*\\s+)(?=[^=]+\\()",
|
||||
"end": "(?={|;)",
|
||||
"name": "meta.new-object.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#code"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "(?<!=|=\\s)(?!new)(?!.*(=|\\/\\/|\\/\\*).*\\()(?=[\\w<].*\\s+.+\\()",
|
||||
"end": "(})|(?=;)",
|
||||
"endCaptures": {
|
||||
"1": {
|
||||
"name": "punctuation.section.method.end.cs"
|
||||
}
|
||||
},
|
||||
"name": "meta.method.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#storage-modifiers"
|
||||
},
|
||||
{
|
||||
"include": "#builtinTypes"
|
||||
},
|
||||
{
|
||||
"begin": "([\\w.]+)\\s*\\(",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "entity.name.function.cs"
|
||||
}
|
||||
},
|
||||
"end": "\\)",
|
||||
"name": "meta.method.identifier.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#parameters"
|
||||
},
|
||||
{
|
||||
"include": "#constants"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "(?=\\w.*\\s+[\\w.]+\\s*\\()",
|
||||
"end": "(?=[\\w.]+\\s*\\()",
|
||||
"name": "meta.method.return-type.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#builtinTypes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": ":\\s*(this|base)\\s*\\(",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "constant.language.cs"
|
||||
}
|
||||
},
|
||||
"end": "\\)",
|
||||
"name": "meta.method.base-call.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#builtinTypes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "{",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.method.begin.cs"
|
||||
}
|
||||
},
|
||||
"end": "(?=})",
|
||||
"name": "meta.method.body.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#code"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "(?!new)(?=[\\w<].*\\s+)(?=[^=]+\\{)",
|
||||
"end": "}",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.property.end.cs"
|
||||
}
|
||||
},
|
||||
"name": "meta.property.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#storage-modifiers"
|
||||
},
|
||||
{
|
||||
"begin": "([\\w.]+)\\s*(?={)",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "entity.name.function.cs"
|
||||
}
|
||||
},
|
||||
"end": "(?={)",
|
||||
"name": "meta.method.identifier.cs"
|
||||
},
|
||||
{
|
||||
"begin": "(?=\\w.*\\s+[\\w.]+\\s*\\{)",
|
||||
"end": "(?=[\\w.]+\\s*\\{)",
|
||||
"name": "meta.method.return-type.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#builtinTypes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "{",
|
||||
"beginCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.section.property.begin.cs"
|
||||
}
|
||||
},
|
||||
"end": "(?=})",
|
||||
"name": "meta.method.body.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#code"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"method-call": {
|
||||
"begin": "([\\w$]+)\\s*(\\()",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "meta.method.cs"
|
||||
},
|
||||
"2": {
|
||||
"name": "punctuation.definition.method-parameters.begin.cs"
|
||||
}
|
||||
},
|
||||
"end": "\\)",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.method-parameters.end.cs"
|
||||
}
|
||||
},
|
||||
"name": "meta.method-call.cs",
|
||||
"patterns": [
|
||||
{
|
||||
"match": ",",
|
||||
"name": "punctuation.definition.seperator.parameter.cs"
|
||||
},
|
||||
{
|
||||
"include": "#code"
|
||||
}
|
||||
]
|
||||
},
|
||||
"parameters": {
|
||||
"begin": "\\b(ref|params|out)?\\s*\\b([\\w.\\[\\]]+)\\s+(\\w+)\\s*(=)?",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "storage.type.modifier.cs"
|
||||
},
|
||||
"2": {
|
||||
"name": "storage.type.generic.cs"
|
||||
},
|
||||
"3": {
|
||||
"name": "variable.parameter.function.cs"
|
||||
},
|
||||
"4": {
|
||||
"name": "keyword.operator.assignment.cs"
|
||||
}
|
||||
},
|
||||
"end": "(?:(,)|(?=[\\)]))",
|
||||
"endCaptures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.separator.parameter.cs"
|
||||
}
|
||||
},
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#constants"
|
||||
},
|
||||
{
|
||||
"include": "#block"
|
||||
}
|
||||
]
|
||||
},
|
||||
"preprocessor": {
|
||||
"patterns": [
|
||||
{
|
||||
"captures": {
|
||||
"2": {
|
||||
"name": "meta.toc-list.region.cs"
|
||||
}
|
||||
},
|
||||
"match": "^\\s*#\\s*(region)\\b\\s*([^\\/]+)\\s",
|
||||
"name": "meta.preprocessor.cs"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"2": {
|
||||
"name": "entity.name.function.preprocessor.cs"
|
||||
}
|
||||
},
|
||||
"match": "^\\s*#\\s*(define|undef|if|elif)\\b\\s*(\\S*)",
|
||||
"name": "meta.preprocessor.cs"
|
||||
},
|
||||
{
|
||||
"match": "^\\s*#\\s*(if|else|elif|endif|define|undef|warning|error|line|pragma|region|endregion)\\b\\s*([^\\/]+)\\s",
|
||||
"name": "meta.preprocessor.cs"
|
||||
}
|
||||
]
|
||||
},
|
||||
"storage-modifiers": {
|
||||
"match": "\\b(event|delegate|internal|public|protected|private|static|const|new|sealed|abstract|virtual|override|extern|unsafe|readonly|volatile|implicit|explicit|operator|async|partial)\\b",
|
||||
"name": "storage.modifier.cs"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "textmate/css.tmbundle",
|
||||
"version": "0.0.0",
|
||||
"license": "TextMate Bundle License",
|
||||
"repositoryURL": "https://github.com/textmate/css.tmbundle",
|
||||
"licenseDetail": [
|
||||
"Copyright (c) textmate-css.tmbundle project authors",
|
||||
"",
|
||||
"If not otherwise specified (see below), files in this folder fall under the following license: ",
|
||||
"",
|
||||
"Permission to copy, use, modify, sell and distribute this",
|
||||
"software is granted. This software is provided \"as is\" without",
|
||||
"express or implied warranty, and with no claim as to its",
|
||||
"suitability for any purpose.",
|
||||
"",
|
||||
"An exception is made for files in readable text which contain their own license information, ",
|
||||
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added ",
|
||||
"to the base-name name of the original file, and an extension of txt, html, or similar. For example ",
|
||||
"\"tidy\" is accompanied by \"tidy-license.txt\"."
|
||||
]
|
||||
}]
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "css",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": { "vscode": "*" },
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "css",
|
||||
"aliases": ["CSS", "css"],
|
||||
"extensions": [".css"],
|
||||
"mimetypes": ["text/css"]
|
||||
}],
|
||||
"grammars": [{
|
||||
"language": "css",
|
||||
"scopeName": "source.css",
|
||||
"path": "./syntaxes/css.plist"
|
||||
}],
|
||||
"snippets": [{
|
||||
"language": "css",
|
||||
"path": "./snippets/css.json"
|
||||
}]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"transition property": {
|
||||
"prefix": "transition",
|
||||
"body": [
|
||||
"transition: ${property} ${duration} ${timing-function} ${delay};",
|
||||
"-webkit-transition: ${property} ${duration} ${timing-function} ${delay};",
|
||||
"-o-transition: ${property} ${duration} ${timing-function} ${delay};",
|
||||
"-moz-transition: ${property} ${duration} ${timing-function} ${delay};"
|
||||
],
|
||||
"description": "The transition property across browsers"
|
||||
},
|
||||
"border": {
|
||||
"prefix": "border",
|
||||
"body": [
|
||||
"border: ${width} ${border-style} ${color};$0"
|
||||
],
|
||||
"description": "[width] [border-style] [color]"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,997 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>css</string>
|
||||
<string>css.erb</string>
|
||||
</array>
|
||||
<key>keyEquivalent</key>
|
||||
<string>^~C</string>
|
||||
<key>name</key>
|
||||
<string>CSS</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#comment-block</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#selector</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\s*((@)charset\b)\s*</string>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.at-rule.charset.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.keyword.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\s*((?=;|$))</string>
|
||||
<key>name</key>
|
||||
<string>meta.at-rule.charset.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-double</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-single</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\s*((@)import\b)\s*</string>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.at-rule.import.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.keyword.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\s*((?=;|\}))</string>
|
||||
<key>name</key>
|
||||
<string>meta.at-rule.import.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-double</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-single</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\s*(url)\s*(\()\s*</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>support.function.url.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\s*(\))\s*</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>[^'") \t]+</string>
|
||||
<key>name</key>
|
||||
<string>variable.parameter.url.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-single</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-double</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#media-query-list</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>^\s*((@)font-face)\s*(?=\{)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.at-rule.font-face.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.keyword.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(?!\G)</string>
|
||||
<key>name</key>
|
||||
<string>meta.at-rule.font-face.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#rule-list</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?=^\s*@media\s*.*?\{)</string>
|
||||
<key>end</key>
|
||||
<string>\s*(\})</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.property-list.end.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>^\s*((@)media)(?=.*?\{)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.at-rule.media.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.keyword.css</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>support.constant.media.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\s*(?=\{)</string>
|
||||
<key>name</key>
|
||||
<string>meta.at-rule.media.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#media-query-list</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\s*(\{)</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.property-list.begin.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(?=\})</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>$self</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?=\{)</string>
|
||||
<key>end</key>
|
||||
<string>(?!\G)</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#rule-list</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>repository</key>
|
||||
<dict>
|
||||
<key>color-values</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>comment</key>
|
||||
<string>http://www.w3.org/TR/CSS21/syndata.html#value-def-color</string>
|
||||
<key>match</key>
|
||||
<string>\b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)\b</string>
|
||||
<key>name</key>
|
||||
<string>support.constant.color.w3c-standard-color-name.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>comment</key>
|
||||
<string>These colours are mostly recognised but will not validate. ref: http://www.w3schools.com/css/css_colornames.asp</string>
|
||||
<key>match</key>
|
||||
<string>\b(aliceblue|antiquewhite|aquamarine|azure|beige|bisque|blanchedalmond|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|gainsboro|ghostwhite|gold|goldenrod|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|limegreen|linen|magenta|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|oldlace|olivedrab|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|thistle|tomato|turquoise|violet|wheat|whitesmoke|yellowgreen)\b</string>
|
||||
<key>name</key>
|
||||
<string>invalid.deprecated.color.w3c-non-standard-color-name.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(hsla?|rgba?)\s*(\()</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>support.function.misc.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(\))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(?x)\b
|
||||
(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\s*,\s*){2}
|
||||
(0*((1?[0-9]{1,2})|(2([0-4][0-9]|5[0-5])))\b)
|
||||
(\s*,\s*((0?\.[0-9]+)|[0-1]))?
|
||||
</string>
|
||||
<key>name</key>
|
||||
<string>constant.other.color.rgb-value.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%,\s*([0-9]{1,2}|100)\s*%</string>
|
||||
<key>name</key>
|
||||
<string>constant.other.color.rgb-percentage.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#numeric-values</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>comment-block</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>/\*</string>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.comment.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\*/</string>
|
||||
<key>name</key>
|
||||
<string>comment.block.css</string>
|
||||
</dict>
|
||||
<key>media-query</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?i)\s*(only|not)?\s*(all|aural|braille|embossed|handheld|print|projection|screen|tty|tv)?</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.logic.media.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>support.constant.media.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\s*(?:(,)|(?=[{;]))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.arbitrary-repitition.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\s*(and)?\s*(\()\s*</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.logic.media.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\)</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?x)
|
||||
(
|
||||
((min|max)-)?
|
||||
(
|
||||
((device-)?(height|width|aspect-ratio))|
|
||||
(color(-index)?)|monochrome|resolution
|
||||
)
|
||||
)|grid|scan|orientation
|
||||
\s*(?=[:)])</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>support.type.property-name.media.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(:)|(?=\))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.separator.key-value.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(portrait|landscape|progressive|interlace)</string>
|
||||
<key>name</key>
|
||||
<string>support.constant.property-value.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.arithmetic.css</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>\s*(\d+)(/)(\d+)</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#numeric-values</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>media-query-list</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\s*(?=[^{;])</string>
|
||||
<key>end</key>
|
||||
<string>\s*(?=[{;])</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#media-query</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>numeric-values</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.constant.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(#)([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b</string>
|
||||
<key>name</key>
|
||||
<string>constant.other.color.rgb-value.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.other.unit.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(?x)
|
||||
(?:-|\+)?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))
|
||||
((?:px|pt|ch|cm|mm|in|r?em|ex|pc|deg|g?rad|dpi|dpcm|s)\b|%)?
|
||||
</string>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.css</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>property-values</key>
|
||||
<dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(absolute|all(-scroll)?|always|armenian|auto|avoid|baseline|below|bidi-override|block|bold|bolder|both|bottom|break-all|break-word|capitalize|center|char|circle|cjk-ideographic|col-resize|collapse|crosshair|dashed|decimal-leading-zero|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|geometricPrecision|georgian|groove|hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|optimize(Legibility|Quality|Speed)|outset|outside|overline|pointer|pre(-(wrap|line))?|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|sub|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|vertical(-(ideographic|text))?|visible(Painted|Fill|Stroke)?|w-resize|wait|whitespace|zero|smaller|larger|((xx?-)?(small|large))|painted|fill|stroke)\b</string>
|
||||
<key>name</key>
|
||||
<string>support.constant.property-value.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>(\b(?i:arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace)\b)</string>
|
||||
<key>name</key>
|
||||
<string>support.constant.font-name.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#numeric-values</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#color-values</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-double</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-single</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(rect)\s*(\()</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>support.function.misc.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(\))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#numeric-values</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(format|local|url|attr|counter|counters)\s*(\()</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>support.function.misc.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>(\))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-single</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#string-double</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>[^'") \t]+</string>
|
||||
<key>name</key>
|
||||
<string>variable.parameter.misc.css</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\!\s*important</string>
|
||||
<key>name</key>
|
||||
<string>keyword.other.important.css</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>rule-list</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\{</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.property-list.begin.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\}</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.property-list.end.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>meta.property-list.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#comment-block</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(?<![-a-z])(?=[-a-z])</string>
|
||||
<key>end</key>
|
||||
<string>$|(?![-a-z])</string>
|
||||
<key>name</key>
|
||||
<string>meta.property-name.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(-webkit-[A-Za-z]+|-moz-[A-Za-z]+|-o-[A-Za-z]+|-ms-[A-Za-z]+|-khtml-[A-Za-z]+|zoom|z-index|y|x|wrap|word-wrap|word-spacing|word-break|word|width|widows|white-space-collapse|white-space|white|weight|volume|voice-volume|voice-stress|voice-rate|voice-pitch-range|voice-pitch|voice-family|voice-duration|voice-balance|voice|visibility|vertical-align|variant|user-select|up|unicode-bidi|unicode|trim|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform|top-width|top-style|top-right-radius|top-left-radius|top-color|top|timing-function|text-wrap|text-transform|text-shadow|text-replace|text-outline|text-justify|text-indent|text-height|text-emphasis|text-decoration|text-align-last|text-align|text|target-position|target-new|target-name|target|table-layout|tab-size|style-type|style-position|style-image|style|string-set|stretch|stress|stacking-strategy|stacking-shift|stacking-ruby|stacking|src|speed|speech-rate|speech|speak-punctuation|speak-numeral|speak-header|speak|span|spacing|space-collapse|space|sizing|size-adjust|size|shadow|respond-to|rule-width|rule-style|rule-color|rule|ruby-span|ruby-position|ruby-overhang|ruby-align|ruby|rows|rotation-point|rotation|role|right-width|right-style|right-color|right|richness|rest-before|rest-after|rest|resource|resolution|resize|reset|replace|repeat|rendering-intent|rate|radius|quotes|punctuation-trim|punctuation|property|profile|presentation-level|presentation|position|pointer-events|point|play-state|play-during|play-count|pitch-range|pitch|phonemes|pause-before|pause-after|pause|page-policy|page-break-inside|page-break-before|page-break-after|page|padding-top|padding-right|padding-left|padding-bottom|padding|pack|overhang|overflow-y|overflow-x|overflow-style|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|origin|orientation|orient|ordinal-group|opacity|offset|numeral|new|nav-up|nav-right|nav-left|nav-index|nav-down|nav|name|move-to|model|min-width|min-height|min|max-width|max-height|max|marquee-style|marquee-speed|marquee-play-count|marquee-direction|marquee|marks|mark-before|mark-after|mark|margin-top|margin-right|margin-left|margin-bottom|margin|mask-image|list-style-type|list-style-position|list-style-image|list-style|list|lines|line-stacking-strategy|line-stacking-shift|line-stacking-ruby|line-stacking|line-height|line|level|letter-spacing|length|left-width|left-style|left-color|left|label|justify|iteration-count|inline-box-align|initial-value|initial-size|initial-before-align|initial-before-adjust|initial-after-align|initial-after-adjust|index|indent|increment|image-resolution|image-orientation|image|icon|hyphens|hyphenate-resource|hyphenate-lines|hyphenate-character|hyphenate-before|hyphenate-after|hyphenate|height|header|hanging-punctuation|grid-rows|grid-columns|grid|gap|font-weight|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-family|font|float-offset|float|flex-group|flex|fit-position|fit|fill|filter|family|empty-cells|emphasis|elevation|duration|drop-initial-value|drop-initial-size|drop-initial-before-align|drop-initial-before-adjust|drop-initial-after-align|drop-initial-after-adjust|drop|down|dominant-baseline|display-role|display-model|display|direction|delay|decoration-break|decoration|cursor|cue-before|cue-after|cue|crop|counter-reset|counter-increment|counter|count|content|columns|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|column-break-before|column-break-after|column|color-profile|color|collapse|clip|clear|character|caption-side|break-inside|break-before|break-after|break|box-sizing|box-shadow|box-pack|box-orient|box-ordinal-group|box-lines|box-flex-group|box-flex|box-direction|box-decoration-break|box-align|box|bottom-width|bottom-style|bottom-right-radius|bottom-left-radius|bottom-color|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-length|border-left-width|border-left-style|border-left-color|border-left|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|bookmark-target|bookmark-level|bookmark-label|bookmark|binding|bidi|before|baseline-shift|baseline|balance|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-break|background-attachment|background|azimuth|attachment|appearance|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-duration|animation-direction|animation-delay|animation|alignment-baseline|alignment-adjust|alignment|align-last|align|after|adjust)\b</string>
|
||||
<key>name</key>
|
||||
<string>support.type.property-name.css</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>(:)\s*</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.separator.key-value.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\s*(;|(?=\}))</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.terminator.rule.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>meta.property-value.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#property-values</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>selector</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>\s*(?=[:.*#a-zA-Z])</string>
|
||||
<key>end</key>
|
||||
<string>(?=[/@{)])</string>
|
||||
<key>name</key>
|
||||
<string>meta.selector.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|datalist|dd|del|details|dfn|dialog|div|dl|dt|em|eventsource|fieldset|figure|figcaption|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|samp|script|section|select|small|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\b</string>
|
||||
<key>name</key>
|
||||
<string>entity.name.tag.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(\.)[a-zA-Z0-9_-]+</string>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.class.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(#)[a-zA-Z][a-zA-Z0-9_-]*</string>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.id.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\*</string>
|
||||
<key>name</key>
|
||||
<string>entity.name.tag.wildcard.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(:+)(after|before|first-letter|first-line|selection)\b</string>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.pseudo-element.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(:)((first|last)-child|(first|last|only)-of-type|empty|root|target|first|left|right)\b</string>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.pseudo-class.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(:)(checked|enabled|default|disabled|indeterminate|invalid|optional|required|valid)\b</string>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.pseudo-class.ui-state.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>((:)not)(\()</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.pseudo-class.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>\)</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>include</key>
|
||||
<string>#selector</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.pseudo-class.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
<key>4</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>constant.numeric.css</string>
|
||||
</dict>
|
||||
<key>5</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.section.function.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>((:)nth-(?:(?:last-)?child|(?:last-)?of-type))(\()(\-?(?:\d+n?|n)(?:\+\d+)?|even|odd)(\))</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(:)(active|hover|link|visited|focus)\b</string>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.pseudo-class.css</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.entity.css</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.other.attribute-name.attribute.css</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.separator.operator.css</string>
|
||||
</dict>
|
||||
<key>4</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>string.unquoted.attribute-value.css</string>
|
||||
</dict>
|
||||
<key>5</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>string.quoted.double.attribute-value.css</string>
|
||||
</dict>
|
||||
<key>6</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.begin.css</string>
|
||||
</dict>
|
||||
<key>7</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.end.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(?i)(\[)\s*(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)(?:\s*([~|^$*]?=)\s*(?:(-?[_a-z\\[[:^ascii:]]][_a-z0-9\-\\[[:^ascii:]]]*)|((?>(['"])(?:[^\\]|\\.)*?(\6)))))?\s*(\])</string>
|
||||
<key>name</key>
|
||||
<string>meta.attribute-selector.css</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>string-double</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>"</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.begin.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>"</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.end.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>string.quoted.double.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\\.</string>
|
||||
<key>name</key>
|
||||
<string>constant.character.escape.css</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>string-single</key>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>'</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.begin.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>'</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.end.css</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>string.quoted.single.css</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\\.</string>
|
||||
<key>name</key>
|
||||
<string>constant.character.escape.css</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>scopeName</key>
|
||||
<string>source.css</string>
|
||||
<key>uuid</key>
|
||||
<string>69AA0917-B7BB-11D9-A7E2-000D93C8BE28</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/// <reference path="../src/vs/vscode.d.ts" />
|
||||
/// <reference path="../src/typings/mocha.d.ts" />
|
||||
/// <reference path="./node.d.ts" />
|
||||
|
||||
declare var define: {
|
||||
(moduleName: string, dependencies: string[], callback: (...args: any[]) => any): any;
|
||||
(moduleName: string, dependencies: string[], definition: any): any;
|
||||
(moduleName: string, callback: (...args: any[]) => any): any;
|
||||
(moduleName: string, definition: any): any;
|
||||
(dependencies: string[], callback: (...args: any[]) => any): any;
|
||||
(dependencies: string[], definition: any): any;
|
||||
};
|
||||
|
||||
declare var require: {
|
||||
toUrl(path: string): string;
|
||||
(moduleName: string): any;
|
||||
(dependencies: string[], callback: (...args: any[]) => any, errorback?: (err: any) => void): any;
|
||||
config(data: any): any;
|
||||
onError: Function;
|
||||
__$__nodeRequire<T>(moduleName: string): T;
|
||||
};
|
||||
|
||||
// Declaring the following because the code gets compiled with es5, which lack definitions for console and timers.
|
||||
declare var console: {
|
||||
info(message?: any, ...optionalParams: any[]): void;
|
||||
profile(reportName?: string): void;
|
||||
assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
|
||||
clear(): void;
|
||||
dir(value?: any, ...optionalParams: any[]): void;
|
||||
warn(message?: any, ...optionalParams: any[]): void;
|
||||
error(message?: any, ...optionalParams: any[]): void;
|
||||
log(message?: any, ...optionalParams: any[]): void;
|
||||
profileEnd(): void;
|
||||
};
|
||||
|
||||
declare function clearTimeout(handle: number): void;
|
||||
declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;
|
||||
declare function clearInterval(handle: number): void;
|
||||
declare function setInterval(handler: any, timeout?: any, ...args: any[]): number;
|
||||
|
||||
declare module 'vs/base/common/async' {
|
||||
|
||||
import vscode = require('vscode');
|
||||
|
||||
export interface ITask<T> {
|
||||
(): T;
|
||||
}
|
||||
|
||||
export class Delayer<T> {
|
||||
|
||||
public defaultDelay: number;
|
||||
|
||||
constructor(defaultDelay: number);
|
||||
|
||||
public trigger(task: ITask<T>, delay?: number): Thenable<T>;
|
||||
|
||||
public isTriggered():boolean;
|
||||
|
||||
public cancel(): void;
|
||||
}
|
||||
|
||||
export class RunOnceScheduler {
|
||||
constructor(runner:()=>void, timeout:number);
|
||||
public dispose(): void;
|
||||
public cancel(): void;
|
||||
public schedule(): void;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'vs/base/node/stdFork' {
|
||||
import cp = require('child_process');
|
||||
export interface IForkOpts {
|
||||
cwd?: string;
|
||||
env?: any;
|
||||
encoding?: string;
|
||||
execArgv?: string[];
|
||||
}
|
||||
export function fork(modulePath: string, args: string[], options: IForkOpts, callback:(error:any, cp:cp.ChildProcess)=>void): void;
|
||||
}
|
||||
|
||||
// Needed by TypeScript plugin to avoid code duplication
|
||||
declare module 'vs/languages/lib/common/wireProtocol' {
|
||||
import stream = require('stream');
|
||||
export interface ICallback<T> {
|
||||
(data:T):void;
|
||||
}
|
||||
export enum ReaderType {
|
||||
Length = 0,
|
||||
Line = 1
|
||||
}
|
||||
export class Reader<T> {
|
||||
constructor(readable: stream.Readable, callback: ICallback<T>, type?: ReaderType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "language-docker",
|
||||
"version": "0.0.0",
|
||||
"license": "Apache2",
|
||||
"repositoryURL": "https://github.com/docker/docker",
|
||||
"description": "The file syntaxes/Dockerfile.tmLanguage was included from https://github.com/docker/docker/blob/master/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage."
|
||||
}]
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": "#"
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "docker",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": { "vscode": "*" },
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "dockerfile",
|
||||
"extensions": [ ".dockerfile" ],
|
||||
"filenames": [ "Dockerfile" ],
|
||||
"aliases": [ "Dockerfile" ],
|
||||
"configuration": "./dockerfile.configuration.json"
|
||||
}],
|
||||
"grammars": [{
|
||||
"language": "dockerfile",
|
||||
"scopeName": "source.dockerfile",
|
||||
"path": "./syntaxes/Dockerfile.tmLanguage"
|
||||
}]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>fileTypes</key>
|
||||
<array>
|
||||
<string>Dockerfile</string>
|
||||
</array>
|
||||
<key>name</key>
|
||||
<string>Dockerfile</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.control.dockerfile</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.other.special-method.dockerfile</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>^\s*(?:(ONBUILD)\s+)?(FROM|MAINTAINER|RUN|EXPOSE|ENV|ADD|VOLUME|USER|WORKDIR|COPY|LABEL|STOPSIGNAL)\s</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.dockerfile</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.other.special-method.dockerfile</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>^\s*(?:(ONBUILD)\s+)?(CMD|ENTRYPOINT)\s</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>"</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.begin.dockerfile</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>"</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.end.dockerfile</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>string.quoted.double.dockerfile</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\\.</string>
|
||||
<key>name</key>
|
||||
<string>constant.character.escaped.dockerfile</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>begin</key>
|
||||
<string>'</string>
|
||||
<key>beginCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.begin.dockerfile</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>end</key>
|
||||
<string>'</string>
|
||||
<key>endCaptures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.string.end.dockerfile</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>name</key>
|
||||
<string>string.quoted.single.dockerfile</string>
|
||||
<key>patterns</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\\.</string>
|
||||
<key>name</key>
|
||||
<string>constant.character.escaped.dockerfile</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.whitespace.comment.leading.dockerfile</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>comment.line.number-sign.dockerfile</string>
|
||||
</dict>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>punctuation.definition.comment.dockerfile</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>comment</key>
|
||||
<string>comment.line</string>
|
||||
<key>match</key>
|
||||
<string>^(\s*)((#).*$\n?)</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>scopeName</key>
|
||||
<string>source.dockerfile</string>
|
||||
<key>uuid</key>
|
||||
<string>a39d8795-59d2-49af-aa00-fe74ee29576e</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,8 @@
|
|||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "ionide/ionide-fsharp",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/ionide/ionide-fsharp",
|
||||
"description": "The file syntaxes/fsharp.json was included from https://github.com/ionide/ionide-fsharp/blob/develop/release/grammars/fsharp.json."
|
||||
}]
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"comments": {
|
||||
"lineComment": "//",
|
||||
"blockComment": [ "(*", "*)" ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "fsharp",
|
||||
"version": "0.1.0",
|
||||
"publisher": "vscode",
|
||||
"engines": { "vscode": "*" },
|
||||
"contributes": {
|
||||
"languages": [{
|
||||
"id": "fsharp",
|
||||
"extensions": [ ".fs", ".fsi", ".ml", ".mli", ".fsx", ".fsscript" ],
|
||||
"aliases": [ "F#", "FSharp", "fsharp" ],
|
||||
"configuration": "./fsharp.configuration.json"
|
||||
}],
|
||||
"grammars": [{
|
||||
"language": "fsharp",
|
||||
"scopeName": "source.fsharp",
|
||||
"path": "./syntaxes/fsharp.json"
|
||||
}]
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue