Merge branch 'main' into aiday/issue157165

This commit is contained in:
aiday-mar
2022-08-30 09:04:11 +02:00
103 changed files with 626 additions and 2014 deletions
@@ -6,10 +6,10 @@
import * as eslint from 'eslint';
import { TSESTree } from '@typescript-eslint/experimental-utils';
import * as path from 'path';
import * as minimatch from 'minimatch';
import minimatch from 'minimatch';
import { createImportRuleListener } from './utils';
const REPO_ROOT = path.normalize(path.join(__dirname, '../../../'));
const REPO_ROOT = path.normalize(path.join(__dirname, '../'));
interface ConditionalPattern {
when?: 'hasBrowser' | 'hasNode' | 'test';
+12
View File
@@ -0,0 +1,12 @@
const glob = require('glob');
const path = require('path');
require('ts-node').register({ experimentalResolver: true, transpileOnly: true });
// Re-export all .ts files as rules
const rules = {};
glob.sync(`${__dirname}/*.ts`).forEach((file) => {
rules[path.basename(file, '.ts')] = require(file);
});
exports.rules = rules;
+26
View File
@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es2020",
"lib": [
"ES2020"
],
"module": "commonjs",
"esModuleInterop": true,
"alwaysStrict": true,
"allowJs": true,
"strict": true,
"exactOptionalPropertyTypes": false,
"useUnknownInCatchVariables": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"newLine": "lf",
"noEmit": true
},
"include": [
"**/*.ts",
"**/*.js"
],
"exclude": [
"node_modules/**"
]
}
+22 -21
View File
@@ -8,7 +8,8 @@
"plugins": [
"@typescript-eslint",
"jsdoc",
"header"
"header",
"local"
],
"rules": {
"constructor-super": "warn",
@@ -61,17 +62,17 @@
]
}
],
"code-no-unused-expressions": [
"local/code-no-unused-expressions": [
"warn",
{
"allowTernary": true
}
],
"code-translation-remind": "warn",
"code-no-nls-in-standalone-editor": "warn",
"code-no-standalone-editor": "warn",
"code-no-unexternalized-strings": "warn",
"code-layering": [
"local/code-translation-remind": "warn",
"local/code-no-nls-in-standalone-editor": "warn",
"local/code-no-standalone-editor": "warn",
"local/code-no-unexternalized-strings": "warn",
"local/code-layering": [
"warn",
{
"common": [],
@@ -122,8 +123,8 @@
"**/*.test.ts"
],
"rules": {
"code-no-test-only": "error",
"code-no-unexternalized-strings": "off"
"local/code-no-test-only": "error",
"local/code-no-unexternalized-strings": "off"
}
},
{
@@ -132,14 +133,14 @@
"**/vscode.proposed.*.d.ts"
],
"rules": {
"vscode-dts-create-func": "warn",
"vscode-dts-literal-or-types": "warn",
"vscode-dts-interface-naming": "warn",
"vscode-dts-cancellation": "warn",
"vscode-dts-use-thenable": "warn",
"vscode-dts-region-comments": "warn",
"vscode-dts-vscode-in-comments": "warn",
"vscode-dts-provider-naming": [
"local/vscode-dts-create-func": "warn",
"local/vscode-dts-literal-or-types": "warn",
"local/vscode-dts-interface-naming": "warn",
"local/vscode-dts-cancellation": "warn",
"local/vscode-dts-use-thenable": "warn",
"local/vscode-dts-region-comments": "warn",
"local/vscode-dts-vscode-in-comments": "warn",
"local/vscode-dts-provider-naming": [
"warn",
{
"allowed": [
@@ -154,7 +155,7 @@
]
}
],
"vscode-dts-event-naming": [
"local/vscode-dts-event-naming": [
"warn",
{
"allowed": [
@@ -200,8 +201,8 @@
"src/**/*.ts"
],
"rules": {
"code-no-look-behind-regex": "warn",
"code-import-patterns": [
"local/code-no-look-behind-regex": "warn",
"local/code-import-patterns": [
"warn",
{
// imports that are allowed in all files of layers:
@@ -576,7 +577,7 @@
"test/**/*.ts"
],
"rules": {
"code-import-patterns": [
"local/code-import-patterns": [
"warn",
{
"target": "test/smoke/**",
-5
View File
@@ -41,11 +41,6 @@
}
}
],
"eslint.options": {
"rulePaths": [
"./build/lib/eslint"
]
},
"typescript.tsdk": "node_modules/typescript/lib",
"npm.exclude": "**/extensions/**",
"npm.packageManager": "yarn",
+1 -2
View File
@@ -13,8 +13,7 @@ function eslint() {
.src(eslintFilter, { base: '.', follow: true, allowEmpty: true })
.pipe(
gulpeslint({
configFile: '.eslintrc.json',
rulePaths: ['./build/lib/eslint'],
configFile: '.eslintrc.json'
})
)
.pipe(gulpeslint.formatEach('compact'))
+1 -2
View File
@@ -173,8 +173,7 @@ function hygiene(some, linting = true) {
.pipe(filter(eslintFilter))
.pipe(
gulpeslint({
configFile: '.eslintrc.json',
rulePaths: ['./build/lib/eslint'],
configFile: '.eslintrc.json'
})
)
.pipe(gulpeslint.formatEach('compact'))
-199
View File
@@ -1,199 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path = require("path");
const minimatch = require("minimatch");
const utils_1 = require("./utils");
const REPO_ROOT = path.normalize(path.join(__dirname, '../../../'));
function isLayerAllowRule(option) {
return !!(option.when && option.allow);
}
/**
* Returns the filename relative to the project root and using `/` as separators
*/
function getRelativeFilename(context) {
const filename = path.normalize(context.getFilename());
return filename.substring(REPO_ROOT.length).replace(/\\/g, '/');
}
module.exports = new class {
constructor() {
this.meta = {
messages: {
badImport: 'Imports violates \'{{restrictions}}\' restrictions. See https://github.com/microsoft/vscode/wiki/Source-Code-Organization',
badFilename: 'Missing definition in `code-import-patterns` for this file. Define rules at https://github.com/microsoft/vscode/blob/main/.eslintrc.json'
},
docs: {
url: 'https://github.com/microsoft/vscode/wiki/Source-Code-Organization'
}
};
this._optionsCache = new WeakMap();
}
create(context) {
const options = context.options;
const configs = this._processOptions(options);
const relativeFilename = getRelativeFilename(context);
for (const config of configs) {
if (minimatch(relativeFilename, config.target)) {
return (0, utils_1.createImportRuleListener)((node, value) => this._checkImport(context, config, node, value));
}
}
context.report({
loc: { line: 1, column: 0 },
messageId: 'badFilename'
});
return {};
}
_processOptions(options) {
if (this._optionsCache.has(options)) {
return this._optionsCache.get(options);
}
function orSegment(variants) {
return (variants.length === 1 ? variants[0] : `{${variants.join(',')}}`);
}
const layerRules = [
{ layer: 'common', deps: orSegment(['common']) },
{ layer: 'worker', deps: orSegment(['common', 'worker']) },
{ layer: 'browser', deps: orSegment(['common', 'browser']), isBrowser: true },
{ layer: 'electron-sandbox', deps: orSegment(['common', 'browser', 'electron-sandbox']), isBrowser: true },
{ layer: 'node', deps: orSegment(['common', 'node']), isNode: true },
{ layer: 'electron-browser', deps: orSegment(['common', 'browser', 'node', 'electron-sandbox', 'electron-browser']), isBrowser: true, isNode: true },
{ layer: 'electron-main', deps: orSegment(['common', 'node', 'electron-main']), isNode: true },
];
let browserAllow = [];
let nodeAllow = [];
let testAllow = [];
for (const option of options) {
if (isLayerAllowRule(option)) {
if (option.when === 'hasBrowser') {
browserAllow = option.allow.slice(0);
}
else if (option.when === 'hasNode') {
nodeAllow = option.allow.slice(0);
}
else if (option.when === 'test') {
testAllow = option.allow.slice(0);
}
}
}
function findLayer(layer) {
for (const layerRule of layerRules) {
if (layerRule.layer === layer) {
return layerRule;
}
}
return null;
}
function generateConfig(layerRule, target, rawRestrictions) {
const restrictions = [];
const testRestrictions = [...testAllow];
if (layerRule.isBrowser) {
restrictions.push(...browserAllow);
}
if (layerRule.isNode) {
restrictions.push(...nodeAllow);
}
for (const rawRestriction of rawRestrictions) {
let importPattern;
let when = undefined;
if (typeof rawRestriction === 'string') {
importPattern = rawRestriction;
}
else {
importPattern = rawRestriction.pattern;
when = rawRestriction.when;
}
if (typeof when === 'undefined'
|| (when === 'hasBrowser' && layerRule.isBrowser)
|| (when === 'hasNode' && layerRule.isNode)) {
restrictions.push(importPattern.replace(/\/\~$/, `/${layerRule.deps}/**`));
testRestrictions.push(importPattern.replace(/\/\~$/, `/test/${layerRule.deps}/**`));
}
else if (when === 'test') {
testRestrictions.push(importPattern.replace(/\/\~$/, `/${layerRule.deps}/**`));
testRestrictions.push(importPattern.replace(/\/\~$/, `/test/${layerRule.deps}/**`));
}
}
testRestrictions.push(...restrictions);
return [
{
target: target.replace(/\/\~$/, `/${layerRule.layer}/**`),
restrictions: restrictions
},
{
target: target.replace(/\/\~$/, `/test/${layerRule.layer}/**`),
restrictions: testRestrictions
}
];
}
const configs = [];
for (const option of options) {
if (isLayerAllowRule(option)) {
continue;
}
const target = option.target;
const targetIsVS = /^src\/vs\//.test(target);
const restrictions = (typeof option.restrictions === 'string' ? [option.restrictions] : option.restrictions).slice(0);
if (targetIsVS) {
// Always add "vs/nls"
restrictions.push('vs/nls');
}
if (targetIsVS && option.layer) {
// single layer => simple substitution for /~
const layerRule = findLayer(option.layer);
if (layerRule) {
const [config, testConfig] = generateConfig(layerRule, target, restrictions);
if (option.test) {
configs.push(testConfig);
}
else {
configs.push(config);
}
}
}
else if (targetIsVS && /\/\~$/.test(target)) {
// generate all layers
for (const layerRule of layerRules) {
const [config, testConfig] = generateConfig(layerRule, target, restrictions);
configs.push(config);
configs.push(testConfig);
}
}
else {
configs.push({ target, restrictions: restrictions.filter(r => typeof r === 'string') });
}
}
this._optionsCache.set(options, configs);
return configs;
}
_checkImport(context, config, node, importPath) {
// resolve relative paths
if (importPath[0] === '.') {
const relativeFilename = getRelativeFilename(context);
importPath = path.posix.join(path.posix.dirname(relativeFilename), importPath);
if (/^src\/vs\//.test(importPath)) {
// resolve using AMD base url
importPath = importPath.substring('src/'.length);
}
}
const restrictions = config.restrictions;
let matched = false;
for (const pattern of restrictions) {
if (minimatch(importPath, pattern)) {
matched = true;
break;
}
}
if (!matched) {
// None of the restrictions matched
context.report({
loc: node.loc,
messageId: 'badImport',
data: {
restrictions: restrictions.join(' or ')
}
});
}
}
};
-68
View File
@@ -1,68 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path_1 = require("path");
const utils_1 = require("./utils");
module.exports = new class {
constructor() {
this.meta = {
messages: {
layerbreaker: 'Bad layering. You are not allowed to access {{from}} from here, allowed layers are: [{{allowed}}]'
},
docs: {
url: 'https://github.com/microsoft/vscode/wiki/Source-Code-Organization'
}
};
}
create(context) {
const fileDirname = (0, path_1.dirname)(context.getFilename());
const parts = fileDirname.split(/\\|\//);
const ruleArgs = context.options[0];
let config;
for (let i = parts.length - 1; i >= 0; i--) {
if (ruleArgs[parts[i]]) {
config = {
allowed: new Set(ruleArgs[parts[i]]).add(parts[i]),
disallowed: new Set()
};
Object.keys(ruleArgs).forEach(key => {
if (!config.allowed.has(key)) {
config.disallowed.add(key);
}
});
break;
}
}
if (!config) {
// nothing
return {};
}
return (0, utils_1.createImportRuleListener)((node, path) => {
if (path[0] === '.') {
path = (0, path_1.join)((0, path_1.dirname)(context.getFilename()), path);
}
const parts = (0, path_1.dirname)(path).split(/\\|\//);
for (let i = parts.length - 1; i >= 0; i--) {
const part = parts[i];
if (config.allowed.has(part)) {
// GOOD - same layer
break;
}
if (config.disallowed.has(part)) {
// BAD - wrong layer
context.report({
loc: node.loc,
messageId: 'layerbreaker',
data: {
from: part,
allowed: [...config.allowed.keys()].join(', ')
}
});
break;
}
}
});
}
};
@@ -1,42 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
const _positiveLookBehind = /\(\?<=.+/;
const _negativeLookBehind = /\(\?<!.+/;
function _containsLookBehind(pattern) {
if (typeof pattern !== 'string') {
return false;
}
return _positiveLookBehind.test(pattern) || _negativeLookBehind.test(pattern);
}
module.exports = {
create(context) {
return {
// /.../
['Literal[regex]']: (node) => {
const pattern = node.regex?.pattern;
if (_containsLookBehind(pattern)) {
context.report({
node,
message: 'Look behind assertions are not yet supported in all browsers'
});
}
},
// new Regex("...")
['NewExpression[callee.name="RegExp"] Literal']: (node) => {
if (_containsLookBehind(node.value)) {
context.report({
node,
message: 'Look behind assertions are not yet supported in all browsers'
});
}
}
};
}
};
@@ -1,38 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path_1 = require("path");
const utils_1 = require("./utils");
module.exports = new class NoNlsInStandaloneEditorRule {
constructor() {
this.meta = {
messages: {
noNls: 'Not allowed to import vs/nls in standalone editor modules. Use standaloneStrings.ts'
}
};
}
create(context) {
const fileName = context.getFilename();
if (/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(fileName)
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(fileName)
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(fileName)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(fileName)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(fileName)) {
return (0, utils_1.createImportRuleListener)((node, path) => {
// resolve relative paths
if (path[0] === '.') {
path = (0, path_1.join)(context.getFilename(), path);
}
if (/vs(\/|\\)nls/.test(path)) {
context.report({
loc: node.loc,
messageId: 'noNls'
});
}
});
}
return {};
}
};
@@ -1,41 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path_1 = require("path");
const utils_1 = require("./utils");
module.exports = new class NoNlsInStandaloneEditorRule {
constructor() {
this.meta = {
messages: {
badImport: 'Not allowed to import standalone editor modules.'
},
docs: {
url: 'https://github.com/microsoft/vscode/wiki/Source-Code-Organization'
}
};
}
create(context) {
if (/vs(\/|\\)editor/.test(context.getFilename())) {
// the vs/editor folder is allowed to use the standalone editor
return {};
}
return (0, utils_1.createImportRuleListener)((node, path) => {
// resolve relative paths
if (path[0] === '.') {
path = (0, path_1.join)(context.getFilename(), path);
}
if (/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(path)
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)) {
context.report({
loc: node.loc,
messageId: 'badImport'
});
}
});
}
};
-17
View File
@@ -1,17 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
module.exports = new class NoTestOnly {
create(context) {
return {
['MemberExpression[object.name="test"][property.name="only"]']: (node) => {
return context.report({
node,
message: 'test.only is a dev-time tool and CANNOT be pushed'
});
}
};
}
};
@@ -1,111 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var _a;
const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
function isStringLiteral(node) {
return !!node && node.type === experimental_utils_1.AST_NODE_TYPES.Literal && typeof node.value === 'string';
}
function isDoubleQuoted(node) {
return node.raw[0] === '"' && node.raw[node.raw.length - 1] === '"';
}
module.exports = new (_a = class NoUnexternalizedStrings {
constructor() {
this.meta = {
messages: {
doubleQuoted: 'Only use double-quoted strings for externalized strings.',
badKey: 'The key \'{{key}}\' doesn\'t conform to a valid localize identifier.',
duplicateKey: 'Duplicate key \'{{key}}\' with different message value.',
badMessage: 'Message argument to \'{{message}}\' must be a string literal.'
}
};
}
create(context) {
const externalizedStringLiterals = new Map();
const doubleQuotedStringLiterals = new Set();
function collectDoubleQuotedStrings(node) {
if (isStringLiteral(node) && isDoubleQuoted(node)) {
doubleQuotedStringLiterals.add(node);
}
}
function visitLocalizeCall(node) {
// localize(key, message)
const [keyNode, messageNode] = node.arguments;
// (1)
// extract key so that it can be checked later
let key;
if (isStringLiteral(keyNode)) {
doubleQuotedStringLiterals.delete(keyNode);
key = keyNode.value;
}
else if (keyNode.type === experimental_utils_1.AST_NODE_TYPES.ObjectExpression) {
for (const property of keyNode.properties) {
if (property.type === experimental_utils_1.AST_NODE_TYPES.Property && !property.computed) {
if (property.key.type === experimental_utils_1.AST_NODE_TYPES.Identifier && property.key.name === 'key') {
if (isStringLiteral(property.value)) {
doubleQuotedStringLiterals.delete(property.value);
key = property.value.value;
break;
}
}
}
}
}
if (typeof key === 'string') {
let array = externalizedStringLiterals.get(key);
if (!array) {
array = [];
externalizedStringLiterals.set(key, array);
}
array.push({ call: node, message: messageNode });
}
// (2)
// remove message-argument from doubleQuoted list and make
// sure it is a string-literal
doubleQuotedStringLiterals.delete(messageNode);
if (!isStringLiteral(messageNode)) {
context.report({
loc: messageNode.loc,
messageId: 'badMessage',
data: { message: context.getSourceCode().getText(node) }
});
}
}
function reportBadStringsAndBadKeys() {
// (1)
// report all strings that are in double quotes
for (const node of doubleQuotedStringLiterals) {
context.report({ loc: node.loc, messageId: 'doubleQuoted' });
}
for (const [key, values] of externalizedStringLiterals) {
// (2)
// report all invalid NLS keys
if (!key.match(NoUnexternalizedStrings._rNlsKeys)) {
for (const value of values) {
context.report({ loc: value.call.loc, messageId: 'badKey', data: { key } });
}
}
// (2)
// report all invalid duplicates (same key, different message)
if (values.length > 1) {
for (let i = 1; i < values.length; i++) {
if (context.getSourceCode().getText(values[i - 1].message) !== context.getSourceCode().getText(values[i].message)) {
context.report({ loc: values[i].call.loc, messageId: 'duplicateKey', data: { key } });
}
}
}
}
}
return {
['Literal']: (node) => collectDoubleQuotedStrings(node),
['ExpressionStatement[directive] Literal:exit']: (node) => doubleQuotedStringLiterals.delete(node),
['CallExpression[callee.type="MemberExpression"][callee.object.name="nls"][callee.property.name="localize"]:exit']: (node) => visitLocalizeCall(node),
['CallExpression[callee.name="localize"][arguments.length>=2]:exit']: (node) => visitLocalizeCall(node),
['Program:exit']: reportBadStringsAndBadKeys,
};
}
},
_a._rNlsKeys = /^[_a-zA-Z0-9][ .\-_a-zA-Z0-9]*$/,
_a);
@@ -1,119 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
type: 'suggestion',
docs: {
description: 'disallow unused expressions',
category: 'Best Practices',
recommended: false,
url: 'https://eslint.org/docs/rules/no-unused-expressions'
},
schema: [
{
type: 'object',
properties: {
allowShortCircuit: {
type: 'boolean',
default: false
},
allowTernary: {
type: 'boolean',
default: false
},
allowTaggedTemplates: {
type: 'boolean',
default: false
}
},
additionalProperties: false
}
]
},
create(context) {
const config = context.options[0] || {}, allowShortCircuit = config.allowShortCircuit || false, allowTernary = config.allowTernary || false, allowTaggedTemplates = config.allowTaggedTemplates || false;
// eslint-disable-next-line jsdoc/require-description
/**
* @param node any node
* @returns whether the given node structurally represents a directive
*/
function looksLikeDirective(node) {
return node.type === 'ExpressionStatement' &&
node.expression.type === 'Literal' && typeof node.expression.value === 'string';
}
// eslint-disable-next-line jsdoc/require-description
/**
* @param predicate ([a] -> Boolean) the function used to make the determination
* @param list the input list
* @returns the leading sequence of members in the given list that pass the given predicate
*/
function takeWhile(predicate, list) {
for (let i = 0; i < list.length; ++i) {
if (!predicate(list[i])) {
return list.slice(0, i);
}
}
return list.slice();
}
// eslint-disable-next-line jsdoc/require-description
/**
* @param node a Program or BlockStatement node
* @returns the leading sequence of directive nodes in the given node's body
*/
function directives(node) {
return takeWhile(looksLikeDirective, node.body);
}
// eslint-disable-next-line jsdoc/require-description
/**
* @param node any node
* @param ancestors the given node's ancestors
* @returns whether the given node is considered a directive in its current position
*/
function isDirective(node, ancestors) {
const parent = ancestors[ancestors.length - 1], grandparent = ancestors[ancestors.length - 2];
return (parent.type === 'Program' || parent.type === 'BlockStatement' &&
(/Function/u.test(grandparent.type))) &&
directives(parent).indexOf(node) >= 0;
}
/**
* Determines whether or not a given node is a valid expression. Recurses on short circuit eval and ternary nodes if enabled by flags.
* @param node any node
* @returns whether the given node is a valid expression
*/
function isValidExpression(node) {
if (allowTernary) {
// Recursive check for ternary and logical expressions
if (node.type === 'ConditionalExpression') {
return isValidExpression(node.consequent) && isValidExpression(node.alternate);
}
}
if (allowShortCircuit) {
if (node.type === 'LogicalExpression') {
return isValidExpression(node.right);
}
}
if (allowTaggedTemplates && node.type === 'TaggedTemplateExpression') {
return true;
}
if (node.type === 'ExpressionStatement') {
return isValidExpression(node.expression);
}
return /^(?:Assignment|OptionalCall|Call|New|Update|Yield|Await|Chain)Expression$/u.test(node.type) ||
(node.type === 'UnaryExpression' && ['delete', 'void'].indexOf(node.operator) >= 0);
}
return {
ExpressionStatement(node) {
if (!isValidExpression(node.expression) && !isDirective(node, context.getAncestors())) {
context.report({ node: node, message: `Expected an assignment or function call and instead saw an expression. ${node.expression}` });
}
}
};
}
};
@@ -1,57 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var _a;
const fs_1 = require("fs");
const utils_1 = require("./utils");
module.exports = new (_a = class TranslationRemind {
constructor() {
this.meta = {
messages: {
missing: 'Please add \'{{resource}}\' to ./build/lib/i18n.resources.json file to use translations here.'
}
};
}
create(context) {
return (0, utils_1.createImportRuleListener)((node, path) => this._checkImport(context, node, path));
}
_checkImport(context, node, path) {
if (path !== TranslationRemind.NLS_MODULE) {
return;
}
const currentFile = context.getFilename();
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
const matchPart = currentFile.match(/vs\/workbench\/contrib\/\w+/);
if (!matchService && !matchPart) {
return;
}
const resource = matchService ? matchService[0] : matchPart[0];
let resourceDefined = false;
let json;
try {
json = (0, fs_1.readFileSync)('./build/lib/i18n.resources.json', 'utf8');
}
catch (e) {
console.error('[translation-remind rule]: File with resources to pull from Transifex was not found. Aborting translation resource check for newly defined workbench part/service.');
return;
}
const workbenchResources = JSON.parse(json).workbench;
workbenchResources.forEach((existingResource) => {
if (existingResource.name === resource) {
resourceDefined = true;
return;
}
});
if (!resourceDefined) {
context.report({
loc: node.loc,
messageId: 'missing',
data: { resource }
});
}
}
},
_a.NLS_MODULE = 'vs/nls',
_a);
-37
View File
@@ -1,37 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createImportRuleListener = void 0;
function createImportRuleListener(validateImport) {
function _checkImport(node) {
if (node && node.type === 'Literal' && typeof node.value === 'string') {
validateImport(node, node.value);
}
}
return {
// import ??? from 'module'
ImportDeclaration: (node) => {
_checkImport(node.source);
},
// import('module').then(...) OR await import('module')
['CallExpression[callee.type="Import"][arguments.length=1] > Literal']: (node) => {
_checkImport(node);
},
// import foo = ...
['TSImportEqualsDeclaration > TSExternalModuleReference > Literal']: (node) => {
_checkImport(node);
},
// export ?? from 'module'
ExportAllDeclaration: (node) => {
_checkImport(node.source);
},
// export {foo} from 'module'
ExportNamedDeclaration: (node) => {
_checkImport(node.source);
},
};
}
exports.createImportRuleListener = createImportRuleListener;
@@ -1,33 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
module.exports = new class ApiProviderNaming {
constructor() {
this.meta = {
messages: {
noToken: 'Function lacks a cancellation token, preferable as last argument',
}
};
}
create(context) {
return {
['TSInterfaceDeclaration[id.name=/.+Provider/] TSMethodSignature[key.name=/^(provide|resolve).+/]']: (node) => {
let found = false;
for (const param of node.params) {
if (param.type === experimental_utils_1.AST_NODE_TYPES.Identifier) {
found = found || param.name === 'token';
}
}
if (!found) {
context.report({
node,
messageId: 'noToken'
});
}
}
};
}
};
@@ -1,34 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
module.exports = new class ApiLiteralOrTypes {
constructor() {
this.meta = {
docs: { url: 'https://github.com/microsoft/vscode/wiki/Extension-API-guidelines#creating-objects' },
messages: { sync: '`createXYZ`-functions are constructor-replacements and therefore must return sync', }
};
}
create(context) {
return {
['TSDeclareFunction Identifier[name=/create.*/]']: (node) => {
const decl = node.parent;
if (decl.returnType?.typeAnnotation.type !== experimental_utils_1.AST_NODE_TYPES.TSTypeReference) {
return;
}
if (decl.returnType.typeAnnotation.typeName.type !== experimental_utils_1.AST_NODE_TYPES.Identifier) {
return;
}
const ident = decl.returnType.typeAnnotation.typeName.name;
if (ident === 'Promise' || ident === 'Thenable') {
context.report({
node,
messageId: 'sync'
});
}
}
};
}
};
@@ -1,86 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var _a;
const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
module.exports = new (_a = class ApiEventNaming {
constructor() {
this.meta = {
docs: {
url: 'https://github.com/microsoft/vscode/wiki/Extension-API-guidelines#event-naming'
},
messages: {
naming: 'Event names must follow this patten: `on[Did|Will]<Verb><Subject>`',
verb: 'Unknown verb \'{{verb}}\' - is this really a verb? Iff so, then add this verb to the configuration',
subject: 'Unknown subject \'{{subject}}\' - This subject has not been used before but it should refer to something in the API',
unknown: 'UNKNOWN event declaration, lint-rule needs tweaking'
}
};
}
create(context) {
const config = context.options[0];
const allowed = new Set(config.allowed);
const verbs = new Set(config.verbs);
return {
['TSTypeAnnotation TSTypeReference Identifier[name="Event"]']: (node) => {
const def = node.parent?.parent?.parent;
const ident = this.getIdent(def);
if (!ident) {
// event on unknown structure...
return context.report({
node,
message: 'unknown'
});
}
if (allowed.has(ident.name)) {
// configured exception
return;
}
const match = ApiEventNaming._nameRegExp.exec(ident.name);
if (!match) {
context.report({
node: ident,
messageId: 'naming'
});
return;
}
// check that <verb> is spelled out (configured) as verb
if (!verbs.has(match[2].toLowerCase())) {
context.report({
node: ident,
messageId: 'verb',
data: { verb: match[2] }
});
}
// check that a subject (if present) has occurred
if (match[3]) {
const regex = new RegExp(match[3], 'ig');
const parts = context.getSourceCode().getText().split(regex);
if (parts.length < 3) {
context.report({
node: ident,
messageId: 'subject',
data: { subject: match[3] }
});
}
}
}
};
}
getIdent(def) {
if (!def) {
return;
}
if (def.type === experimental_utils_1.AST_NODE_TYPES.Identifier) {
return def;
}
else if ((def.type === experimental_utils_1.AST_NODE_TYPES.TSPropertySignature || def.type === experimental_utils_1.AST_NODE_TYPES.PropertyDefinition) && def.key.type === experimental_utils_1.AST_NODE_TYPES.Identifier) {
return def.key;
}
return this.getIdent(def.parent);
}
},
_a._nameRegExp = /on(Did|Will)([A-Z][a-z]+)([A-Z][a-z]+)?/,
_a);
@@ -1,30 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var _a;
module.exports = new (_a = class ApiInterfaceNaming {
constructor() {
this.meta = {
messages: {
naming: 'Interfaces must not be prefixed with uppercase `I`',
}
};
}
create(context) {
return {
['TSInterfaceDeclaration Identifier']: (node) => {
const name = node.name;
if (ApiInterfaceNaming._nameRegExp.test(name)) {
context.report({
node,
messageId: 'naming'
});
}
}
};
}
},
_a._nameRegExp = /I[A-Z]/,
_a);
@@ -1,25 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
module.exports = new class ApiLiteralOrTypes {
constructor() {
this.meta = {
docs: { url: 'https://github.com/microsoft/vscode/wiki/Extension-API-guidelines#enums' },
messages: { useEnum: 'Use enums, not literal-or-types', }
};
}
create(context) {
return {
['TSTypeAnnotation TSUnionType']: (node) => {
if (node.types.every(value => value.type === 'TSLiteralType')) {
context.report({
node: node,
messageId: 'useEnum'
});
}
}
};
}
};
@@ -1,37 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var _a;
module.exports = new (_a = class ApiProviderNaming {
constructor() {
this.meta = {
messages: {
naming: 'A provider should only have functions like provideXYZ or resolveXYZ',
}
};
}
create(context) {
const config = context.options[0];
const allowed = new Set(config.allowed);
return {
['TSInterfaceDeclaration[id.name=/.+Provider/] TSMethodSignature']: (node) => {
const interfaceName = (node.parent?.parent).id.name;
if (allowed.has(interfaceName)) {
// allowed
return;
}
const methodName = node.key.name;
if (!ApiProviderNaming._providerFunctionNames.test(methodName)) {
context.report({
node,
messageId: 'naming'
});
}
}
};
}
},
_a._providerFunctionNames = /^(provide|resolve|prepare).+/,
_a);
@@ -1,35 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
module.exports = new class ApiEventNaming {
constructor() {
this.meta = {
messages: {
comment: 'region comments should start with a camel case identifier, `:`, then either a GH issue link or owner, e.g #region myProposalName: https://github.com/microsoft/vscode/issues/<number>',
}
};
}
create(context) {
const sourceCode = context.getSourceCode();
return {
['Program']: (_node) => {
for (const comment of sourceCode.getAllComments()) {
if (comment.type !== 'Line') {
continue;
}
if (!/^\s*#region /.test(comment.value)) {
continue;
}
if (!/^\s*#region ([a-z]+): (@[a-z]+|https:\/\/github.com\/microsoft\/vscode\/issues\/\d+)/i.test(comment.value)) {
context.report({
node: comment,
messageId: 'comment',
});
}
}
}
};
}
};
@@ -1,24 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
module.exports = new class ApiEventNaming {
constructor() {
this.meta = {
messages: {
usage: 'Use the Thenable-type instead of the Promise type',
}
};
}
create(context) {
return {
['TSTypeAnnotation TSTypeReference Identifier[name="Promise"]']: (node) => {
context.report({
node,
messageId: 'usage',
});
}
};
}
};
@@ -1,45 +0,0 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
module.exports = new class ApiVsCodeInComments {
constructor() {
this.meta = {
messages: {
comment: `Don't use the term 'vs code' in comments`
}
};
}
create(context) {
const sourceCode = context.getSourceCode();
return {
['Program']: (_node) => {
for (const comment of sourceCode.getAllComments()) {
if (comment.type !== 'Block') {
continue;
}
if (!comment.range) {
continue;
}
const startIndex = comment.range[0] + '/*'.length;
const re = /vs code/ig;
let match;
while ((match = re.exec(comment.value))) {
// Allow using 'VS Code' in quotes
if (comment.value[match.index - 1] === `'` && comment.value[match.index + match[0].length] === `'`) {
continue;
}
// Types for eslint seem incorrect
const start = sourceCode.getLocFromIndex(startIndex + match.index);
const end = sourceCode.getLocFromIndex(startIndex + match.index + match[0].length);
context.report({
messageId: 'comment',
loc: { start, end }
});
}
}
}
};
}
};
+1 -1
View File
@@ -4,7 +4,7 @@
"lib": [
"ES2020"
],
"module": "node12",
"module": "node16",
"checkJs": true,
"noEmit": true
}
+2 -2
View File
@@ -6,7 +6,7 @@
import { spawn as _spawn } from 'child_process';
import { readdirSync, readFileSync } from 'fs';
import { join } from 'path';
import url from 'url'
import url from 'url';
async function spawn(cmd, args, opts) {
return new Promise((c, e) => {
@@ -20,7 +20,7 @@ async function main() {
for (const extension of readdirSync('extensions')) {
try {
let packageJSON = JSON.parse(readFileSync(join('extensions', extension, 'package.json')).toString());
const packageJSON = JSON.parse(readFileSync(join('extensions', extension, 'package.json')).toString());
if (!(packageJSON && packageJSON.scripts && packageJSON.scripts['update-grammar'])) {
continue;
}
-2
View File
@@ -40,8 +40,6 @@
"@types/underscore": "^1.8.9",
"@types/webpack": "^4.41.25",
"@types/xml2js": "0.0.33",
"@typescript-eslint/experimental-utils": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0",
"@vscode/iconv-lite-umd": "0.7.0",
"byline": "^5.0.0",
"colors": "^1.4.0",
+3
View File
@@ -7,5 +7,8 @@
},
"include": [
"**/*.ts"
],
"exclude": [
"lib/eslint-plugin-vscode/**/*"
]
}
+4 -275
View File
@@ -232,27 +232,6 @@
dependencies:
cross-spawn "^7.0.1"
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
dependencies:
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
"@nodelib/fs.walk@^1.2.3":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
dependencies:
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@opentelemetry/api@^1.0.1":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.0.3.tgz#13a12ae9e05c2a782f7b5e84c3cbfda4225eaf80"
@@ -470,11 +449,6 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
"@types/json-schema@^7.0.9":
version "7.0.9"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
"@types/keyv@*":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
@@ -682,103 +656,6 @@
dependencies:
"@types/node" "*"
"@typescript-eslint/experimental-utils@^5.10.0":
version "5.10.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.10.1.tgz#49fa5a7800ed08ea70aef14fccb14fbae85116ab"
integrity sha512-Ryeb8nkJa/1zKl8iujNtJC8tgj6PgaY0sDUnrTqbmC70nrKKkZaHfiRDTcqICmCSCEQyLQcJAoh0AukLaIaGTw==
dependencies:
"@typescript-eslint/utils" "5.10.1"
"@typescript-eslint/parser@^5.10.0":
version "5.10.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.0.tgz#8f59e036f5f1cffc178cacbd5ccdd02aeb96c91c"
integrity sha512-pJB2CCeHWtwOAeIxv8CHVGJhI5FNyJAIpx5Pt72YkK3QfEzt6qAlXZuyaBmyfOdM62qU0rbxJzNToPTVeJGrQw==
dependencies:
"@typescript-eslint/scope-manager" "5.10.0"
"@typescript-eslint/types" "5.10.0"
"@typescript-eslint/typescript-estree" "5.10.0"
debug "^4.3.2"
"@typescript-eslint/scope-manager@5.10.0":
version "5.10.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.0.tgz#bb5d872e8b9e36203908595507fbc4d3105329cb"
integrity sha512-tgNgUgb4MhqK6DoKn3RBhyZ9aJga7EQrw+2/OiDk5hKf3pTVZWyqBi7ukP+Z0iEEDMF5FDa64LqODzlfE4O/Dg==
dependencies:
"@typescript-eslint/types" "5.10.0"
"@typescript-eslint/visitor-keys" "5.10.0"
"@typescript-eslint/scope-manager@5.10.1":
version "5.10.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.1.tgz#f0539c73804d2423506db2475352a4dec36cd809"
integrity sha512-Lyvi559Gvpn94k7+ElXNMEnXu/iundV5uFmCUNnftbFrUbAJ1WBoaGgkbOBm07jVZa682oaBU37ao/NGGX4ZDg==
dependencies:
"@typescript-eslint/types" "5.10.1"
"@typescript-eslint/visitor-keys" "5.10.1"
"@typescript-eslint/types@5.10.0":
version "5.10.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.0.tgz#beb3cb345076f5b088afe996d57bcd1dfddaa75c"
integrity sha512-wUljCgkqHsMZbw60IbOqT/puLfyqqD5PquGiBo1u1IS3PLxdi3RDGlyf032IJyh+eQoGhz9kzhtZa+VC4eWTlQ==
"@typescript-eslint/types@5.10.1":
version "5.10.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.1.tgz#dca9bd4cb8c067fc85304a31f38ec4766ba2d1ea"
integrity sha512-ZvxQ2QMy49bIIBpTqFiOenucqUyjTQ0WNLhBM6X1fh1NNlYAC6Kxsx8bRTY3jdYsYg44a0Z/uEgQkohbR0H87Q==
"@typescript-eslint/typescript-estree@5.10.0":
version "5.10.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.0.tgz#4be24a3dea0f930bb1397c46187d0efdd955a224"
integrity sha512-x+7e5IqfwLwsxTdliHRtlIYkgdtYXzE0CkFeV6ytAqq431ZyxCFzNMNR5sr3WOlIG/ihVZr9K/y71VHTF/DUQA==
dependencies:
"@typescript-eslint/types" "5.10.0"
"@typescript-eslint/visitor-keys" "5.10.0"
debug "^4.3.2"
globby "^11.0.4"
is-glob "^4.0.3"
semver "^7.3.5"
tsutils "^3.21.0"
"@typescript-eslint/typescript-estree@5.10.1":
version "5.10.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.1.tgz#b268e67be0553f8790ba3fe87113282977adda15"
integrity sha512-PwIGnH7jIueXv4opcwEbVGDATjGPO1dx9RkUl5LlHDSe+FXxPwFL5W/qYd5/NHr7f6lo/vvTrAzd0KlQtRusJQ==
dependencies:
"@typescript-eslint/types" "5.10.1"
"@typescript-eslint/visitor-keys" "5.10.1"
debug "^4.3.2"
globby "^11.0.4"
is-glob "^4.0.3"
semver "^7.3.5"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.10.1":
version "5.10.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.10.1.tgz#fa682a33af47080ba2c4368ee0ad2128213a1196"
integrity sha512-RRmlITiUbLuTRtn/gcPRi4202niF+q7ylFLCKu4c+O/PcpRvZ/nAUwQ2G00bZgpWkhrNLNnvhZLbDn8Ml0qsQw==
dependencies:
"@types/json-schema" "^7.0.9"
"@typescript-eslint/scope-manager" "5.10.1"
"@typescript-eslint/types" "5.10.1"
"@typescript-eslint/typescript-estree" "5.10.1"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
"@typescript-eslint/visitor-keys@5.10.0":
version "5.10.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.0.tgz#770215497ad67cd15a572b52089991d5dfe06281"
integrity sha512-GMxj0K1uyrFLPKASLmZzCuSddmjZVbVj3Ouy5QVuIGKZopxvOr24JsS7gruz6C3GExE01mublZ3mIBOaon9zuQ==
dependencies:
"@typescript-eslint/types" "5.10.0"
eslint-visitor-keys "^3.0.0"
"@typescript-eslint/visitor-keys@5.10.1":
version "5.10.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.1.tgz#29102de692f59d7d34ecc457ed59ab5fc558010b"
integrity sha512-NjQ0Xinhy9IL979tpoTRuLKxMc0zJC7QVSdeerXs2/QvOy2yRkzX5dRb10X5woNUdJgU8G3nYRDlI33sq1K4YQ==
dependencies:
"@typescript-eslint/types" "5.10.1"
eslint-visitor-keys "^3.0.0"
"@vscode/iconv-lite-umd@0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48"
@@ -877,11 +754,6 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
array-union@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
asar@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/asar/-/asar-3.0.3.tgz#1fef03c2d6d2de0cbad138788e4f7ae03b129c7b"
@@ -971,7 +843,7 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
braces@^3.0.1, braces@~3.0.2:
braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
@@ -1395,13 +1267,6 @@ dir-compare@^2.4.0:
commander "2.9.0"
minimatch "3.0.4"
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
dependencies:
path-type "^4.0.0"
dom-serializer@^1.0.1, dom-serializer@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
@@ -1611,48 +1476,6 @@ escape-string-regexp@^4.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-scope@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
dependencies:
esrecurse "^4.3.0"
estraverse "^4.1.1"
eslint-utils@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
dependencies:
eslint-visitor-keys "^2.0.0"
eslint-visitor-keys@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
eslint-visitor-keys@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1"
integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
dependencies:
estraverse "^5.2.0"
estraverse@^4.1.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
events@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"
@@ -1692,29 +1515,11 @@ fancy-log@^1.3.3:
parse-node-version "^1.0.0"
time-stamp "^1.0.0"
fast-glob@^3.2.9:
version "3.2.11"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
"@nodelib/fs.walk" "^1.2.3"
glob-parent "^5.1.2"
merge2 "^1.3.0"
micromatch "^4.0.4"
fast-json-stable-stringify@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
fastq@^1.6.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==
dependencies:
reusify "^1.0.4"
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
@@ -1840,7 +1645,7 @@ github-from-package@0.0.0:
resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0:
glob-parent@^5.1.1, glob-parent@~5.1.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
@@ -1901,18 +1706,6 @@ globalthis@^1.0.1:
dependencies:
define-properties "^1.1.3"
globby@^11.0.4:
version "11.1.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
fast-glob "^3.2.9"
ignore "^5.2.0"
merge2 "^1.4.1"
slash "^3.0.0"
got@11.8.5:
version "11.8.5"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046"
@@ -2064,11 +1857,6 @@ ieee754@^1.1.13:
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@@ -2130,7 +1918,7 @@ is-glob@^4.0.1:
dependencies:
is-extglob "^2.1.1"
is-glob@^4.0.3, is-glob@~4.0.1:
is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
@@ -2412,19 +2200,6 @@ mdurl@^1.0.1:
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
merge2@^1.3.0, merge2@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
dependencies:
braces "^3.0.1"
picomatch "^2.2.3"
mime-db@1.45.0:
version "1.45.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea"
@@ -2678,11 +2453,6 @@ path-key@^3.1.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
@@ -2693,7 +2463,7 @@ picomatch@^2.0.4:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
picomatch@^2.2.1, picomatch@^2.2.3:
picomatch@^2.2.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@@ -2809,11 +2579,6 @@ qs@^6.9.1:
dependencies:
side-channel "^1.0.4"
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
quick-lru@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
@@ -2894,11 +2659,6 @@ responselike@^2.0.0:
dependencies:
lowercase-keys "^2.0.0"
reusify@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rimraf@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
@@ -2918,13 +2678,6 @@ roarr@^2.15.3:
semver-compare "^1.0.0"
sprintf-js "^1.1.2"
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
dependencies:
queue-microtask "^1.2.2"
safe-buffer@^5.0.1, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
@@ -2972,13 +2725,6 @@ semver@^7.3.2:
dependencies:
lru-cache "^6.0.0"
semver@^7.3.5:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
dependencies:
lru-cache "^6.0.0"
serialize-error@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
@@ -3031,11 +2777,6 @@ simple-get@^3.0.3:
once "^1.3.1"
simple-concat "^1.0.0"
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
@@ -3260,11 +3001,6 @@ tslib@^1.10.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^1.8.1:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
tslib@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c"
@@ -3275,13 +3011,6 @@ tslib@^2.2.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
dependencies:
tslib "^1.8.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+1 -1
View File
@@ -481,7 +481,7 @@ export class Git {
const repoUri = Uri.file(repoPath);
const pathUri = Uri.file(repositoryPath);
if (repoUri.authority.length !== 0 && pathUri.authority.length === 0) {
// eslint-disable-next-line code-no-look-behind-regex
// eslint-disable-next-line local/code-no-look-behind-regex
const match = /(?<=^\/?)([a-zA-Z])(?=:\/)/.exec(pathUri.path);
if (match !== null) {
const [, letter] = match;
@@ -113,7 +113,7 @@ ol ol {
margin-bottom: 0;
}
img {
img, video {
max-width: 100%;
max-height: 100%;
}
+1 -2
View File
@@ -8,7 +8,6 @@
},
"include": [
"src/**/*",
"../../src/vscode-dts/vscode.d.ts",
"../../src/vscode-dts/vscode.proposed.notebookEditorEdit.d.ts",
"../../src/vscode-dts/vscode.d.ts"
]
}
@@ -314,9 +314,10 @@ export class PackageJSONContribution implements IJSONContribution {
headers: { agent: USER_AGENT }
});
const obj = JSON.parse(success.responseText);
const version = obj['dist-tags']?.latest || Object.keys(obj.versions).pop() || '';
return {
description: obj.description || '',
version: Object.keys(obj.versions).pop(),
version,
homepage: obj.homepage || ''
};
}
@@ -294,7 +294,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
await provideCalled;
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCellMetadata(notebook.uri, 0, { inputCollapsed: true });
edit.set(notebook.uri, [vscode.NotebookEdit.updateCellMetadata(0, { inputCollapsed: true })]);
await vscode.workspace.applyEdit(edit);
await provideCalled;
});
@@ -173,7 +173,7 @@ suite('Notebook Document', function () {
// inserting two new cells
{
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, new vscode.NotebookRange(0, 0), [{
edit.set(document.uri, [vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(0, 0), [{
kind: vscode.NotebookCellKind.Markup,
languageId: 'markdown',
metadata: undefined,
@@ -185,7 +185,7 @@ suite('Notebook Document', function () {
metadata: undefined,
outputs: [],
value: 'new_code'
}]);
}])]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
@@ -198,8 +198,10 @@ suite('Notebook Document', function () {
// deleting cell 1 and 3
{
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, new vscode.NotebookRange(0, 1), []);
edit.replaceNotebookCells(document.uri, new vscode.NotebookRange(2, 3), []);
edit.set(document.uri, [
vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(0, 1), []),
vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(2, 3), [])
]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
}
@@ -210,7 +212,7 @@ suite('Notebook Document', function () {
// replacing all cells
{
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, new vscode.NotebookRange(0, 1), [{
edit.set(document.uri, [vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(0, 1), [{
kind: vscode.NotebookCellKind.Markup,
languageId: 'markdown',
metadata: undefined,
@@ -222,7 +224,7 @@ suite('Notebook Document', function () {
metadata: undefined,
outputs: [],
value: 'new2_code'
}]);
}])]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
}
@@ -233,7 +235,7 @@ suite('Notebook Document', function () {
// remove all cells
{
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, new vscode.NotebookRange(0, document.cellCount), []);
edit.set(document.uri, [vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(0, document.cellCount), [])]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
}
@@ -246,7 +248,7 @@ suite('Notebook Document', function () {
assert.strictEqual(document.cellCount, 1);
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, new vscode.NotebookRange(0, 0), [{
edit.set(document.uri, [vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(0, 0), [{
kind: vscode.NotebookCellKind.Markup,
languageId: 'markdown',
metadata: undefined,
@@ -258,7 +260,7 @@ suite('Notebook Document', function () {
metadata: undefined,
outputs: [],
value: 'new_code'
}]);
}])]);
const event = utils.asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
@@ -287,7 +289,7 @@ suite('Notebook Document', function () {
const document = await vscode.workspace.openNotebookDocument(uri);
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCellMetadata(document.uri, 0, { inputCollapsed: true });
edit.set(document.uri, [vscode.NotebookEdit.updateCellMetadata(0, { inputCollapsed: true })]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
assert.strictEqual(document.cellAt(0).metadata.inputCollapsed, true);
@@ -300,7 +302,7 @@ suite('Notebook Document', function () {
const edit = new vscode.WorkspaceEdit();
const event = utils.asPromise<vscode.NotebookDocumentChangeEvent>(vscode.workspace.onDidChangeNotebookDocument);
edit.replaceNotebookCellMetadata(document.uri, 0, { inputCollapsed: true });
edit.set(document.uri, [vscode.NotebookEdit.updateCellMetadata(0, { inputCollapsed: true })]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
const data = await event;
@@ -338,7 +340,7 @@ suite('Notebook Document', function () {
assert.strictEqual(notebook.notebookType, 'notebook.nbdtest');
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(notebook.uri, new vscode.NotebookRange(0, 0), [{
edit.set(notebook.uri, [vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(0, 0), [{
kind: vscode.NotebookCellKind.Markup,
languageId: 'markdown',
metadata: undefined,
@@ -350,7 +352,7 @@ suite('Notebook Document', function () {
metadata: undefined,
outputs: [],
value: 'new_code'
}]);
}])]);
const success = await vscode.workspace.applyEdit(edit);
assert.strictEqual(success, true);
@@ -399,7 +401,7 @@ suite('Notebook Document', function () {
assert.strictEqual(document.isDirty, false);
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, new vscode.NotebookRange(0, document.cellCount), []);
edit.set(document.uri, [vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(0, document.cellCount), [])]);
assert.ok(await vscode.workspace.applyEdit(edit));
assert.strictEqual(document.isDirty, true);
@@ -414,7 +416,7 @@ suite('Notebook Document', function () {
assert.strictEqual(document.isDirty, false);
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(document.uri, new vscode.NotebookRange(0, document.cellCount), []);
edit.set(document.uri, [vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(0, document.cellCount), [])]);
assert.ok(await vscode.workspace.applyEdit(edit));
assert.strictEqual(document.isDirty, true);
@@ -406,7 +406,7 @@ const apiTestContentProvider: vscode.NotebookContentProvider = {
// Delete executing cell
const edit = new vscode.WorkspaceEdit();
edit.replaceNotebookCells(cell!.notebook.uri, new vscode.NotebookRange(cell!.index, cell!.index + 1), []);
edit.set(cell!.notebook.uri, [vscode.NotebookEdit.replaceCells(new vscode.NotebookRange(cell!.index, cell!.index + 1), [])]);
await vscode.workspace.applyEdit(edit);
assert.strictEqual(executionWasCancelled, true);
+6 -3
View File
@@ -86,12 +86,12 @@
"vscode-proxy-agent": "^0.12.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "7.0.1",
"xterm": "5.0.0-beta.36",
"xterm-addon-canvas": "0.2.0-beta.17",
"xterm": "5.0.0-beta.44",
"xterm-addon-canvas": "0.2.0-beta.21",
"xterm-addon-search": "0.10.0-beta.5",
"xterm-addon-serialize": "0.8.0-beta.5",
"xterm-addon-unicode11": "0.4.0-beta.5",
"xterm-addon-webgl": "0.13.0-beta.37",
"xterm-addon-webgl": "0.13.0-beta.45",
"xterm-headless": "5.0.0-beta.5",
"yauzl": "^2.9.2",
"yazl": "^2.4.3"
@@ -123,6 +123,7 @@
"@types/winreg": "^1.2.30",
"@types/yauzl": "^2.9.1",
"@types/yazl": "^2.4.2",
"@typescript-eslint/experimental-utils": "^5.10.0",
"@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0",
"@vscode/telemetry-extractor": "^1.9.8",
@@ -141,6 +142,7 @@
"eslint": "8.7.0",
"eslint-plugin-header": "3.1.1",
"eslint-plugin-jsdoc": "^39.3.2",
"eslint-plugin-local": "^1.0.0",
"event-stream": "3.3.4",
"fancy-log": "^1.3.3",
"fast-plist": "0.1.2",
@@ -200,6 +202,7 @@
"source-map-support": "^0.3.2",
"style-loader": "^1.3.0",
"ts-loader": "^9.2.7",
"ts-node": "^10.9.1",
"tsec": "0.1.4",
"typescript": "^4.9.0-dev.20220825",
"typescript-formatter": "7.1.0",
+3 -3
View File
@@ -24,12 +24,12 @@
"vscode-proxy-agent": "^0.12.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "7.0.1",
"xterm": "5.0.0-beta.36",
"xterm-addon-canvas": "0.2.0-beta.17",
"xterm": "5.0.0-beta.44",
"xterm-addon-canvas": "0.2.0-beta.21",
"xterm-addon-search": "0.10.0-beta.5",
"xterm-addon-serialize": "0.8.0-beta.5",
"xterm-addon-unicode11": "0.4.0-beta.5",
"xterm-addon-webgl": "0.13.0-beta.37",
"xterm-addon-webgl": "0.13.0-beta.45",
"xterm-headless": "5.0.0-beta.5",
"yauzl": "^2.9.2",
"yazl": "^2.4.3"
+3 -3
View File
@@ -11,10 +11,10 @@
"tas-client-umd": "0.1.6",
"vscode-oniguruma": "1.6.1",
"vscode-textmate": "7.0.1",
"xterm": "5.0.0-beta.36",
"xterm-addon-canvas": "0.2.0-beta.17",
"xterm": "5.0.0-beta.44",
"xterm-addon-canvas": "0.2.0-beta.21",
"xterm-addon-search": "0.10.0-beta.5",
"xterm-addon-unicode11": "0.4.0-beta.5",
"xterm-addon-webgl": "0.13.0-beta.37"
"xterm-addon-webgl": "0.13.0-beta.45"
}
}
+12 -12
View File
@@ -68,10 +68,10 @@ vscode-textmate@7.0.1:
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-7.0.1.tgz#8118a32b02735dccd14f893b495fa5389ad7de79"
integrity sha512-zQ5U/nuXAAMsh691FtV0wPz89nSkHbs+IQV8FDk+wew9BlSDhf4UmWGlWJfTR2Ti6xZv87Tj5fENzKf6Qk7aLw==
xterm-addon-canvas@0.2.0-beta.17:
version "0.2.0-beta.17"
resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.17.tgz#e84a86530b20bd3edcce16b4566f346cd186ab4d"
integrity sha512-2ukPdCA92VTFYQRE56ylzvI3cfaQYDWd/Mc4jlEItI6sV/EA5RnUbbP+2sFIx0JlmHK6nVYXXNY2p6QRB7MRew==
xterm-addon-canvas@0.2.0-beta.21:
version "0.2.0-beta.21"
resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.21.tgz#df79eac3408dcf24b1d42d4979a227efad3e6836"
integrity sha512-d1JjbPLQibDvG31Ii3M4Hz2m6ZINPU43c+O2j73/5ebBVo9zXV6deUFySedqXj+fFxLDgV0Twn09DrIR/j+PZA==
xterm-addon-search@0.10.0-beta.5:
version "0.10.0-beta.5"
@@ -83,12 +83,12 @@ xterm-addon-unicode11@0.4.0-beta.5:
resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.5.tgz#3900e66f10d2e506133b61d7421aab6878d32665"
integrity sha512-+g+fuxAd/tkCEJ/jhdnebXKtdPrhsu4VKWNnB/3qM35GbuGQOasmYFYnKL+HYZMpbQ6YqeZcXTVg/wnCTttz0g==
xterm-addon-webgl@0.13.0-beta.37:
version "0.13.0-beta.37"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.37.tgz#46819028abbe66cfabc60a615c4cc7bcd9156305"
integrity sha512-XoJdN8CELScYLPnEJKo9s0r3tC9/szGnmBEymV1+oLbMrQNeaV5VQqbiYzgKTyDHc12Gc5lPvih3/r6eL/9gig==
xterm-addon-webgl@0.13.0-beta.45:
version "0.13.0-beta.45"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.45.tgz#f1f3c08e2a819970c1af0362eeb61185babcb6fc"
integrity sha512-TXq5mxvG2alo5hSj/aFqHDzR2RSV2HH4is7R7kVmSCVPnl2RgDfAPilXOEJyYFLF09EgiGiG5UZASYJjvJfMRg==
xterm@5.0.0-beta.36:
version "5.0.0-beta.36"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.36.tgz#c07721d04fddc0f86417bc95a2f0824040c0eca9"
integrity sha512-6aND1UOAcCn42WlVrQbIU7a+ZFD4o3Gy2yE1BeDLTCFfK6oqc1QpRrH1plGOUypeabxCTADrw5vhl5W/45kutg==
xterm@5.0.0-beta.44:
version "5.0.0-beta.44"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.44.tgz#854ed16c06808295777afc4ef7b78ccd55e59d4a"
integrity sha512-raKvoikUjKZTO9duYliDp5hSKAwYia9P51QCumHY30V/bRZ2fq9ryyKQ65PxW8LzGYK8o7x7vNRUHVWbS073Tw==
+12 -12
View File
@@ -788,10 +788,10 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
xterm-addon-canvas@0.2.0-beta.17:
version "0.2.0-beta.17"
resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.17.tgz#e84a86530b20bd3edcce16b4566f346cd186ab4d"
integrity sha512-2ukPdCA92VTFYQRE56ylzvI3cfaQYDWd/Mc4jlEItI6sV/EA5RnUbbP+2sFIx0JlmHK6nVYXXNY2p6QRB7MRew==
xterm-addon-canvas@0.2.0-beta.21:
version "0.2.0-beta.21"
resolved "https://registry.yarnpkg.com/xterm-addon-canvas/-/xterm-addon-canvas-0.2.0-beta.21.tgz#df79eac3408dcf24b1d42d4979a227efad3e6836"
integrity sha512-d1JjbPLQibDvG31Ii3M4Hz2m6ZINPU43c+O2j73/5ebBVo9zXV6deUFySedqXj+fFxLDgV0Twn09DrIR/j+PZA==
xterm-addon-search@0.10.0-beta.5:
version "0.10.0-beta.5"
@@ -808,20 +808,20 @@ xterm-addon-unicode11@0.4.0-beta.5:
resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.5.tgz#3900e66f10d2e506133b61d7421aab6878d32665"
integrity sha512-+g+fuxAd/tkCEJ/jhdnebXKtdPrhsu4VKWNnB/3qM35GbuGQOasmYFYnKL+HYZMpbQ6YqeZcXTVg/wnCTttz0g==
xterm-addon-webgl@0.13.0-beta.37:
version "0.13.0-beta.37"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.37.tgz#46819028abbe66cfabc60a615c4cc7bcd9156305"
integrity sha512-XoJdN8CELScYLPnEJKo9s0r3tC9/szGnmBEymV1+oLbMrQNeaV5VQqbiYzgKTyDHc12Gc5lPvih3/r6eL/9gig==
xterm-addon-webgl@0.13.0-beta.45:
version "0.13.0-beta.45"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.45.tgz#f1f3c08e2a819970c1af0362eeb61185babcb6fc"
integrity sha512-TXq5mxvG2alo5hSj/aFqHDzR2RSV2HH4is7R7kVmSCVPnl2RgDfAPilXOEJyYFLF09EgiGiG5UZASYJjvJfMRg==
xterm-headless@5.0.0-beta.5:
version "5.0.0-beta.5"
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.0.0-beta.5.tgz#e29b6c5081f31f887122b7263ba996b0c46b3c22"
integrity sha512-CMQ1+prBNF92oBMeZzc2rfTcmOaCGfwwSaoPYNTjyziZT6mZsEg7amajYkb0YAnqJ29MFm4kPGZbU78/dX4k2A==
xterm@5.0.0-beta.36:
version "5.0.0-beta.36"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.36.tgz#c07721d04fddc0f86417bc95a2f0824040c0eca9"
integrity sha512-6aND1UOAcCn42WlVrQbIU7a+ZFD4o3Gy2yE1BeDLTCFfK6oqc1QpRrH1plGOUypeabxCTADrw5vhl5W/45kutg==
xterm@5.0.0-beta.44:
version "5.0.0-beta.44"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.0.0-beta.44.tgz#854ed16c06808295777afc4ef7b78ccd55e59d4a"
integrity sha512-raKvoikUjKZTO9duYliDp5hSKAwYia9P51QCumHY30V/bRZ2fq9ryyKQ65PxW8LzGYK8o7x7vNRUHVWbS073Tw==
yallist@^4.0.0:
version "4.0.0"
+1 -9
View File
@@ -108,14 +108,6 @@ export function markAsSingleton<T extends IDisposable>(singleton: T): T {
return singleton;
}
export class MultiDisposeError extends Error {
constructor(
public readonly errors: any[]
) {
super(`Encountered errors while disposing of store. Errors: [${errors.join(', ')}]`);
}
}
export interface IDisposable {
dispose(): void;
}
@@ -146,7 +138,7 @@ export function dispose<T extends IDisposable>(arg: T | IterableIterator<T> | un
if (errors.length === 1) {
throw errors[0];
} else if (errors.length > 1) {
throw new MultiDisposeError(errors);
throw new AggregateError(errors, 'Encountered errors while disposing of store');
}
return Array.isArray(arg) ? [] : arg;
+9 -9
View File
@@ -5,7 +5,7 @@
import * as assert from 'assert';
import { Emitter } from 'vs/base/common/event';
import { DisposableStore, dispose, IDisposable, markAsSingleton, MultiDisposeError, ReferenceCollection, SafeDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { DisposableStore, dispose, IDisposable, markAsSingleton, ReferenceCollection, SafeDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { ensureNoDisposablesAreLeakedInTestSuite, throwIfDisposablesAreLeaked } from 'vs/base/test/common/utils';
class Disposable implements IDisposable {
@@ -88,10 +88,10 @@ suite('Lifecycle', () => {
assert.ok(disposedValues.has(1));
assert.ok(disposedValues.has(4));
assert.ok(thrownError instanceof MultiDisposeError);
assert.strictEqual((thrownError as MultiDisposeError).errors.length, 2);
assert.strictEqual((thrownError as MultiDisposeError).errors[0].message, 'I am error 1');
assert.strictEqual((thrownError as MultiDisposeError).errors[1].message, 'I am error 2');
assert.ok(thrownError instanceof AggregateError);
assert.strictEqual((thrownError as AggregateError).errors.length, 2);
assert.strictEqual((thrownError as AggregateError).errors[0].message, 'I am error 1');
assert.strictEqual((thrownError as AggregateError).errors[1].message, 'I am error 2');
});
test('Action bar has broken accessibility #100273', function () {
@@ -167,10 +167,10 @@ suite('DisposableStore', () => {
assert.ok(disposedValues.has(1));
assert.ok(disposedValues.has(4));
assert.ok(thrownError instanceof MultiDisposeError);
assert.strictEqual((thrownError as MultiDisposeError).errors.length, 2);
assert.strictEqual((thrownError as MultiDisposeError).errors[0].message, 'I am error 1');
assert.strictEqual((thrownError as MultiDisposeError).errors[1].message, 'I am error 2');
assert.ok(thrownError instanceof AggregateError);
assert.strictEqual((thrownError as AggregateError).errors.length, 2);
assert.strictEqual((thrownError as AggregateError).errors[0].message, 'I am error 1');
assert.strictEqual((thrownError as AggregateError).errors[1].message, 'I am error 2');
});
});
@@ -27,7 +27,9 @@ import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
import { NativeHostService } from 'vs/platform/native/electron-sandbox/nativeHostService';
import { applyZoom, zoomIn, zoomOut } from 'vs/platform/window/electron-sandbox/window';
const MAX_URL_LENGTH = 2045;
// GitHub has let us know that we could up our limit here to 8k. We chose 7500 to play it safe.
// ref https://github.com/microsoft/vscode/issues/159191
const MAX_URL_LENGTH = 7500;
interface SearchResult {
html_url: string;
@@ -11,7 +11,7 @@ import { Action, IAction, Separator } from 'vs/base/common/actions';
import { canceled } from 'vs/base/common/errors';
import { ResolvedKeybinding } from 'vs/base/common/keybindings';
import { Lazy } from 'vs/base/common/lazy';
import { Disposable, dispose, MutableDisposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Disposable, MutableDisposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import 'vs/css!./media/action';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
@@ -101,138 +101,127 @@ export interface ICodeMenuOptions {
optionsAsChildren?: boolean;
}
export interface ICodeActionMenuTemplateData {
root: HTMLElement;
text: HTMLElement;
detail: HTMLElement;
decoratorRight: HTMLElement;
disposables: IDisposable[];
icon: HTMLElement;
interface ICodeActionMenuTemplateData {
readonly root: HTMLElement;
readonly text: HTMLElement;
readonly disposables: DisposableStore;
readonly icon: HTMLElement;
}
enum TemplateIds {
Header = 'header',
Separator = 'separator',
Base = 'base',
}
const TEMPLATE_ID = 'codeActionWidget';
const codeActionLineHeight = 24;
const headerLineHeight = 26;
// TODO: Take a look at user storage for this so it is preserved across windows and on reload.
let showDisabled = false;
class CodeMenuRenderer implements IListRenderer<ICodeActionMenuItem, ICodeActionMenuTemplateData> {
class CodeActionItemRenderer implements IListRenderer<ICodeActionMenuItem, ICodeActionMenuTemplateData> {
constructor(
private readonly acceptKeybindings: [string, string],
@IKeybindingService private readonly keybindingService: IKeybindingService,
) { }
get templateId(): string { return TEMPLATE_ID; }
get templateId(): string { return TemplateIds.Base; }
renderTemplate(container: HTMLElement): ICodeActionMenuTemplateData {
const data: ICodeActionMenuTemplateData = Object.create(null);
data.disposables = [];
data.root = container;
data.text = document.createElement('span');
const iconContainer = document.createElement('div');
iconContainer.className = 'icon-container';
data.icon = document.createElement('div');
iconContainer.append(data.icon);
container.append(iconContainer);
container.append(data.text);
return data;
const icon = document.createElement('div');
iconContainer.append(icon);
const text = document.createElement('span');
container.append(text);
return {
root: container,
icon,
text,
disposables: new DisposableStore(),
};
}
renderElement(element: ICodeActionMenuItem, index: number, templateData: ICodeActionMenuTemplateData): void {
const data: ICodeActionMenuTemplateData = templateData;
const isSeparator = element.isSeparator;
const isHeader = element.isHeader;
const text = element.action.label;
element.isEnabled = element.action.enabled;
// Renders differently based on element type.
if (isSeparator) {
data.root.classList.add('separator');
data.root.style.height = '10px';
} else if (isHeader) {
const text = element.headerTitle;
data.text.textContent = text;
element.isEnabled = false;
data.root.classList.add('group-header');
} else {
const text = element.action.label;
element.isEnabled = element.action.enabled;
if (element.action instanceof CodeActionAction) {
const openedFromString = (element.params?.options.fromLightbulb) ? CodeActionTriggerSource.Lightbulb : element.params?.trigger.triggerAction;
if (element.action instanceof CodeActionAction) {
const openedFromString = (element.params?.options.fromLightbulb) ? CodeActionTriggerSource.Lightbulb : element.params?.trigger.triggerAction;
// Check documentation type
element.isDocumentation = element.action.action.kind === CodeActionMenu.documentationID;
if (element.isDocumentation) {
element.isEnabled = false;
data.root.classList.add('documentation');
// Check documentation type
element.isDocumentation = element.action.action.kind === CodeActionMenu.documentationID;
const container = data.root;
if (element.isDocumentation) {
element.isEnabled = false;
data.root.classList.add('documentation');
const actionbarContainer = dom.append(container, dom.$('.codeActionWidget-action-bar'));
const container = data.root;
const reRenderAction = showDisabled ?
<IAction>{
id: 'hideMoreCodeActions',
label: localize('hideMoreCodeActions', 'Hide Disabled'),
enabled: true,
run: () => CodeActionMenu.toggleDisabledOptions(element.params)
} :
<IAction>{
id: 'showMoreCodeActions',
label: localize('showMoreCodeActions', 'Show Disabled'),
enabled: true,
run: () => CodeActionMenu.toggleDisabledOptions(element.params)
};
const actionbarContainer = dom.append(container, dom.$('.codeActionWidget-action-bar'));
const actionbar = new ActionBar(actionbarContainer);
data.disposables.add(actionbar);
const reRenderAction = showDisabled ?
<IAction>{
id: 'hideMoreCodeActions',
label: localize('hideMoreCodeActions', 'Hide Disabled'),
enabled: true,
run: () => CodeActionMenu.toggleDisabledOptions(element.params)
} :
<IAction>{
id: 'showMoreCodeActions',
label: localize('showMoreCodeActions', 'Show Disabled'),
enabled: true,
run: () => CodeActionMenu.toggleDisabledOptions(element.params)
};
const actionbar = new ActionBar(actionbarContainer);
data.disposables.push(actionbar);
if (openedFromString === CodeActionTriggerSource.Refactor && (element.params.codeActions.validActions.length > 0 || element.params.codeActions.allActions.length === element.params.codeActions.validActions.length)) {
actionbar.push([element.action, reRenderAction], { icon: false, label: true });
} else {
actionbar.push([element.action], { icon: false, label: true });
}
if (openedFromString === CodeActionTriggerSource.Refactor && (element.params.codeActions.validActions.length > 0 || element.params.codeActions.allActions.length === element.params.codeActions.validActions.length)) {
actionbar.push([element.action, reRenderAction], { icon: false, label: true });
} else {
data.text.textContent = text;
actionbar.push([element.action], { icon: false, label: true });
}
} else {
data.text.textContent = text;
// Icons and Label modifaction based on group
const group = element.action.action.kind;
if (CodeActionKind.SurroundWith.contains(new CodeActionKind(String(group)))) {
data.icon.className = Codicon.symbolArray.classNames;
} else if (CodeActionKind.Extract.contains(new CodeActionKind(String(group)))) {
data.icon.className = Codicon.wrench.classNames;
} else if (CodeActionKind.Convert.contains(new CodeActionKind(String(group)))) {
data.icon.className = Codicon.zap.classNames;
data.icon.style.color = `var(--vscode-editorLightBulbAutoFix-foreground)`;
} else if (CodeActionKind.QuickFix.contains(new CodeActionKind(String(group)))) {
data.icon.className = Codicon.lightBulb.classNames;
data.icon.style.color = `var(--vscode-editorLightBulb-foreground)`;
} else {
data.icon.className = Codicon.lightBulb.classNames;
data.icon.style.color = `var(--vscode-editorLightBulb-foreground)`;
}
// Icons and Label modifaction based on group
const group = element.action.action.kind;
if (CodeActionKind.SurroundWith.contains(new CodeActionKind(String(group)))) {
data.icon.className = Codicon.symbolArray.classNames;
} else if (CodeActionKind.Extract.contains(new CodeActionKind(String(group)))) {
data.icon.className = Codicon.wrench.classNames;
} else if (CodeActionKind.Convert.contains(new CodeActionKind(String(group)))) {
data.icon.className = Codicon.zap.classNames;
data.icon.style.color = `var(--vscode-editorLightBulbAutoFix-foreground)`;
} else if (CodeActionKind.QuickFix.contains(new CodeActionKind(String(group)))) {
data.icon.className = Codicon.lightBulb.classNames;
data.icon.style.color = `var(--vscode-editorLightBulb-foreground)`;
} else {
data.icon.className = Codicon.lightBulb.classNames;
data.icon.style.color = `var(--vscode-editorLightBulb-foreground)`;
}
// Check if action has disabled reason
if (element.action.action.disabled) {
data.root.title = element.action.action.disabled;
} else {
const updateLabel = () => {
const [accept, preview] = this.acceptKeybindings;
// Check if action has disabled reason
if (element.action.action.disabled) {
data.root.title = element.action.action.disabled;
} else {
const updateLabel = () => {
const [accept, preview] = this.acceptKeybindings;
data.root.title = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Apply, Shift+F2 to Preview"'] }, "{0} to Apply, {1} to Preview", this.keybindingService.lookupKeybinding(accept)?.getLabel(), this.keybindingService.lookupKeybinding(preview)?.getLabel());
data.root.title = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Apply, Shift+F2 to Preview"'] }, "{0} to Apply, {1} to Preview", this.keybindingService.lookupKeybinding(accept)?.getLabel(), this.keybindingService.lookupKeybinding(preview)?.getLabel());
};
updateLabel();
}
};
updateLabel();
}
}
}
if (!element.isEnabled) {
@@ -243,8 +232,59 @@ class CodeMenuRenderer implements IListRenderer<ICodeActionMenuItem, ICodeAction
data.root.classList.remove('option-disabled');
}
}
disposeTemplate(templateData: ICodeActionMenuTemplateData): void {
templateData.disposables = dispose(templateData.disposables);
templateData.disposables.dispose();
}
}
interface HeaderTemplateData {
readonly root: HTMLElement;
readonly text: HTMLElement;
}
class HeaderRenderer implements IListRenderer<ICodeActionMenuItem, HeaderTemplateData> {
get templateId(): string { return TemplateIds.Header; }
renderTemplate(container: HTMLElement): HeaderTemplateData {
container.classList.add('group-header', 'option-disabled');
const text = document.createElement('span');
container.append(text);
return {
root: container,
text,
};
}
renderElement(element: ICodeActionMenuItem, _index: number, templateData: HeaderTemplateData): void {
templateData.text.textContent = element.headerTitle;
element.isEnabled = false;
}
disposeTemplate(_templateData: HeaderTemplateData): void {
// noop
}
}
class SeparatorRenderer implements IListRenderer<ICodeActionMenuItem, void> {
get templateId(): string { return TemplateIds.Separator; }
renderTemplate(container: HTMLElement): void {
container.classList.add('separator');
container.style.height = '10px';
}
renderElement(_element: ICodeActionMenuItem, _index: number, _templateData: void): void {
// noop
}
disposeTemplate(_templateData: void): void {
// noop
}
}
@@ -270,13 +310,12 @@ export class CodeActionMenu extends Disposable implements IEditorContribution {
}
private readonly _keybindingResolver: CodeActionKeybindingResolver;
private listRenderer: CodeMenuRenderer;
constructor(
private readonly _editor: ICodeEditor,
private readonly _delegate: CodeActionWidgetDelegate,
@IContextMenuService private readonly _contextMenuService: IContextMenuService,
@IKeybindingService keybindingService: IKeybindingService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@IThemeService _themeService: IThemeService,
@@ -291,7 +330,6 @@ export class CodeActionMenu extends Disposable implements IEditorContribution {
});
this._ctxMenuWidgetVisible = Context.Visible.bindTo(this._contextKeyService);
this.listRenderer = new CodeMenuRenderer([acceptSelectedCodeActionCommand, previewSelectedCodeActionCommand], keybindingService);
}
get isVisible(): boolean {
@@ -384,34 +422,43 @@ export class CodeActionMenu extends Disposable implements IEditorContribution {
return 10;
} else if (element.isHeader) {
return headerLineHeight;
} else {
return codeActionLineHeight;
}
return codeActionLineHeight;
},
getTemplateId(element) {
return 'codeActionWidget';
}
}, [this.listRenderer],
{
keyboardSupport: false,
accessibilityProvider: {
getAriaLabel: element => {
if (element.action instanceof CodeActionAction) {
let label = element.action.label;
if (!element.action.enabled) {
if (element.action instanceof CodeActionAction) {
label = localize({ key: 'customCodeActionWidget.labels', comment: ['Code action labels for accessibility.'] }, "{0}, Disabled Reason: {1}", label, element.action.action.disabled);
}
}
return label;
}
return null;
},
getWidgetAriaLabel: () => localize({ key: 'customCodeActionWidget', comment: ['A Code Action Option'] }, "Code Action Widget"),
getRole: () => 'option',
getWidgetRole: () => 'code-action-widget'
if (element.isHeader) {
return TemplateIds.Header;
} else if (element.isSeparator) {
return TemplateIds.Separator;
} else {
return TemplateIds.Base;
}
}
);
}, [
new CodeActionItemRenderer([acceptSelectedCodeActionCommand, previewSelectedCodeActionCommand], this.keybindingService),
new HeaderRenderer(),
new SeparatorRenderer(),
], {
keyboardSupport: false,
accessibilityProvider: {
getAriaLabel: element => {
if (element.action instanceof CodeActionAction) {
let label = element.action.label;
if (!element.action.enabled) {
if (element.action instanceof CodeActionAction) {
label = localize({ key: 'customCodeActionWidget.labels', comment: ['Code action labels for accessibility.'] }, "{0}, Disabled Reason: {1}", label, element.action.action.disabled);
}
}
return label;
}
return null;
},
getWidgetAriaLabel: () => localize({ key: 'customCodeActionWidget', comment: ['A Code Action Option'] }, "Code Action Widget"),
getRole: () => 'option',
getWidgetRole: () => 'code-action-widget'
}
});
const pointerBlockDiv = document.createElement('div');
this.pointerBlock = element.appendChild(pointerBlockDiv);
@@ -559,8 +606,8 @@ export class CodeActionMenu extends Disposable implements IEditorContribution {
if (!this.codeActionList.value) {
return;
}
const element = document.getElementById(this.codeActionList.value?.getElementID(index))?.getElementsByTagName('span')[0].offsetWidth;
arr.push(Number(element));
const element = document.getElementById(this.codeActionList.value?.getElementID(index))?.querySelector('span')?.offsetWidth;
arr.push(element ?? 0);
});
// resize observer - can be used in the future since list widget supports dynamic height but not width
@@ -943,14 +943,6 @@ export class ConfigurationChangeEvent implements IConfigurationChangeEvent {
}
}
export class AllKeysConfigurationChangeEvent extends ConfigurationChangeEvent {
constructor(configuration: Configuration, workspace: Workspace, source: ConfigurationTarget, sourceConfig: any) {
super({ keys: configuration.allKeys(), overrides: [] }, undefined, configuration, workspace);
this.source = source;
this.sourceConfig = sourceConfig;
}
}
function compare(from: ConfigurationModel | undefined, to: ConfigurationModel | undefined): IConfigurationCompareResult {
const { added, removed, updated } = compareConfigurationContents(to, from);
const overrides: [string, string[]][] = [];
@@ -5,8 +5,7 @@
import * as assert from 'assert';
import { join } from 'vs/base/common/path';
import { URI } from 'vs/base/common/uri';
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { AllKeysConfigurationChangeEvent, Configuration, ConfigurationChangeEvent, ConfigurationModel, ConfigurationModelParser, mergeChanges } from 'vs/platform/configuration/common/configurationModels';
import { Configuration, ConfigurationChangeEvent, ConfigurationModel, ConfigurationModelParser, mergeChanges } from 'vs/platform/configuration/common/configurationModels';
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { DefaultConfigurationModel } from 'vs/platform/configuration/common/configurations';
import { Registry } from 'vs/platform/registry/common/platform';
@@ -1014,101 +1013,6 @@ suite('ConfigurationChangeEvent', () => {
});
suite('AllKeysConfigurationChangeEvent', () => {
test('changeEvent', () => {
const configuration = new Configuration(new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel());
configuration.updateDefaultConfiguration(toConfigurationModel({
'editor.lineNumbers': 'off',
'[markdown]': {
'editor.wordWrap': 'off'
}
}));
configuration.updateLocalUserConfiguration(toConfigurationModel({
'[json]': {
'editor.lineNumbers': 'relative'
}
}));
configuration.updateWorkspaceConfiguration(toConfigurationModel({ 'window.title': 'custom' }));
configuration.updateFolderConfiguration(URI.file('file1'), toConfigurationModel({ 'window.zoomLevel': 2, 'window.restoreFullscreen': true }));
configuration.updateFolderConfiguration(URI.file('file2'), toConfigurationModel({ 'workbench.editor.enablePreview': true, 'window.restoreWindows': true }));
const workspace = new Workspace('a', [new WorkspaceFolder({ index: 0, name: 'a', uri: URI.file('file1') }), new WorkspaceFolder({ index: 1, name: 'b', uri: URI.file('file2') }), new WorkspaceFolder({ index: 2, name: 'c', uri: URI.file('folder3') })]);
const testObject = new AllKeysConfigurationChangeEvent(configuration, workspace, ConfigurationTarget.USER, null);
assert.deepStrictEqual(testObject.affectedKeys, ['editor.lineNumbers', '[markdown]', '[json]', 'window.title', 'window.zoomLevel', 'window.restoreFullscreen', 'workbench.editor.enablePreview', 'window.restoreWindows']);
assert.ok(testObject.affectsConfiguration('window.title'));
assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('file1') }));
assert.ok(testObject.affectsConfiguration('window.title', { resource: URI.file('file2') }));
assert.ok(testObject.affectsConfiguration('window'));
assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('file1') }));
assert.ok(testObject.affectsConfiguration('window', { resource: URI.file('file2') }));
assert.ok(testObject.affectsConfiguration('window.zoomLevel'));
assert.ok(testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file('file1') }));
assert.ok(!testObject.affectsConfiguration('window.zoomLevel', { resource: URI.file('file2') }));
assert.ok(testObject.affectsConfiguration('window.restoreFullscreen'));
assert.ok(testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file('file1') }));
assert.ok(!testObject.affectsConfiguration('window.restoreFullscreen', { resource: URI.file('file2') }));
assert.ok(testObject.affectsConfiguration('window.restoreWindows'));
assert.ok(testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file('file2') }));
assert.ok(!testObject.affectsConfiguration('window.restoreWindows', { resource: URI.file('file1') }));
assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview'));
assert.ok(testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file('file2') }));
assert.ok(!testObject.affectsConfiguration('workbench.editor.enablePreview', { resource: URI.file('file1') }));
assert.ok(testObject.affectsConfiguration('workbench.editor'));
assert.ok(testObject.affectsConfiguration('workbench.editor', { resource: URI.file('file2') }));
assert.ok(!testObject.affectsConfiguration('workbench.editor', { resource: URI.file('file1') }));
assert.ok(testObject.affectsConfiguration('workbench'));
assert.ok(testObject.affectsConfiguration('workbench', { resource: URI.file('file2') }));
assert.ok(!testObject.affectsConfiguration('workbench', { resource: URI.file('file1') }));
assert.ok(!testObject.affectsConfiguration('files'));
assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file('file1') }));
assert.ok(!testObject.affectsConfiguration('files', { resource: URI.file('file2') }));
assert.ok(testObject.affectsConfiguration('editor'));
assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file1') }));
assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file2') }));
assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file1'), overrideIdentifier: 'json' }));
assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file1'), overrideIdentifier: 'markdown' }));
assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file1'), overrideIdentifier: 'typescript' }));
assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file2'), overrideIdentifier: 'json' }));
assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file2'), overrideIdentifier: 'markdown' }));
assert.ok(testObject.affectsConfiguration('editor', { resource: URI.file('file2'), overrideIdentifier: 'typescript' }));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers'));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file1') }));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file2') }));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file1'), overrideIdentifier: 'json' }));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file1'), overrideIdentifier: 'markdown' }));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file1'), overrideIdentifier: 'typescript' }));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file2'), overrideIdentifier: 'json' }));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file2'), overrideIdentifier: 'markdown' }));
assert.ok(testObject.affectsConfiguration('editor.lineNumbers', { resource: URI.file('file2'), overrideIdentifier: 'typescript' }));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap'));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file1') }));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file2') }));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file1'), overrideIdentifier: 'json' }));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file1'), overrideIdentifier: 'markdown' }));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file1'), overrideIdentifier: 'typescript' }));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file2'), overrideIdentifier: 'json' }));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file2'), overrideIdentifier: 'markdown' }));
assert.ok(!testObject.affectsConfiguration('editor.wordWrap', { resource: URI.file('file2'), overrideIdentifier: 'typescript' }));
assert.ok(!testObject.affectsConfiguration('editor.fontSize'));
assert.ok(!testObject.affectsConfiguration('editor.fontSize', { resource: URI.file('file1') }));
assert.ok(!testObject.affectsConfiguration('editor.fontSize', { resource: URI.file('file2') }));
});
});
function toConfigurationModel(obj: any): ConfigurationModel {
const parser = new ConfigurationModelParser('test');
parser.parse(JSON.stringify(obj));
@@ -10,7 +10,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { ICommandDetectionCapability, TerminalCapability, ITerminalCommand, IHandleCommandOptions, ICommandInvalidationRequest, CommandInvalidationReason } from 'vs/platform/terminal/common/capabilities/capabilities';
import { ISerializedCommand, ISerializedCommandDetectionCapability } from 'vs/platform/terminal/common/terminalProcess';
// Importing types is safe in any layer
// eslint-disable-next-line code-import-patterns
// eslint-disable-next-line local/code-import-patterns
import type { IBuffer, IBufferLine, IDisposable, IMarker, Terminal } from 'xterm-headless';
export interface ICurrentPartialCommand {
@@ -6,7 +6,7 @@
import { Emitter } from 'vs/base/common/event';
import { IPartialCommandDetectionCapability, TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities';
// Importing types is safe in any layer
// eslint-disable-next-line code-import-patterns
// eslint-disable-next-line local/code-import-patterns
import { IMarker, Terminal } from 'xterm-headless';
const enum Constants {
@@ -580,6 +580,9 @@ export interface IShellLaunchConfigDto {
env?: ITerminalEnvironment;
useShellEnvironment?: boolean;
hideFromUser?: boolean;
reconnectionProperties?: IReconnectionProperties;
type?: 'Task' | 'Local';
isFeatureTerminal?: boolean;
}
/**
@@ -12,7 +12,7 @@ import { ICommandDetectionCapability, ICwdDetectionCapability, TerminalCapabilit
import { PartialCommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/partialCommandDetectionCapability';
import { ILogService } from 'vs/platform/log/common/log';
// Importing types is safe in any layer
// eslint-disable-next-line code-import-patterns
// eslint-disable-next-line local/code-import-patterns
import type { ITerminalAddon, Terminal } from 'xterm-headless';
import { ISerializedCommandDetectionCapability } from 'vs/platform/terminal/common/terminalProcess';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
+4 -1
View File
@@ -185,7 +185,10 @@ export class RemoteTerminalChannel extends Disposable implements IServerChannel<
: URI.revive(uriTransformer.transformIncoming(args.shellLaunchConfig.cwd))
),
env: args.shellLaunchConfig.env,
useShellEnvironment: args.shellLaunchConfig.useShellEnvironment
useShellEnvironment: args.shellLaunchConfig.useShellEnvironment,
reconnectionProperties: args.shellLaunchConfig.reconnectionProperties,
type: args.shellLaunchConfig.type,
isFeatureTerminal: args.shellLaunchConfig.isFeatureTerminal
};
@@ -4,20 +4,18 @@
*--------------------------------------------------------------------------------------------*/
import { DisposableStore, dispose } from 'vs/base/common/lifecycle';
import { equals } from 'vs/base/common/objects';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { EditorActivation } from 'vs/platform/editor/common/editor';
import { getNotebookEditorFromEditorPane, INotebookEditor, INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService';
import { ExtHostContext, ExtHostNotebookEditorsShape, ICellEditOperationDto, INotebookDocumentShowOptions, INotebookEditorViewColumnInfo, MainThreadNotebookEditorsShape, NotebookEditorRevealType } from '../common/extHost.protocol';
import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
import { ILogService } from 'vs/platform/log/common/log';
import { URI, UriComponents } from 'vs/base/common/uri';
import { EditorActivation } from 'vs/platform/editor/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { columnToEditorGroup, editorGroupToColumn } from 'vs/workbench/services/editor/common/editorGroupColumn';
import { equals } from 'vs/base/common/objects';
import { NotebookDto } from 'vs/workbench/api/browser/mainThreadNotebookDto';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ExtHostContext, ExtHostNotebookEditorsShape, INotebookDocumentShowOptions, INotebookEditorViewColumnInfo, MainThreadNotebookEditorsShape, NotebookEditorRevealType } from '../common/extHost.protocol';
class MainThreadNotebook {
@@ -43,7 +41,6 @@ export class MainThreadNotebookEditors implements MainThreadNotebookEditorsShape
constructor(
extHostContext: IExtHostContext,
@IEditorService private readonly _editorService: IEditorService,
@ILogService private readonly _logService: ILogService,
@INotebookEditorService private readonly _notebookEditorService: INotebookEditorService,
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
@IConfigurationService private readonly _configurationService: IConfigurationService
@@ -99,23 +96,6 @@ export class MainThreadNotebookEditors implements MainThreadNotebookEditorsShape
}
}
async $tryApplyEdits(editorId: string, modelVersionId: number, cellEdits: ICellEditOperationDto[]): Promise<boolean> {
const wrapper = this._mainThreadEditors.get(editorId);
if (!wrapper) {
return false;
}
const { editor } = wrapper;
if (!editor.textModel) {
this._logService.warn('Notebook editor has NO model', editorId);
return false;
}
if (editor.textModel.versionId !== modelVersionId) {
return false;
}
//todo@jrieken use proper selection logic!
return editor.textModel.applyEdits(cellEdits.map(NotebookDto.fromCellEditOperationDto), true, undefined, () => undefined, undefined, true);
}
async $tryShowNotebookDocument(resource: UriComponents, viewType: string, options: INotebookDocumentShowOptions): Promise<string> {
const editorOptions: INotebookEditorOptions = {
cellSelections: options.selections,
@@ -65,9 +65,17 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre
if (value.extensionId === extensionId) {
return value.content;
}
} catch (e) {
this.logService.error(e);
throw new Error('Cannot get password');
} catch (parseError) {
this.logService.error(parseError);
// If we can't parse the decrypted value, then it's not a valid secret so we should try to delete it
try {
await this.credentialsService.deletePassword(fullKey, key);
} catch (e) {
this.logService.error(e);
}
throw new Error('Unable to parse decrypted password');
}
}
@@ -978,7 +978,6 @@ export interface MainThreadNotebookEditorsShape extends IDisposable {
$tryShowNotebookDocument(uriComponents: UriComponents, viewType: string, options: INotebookDocumentShowOptions): Promise<string>;
$tryRevealRange(id: string, range: ICellRange, revealType: NotebookEditorRevealType): Promise<void>;
$trySetSelections(id: string, range: ICellRange[]): void;
$tryApplyEdits(editorId: string, modelVersionId: number, cellEdits: ICellEditOperationDto[]): Promise<boolean>;
}
export interface MainThreadNotebookDocumentsShape extends IDisposable {
@@ -3,74 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ICellEditOperationDto, MainThreadNotebookEditorsShape } from 'vs/workbench/api/common/extHost.protocol';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { illegalArgument } from 'vs/base/common/errors';
import { MainThreadNotebookEditorsShape } from 'vs/workbench/api/common/extHost.protocol';
import * as extHostConverter from 'vs/workbench/api/common/extHostTypeConverters';
import { CellEditType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import * as vscode from 'vscode';
import { ExtHostNotebookDocument } from './extHostNotebookDocument';
import { illegalArgument } from 'vs/base/common/errors';
interface INotebookEditData {
documentVersionId: number;
cellEdits: ICellEditOperationDto[];
}
class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit {
private readonly _documentVersionId: number;
private _finalized: boolean = false;
private _collectedEdits: ICellEditOperationDto[] = [];
constructor(documentVersionId: number) {
this._documentVersionId = documentVersionId;
}
finalize(): INotebookEditData {
this._finalized = true;
return {
documentVersionId: this._documentVersionId,
cellEdits: this._collectedEdits
};
}
private _throwIfFinalized() {
if (this._finalized) {
throw new Error('Edit is only valid while callback runs');
}
}
replaceMetadata(value: { [key: string]: any }): void {
this._throwIfFinalized();
this._collectedEdits.push({
editType: CellEditType.DocumentMetadata,
metadata: value
});
}
replaceCellMetadata(index: number, metadata: Record<string, any>): void {
this._throwIfFinalized();
this._collectedEdits.push({
editType: CellEditType.PartialMetadata,
index,
metadata
});
}
replaceCells(from: number, to: number, cells: vscode.NotebookCellData[]): void {
this._throwIfFinalized();
if (from === to && cells.length === 0) {
return;
}
this._collectedEdits.push({
editType: CellEditType.Replace,
index: from,
count: to - from,
cells: cells.map(extHostConverter.NotebookCellData.from)
});
}
}
export class ExtHostNotebookEditor {
@@ -136,11 +74,6 @@ export class ExtHostNotebookEditor {
get viewColumn() {
return that._viewColumn;
},
edit(callback) {
const edit = new NotebookEditorCellEditBuilder(this.document.version);
callback(edit);
return that._applyEdit(edit.finalize());
},
};
ExtHostNotebookEditor.apiEditorsToExtHost.set(this._editor, this);
@@ -171,40 +104,4 @@ export class ExtHostNotebookEditor {
_acceptViewColumn(value: vscode.ViewColumn | undefined) {
this._viewColumn = value;
}
private _applyEdit(editData: INotebookEditData): Promise<boolean> {
// return when there is nothing to do
if (editData.cellEdits.length === 0) {
return Promise.resolve(true);
}
const compressedEdits: ICellEditOperationDto[] = [];
let compressedEditsIndex = -1;
for (let i = 0; i < editData.cellEdits.length; i++) {
if (compressedEditsIndex < 0) {
compressedEdits.push(editData.cellEdits[i]);
compressedEditsIndex++;
continue;
}
const prevIndex = compressedEditsIndex;
const prev = compressedEdits[prevIndex];
const edit = editData.cellEdits[i];
if (prev.editType === CellEditType.Replace && edit.editType === CellEditType.Replace) {
if (prev.index === edit.index) {
prev.cells.push(...(editData.cellEdits[i] as any).cells);
prev.count += (editData.cellEdits[i] as any).count;
continue;
}
}
compressedEdits.push(editData.cellEdits[i]);
compressedEditsIndex++;
}
return this._proxy.$tryApplyEdits(this.id, editData.documentVersionId, compressedEdits);
}
}
+6 -26
View File
@@ -737,40 +737,20 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
// --- notebook
replaceNotebookMetadata(uri: URI, value: Record<string, any>, metadata?: vscode.WorkspaceEditEntryMetadata): void {
private replaceNotebookMetadata(uri: URI, value: Record<string, any>, metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.DocumentMetadata, metadata: value }, notebookMetadata: value });
}
replaceNotebookCells(uri: URI, range: vscode.NotebookRange, cells: vscode.NotebookCellData[], metadata?: vscode.WorkspaceEditEntryMetadata): void;
replaceNotebookCells(uri: URI, start: number, end: number, cells: vscode.NotebookCellData[], metadata?: vscode.WorkspaceEditEntryMetadata): void;
replaceNotebookCells(uri: URI, startOrRange: number | vscode.NotebookRange, endOrCells: number | vscode.NotebookCellData[], cellsOrMetadata?: vscode.NotebookCellData[] | vscode.WorkspaceEditEntryMetadata, metadata?: vscode.WorkspaceEditEntryMetadata): void {
let start: number | undefined;
let end: number | undefined;
let cellData: vscode.NotebookCellData[] = [];
let workspaceEditMetadata: vscode.WorkspaceEditEntryMetadata | undefined;
if (NotebookRange.isNotebookRange(startOrRange) && NotebookCellData.isNotebookCellDataArray(endOrCells) && !NotebookCellData.isNotebookCellDataArray(cellsOrMetadata)) {
start = startOrRange.start;
end = startOrRange.end;
cellData = endOrCells;
workspaceEditMetadata = cellsOrMetadata;
} else if (typeof startOrRange === 'number' && typeof endOrCells === 'number' && NotebookCellData.isNotebookCellDataArray(cellsOrMetadata)) {
start = startOrRange;
end = endOrCells;
cellData = cellsOrMetadata;
workspaceEditMetadata = metadata;
}
if (start === undefined || end === undefined) {
throw new Error('Invalid arguments');
}
private replaceNotebookCells(uri: URI, startOrRange: vscode.NotebookRange, cellData: vscode.NotebookCellData[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
const start = startOrRange.start;
const end = startOrRange.end;
if (start !== end || cellData.length > 0) {
this._edits.push({ _type: FileEditType.CellReplace, uri, index: start, count: end - start, cells: cellData, metadata: workspaceEditMetadata });
this._edits.push({ _type: FileEditType.CellReplace, uri, index: start, count: end - start, cells: cellData, metadata });
}
}
replaceNotebookCellMetadata(uri: URI, index: number, cellMetadata: Record<string, any>, metadata?: vscode.WorkspaceEditEntryMetadata): void {
private replaceNotebookCellMetadata(uri: URI, index: number, cellMetadata: Record<string, any>, metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.PartialMetadata, index, metadata: cellMetadata } });
}
@@ -427,18 +427,20 @@ export abstract class BasePanelPart extends CompositePart<PaneComposite> impleme
private onDidRegisterExtensions(): void {
this.extensionsRegistered = true;
this.removeNotExistingComposites();
this.saveCachedPanels();
}
private removeNotExistingComposites(): void {
// hide/remove composites
const panels = this.getPaneComposites();
for (const { id } of this.getCachedPanels()) { // should this value match viewlet (load on ctor)
for (const { id } of this.getCachedPanels()) {
if (panels.every(panel => panel.id !== id)) {
this.hideComposite(id);
if (this.viewDescriptorService.isViewContainerRemovedPermanently(id)) {
this.removeComposite(id);
} else {
this.hideComposite(id);
}
}
}
this.saveCachedPanels();
}
private hideComposite(compositeId: string): void {
+16 -4
View File
@@ -203,9 +203,7 @@ export class BrowserWindow extends Disposable {
invokeProtocolHandler();
// We cannot know whether the protocol handler succeeded.
// Display guidance in case it did not, e.g. the app is not installed locally.
if (matchesScheme(href, this.productService.urlProtocol)) {
const showProtocolUrlOpenedDialog = async () => {
const showResult = await this.dialogService.show(
Severity.Info,
localize('openExternalDialogTitle', "All done. You can close this tab now."),
@@ -223,8 +221,22 @@ export class BrowserWindow extends Disposable {
if (showResult.choice === 0) {
invokeProtocolHandler();
} else if (showResult.choice === 1) {
await this.openerService.open(URI.parse(`http://aka.ms/vscode-install`));
// Route the user to the appropriate install link
await this.openerService.open(URI.parse(
this.productService.quality === 'stable'
? `http://aka.ms/vscode-install`
: `http://aka.ms/vscode-install-insiders`
));
// Re-show the dialog so that the user can come back after installing and try again
showProtocolUrlOpenedDialog();
}
};
// We cannot know whether the protocol handler succeeded.
// Display guidance in case it did not, e.g. the app is not installed locally.
if (matchesScheme(href, this.productService.urlProtocol)) {
await showProtocolUrlOpenedDialog();
}
}
@@ -199,7 +199,7 @@
}
.extension-list-item > .details > .footer > .monaco-action-bar > .actions-container .action-label:not(.icon) {
border-radius: 0;
border-radius: 2px;
}
.extension-list-item > .details > .footer > .monaco-action-bar > .actions-container .extension-action.label {
@@ -8,22 +8,31 @@ import { Codicon } from 'vs/base/common/codicons';
import { language } from 'vs/base/common/platform';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
import { IdleValue } from 'vs/base/common/async';
export const LOCAL_HISTORY_DATE_FORMATTER: IdleValue<{ format: (timestamp: number) => string }> = new IdleValue(() => {
const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' };
interface ILocalHistoryDateFormatter {
format: (timestamp: number) => string;
}
let formatter: Intl.DateTimeFormat;
try {
formatter = new Intl.DateTimeFormat(language, options);
} catch (error) {
formatter = new Intl.DateTimeFormat(undefined, options); // error can happen when language is invalid (https://github.com/microsoft/vscode/issues/147086)
let localHistoryDateFormatter: ILocalHistoryDateFormatter | undefined = undefined;
export function getLocalHistoryDateFormatter(): ILocalHistoryDateFormatter {
if (!localHistoryDateFormatter) {
const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' };
let formatter: Intl.DateTimeFormat;
try {
formatter = new Intl.DateTimeFormat(language, options);
} catch (error) {
formatter = new Intl.DateTimeFormat(undefined, options); // error can happen when language is invalid (https://github.com/microsoft/vscode/issues/147086)
}
localHistoryDateFormatter = {
format: date => formatter.format(date)
};
}
return {
format: date => formatter.format(date)
};
});
return localHistoryDateFormatter;
}
export const LOCAL_HISTORY_MENU_CONTEXT_VALUE = 'localHistory:item';
export const LOCAL_HISTORY_MENU_CONTEXT_KEY = ContextKeyExpr.equals('timelineItem', LOCAL_HISTORY_MENU_CONTEXT_VALUE);
@@ -30,7 +30,7 @@ import { IModelService } from 'vs/editor/common/services/model';
import { ILanguageService } from 'vs/editor/common/languages/language';
import { ILabelService } from 'vs/platform/label/common/label';
import { firstOrDefault } from 'vs/base/common/arrays';
import { LOCAL_HISTORY_DATE_FORMATTER, LOCAL_HISTORY_ICON_RESTORE, LOCAL_HISTORY_MENU_CONTEXT_KEY } from 'vs/workbench/contrib/localHistory/browser/localHistory';
import { getLocalHistoryDateFormatter, LOCAL_HISTORY_ICON_RESTORE, LOCAL_HISTORY_MENU_CONTEXT_KEY } from 'vs/workbench/contrib/localHistory/browser/localHistory';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
const LOCAL_HISTORY_CATEGORY = { value: localize('localHistory.category', "Local History"), original: 'Local History' };
@@ -646,7 +646,7 @@ export async function findLocalHistoryEntry(workingCopyHistoryService: IWorkingC
const SEP = /\//g;
function toLocalHistoryEntryDateLabel(timestamp: number): string {
return `${LOCAL_HISTORY_DATE_FORMATTER.value.format(timestamp).replace(SEP, '-')}`; // preserving `/` will break editor labels, so replace it with a non-path symbol
return `${getLocalHistoryDateFormatter().format(timestamp).replace(SEP, '-')}`; // preserving `/` will break editor labels, so replace it with a non-path symbol
}
//#endregion
@@ -20,7 +20,7 @@ import { SaveSourceRegistry } from 'vs/workbench/common/editor';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { COMPARE_WITH_FILE_LABEL, toDiffEditorArguments } from 'vs/workbench/contrib/localHistory/browser/localHistoryCommands';
import { MarkdownString } from 'vs/base/common/htmlContent';
import { LOCAL_HISTORY_DATE_FORMATTER, LOCAL_HISTORY_ICON_ENTRY, LOCAL_HISTORY_MENU_CONTEXT_VALUE } from 'vs/workbench/contrib/localHistory/browser/localHistory';
import { getLocalHistoryDateFormatter, LOCAL_HISTORY_ICON_ENTRY, LOCAL_HISTORY_MENU_CONTEXT_VALUE } from 'vs/workbench/contrib/localHistory/browser/localHistory';
import { Schemas } from 'vs/base/common/network';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { getVirtualWorkspaceAuthority } from 'vs/platform/workspace/common/virtualWorkspace';
@@ -151,7 +151,7 @@ export class LocalHistoryTimeline extends Disposable implements IWorkbenchContri
return {
handle: entry.id,
label: SaveSourceRegistry.getSourceLabel(entry.source),
tooltip: new MarkdownString(`$(history) ${LOCAL_HISTORY_DATE_FORMATTER.value.format(entry.timestamp)}\n\n${SaveSourceRegistry.getSourceLabel(entry.source)}`, { supportThemeIcons: true }),
tooltip: new MarkdownString(`$(history) ${getLocalHistoryDateFormatter().format(entry.timestamp)}\n\n${SaveSourceRegistry.getSourceLabel(entry.source)}`, { supportThemeIcons: true }),
source: LocalHistoryTimeline.ID,
timestamp: entry.timestamp,
themeIcon: LOCAL_HISTORY_ICON_ENTRY,
@@ -384,6 +384,12 @@ export abstract class AbstractListSettingWidget<TDataItem extends object> extend
this.listDisposables.add(disposableTimeout(() => rowElement.focus()));
}
this.listDisposables.add(DOM.addDisposableListener(rowElement, 'click', (e) => {
// There is a parent list widget, which is the one that holds the list of settings.
// Prevent the parent widget from trying to interpret this click event.
e.stopPropagation();
}));
return rowElement;
}
@@ -1228,7 +1228,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
if (runSource === TaskRunSource.User) {
const workspaceTasks = await this.getWorkspaceTasks();
RunAutomaticTasks.promptForPermission(this, this._storageService, this._notificationService, this._workspaceTrustManagementService, this._openerService, this._configurationService, workspaceTasks);
RunAutomaticTasks.runWithPermission(this, this._storageService, this._notificationService, this._workspaceTrustManagementService, this._openerService, this._configurationService, workspaceTasks);
}
return executeTaskResult;
} catch (error) {
@@ -29,7 +29,10 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut
@ITaskService private readonly _taskService: ITaskService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IWorkspaceTrustManagementService private readonly _workspaceTrustManagementService: IWorkspaceTrustManagementService,
@ILogService private readonly _logService: ILogService) {
@ILogService private readonly _logService: ILogService,
@IStorageService private readonly _storageService: IStorageService,
@IOpenerService private readonly _openerService: IOpenerService,
@INotificationService private readonly _notificationService: INotificationService) {
super();
this._tryRunTasks();
}
@@ -42,21 +45,9 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut
await Event.toPromise(Event.once(this._taskService.onDidChangeTaskSystemInfo));
}
this._logService.trace('RunAutomaticTasks: Checking if automatic tasks should run.');
const isFolderAutomaticAllowed = this._configurationService.getValue(ALLOW_AUTOMATIC_TASKS) !== 'off';
await this._workspaceTrustManagementService.workspaceTrustInitialized;
const isWorkspaceTrusted = this._workspaceTrustManagementService.isWorkspaceTrusted();
// Only run if allowed. Prompting for permission occurs when a user first tries to run a task.
if (isFolderAutomaticAllowed && isWorkspaceTrusted) {
this._taskService.getWorkspaceTasks(TaskRunSource.FolderOpen).then(workspaceTaskResult => {
const { tasks } = RunAutomaticTasks._findAutoTasks(this._taskService, workspaceTaskResult);
this._logService.trace(`RunAutomaticTasks: Found ${tasks.length} automatic tasks tasks`);
if (tasks.length > 0) {
RunAutomaticTasks._runTasks(this._taskService, tasks);
}
});
}
const workspaceTasks = await this._taskService.getWorkspaceTasks(TaskRunSource.FolderOpen);
this._logService.trace(`RunAutomaticTasks: Found ${workspaceTasks.size} automatic tasks`);
await RunAutomaticTasks.runWithPermission(this._taskService, this._storageService, this._notificationService, this._workspaceTrustManagementService, this._openerService, this._configurationService, workspaceTasks);
}
private static _runTasks(taskService: ITaskService, tasks: Array<Task | Promise<Task | undefined>>) {
@@ -128,29 +119,31 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut
return { tasks, taskNames, locations };
}
public static async promptForPermission(taskService: ITaskService, storageService: IStorageService, notificationService: INotificationService, workspaceTrustManagementService: IWorkspaceTrustManagementService,
public static async runWithPermission(taskService: ITaskService, storageService: IStorageService, notificationService: INotificationService, workspaceTrustManagementService: IWorkspaceTrustManagementService,
openerService: IOpenerService, configurationService: IConfigurationService, workspaceTaskResult: Map<string, IWorkspaceFolderTaskResult>) {
const isWorkspaceTrusted = workspaceTrustManagementService.isWorkspaceTrusted;
if (!isWorkspaceTrusted) {
return;
}
if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'off') {
if (!isWorkspaceTrusted || configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'off') {
return;
}
const hasShownPromptForAutomaticTasks = storageService.getBoolean(HAS_PROMPTED_FOR_AUTOMATIC_TASKS, StorageScope.WORKSPACE, undefined);
const hasShownPromptForAutomaticTasks = storageService.getBoolean(HAS_PROMPTED_FOR_AUTOMATIC_TASKS, StorageScope.WORKSPACE, false);
const { tasks, taskNames, locations } = RunAutomaticTasks._findAutoTasks(taskService, workspaceTaskResult);
if (taskNames.length > 0) {
if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'on') {
RunAutomaticTasks._runTasks(taskService, tasks);
} else if (!hasShownPromptForAutomaticTasks) {
// We have automatic tasks, prompt to allow.
this._showPrompt(notificationService, storageService, openerService, configurationService, taskNames, locations).then(allow => {
if (allow) {
RunAutomaticTasks._runTasks(taskService, tasks);
}
});
}
if (taskNames.length === 0) {
return;
}
if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'on') {
RunAutomaticTasks._runTasks(taskService, tasks);
} else if (configurationService.getValue(ALLOW_AUTOMATIC_TASKS) === 'auto' && !hasShownPromptForAutomaticTasks) {
// by default, only prompt once per folder
// otherwise, this can be configured via the setting
this._showPrompt(notificationService, storageService, openerService, configurationService, taskNames, locations).then(allow => {
if (allow) {
storageService.store(HAS_PROMPTED_FOR_AUTOMATIC_TASKS, true, StorageScope.WORKSPACE, StorageTarget.USER);
RunAutomaticTasks._runTasks(taskService, tasks);
}
});
}
}
@@ -500,11 +500,11 @@ configurationRegistry.registerConfiguration({
type: 'string',
enum: ['on', 'auto', 'off'],
enumDescriptions: [
nls.localize('ttask.allowAutomaticTasks.on', "Always"),
nls.localize('task.allowAutomaticTasks.on', "Always"),
nls.localize('task.allowAutomaticTasks.auto', "Prompt for permission for each folder"),
nls.localize('task.allowAutomaticTasks.off', "Never"),
],
description: nls.localize('task.allowAutomaticTasks', "Enable automatic tasks in the folder."),
description: nls.localize('task.allowAutomaticTasks', "Enable automatic tasks in the folder - note that tasks won't run in an untrusted workspace."),
default: 'auto',
restricted: true
},
@@ -1323,7 +1323,6 @@ export class TerminalTaskSystem extends Disposable implements ITaskSystem {
}
// Either no group is used, no terminal with the group exists or splitting an existing terminal failed.
const createdTerminal = await this._terminalService.createTerminal({ location: TerminalLocation.Panel, config: launchConfigs });
this._logService.trace('Created a new task terminal');
createdTerminal.onDisposed((terminal) => this._fireTaskEvent({ kind: TaskEventKind.Terminated, exitReason: terminal.exitReason, taskId: task.getRecentlyUsedKey() }));
return createdTerminal;
}
@@ -209,7 +209,10 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack
args: shellLaunchConfig.args,
cwd: shellLaunchConfig.cwd,
env: shellLaunchConfig.env,
useShellEnvironment: shellLaunchConfig.useShellEnvironment
useShellEnvironment: shellLaunchConfig.useShellEnvironment,
reconnectionProperties: shellLaunchConfig.reconnectionProperties,
type: shellLaunchConfig.type,
isFeatureTerminal: shellLaunchConfig.isFeatureTerminal
};
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
@@ -13,7 +13,7 @@ import { getPathFromAmdModule } from 'vs/base/test/node/testUtils';
import { CancellationToken } from 'vs/base/common/cancellation';
import { RequestService } from 'vs/platform/request/node/requestService';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
// eslint-disable-next-line code-import-patterns
// eslint-disable-next-line local/code-import-patterns
import 'vs/workbench/workbench.desktop.main';
import { NullLogService } from 'vs/platform/log/common/log';
import { mock } from 'vs/base/test/common/mock';
@@ -99,7 +99,7 @@
padding: 0 20px;
}
img {
img, video {
max-width: 100%;
max-height: 100%;
}
@@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'none'; script-src 'sha256-JpX/ganPoxpavjxWCz9DUZgwVZ59o2lwSYTQrziPsdU=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
content="default-src 'none'; script-src 'sha256-EDTzzejMryXNJsvXPm3ha4m5Mi6h2Y//JRojh+K0+bY=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
<!-- Disable pinch zooming -->
<meta name="viewport"
@@ -100,7 +100,7 @@
padding: 0 20px;
}
img {
img, video {
max-width: 100%;
max-height: 100%;
}
@@ -11,7 +11,7 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Queue, Barrier, runWhenIdle, Promises } from 'vs/base/common/async';
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import { IWorkspaceContextService, Workspace as BaseWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, WorkspaceFolder, toWorkspaceFolder, isWorkspaceFolder, IWorkspaceFoldersWillChangeEvent, IEmptyWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier, IAnyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
import { ConfigurationModel, ConfigurationChangeEvent, AllKeysConfigurationChangeEvent, mergeChanges } from 'vs/platform/configuration/common/configurationModels';
import { ConfigurationModel, ConfigurationChangeEvent, mergeChanges } from 'vs/platform/configuration/common/configurationModels';
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, isConfigurationOverrides, IConfigurationData, IConfigurationValue, IConfigurationChange, ConfigurationTargetToString, IConfigurationUpdateOverrides, isConfigurationUpdateOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IPolicyConfiguration, NullPolicyConfiguration, PolicyConfiguration } from 'vs/platform/configuration/common/configurations';
import { Configuration } from 'vs/workbench/services/configuration/common/configurationModels';
@@ -692,9 +692,6 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat
const change = this._configuration.compare(currentConfiguration);
this.triggerConfigurationChange(change, { data: currentConfiguration.toData(), workspace: this.workspace }, ConfigurationTarget.WORKSPACE);
} else {
if (this._onDidChangeConfiguration.hasListeners()) {
this._onDidChangeConfiguration.fire(new AllKeysConfigurationChangeEvent(this._configuration, this.workspace, ConfigurationTarget.WORKSPACE, this.getTargetConfiguration(ConfigurationTarget.WORKSPACE)));
}
this.initialized = true;
}
@@ -43,7 +43,6 @@ export const allApiProposals = Object.freeze({
notebookDebugOptions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookDebugOptions.d.ts',
notebookDeprecated: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookDeprecated.d.ts',
notebookEditor: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookEditor.d.ts',
notebookEditorEdit: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookEditorEdit.d.ts',
notebookKernelSource: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookKernelSource.d.ts',
notebookLiveShare: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookLiveShare.d.ts',
notebookMessaging: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookMessaging.d.ts',
@@ -3,8 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/* eslint-disable code-import-patterns */
/* eslint-disable code-layering */
/* eslint-disable local/code-import-patterns */
/* eslint-disable local/code-layering */
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
+1 -1
View File
@@ -23,7 +23,7 @@ declare module 'vscode' {
*
* @return Thenable indicating that the webview editor has been moved.
*/
// eslint-disable-next-line vscode-dts-provider-naming
// eslint-disable-next-line local/vscode-dts-provider-naming
moveCustomTextEditor?(newDocument: TextDocument, existingWebviewPanel: WebviewPanel, token: CancellationToken): Thenable<void>;
}
}
@@ -16,7 +16,7 @@ declare module 'vscode' {
}
export interface InlineCompletionItemProviderNew {
// eslint-disable-next-line vscode-dts-provider-naming
// eslint-disable-next-line local/vscode-dts-provider-naming
handleDidShowCompletionItem?(completionItem: InlineCompletionItemNew): void;
}
@@ -29,7 +29,7 @@ declare module 'vscode' {
}
export interface InlineCompletionItemProvider {
// eslint-disable-next-line vscode-dts-provider-naming
// eslint-disable-next-line local/vscode-dts-provider-naming
handleDidShowCompletionItem?(completionItem: InlineCompletionItem): void;
}
+1 -1
View File
@@ -5,7 +5,7 @@
declare module 'vscode' {
// eslint-disable-next-line vscode-dts-region-comments
// eslint-disable-next-line local/vscode-dts-region-comments
// @roblourens: debugUI.simple: https://github.com/microsoft/vscode/issues/147264. Used for Jupyter's Run By Line.
// suppressSaveBeforeStart: https://github.com/microsoft/vscode/issues/147263. Used to enable debugging untitled/unsaved notebooks.
-56
View File
@@ -1,56 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/106744
export interface WorkspaceEdit {
replaceNotebookMetadata(uri: Uri, value: { [key: string]: any }): void;
/**
* @deprecated Please migrate to the new `notebookWorkspaceEdit` proposed API.
*/
replaceNotebookCells(uri: Uri, range: NotebookRange, cells: NotebookCellData[], metadata?: WorkspaceEditEntryMetadata): void;
/**
* @deprecated Please migrate to the new `notebookWorkspaceEdit` proposed API.
*/
replaceNotebookCellMetadata(uri: Uri, index: number, cellMetadata: { [key: string]: any }, metadata?: WorkspaceEditEntryMetadata): void;
}
export interface NotebookEditorEdit {
/**
* @deprecated Please migrate to the new `notebookWorkspaceEdit` proposed API.
*/
replaceMetadata(value: { [key: string]: any }): void;
/**
* @deprecated Please migrate to the new `notebookWorkspaceEdit` proposed API.
*/
replaceCells(start: number, end: number, cells: NotebookCellData[]): void;
/**
* @deprecated Please migrate to the new `notebookWorkspaceEdit` proposed API.
*/
replaceCellMetadata(index: number, metadata: { [key: string]: any }): void;
}
export interface NotebookEditor {
/**
* Perform an edit on the notebook associated with this notebook editor.
*
* The given callback-function is invoked with an {@link NotebookEditorEdit edit-builder} which must
* be used to make edits. Note that the edit-builder is only valid while the
* callback executes.
*
* @deprecated Please migrate to the new `notebookWorkspaceEdit` proposed API.
*
* @param callback A function which can create edits using an {@link NotebookEditorEdit edit-builder}.
* @return A promise that resolves with a value indicating if the edits could be applied.
*/
edit(callback: (editBuilder: NotebookEditorEdit) => void): Thenable<boolean>;
}
}
+1 -1
View File
@@ -196,7 +196,7 @@ declare module 'vscode' {
export interface ResourceLabelFormatting {
label: string; // myLabel:/${path}
// For historic reasons we use an or string here. Once we finalize this API we should start using enums instead and adopt it in extensions.
// eslint-disable-next-line vscode-dts-literal-or-types
// eslint-disable-next-line local/vscode-dts-literal-or-types
separator: '/' | '\\' | '';
tildify?: boolean;
normalizeDriveLetter?: boolean;

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