Merge remote-tracking branch 'upstream/master'
@@ -18,40 +18,127 @@
|
||||
assignees: [ weinand ],
|
||||
assignLabel: false
|
||||
},
|
||||
diff-editor: [],
|
||||
dropdown: [],
|
||||
editor: {
|
||||
diff-editor: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
dropdown: [],
|
||||
editor: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-1000-limit: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-autoclosing: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-autoindent: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-brackets: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-clipboard: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-code-actions: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-code-lens: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-color-picker: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-colors: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-columnselect: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-commands: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-contrib: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-drag-and-drop: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-find: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-folding: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-hover: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-ime: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-input: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-ligatures: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-links: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-minimap: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-multicursor: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-parameter-hints: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-rendering: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-smooth: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-symbols: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-textbuffer: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-wrapping: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-1000-limit: [],
|
||||
editor-autoclosing: [],
|
||||
editor-autoindent: [],
|
||||
editor-brackets: [],
|
||||
editor-clipboard: [],
|
||||
editor-code-actions: [],
|
||||
editor-code-lens: [],
|
||||
editor-color-picker: [],
|
||||
editor-colors: [],
|
||||
editor-columnselect: [],
|
||||
editor-commands: [],
|
||||
editor-contrib: [],
|
||||
editor-drag-and-drop: [],
|
||||
editor-find: [],
|
||||
editor-folding: [],
|
||||
editor-hover: [],
|
||||
editor-ime: [],
|
||||
editor-input: [],
|
||||
editor-ligatures: [],
|
||||
editor-links: [],
|
||||
editor-minimap: [],
|
||||
editor-multicursor: [],
|
||||
editor-parameter-hints: [],
|
||||
editor-rendering: [],
|
||||
editor-smooth: [],
|
||||
editor-symbols: [],
|
||||
editor-textbuffer: [],
|
||||
editor-wrapping: [],
|
||||
emmet: [ octref ],
|
||||
error-list: [],
|
||||
explorer-custom: [],
|
||||
@@ -63,7 +150,7 @@
|
||||
assignLabel: false
|
||||
},
|
||||
file-explorer: {
|
||||
assignees: [ ],
|
||||
assignees: [ isidorn ],
|
||||
assignLabel: false
|
||||
},
|
||||
file-glob: [],
|
||||
@@ -87,8 +174,14 @@
|
||||
issue-reporter: [ RMacfarlane ],
|
||||
javascript: [ mjbvz ],
|
||||
json: [],
|
||||
keyboard-layout: [],
|
||||
keybindings: [],
|
||||
keyboard-layout: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
keybindings: : {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
keybindings-editor: [],
|
||||
lang-diagnostics: [],
|
||||
languages basic: [],
|
||||
|
||||
@@ -59,5 +59,6 @@
|
||||
"git.ignoreLimitWarning": true,
|
||||
"remote.extensionKind": {
|
||||
"msjsdiag.debugger-for-chrome": "workspace"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files.insertFinalNewline": true
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
disturl "https://atom.io/download/electron"
|
||||
target "4.2.5"
|
||||
target "4.2.7"
|
||||
runtime "electron"
|
||||
|
||||
@@ -31,12 +31,12 @@ steps:
|
||||
git remote add distro "https://github.com/$VSCODE_MIXIN_REPO.git"
|
||||
git fetch distro
|
||||
|
||||
# Push master branch into master and oss/master
|
||||
git push distro origin/master:refs/heads/master origin/master:refs/heads/oss/master
|
||||
# Push master branch into oss/master
|
||||
git push distro origin/master:refs/heads/oss/master
|
||||
|
||||
# Push every release branch into oss/release
|
||||
git for-each-ref --format="%(refname:short)" refs/remotes/origin/release/* | sed 's/^origin\/\(.*\)$/\0:refs\/heads\/oss\/\1/' | xargs git push distro
|
||||
|
||||
git merge $(node -p "require('./package.json').distro")
|
||||
|
||||
displayName: Sync & Merge Distro
|
||||
displayName: Sync & Merge Distro
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
{
|
||||
"name": "ms-vscode.references-view",
|
||||
"version": "0.0.28",
|
||||
"version": "0.0.29",
|
||||
"repo": "https://github.com/Microsoft/vscode-reference-view",
|
||||
"metadata": {
|
||||
"id": "dc489f46-520d-4556-ae85-1f9eab3c412d",
|
||||
|
||||
@@ -119,7 +119,8 @@ const copyrightFilter = [
|
||||
'!resources/completions/**',
|
||||
'!extensions/markdown-language-features/media/highlight.css',
|
||||
'!extensions/html-language-features/server/src/modes/typescript/*',
|
||||
'!extensions/*/server/bin/*'
|
||||
'!extensions/*/server/bin/*',
|
||||
'!src/vs/editor/test/node/classification/typescript-test.ts',
|
||||
];
|
||||
|
||||
const eslintFilter = [
|
||||
|
||||
@@ -17,7 +17,7 @@ const gunzip = require('gulp-gunzip');
|
||||
const untar = require('gulp-untar');
|
||||
const File = require('vinyl');
|
||||
const fs = require('fs');
|
||||
const remote = require('gulp-remote-src');
|
||||
const remote = require('gulp-remote-retry-src');
|
||||
const rename = require('gulp-rename');
|
||||
const filter = require('gulp-filter');
|
||||
const cp = require('child_process');
|
||||
|
||||
@@ -13,7 +13,7 @@ const File = require("vinyl");
|
||||
const vsce = require("vsce");
|
||||
const stats_1 = require("./stats");
|
||||
const util2 = require("./util");
|
||||
const remote = require("gulp-remote-src");
|
||||
const remote = require("gulp-remote-retry-src");
|
||||
const vzip = require('gulp-vinyl-zip');
|
||||
const filter = require("gulp-filter");
|
||||
const rename = require("gulp-rename");
|
||||
|
||||
@@ -13,7 +13,7 @@ import * as File from 'vinyl';
|
||||
import * as vsce from 'vsce';
|
||||
import { createStatsStream } from './stats';
|
||||
import * as util2 from './util';
|
||||
import remote = require('gulp-remote-src');
|
||||
import remote = require('gulp-remote-retry-src');
|
||||
const vzip = require('gulp-vinyl-zip');
|
||||
import filter = require('gulp-filter');
|
||||
import rename = require('gulp-rename');
|
||||
|
||||
@@ -31,6 +31,7 @@ function extractEditor(options) {
|
||||
let compilerOptions;
|
||||
if (tsConfig.extends) {
|
||||
compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
|
||||
delete tsConfig.extends;
|
||||
}
|
||||
else {
|
||||
compilerOptions = tsConfig.compilerOptions;
|
||||
@@ -40,9 +41,9 @@ function extractEditor(options) {
|
||||
compilerOptions.noUnusedLocals = false;
|
||||
compilerOptions.preserveConstEnums = false;
|
||||
compilerOptions.declaration = false;
|
||||
compilerOptions.noImplicitAny = false;
|
||||
compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
|
||||
options.compilerOptions = compilerOptions;
|
||||
console.log(`Running with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`);
|
||||
let result = tss.shake(options);
|
||||
for (let fileName in result) {
|
||||
if (result.hasOwnProperty(fileName)) {
|
||||
@@ -91,8 +92,6 @@ function extractEditor(options) {
|
||||
}
|
||||
delete tsConfig.compilerOptions.moduleResolution;
|
||||
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
|
||||
const tsConfigBase = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.base.json')).toString());
|
||||
writeOutputFile('tsconfig.base.json', JSON.stringify(tsConfigBase, null, '\t'));
|
||||
[
|
||||
'vs/css.build.js',
|
||||
'vs/css.d.ts',
|
||||
|
||||
@@ -35,6 +35,7 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
|
||||
let compilerOptions: { [key: string]: any };
|
||||
if (tsConfig.extends) {
|
||||
compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
|
||||
delete tsConfig.extends;
|
||||
} else {
|
||||
compilerOptions = tsConfig.compilerOptions;
|
||||
}
|
||||
@@ -44,12 +45,13 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
|
||||
compilerOptions.noUnusedLocals = false;
|
||||
compilerOptions.preserveConstEnums = false;
|
||||
compilerOptions.declaration = false;
|
||||
compilerOptions.noImplicitAny = false;
|
||||
compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
|
||||
|
||||
|
||||
options.compilerOptions = compilerOptions;
|
||||
|
||||
console.log(`Running with shakeLevel ${tss.toStringShakeLevel(options.shakeLevel)}`);
|
||||
|
||||
let result = tss.shake(options);
|
||||
for (let fileName in result) {
|
||||
if (result.hasOwnProperty(fileName)) {
|
||||
@@ -100,8 +102,6 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
|
||||
|
||||
delete tsConfig.compilerOptions.moduleResolution;
|
||||
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
|
||||
const tsConfigBase = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.base.json')).toString());
|
||||
writeOutputFile('tsconfig.base.json', JSON.stringify(tsConfigBase, null, '\t'));
|
||||
|
||||
[
|
||||
'vs/css.build.js',
|
||||
|
||||
@@ -14,6 +14,17 @@ var ShakeLevel;
|
||||
ShakeLevel[ShakeLevel["InnerFile"] = 1] = "InnerFile";
|
||||
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
|
||||
})(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {}));
|
||||
function toStringShakeLevel(shakeLevel) {
|
||||
switch (shakeLevel) {
|
||||
case 0 /* Files */:
|
||||
return 'Files (0)';
|
||||
case 1 /* InnerFile */:
|
||||
return 'InnerFile (1)';
|
||||
case 2 /* ClassMembers */:
|
||||
return 'ClassMembers (2)';
|
||||
}
|
||||
}
|
||||
exports.toStringShakeLevel = toStringShakeLevel;
|
||||
function printDiagnostics(diagnostics) {
|
||||
for (const diag of diagnostics) {
|
||||
let result = '';
|
||||
@@ -394,6 +405,7 @@ function markNodes(languageService, options) {
|
||||
|| memberName === 'toJSON'
|
||||
|| memberName === 'toString'
|
||||
|| memberName === 'dispose' // TODO: keeping all `dispose` methods
|
||||
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
|
||||
) {
|
||||
enqueue_black(member);
|
||||
}
|
||||
@@ -513,10 +525,6 @@ function generateResult(languageService, shakeLevel) {
|
||||
// keep method
|
||||
continue;
|
||||
}
|
||||
if (/^_(.*)Brand$/.test(member.name.getText())) {
|
||||
// TODO: keep all members ending with `Brand`...
|
||||
continue;
|
||||
}
|
||||
let pos = member.pos - node.pos;
|
||||
let end = member.end - node.pos;
|
||||
toWrite = toWrite.substring(0, pos) + toWrite.substring(end);
|
||||
|
||||
@@ -17,6 +17,17 @@ export const enum ShakeLevel {
|
||||
ClassMembers = 2
|
||||
}
|
||||
|
||||
export function toStringShakeLevel(shakeLevel: ShakeLevel): string {
|
||||
switch(shakeLevel) {
|
||||
case ShakeLevel.Files:
|
||||
return 'Files (0)';
|
||||
case ShakeLevel.InnerFile:
|
||||
return 'InnerFile (1)';
|
||||
case ShakeLevel.ClassMembers:
|
||||
return 'ClassMembers (2)';
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITreeShakingOptions {
|
||||
/**
|
||||
* The full path to the root where sources are.
|
||||
@@ -513,6 +524,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
|
||||
|| memberName === 'toJSON'
|
||||
|| memberName === 'toString'
|
||||
|| memberName === 'dispose'// TODO: keeping all `dispose` methods
|
||||
|| /^_(.*)Brand$/.test(memberName || '') // TODO: keeping all members ending with `Brand`...
|
||||
) {
|
||||
enqueue_black(member);
|
||||
}
|
||||
@@ -642,10 +654,6 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
|
||||
// keep method
|
||||
continue;
|
||||
}
|
||||
if (/^_(.*)Brand$/.test(member.name.getText())) {
|
||||
// TODO: keep all members ending with `Brand`...
|
||||
continue;
|
||||
}
|
||||
|
||||
let pos = member.pos - node.pos;
|
||||
let end = member.end - node.pos;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
declare module 'gulp-remote-src' {
|
||||
declare module 'gulp-remote-retry-src' {
|
||||
|
||||
import stream = require("stream");
|
||||
|
||||
@@ -20,4 +20,4 @@ declare module 'gulp-remote-src' {
|
||||
}
|
||||
|
||||
export = remote;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,8 +306,8 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
|
||||
let usageImports = [];
|
||||
let usage = [];
|
||||
let failed = false;
|
||||
usage.push(`var a;`);
|
||||
usage.push(`var b;`);
|
||||
usage.push(`var a: any;`);
|
||||
usage.push(`var b: any;`);
|
||||
const generateUsageImport = (moduleId) => {
|
||||
let importName = 'm' + (++usageCounter);
|
||||
usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`);
|
||||
|
||||
@@ -366,8 +366,8 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
|
||||
|
||||
let failed = false;
|
||||
|
||||
usage.push(`var a;`);
|
||||
usage.push(`var b;`);
|
||||
usage.push(`var a: any;`);
|
||||
usage.push(`var b: any;`);
|
||||
|
||||
const generateUsageImport = (moduleId: string) => {
|
||||
let importName = 'm' + (++usageCounter);
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
declare namespace monaco {
|
||||
|
||||
// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.
|
||||
|
||||
export type Thenable<T> = PromiseLike<T>;
|
||||
|
||||
export interface IDisposable {
|
||||
|
||||
@@ -30,7 +30,7 @@ import * as editorAPI from './vs/editor/editor.api';
|
||||
a = (<ServiceIdentifier<any>>b).type;
|
||||
a = (<IHighlight>b).start;
|
||||
a = (<IHighlight>b).end;
|
||||
a = (<SimpleWorkerClient<any>>b).getProxyObject; // IWorkerClient
|
||||
a = (<SimpleWorkerClient<any, any>>b).getProxyObject; // IWorkerClient
|
||||
a = create1;
|
||||
a = create2;
|
||||
a = (<DocumentRangeFormattingEditProvider>b).extensionId;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"@types/minimatch": "^3.0.3",
|
||||
"@types/minimist": "^1.2.0",
|
||||
"@types/mocha": "2.2.39",
|
||||
"@types/node": "8.0.33",
|
||||
"@types/node": "^10.14.8",
|
||||
"@types/pump": "^1.0.1",
|
||||
"@types/request": "^2.47.0",
|
||||
"@types/rimraf": "^2.0.2",
|
||||
@@ -29,7 +29,7 @@
|
||||
"@types/uglify-es": "^3.0.0",
|
||||
"@types/underscore": "^1.8.9",
|
||||
"@types/xml2js": "0.0.33",
|
||||
"applicationinsights": "1.0.6",
|
||||
"applicationinsights": "1.0.8",
|
||||
"azure-storage": "^2.1.0",
|
||||
"documentdb": "1.13.0",
|
||||
"github-releases": "^0.4.1",
|
||||
@@ -42,7 +42,7 @@
|
||||
"tslint": "^5.9.1",
|
||||
"typescript": "3.5.2",
|
||||
"vsce": "1.48.0",
|
||||
"vscode-telemetry-extractor": "1.4.3",
|
||||
"vscode-telemetry-extractor": "1.5.3",
|
||||
"xml2js": "^0.4.17"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -51,4 +51,4 @@
|
||||
"postinstall": "npm run compile",
|
||||
"npmCheckJs": "tsc --noEmit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,10 +195,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb"
|
||||
integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==
|
||||
|
||||
"@types/node@8.0.33":
|
||||
version "8.0.33"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd"
|
||||
integrity sha512-vmCdO8Bm1ExT+FWfC9sd9r4jwqM7o97gGy2WBshkkXbf/2nLAJQUrZfIhw27yVOtLUev6kSZc4cav/46KbDd8A==
|
||||
"@types/node@^10.14.8":
|
||||
version "10.14.13"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7"
|
||||
integrity sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ==
|
||||
|
||||
"@types/pump@^1.0.1":
|
||||
version "1.0.1"
|
||||
@@ -357,10 +357,10 @@ ansi-wrap@0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
|
||||
integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768=
|
||||
|
||||
applicationinsights@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.6.tgz#bc201810de91cea910dab34e8ad35ecde488edeb"
|
||||
integrity sha512-VQT3kBpJVPw5fCO5n+WUeSx0VHjxFtD7znYbILBlVgOS9/cMDuGFmV2Br3ObzFyZUDGNbEfW36fD1y2/vAiCKw==
|
||||
applicationinsights@1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5"
|
||||
integrity sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg==
|
||||
dependencies:
|
||||
diagnostic-channel "0.2.0"
|
||||
diagnostic-channel-publishers "0.2.1"
|
||||
@@ -1257,7 +1257,12 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
@@ -2119,7 +2124,7 @@ tough-cookie@~2.3.3:
|
||||
dependencies:
|
||||
punycode "^1.4.1"
|
||||
|
||||
ts-morph@^3.1.2:
|
||||
ts-morph@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-3.1.3.tgz#bbfa1d14481ee23bdd1c030340ccf4a243cfc844"
|
||||
integrity sha512-CwjgyJTtd3f8vBi7Vr0IOgdOY6Wi/Tq0MhieXOE2B5ns5WWRD7BwMNHtv+ZufKI/S2U/lMrh+Q3bOauE4tsv2g==
|
||||
@@ -2308,19 +2313,19 @@ vsce@1.48.0:
|
||||
yauzl "^2.3.1"
|
||||
yazl "^2.2.2"
|
||||
|
||||
vscode-ripgrep@^1.4.0:
|
||||
vscode-ripgrep@^1.5.5:
|
||||
version "1.5.5"
|
||||
resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.5.tgz#24c0e9cb356cf889c98e15ecb58f9cf654a1d961"
|
||||
integrity sha512-OrPrAmcun4+uZAuNcQvE6CCPskh+5AsjANod/Q3zRcJcGNxgoOSGlQN9RPtatkUNmkN8Nn8mZBnS1jMylu/dKg==
|
||||
|
||||
vscode-telemetry-extractor@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-telemetry-extractor/-/vscode-telemetry-extractor-1.4.3.tgz#e4af380beb4e2a63d6e4fa819b25ba7ef6dc4a10"
|
||||
integrity sha512-OFklPErZnUBjrKte3hg+irQXue5rzgz4qnvE8kdaOnW1E/wynHUEXW9t5vF5q0hu2lodpGMkybwLkSjONZVzvg==
|
||||
vscode-telemetry-extractor@1.5.3:
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-telemetry-extractor/-/vscode-telemetry-extractor-1.5.3.tgz#c17f9065a47425edafd23ea161e80c23274e009d"
|
||||
integrity sha512-feioJ1e1KyMa9rzblnLbSOduo+Ny0l62H3/bSDgfgCSnU/km+tTSYxPBvZHVr7iQfQGC95J61yC/ObqS9EbaQg==
|
||||
dependencies:
|
||||
command-line-args "^5.1.1"
|
||||
ts-morph "^3.1.2"
|
||||
vscode-ripgrep "^1.4.0"
|
||||
ts-morph "^3.1.3"
|
||||
vscode-ripgrep "^1.5.5"
|
||||
|
||||
vso-node-api@6.1.2-preview:
|
||||
version "6.1.2-preview"
|
||||
|
||||
@@ -60,12 +60,12 @@
|
||||
"git": {
|
||||
"name": "electron",
|
||||
"repositoryUrl": "https://github.com/electron/electron",
|
||||
"commitHash": "5d67ec3da5376a5058990e8a9557bc9124ad59a8"
|
||||
"commitHash": "36ea114ac0616e469e75ae94e6d53af48925e036"
|
||||
}
|
||||
},
|
||||
"isOnlyProductionDependency": true,
|
||||
"license": "MIT",
|
||||
"version": "4.2.5"
|
||||
"version": "4.2.7"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
{ "open": "{", "close": "}" },
|
||||
{ "open": "(", "close": ")" },
|
||||
{ "open": "'", "close": "'", "notIn": ["string", "comment"] },
|
||||
{ "open": "\"", "close": "\"", "notIn": ["string"] },
|
||||
{ "open": "/**", "close": " */", "notIn": ["string", "comment"] }
|
||||
{ "open": "\"", "close": "\"", "notIn": ["string"] }
|
||||
],
|
||||
"surroundingPairs": [
|
||||
["{", "}"],
|
||||
@@ -30,4 +29,4 @@
|
||||
"end": "^\\s*#pragma\\s+endregion\\b"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
},
|
||||
{
|
||||
"id": "cpp",
|
||||
"extensions": [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".ino", ".inl", ".ipp", ".hpp.in", ".h.in" ],
|
||||
"extensions": [ ".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx", ".h", ".i", ".ino", ".inl", ".ipp", ".hpp.in", ".h.in" ],
|
||||
"aliases": [ "C++", "Cpp", "cpp"],
|
||||
"configuration": "./language-configuration.json"
|
||||
}],
|
||||
@@ -45,4 +45,4 @@
|
||||
"path": "./snippets/cpp.json"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,6 +730,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"jsonValidation": [
|
||||
{
|
||||
"fileMatch": "*.css-data.json",
|
||||
"url": "https://raw.githubusercontent.com/Microsoft/vscode-css-languageservice/master/docs/customData.schema.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"main": "./out/cssServerMain",
|
||||
"dependencies": {
|
||||
"vscode-css-languageservice": "^4.0.3-next.0",
|
||||
"vscode-css-languageservice": "^4.0.3-next.1",
|
||||
"vscode-languageserver": "^5.3.0-next.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -121,9 +121,9 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
scopedSettingsSupport = !!getClientCapability('workspace.configuration', false);
|
||||
foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
|
||||
languageServices.css = getCSSLanguageService({ customDataProviders, fileSystemProvider });
|
||||
languageServices.scss = getSCSSLanguageService({ customDataProviders, fileSystemProvider });
|
||||
languageServices.less = getLESSLanguageService({ customDataProviders, fileSystemProvider });
|
||||
languageServices.css = getCSSLanguageService({ customDataProviders, fileSystemProvider, clientCapabilities: params.capabilities });
|
||||
languageServices.scss = getSCSSLanguageService({ customDataProviders, fileSystemProvider, clientCapabilities: params.capabilities });
|
||||
languageServices.less = getLESSLanguageService({ customDataProviders, fileSystemProvider, clientCapabilities: params.capabilities });
|
||||
|
||||
const capabilities: ServerCapabilities = {
|
||||
// Tell the client that the server works in FULL text document sync mode
|
||||
@@ -140,7 +140,8 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
codeActionProvider: true,
|
||||
renameProvider: true,
|
||||
colorProvider: {},
|
||||
foldingRangeProvider: true
|
||||
foldingRangeProvider: true,
|
||||
selectionRangeProvider: true
|
||||
};
|
||||
return { capabilities };
|
||||
});
|
||||
|
||||
@@ -154,10 +154,10 @@ function pathToReplaceRange(valueBeforeCursor: string, fullValue: string, fullVa
|
||||
const valueAfterLastSlash = fullValue.slice(lastIndexOfSlash + 1);
|
||||
const startPos = shiftPosition(fullValueRange.end, -valueAfterLastSlash.length);
|
||||
// If whitespace exists, replace until it
|
||||
const whiteSpaceIndex = valueAfterLastSlash.indexOf(' ');
|
||||
const whitespaceIndex = valueAfterLastSlash.indexOf(' ');
|
||||
let endPos;
|
||||
if (whiteSpaceIndex !== -1) {
|
||||
endPos = shiftPosition(startPos, whiteSpaceIndex);
|
||||
if (whitespaceIndex !== -1) {
|
||||
endPos = shiftPosition(startPos, whitespaceIndex);
|
||||
} else {
|
||||
endPos = fullValueRange.end;
|
||||
}
|
||||
|
||||
@@ -781,10 +781,10 @@ supports-color@^5.3.0:
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
vscode-css-languageservice@^4.0.3-next.0:
|
||||
version "4.0.3-next.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.0.tgz#ba96894cf2a0c86c744a1274590f27e55ea60f58"
|
||||
integrity sha512-ku58Y5jDFNfDicv2AAhgu1edgfGcRZPwlKu6EBK2ck/O/Vco7Zy64FDoClJghcYBhJiDs7sy2q/UtQD0IoGbRw==
|
||||
vscode-css-languageservice@^4.0.3-next.1:
|
||||
version "4.0.3-next.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.1.tgz#e89d01ce0d79b3e6c2642f5e3ad73cb8160d38d9"
|
||||
integrity sha512-Zrm5TeraVUJ8vRikWhFt259dQu+WK+Ie3K5UA8BB4kqcanoM+1mcnIt8fPkTXlZLbiEWElrkJ9yuYbDNkufeBg==
|
||||
dependencies:
|
||||
vscode-languageserver-types "^3.15.0-next.2"
|
||||
vscode-nls "^4.1.1"
|
||||
|
||||
@@ -84,8 +84,8 @@ function doWrapping(individualLines: boolean, args: any) {
|
||||
|
||||
const firstLineOfSelection = editor.document.lineAt(rangeToReplace.start).text.substr(rangeToReplace.start.character);
|
||||
const matches = firstLineOfSelection.match(/^(\s*)/);
|
||||
const extraWhiteSpaceSelected = matches ? matches[1].length : 0;
|
||||
rangeToReplace = new vscode.Range(rangeToReplace.start.line, rangeToReplace.start.character + extraWhiteSpaceSelected, rangeToReplace.end.line, rangeToReplace.end.character);
|
||||
const extraWhitespaceSelected = matches ? matches[1].length : 0;
|
||||
rangeToReplace = new vscode.Range(rangeToReplace.start.line, rangeToReplace.start.character + extraWhitespaceSelected, rangeToReplace.end.line, rangeToReplace.end.character);
|
||||
|
||||
let textToWrapInPreview: string[];
|
||||
let textToReplace = editor.document.getText(rangeToReplace);
|
||||
@@ -94,8 +94,8 @@ function doWrapping(individualLines: boolean, args: any) {
|
||||
} else {
|
||||
const wholeFirstLine = editor.document.lineAt(rangeToReplace.start).text;
|
||||
const otherMatches = wholeFirstLine.match(/^(\s*)/);
|
||||
const preceedingWhiteSpace = otherMatches ? otherMatches[1] : '';
|
||||
textToWrapInPreview = rangeToReplace.isSingleLine ? [textToReplace] : ['\n\t' + textToReplace.split('\n' + preceedingWhiteSpace).join('\n\t') + '\n'];
|
||||
const preceedingWhitespace = otherMatches ? otherMatches[1] : '';
|
||||
textToWrapInPreview = rangeToReplace.isSingleLine ? [textToReplace] : ['\n\t' + textToReplace.split('\n' + preceedingWhitespace).join('\n\t') + '\n'];
|
||||
}
|
||||
textToWrapInPreview = textToWrapInPreview.map(e => e.replace(/(\$\d)/g, '\\$1'));
|
||||
|
||||
|
||||
@@ -158,4 +158,4 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
|
||||
return new vscode.CompletionList(newItems, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Model } from '../model';
|
||||
import { Repository as BaseRepository, Resource } from '../repository';
|
||||
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions } from './git';
|
||||
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState } from './git';
|
||||
import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode';
|
||||
import { mapEvent } from '../util';
|
||||
|
||||
@@ -214,6 +214,14 @@ export class ApiImpl implements API {
|
||||
|
||||
readonly git = new ApiGit(this._model);
|
||||
|
||||
get state(): APIState {
|
||||
return this._model.state;
|
||||
}
|
||||
|
||||
get onDidChangeState(): Event<APIState> {
|
||||
return this._model.onDidChangeState;
|
||||
}
|
||||
|
||||
get onDidOpenRepository(): Event<Repository> {
|
||||
return mapEvent(this._model.onDidOpenRepository, r => new ApiRepository(r));
|
||||
}
|
||||
|
||||
@@ -176,7 +176,11 @@ export interface Repository {
|
||||
log(options?: LogOptions): Promise<Commit[]>;
|
||||
}
|
||||
|
||||
export type APIState = 'uninitialized' | 'initialized';
|
||||
|
||||
export interface API {
|
||||
readonly state: APIState;
|
||||
readonly onDidChangeState: Event<APIState>;
|
||||
readonly git: Git;
|
||||
readonly repositories: Repository[];
|
||||
readonly onDidOpenRepository: Event<Repository>;
|
||||
|
||||
@@ -1115,7 +1115,7 @@ export class CommandCenter {
|
||||
|
||||
if (scmResources.length === 1) {
|
||||
if (untrackedCount > 0) {
|
||||
message = localize('confirm delete', "Are you sure you want to DELETE {0}?", path.basename(scmResources[0].resourceUri.fsPath));
|
||||
message = localize('confirm delete', "Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST.", path.basename(scmResources[0].resourceUri.fsPath));
|
||||
yes = localize('delete file', "Delete file");
|
||||
} else {
|
||||
if (scmResources[0].type === Status.DELETED) {
|
||||
@@ -1134,7 +1134,7 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
if (untrackedCount > 0) {
|
||||
message = `${message}\n\n${localize('warn untracked', "This will DELETE {0} untracked files!", untrackedCount)}`;
|
||||
message = `${message}\n\n${localize('warn untracked', "This will DELETE {0} untracked files!\nThis is IRREVERSIBLE!\nThese files will be FOREVER LOST.", untrackedCount)}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1175,7 +1175,7 @@ export class CommandCenter {
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
return;
|
||||
} else if (resources.length === 1) {
|
||||
const message = localize('confirm delete', "Are you sure you want to DELETE {0}?", path.basename(resources[0].resourceUri.fsPath));
|
||||
const message = localize('confirm delete', "Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST.", path.basename(resources[0].resourceUri.fsPath));
|
||||
const yes = localize('delete file', "Delete file");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { fromGitUri } from './uri';
|
||||
import { GitErrorCodes } from './api/git';
|
||||
import { GitErrorCodes, APIState as State } from './api/git';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -63,15 +63,22 @@ export class Model {
|
||||
|
||||
private possibleGitRepositoryPaths = new Set<string>();
|
||||
|
||||
private _onDidChangeState = new EventEmitter<State>();
|
||||
readonly onDidChangeState = this._onDidChangeState.event;
|
||||
|
||||
private _state: State = 'uninitialized';
|
||||
get state(): State { return this._state; }
|
||||
|
||||
setState(state: State): void {
|
||||
this._state = state;
|
||||
this._onDidChangeState.fire(state);
|
||||
}
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(readonly git: Git, private globalState: Memento, private outputChannel: OutputChannel) {
|
||||
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
|
||||
this.onDidChangeWorkspaceFolders({ added: workspace.workspaceFolders || [], removed: [] });
|
||||
|
||||
window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables);
|
||||
this.onDidChangeVisibleTextEditors(window.visibleTextEditors);
|
||||
|
||||
workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables);
|
||||
|
||||
const fsWatcher = workspace.createFileSystemWatcher('**');
|
||||
@@ -82,7 +89,15 @@ export class Model {
|
||||
const onPossibleGitRepositoryChange = filterEvent(onGitRepositoryChange, uri => !this.getRepository(uri));
|
||||
onPossibleGitRepositoryChange(this.onPossibleGitRepositoryChange, this, this.disposables);
|
||||
|
||||
this.scanWorkspaceFolders();
|
||||
this.doInitialScan().finally(() => this.setState('initialized'));
|
||||
}
|
||||
|
||||
private async doInitialScan(): Promise<void> {
|
||||
await Promise.all([
|
||||
this.onDidChangeWorkspaceFolders({ added: workspace.workspaceFolders || [], removed: [] }),
|
||||
this.onDidChangeVisibleTextEditors(window.visibleTextEditors),
|
||||
this.scanWorkspaceFolders()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,8 +172,8 @@ export class Model {
|
||||
.filter(r => !activeRepositories.has(r!.repository))
|
||||
.filter(r => !(workspace.workspaceFolders || []).some(f => isDescendant(f.uri.fsPath, r!.repository.root))) as OpenRepository[];
|
||||
|
||||
possibleRepositoryFolders.forEach(p => this.openRepository(p.uri.fsPath));
|
||||
openRepositoriesToDispose.forEach(r => r.dispose());
|
||||
await Promise.all(possibleRepositoryFolders.map(p => this.openRepository(p.uri.fsPath)));
|
||||
}
|
||||
|
||||
private onDidChangeConfiguration(): void {
|
||||
@@ -175,7 +190,7 @@ export class Model {
|
||||
openRepositoriesToDispose.forEach(r => r.dispose());
|
||||
}
|
||||
|
||||
private onDidChangeVisibleTextEditors(editors: TextEditor[]): void {
|
||||
private async onDidChangeVisibleTextEditors(editors: TextEditor[]): Promise<void> {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
|
||||
|
||||
@@ -183,7 +198,7 @@ export class Model {
|
||||
return;
|
||||
}
|
||||
|
||||
editors.forEach(editor => {
|
||||
await Promise.all(editors.map(async editor => {
|
||||
const uri = editor.document.uri;
|
||||
|
||||
if (uri.scheme !== 'file') {
|
||||
@@ -196,8 +211,8 @@ export class Model {
|
||||
return;
|
||||
}
|
||||
|
||||
this.openRepository(path.dirname(uri.fsPath));
|
||||
});
|
||||
await this.openRepository(path.dirname(uri.fsPath));
|
||||
}));
|
||||
}
|
||||
|
||||
@sequentialize
|
||||
@@ -236,6 +251,7 @@ export class Model {
|
||||
const repository = new Repository(this.git.open(repositoryRoot, dotGit), this.globalState, this.outputChannel);
|
||||
|
||||
this.open(repository);
|
||||
await repository.status();
|
||||
} catch (err) {
|
||||
if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) {
|
||||
return;
|
||||
@@ -421,4 +437,4 @@ export class Model {
|
||||
this.possibleGitRepositoryPaths.clear();
|
||||
this.disposables = dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,8 +519,8 @@ class DotGitWatcher implements IFileWatcher {
|
||||
this.transientDisposables.push(upstreamWatcher);
|
||||
upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables);
|
||||
} catch (err) {
|
||||
if (env.logLevel <= LogLevel.Info) {
|
||||
this.outputChannel.appendLine(`Failed to watch ref '${upstreamPath}'. Ref is most likely packed.`);
|
||||
if (env.logLevel <= LogLevel.Error) {
|
||||
this.outputChannel.appendLine(`Failed to watch ref '${upstreamPath}', is most likely packed.\n${err.stack || err}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -651,19 +651,30 @@ export class Repository implements Disposable {
|
||||
const onWorkspaceRepositoryFileChange = filterEvent(onWorkspaceFileChange, uri => isDescendant(repository.root, uri.fsPath));
|
||||
const onWorkspaceWorkingTreeFileChange = filterEvent(onWorkspaceRepositoryFileChange, uri => !/\/\.git($|\/)/.test(uri.path));
|
||||
|
||||
const dotGitFileWatcher = new DotGitWatcher(this, outputChannel);
|
||||
this.disposables.push(dotGitFileWatcher);
|
||||
let onDotGitFileChange: Event<Uri>;
|
||||
|
||||
try {
|
||||
const dotGitFileWatcher = new DotGitWatcher(this, outputChannel);
|
||||
onDotGitFileChange = dotGitFileWatcher.event;
|
||||
this.disposables.push(dotGitFileWatcher);
|
||||
} catch (err) {
|
||||
if (env.logLevel <= LogLevel.Error) {
|
||||
outputChannel.appendLine(`Failed to watch '${this.dotGit}', reverting to legacy API file watched. Some events might be lost.\n${err.stack || err}`);
|
||||
}
|
||||
|
||||
onDotGitFileChange = filterEvent(onWorkspaceRepositoryFileChange, uri => /\/\.git($|\/)/.test(uri.path));
|
||||
}
|
||||
|
||||
// FS changes should trigger `git status`:
|
||||
// - any change inside the repository working tree
|
||||
// - any change whithin the first level of the `.git` folder, except the folder itself and `index.lock`
|
||||
const onFileChange = anyEvent(onWorkspaceWorkingTreeFileChange, dotGitFileWatcher.event);
|
||||
const onFileChange = anyEvent(onWorkspaceWorkingTreeFileChange, onDotGitFileChange);
|
||||
onFileChange(this.onFileChange, this, this.disposables);
|
||||
|
||||
// Relevate repository changes should trigger virtual document change events
|
||||
dotGitFileWatcher.event(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables);
|
||||
onDotGitFileChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables);
|
||||
|
||||
this.disposables.push(new FileEventLogger(onWorkspaceWorkingTreeFileChange, dotGitFileWatcher.event, outputChannel));
|
||||
this.disposables.push(new FileEventLogger(onWorkspaceWorkingTreeFileChange, onDotGitFileChange, outputChannel));
|
||||
|
||||
const root = Uri.file(repository.root);
|
||||
this._sourceControl = scm.createSourceControl('git', 'Git', root);
|
||||
@@ -713,7 +724,6 @@ export class Repository implements Disposable {
|
||||
this.disposables.push(progressManager);
|
||||
|
||||
this.updateCommitTemplate();
|
||||
this.status();
|
||||
}
|
||||
|
||||
validateInput(text: string, position: number): SourceControlInputBoxValidation | undefined {
|
||||
|
||||
@@ -173,7 +173,13 @@
|
||||
"description": "%html.trace.server.desc%"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsonValidation": [
|
||||
{
|
||||
"fileMatch": "*.html-data.json",
|
||||
"url": "https://raw.githubusercontent.com/Microsoft/vscode-html-languageservice/master/docs/customData.schema.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
},
|
||||
"main": "./out/htmlServerMain",
|
||||
"dependencies": {
|
||||
"vscode-css-languageservice": "^4.0.2",
|
||||
"vscode-html-languageservice": "^3.0.0",
|
||||
"vscode-css-languageservice": "^4.0.3-next.1",
|
||||
"vscode-html-languageservice": "^3.0.4-next.0",
|
||||
"vscode-languageserver": "^5.3.0-next.8",
|
||||
"vscode-languageserver-types": "3.15.0-next.2",
|
||||
"vscode-nls": "^4.1.1",
|
||||
"vscode-uri": "^2.0.1"
|
||||
"vscode-uri": "^2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "2.2.33",
|
||||
|
||||
@@ -96,7 +96,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
get folders() { return workspaceFolders; }
|
||||
};
|
||||
|
||||
languageModes = getLanguageModes(initializationOptions ? initializationOptions.embeddedLanguages : { css: true, javascript: true }, workspace, providers);
|
||||
languageModes = getLanguageModes(initializationOptions ? initializationOptions.embeddedLanguages : { css: true, javascript: true }, workspace, params.capabilities, providers);
|
||||
|
||||
documents.onDidClose(e => {
|
||||
languageModes.onDocumentRemoved(e.document);
|
||||
@@ -135,7 +135,8 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
signatureHelpProvider: { triggerCharacters: ['('] },
|
||||
referencesProvider: true,
|
||||
colorProvider: {},
|
||||
foldingRangeProvider: true
|
||||
foldingRangeProvider: true,
|
||||
selectionRangeProvider: true
|
||||
};
|
||||
return { capabilities };
|
||||
});
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
|
||||
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
|
||||
import { TextDocument, Position, Range, CompletionList } from 'vscode-languageserver-types';
|
||||
import { getCSSLanguageService, Stylesheet, FoldingRange } from 'vscode-css-languageservice';
|
||||
import { Stylesheet, FoldingRange, LanguageService as CSSLanguageService } from 'vscode-css-languageservice';
|
||||
import { LanguageMode, Workspace } from './languageModes';
|
||||
import { HTMLDocumentRegions, CSS_STYLE_RULE } from './embeddedSupport';
|
||||
import { Color } from 'vscode-languageserver';
|
||||
|
||||
export function getCSSMode(documentRegions: LanguageModelCache<HTMLDocumentRegions>, workspace: Workspace): LanguageMode {
|
||||
let cssLanguageService = getCSSLanguageService();
|
||||
export function getCSSMode(cssLanguageService: CSSLanguageService, documentRegions: LanguageModelCache<HTMLDocumentRegions>, workspace: Workspace): LanguageMode {
|
||||
let embeddedCSSDocuments = getLanguageModelCache<TextDocument>(10, 60, document => documentRegions.get(document).getEmbeddedDocument('css'));
|
||||
let cssStylesheets = getLanguageModelCache<Stylesheet>(10, 60, document => cssLanguageService.parseStylesheet(document));
|
||||
|
||||
|
||||
@@ -3,18 +3,15 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getLanguageService as getHTMLLanguageService, DocumentContext, IHTMLDataProvider, SelectionRange } from 'vscode-html-languageservice';
|
||||
import {
|
||||
CompletionItem, Location, SignatureHelp, Definition, TextEdit, TextDocument, Diagnostic, DocumentLink, Range,
|
||||
Hover, DocumentHighlight, CompletionList, Position, FormattingOptions, SymbolInformation, FoldingRange
|
||||
} from 'vscode-languageserver-types';
|
||||
import { ColorInformation, ColorPresentation, Color, WorkspaceFolder } from 'vscode-languageserver';
|
||||
|
||||
import { getCSSLanguageService } from 'vscode-css-languageservice';
|
||||
import { ClientCapabilities, DocumentContext, getLanguageService as getHTMLLanguageService, IHTMLDataProvider, SelectionRange } from 'vscode-html-languageservice';
|
||||
import { Color, ColorInformation, ColorPresentation, WorkspaceFolder } from 'vscode-languageserver';
|
||||
import { CompletionItem, CompletionList, Definition, Diagnostic, DocumentHighlight, DocumentLink, FoldingRange, FormattingOptions, Hover, Location, Position, Range, SignatureHelp, SymbolInformation, TextDocument, TextEdit } from 'vscode-languageserver-types';
|
||||
import { getLanguageModelCache, LanguageModelCache } from '../languageModelCache';
|
||||
import { getDocumentRegions, HTMLDocumentRegions } from './embeddedSupport';
|
||||
import { getCSSMode } from './cssMode';
|
||||
import { getJavaScriptMode } from './javascriptMode';
|
||||
import { getDocumentRegions, HTMLDocumentRegions } from './embeddedSupport';
|
||||
import { getHTMLMode } from './htmlMode';
|
||||
import { getJavaScriptMode } from './javascriptMode';
|
||||
|
||||
export { ColorInformation, ColorPresentation, Color };
|
||||
|
||||
@@ -66,8 +63,9 @@ export interface LanguageModeRange extends Range {
|
||||
attributeValue?: boolean;
|
||||
}
|
||||
|
||||
export function getLanguageModes(supportedLanguages: { [languageId: string]: boolean; }, workspace: Workspace, customDataProviders?: IHTMLDataProvider[]): LanguageModes {
|
||||
const htmlLanguageService = getHTMLLanguageService({ customDataProviders });
|
||||
export function getLanguageModes(supportedLanguages: { [languageId: string]: boolean; }, workspace: Workspace, clientCapabilities: ClientCapabilities, customDataProviders?: IHTMLDataProvider[]): LanguageModes {
|
||||
const htmlLanguageService = getHTMLLanguageService({ customDataProviders, clientCapabilities });
|
||||
const cssLanguageService = getCSSLanguageService({ clientCapabilities });
|
||||
|
||||
let documentRegions = getLanguageModelCache<HTMLDocumentRegions>(10, 60, document => getDocumentRegions(htmlLanguageService, document));
|
||||
|
||||
@@ -77,7 +75,7 @@ export function getLanguageModes(supportedLanguages: { [languageId: string]: boo
|
||||
let modes = Object.create(null);
|
||||
modes['html'] = getHTMLMode(htmlLanguageService, workspace);
|
||||
if (supportedLanguages['css']) {
|
||||
modes['css'] = getCSSMode(documentRegions, workspace);
|
||||
modes['css'] = getCSSMode(cssLanguageService, documentRegions, workspace);
|
||||
}
|
||||
if (supportedLanguages['javascript']) {
|
||||
modes['javascript'] = getJavaScriptMode(documentRegions);
|
||||
|
||||
@@ -108,11 +108,12 @@ function pathToSuggestion(p: string, valueBeforeCursor: string, fullValue: strin
|
||||
// Find the last slash before cursor, and calculate the start of replace range from there
|
||||
const valueAfterLastSlash = fullValue.slice(lastIndexOfSlash + 1);
|
||||
const startPos = shiftPosition(range.end, -1 - valueAfterLastSlash.length);
|
||||
// If whitespace exists, replace until it
|
||||
const whiteSpaceIndex = valueAfterLastSlash.indexOf(' ');
|
||||
|
||||
// If whitespace exists, replace until there is no more
|
||||
const whitespaceIndex = valueAfterLastSlash.indexOf(' ');
|
||||
let endPos;
|
||||
if (whiteSpaceIndex !== -1) {
|
||||
endPos = shiftPosition(startPos, whiteSpaceIndex);
|
||||
if (whitespaceIndex !== -1) {
|
||||
endPos = shiftPosition(startPos, whitespaceIndex);
|
||||
} else {
|
||||
endPos = shiftPosition(range.end, -1);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { URI } from 'vscode-uri';
|
||||
import { TextDocument, CompletionList, CompletionItemKind } from 'vscode-languageserver-types';
|
||||
import { getLanguageModes } from '../modes/languageModes';
|
||||
import { WorkspaceFolder } from 'vscode-languageserver';
|
||||
import { ClientCapabilities } from 'vscode-html-languageservice';
|
||||
|
||||
export interface ItemDescription {
|
||||
label: string;
|
||||
@@ -58,7 +59,7 @@ export function testCompletionFor(value: string, expected: { count?: number, ite
|
||||
let document = TextDocument.create(uri, 'html', 0, value);
|
||||
let position = document.positionAt(offset);
|
||||
|
||||
const languageModes = getLanguageModes({ css: true, javascript: true }, workspace);
|
||||
const languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST);
|
||||
const mode = languageModes.getModeAtPosition(document, position)!;
|
||||
|
||||
let list = mode.doComplete!(document, position);
|
||||
|
||||
@@ -8,6 +8,7 @@ import * as assert from 'assert';
|
||||
import { TextDocument } from 'vscode-languageserver';
|
||||
import { getFoldingRanges } from '../modes/htmlFolding';
|
||||
import { getLanguageModes } from '../modes/languageModes';
|
||||
import { ClientCapabilities } from 'vscode-css-languageservice';
|
||||
|
||||
interface ExpectedIndentRange {
|
||||
startLine: number;
|
||||
@@ -21,7 +22,7 @@ function assertRanges(lines: string[], expected: ExpectedIndentRange[], message?
|
||||
settings: {},
|
||||
folders: [{ name: 'foo', uri: 'test://foo' }]
|
||||
};
|
||||
let languageModes = getLanguageModes({ css: true, javascript: true }, workspace);
|
||||
let languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST);
|
||||
let actual = getFoldingRanges(languageModes, document, nRanges, null);
|
||||
|
||||
let actualRanges = [];
|
||||
|
||||
@@ -11,6 +11,7 @@ import { getLanguageModes } from '../modes/languageModes';
|
||||
import { TextDocument, Range, FormattingOptions } from 'vscode-languageserver-types';
|
||||
|
||||
import { format } from '../modes/formatting';
|
||||
import { ClientCapabilities } from 'vscode-html-languageservice';
|
||||
|
||||
suite('HTML Embedded Formatting', () => {
|
||||
|
||||
@@ -19,7 +20,7 @@ suite('HTML Embedded Formatting', () => {
|
||||
settings: options,
|
||||
folders: [{ name: 'foo', uri: 'test://foo' }]
|
||||
};
|
||||
var languageModes = getLanguageModes({ css: true, javascript: true }, workspace);
|
||||
var languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST);
|
||||
|
||||
let rangeStartOffset = value.indexOf('|');
|
||||
let rangeEndOffset;
|
||||
|
||||
@@ -32,7 +32,11 @@ export function getDocumentContext(documentUri: string, workspaceFolders: Worksp
|
||||
}
|
||||
}
|
||||
}
|
||||
return url.resolve(base, ref);
|
||||
try {
|
||||
return url.resolve(base, ref);
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -229,22 +229,23 @@ supports-color@5.4.0:
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
vscode-css-languageservice@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.2.tgz#7496e538b0c151feac16d5888cc0b1b104f4c736"
|
||||
integrity sha512-pTnfXbsME3pl+yDfhUp/mtvPyIJk0Le4zqJxDn56s9GY9LqY0RmkSEh0oHH6D0HXR3Ni6wKosIaqu8a2G0+jdw==
|
||||
vscode-css-languageservice@^4.0.3-next.1:
|
||||
version "4.0.3-next.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.1.tgz#e89d01ce0d79b3e6c2642f5e3ad73cb8160d38d9"
|
||||
integrity sha512-Zrm5TeraVUJ8vRikWhFt259dQu+WK+Ie3K5UA8BB4kqcanoM+1mcnIt8fPkTXlZLbiEWElrkJ9yuYbDNkufeBg==
|
||||
dependencies:
|
||||
vscode-languageserver-types "^3.15.0-next.2"
|
||||
vscode-nls "^4.1.1"
|
||||
vscode-uri "^2.0.3"
|
||||
|
||||
vscode-html-languageservice@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.0.0.tgz#b9649aa0713d68665d7546bd3772dd10e4dbe200"
|
||||
integrity sha512-AgNyjaYrmgundh5gXP0bqCLeLdfUTyvNafF1moNwYdqeNh6DIpMG6RjwYwgtNChXSsVGXnaHiwGMtAUwMxkQUQ==
|
||||
vscode-html-languageservice@^3.0.4-next.0:
|
||||
version "3.0.4-next.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.0.4-next.0.tgz#d4f5a103b94753a19b374158212fe734dbe670e8"
|
||||
integrity sha512-5Z5ITtokWt/zuPKemKEXfC+4XHoQryBAZVAcTwpAel2qqueUwGqjd5ZrVy/2x5GZAdZAipl0BvsTTMkOBS1BFQ==
|
||||
dependencies:
|
||||
vscode-languageserver-types "^3.15.0-next.2"
|
||||
vscode-nls "^4.1.1"
|
||||
vscode-uri "^2.0.1"
|
||||
vscode-uri "^2.0.3"
|
||||
|
||||
vscode-jsonrpc@^4.1.0-next.2:
|
||||
version "4.1.0-next.2"
|
||||
@@ -288,10 +289,10 @@ vscode-uri@^1.0.6:
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.6.tgz#6b8f141b0bbc44ad7b07e94f82f168ac7608ad4d"
|
||||
integrity sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==
|
||||
|
||||
vscode-uri@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.1.tgz#5448e4f77d21d93ffa34b96f84c6c5e09e3f5a9b"
|
||||
integrity sha512-s/k0zsYr6y+tsocFyxT/+G5aq8mEdpDZuph3LZ+UmCs7LNhx/xomiCy5kyP+jOAKC7RMCUvb6JbPD1/TgAvq0g==
|
||||
vscode-uri@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543"
|
||||
integrity sha512-4D3DI3F4uRy09WNtDGD93H9q034OHImxiIcSq664Hq1Y1AScehlP3qqZyTkX/RWxeu0MRMHGkrxYqm2qlDF/aw==
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^2.1.0",
|
||||
"request-light": "^0.2.4",
|
||||
"vscode-json-languageservice": "^3.3.0",
|
||||
"vscode-json-languageservice": "^3.3.1",
|
||||
"vscode-languageserver": "^5.3.0-next.8",
|
||||
"vscode-nls": "^4.1.1",
|
||||
"vscode-uri": "^2.0.1"
|
||||
"vscode-uri": "^2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "2.2.33",
|
||||
|
||||
@@ -14,7 +14,7 @@ import * as fs from 'fs';
|
||||
import { URI } from 'vscode-uri';
|
||||
import * as URL from 'url';
|
||||
import { formatError, runSafe, runSafeAsync } from './utils/runner';
|
||||
import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration } from 'vscode-json-languageservice';
|
||||
import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities } from 'vscode-json-languageservice';
|
||||
import { getLanguageModelCache } from './languageModelCache';
|
||||
|
||||
interface ISchemaAssociations {
|
||||
@@ -103,6 +103,7 @@ function getSchemaRequestService(handledSchemas: { [schema: string]: boolean })
|
||||
let languageService = getLanguageService({
|
||||
workspaceContext,
|
||||
contributions: [],
|
||||
clientCapabilities: ClientCapabilities.LATEST
|
||||
});
|
||||
|
||||
// Create a text document manager.
|
||||
@@ -154,7 +155,8 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
documentSymbolProvider: true,
|
||||
documentRangeFormattingProvider: false,
|
||||
colorProvider: {},
|
||||
foldingRangeProvider: true
|
||||
foldingRangeProvider: true,
|
||||
selectionRangeProvider: true
|
||||
};
|
||||
|
||||
return { capabilities };
|
||||
|
||||
@@ -73,15 +73,15 @@ request-light@^0.2.4:
|
||||
https-proxy-agent "^2.2.1"
|
||||
vscode-nls "^4.0.0"
|
||||
|
||||
vscode-json-languageservice@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.0.tgz#f80ec21c19fb8648c815220a2857f9f0b22e1094"
|
||||
integrity sha512-upq1PhwDItazdtRJ/R7uU0Fgrf9iaYa1xLK4WFLExR0DgbPojd0YgMpfyknVyXGlxsg3fJQ0H7J++QeByXHh9w==
|
||||
vscode-json-languageservice@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.1.tgz#4ad2c82db849a7bbe54fcbf5c9b3a2ed26dc8fee"
|
||||
integrity sha512-Qyvlrftexu1acvwbMt+CDehVrDZtFV1GAJrKdOCHQL9bWNhzI06KEiSd4iXR0NUOuAdroG/uU4wBkH6e5CcTXg==
|
||||
dependencies:
|
||||
jsonc-parser "^2.1.0"
|
||||
vscode-languageserver-types "^3.15.0-next.2"
|
||||
vscode-nls "^4.1.1"
|
||||
vscode-uri "^2.0.1"
|
||||
vscode-uri "^2.0.3"
|
||||
|
||||
vscode-jsonrpc@^4.1.0-next.2:
|
||||
version "4.1.0-next.2"
|
||||
@@ -130,7 +130,7 @@ vscode-uri@^1.0.6:
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.6.tgz#6b8f141b0bbc44ad7b07e94f82f168ac7608ad4d"
|
||||
integrity sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==
|
||||
|
||||
vscode-uri@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.1.tgz#5448e4f77d21d93ffa34b96f84c6c5e09e3f5a9b"
|
||||
integrity sha512-s/k0zsYr6y+tsocFyxT/+G5aq8mEdpDZuph3LZ+UmCs7LNhx/xomiCy5kyP+jOAKC7RMCUvb6JbPD1/TgAvq0g==
|
||||
vscode-uri@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543"
|
||||
integrity sha512-4D3DI3F4uRy09WNtDGD93H9q034OHImxiIcSq664Hq1Y1AScehlP3qqZyTkX/RWxeu0MRMHGkrxYqm2qlDF/aw==
|
||||
|
||||
@@ -186,6 +186,7 @@ pre.hljs code > div {
|
||||
|
||||
pre code {
|
||||
color: var(--vscode-editor-foreground);
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ export class PreviewDocumentVersion {
|
||||
|
||||
export class MarkdownPreview extends Disposable {
|
||||
|
||||
public static viewType = 'markdown.preview';
|
||||
public static readonly viewType = 'markdown.preview';
|
||||
|
||||
private _resource: vscode.Uri;
|
||||
private _locked: boolean;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"activationEvents": [
|
||||
"onCommand:workbench.action.tasks.runTask",
|
||||
"onLanguage:json",
|
||||
"workspaceContains:package.json",
|
||||
"onView:npm"
|
||||
],
|
||||
"contributes": {
|
||||
@@ -47,7 +48,7 @@
|
||||
{
|
||||
"id": "npm",
|
||||
"name": "%view.name%",
|
||||
"when": "config.npm.enableScriptExplorer"
|
||||
"when": "npm:showScriptExplorer || config.npm.enableScriptExplorer"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.80723 14.9754C2.57119 14.9721 2.33826 14.9211 2.12247 14.8254C1.90667 14.7297 1.71248 14.5913 1.55158 14.4186C1.2385 14.1334 1.04433 13.7408 1.00775 13.3189C0.966225 12.8828 1.09269 12.4473 1.36133 12.1013C2.56779 10.8289 4.9473 8.4494 6.67811 6.75479C6.30983 5.75887 6.32704 4.66127 6.72637 3.67739C7.05474 2.85876 7.63869 2.16805 8.39129 1.70807C8.9817 1.31706 9.66031 1.07944 10.3657 1.01673C11.0711 0.954022 11.7809 1.06819 12.4311 1.34892L13.0482 1.6162L10.1824 4.56738L11.4371 5.82582L14.3809 2.94887L14.6482 3.56788C14.8735 4.08976 14.993 4.65119 14.9997 5.21961C15.0064 5.78802 14.9002 6.35211 14.6872 6.87915C14.476 7.40029 14.1623 7.87368 13.7647 8.27122C13.5394 8.49169 13.2904 8.68653 13.0222 8.85218C12.4673 9.22275 11.8324 9.45636 11.1697 9.5338C10.5069 9.61124 9.83521 9.5303 9.20982 9.29764C8.11194 10.4113 5.37142 13.1704 3.89119 14.5522C3.59426 14.8219 3.20832 14.9726 2.80723 14.9754ZM10.7448 1.92802C10.087 1.92637 9.44359 2.12018 8.89614 2.48485C8.68265 2.6152 8.48437 2.76897 8.30498 2.9433C7.82789 3.42423 7.50926 4.03953 7.39182 4.70669C7.27438 5.37385 7.36374 6.06098 7.64792 6.67591L7.78342 6.97288L7.55048 7.20025C5.81224 8.89672 3.28146 11.4201 2.06479 12.7045C1.95646 12.8658 1.91012 13.0608 1.93435 13.2535C1.95857 13.4463 2.05171 13.6238 2.19657 13.7532C2.28005 13.8462 2.38177 13.9211 2.49541 13.9731C2.59557 14.0184 2.70383 14.043 2.81373 14.0455C2.98064 14.0413 3.14044 13.977 3.26383 13.8646C4.83687 12.3964 7.87622 9.32641 8.76807 8.42435L8.9973 8.19326L9.29242 8.32783C9.80617 8.56732 10.3731 8.66985 10.9382 8.62545C11.5033 8.58106 12.0473 8.39125 12.5174 8.07447C12.7313 7.9426 12.9296 7.78694 13.1085 7.61045C13.4183 7.30153 13.6631 6.93374 13.8286 6.52874C13.994 6.12375 14.0767 5.68974 14.0719 5.25228C14.0719 5.03662 14.0505 4.82148 14.0078 4.61007L11.4306 7.12508L8.87944 4.57759L11.3944 1.98834C11.1804 1.94674 10.9628 1.92653 10.7448 1.92802Z" fill="#C5C5C5"/>
|
||||
<g opacity="0.5">
|
||||
<path d="M2.80723 14.9754C2.57119 14.9721 2.33826 14.9211 2.12247 14.8254C1.90667 14.7297 1.71248 14.5913 1.55158 14.4186C1.2385 14.1334 1.04433 13.7408 1.00775 13.3189C0.966225 12.8828 1.09269 12.4473 1.36133 12.1013C2.56779 10.8289 4.9473 8.4494 6.67811 6.75479C6.30983 5.75887 6.32704 4.66127 6.72637 3.67739C7.05474 2.85876 7.63869 2.16805 8.39129 1.70807C8.9817 1.31706 9.66031 1.07944 10.3657 1.01673C11.0711 0.954022 11.7809 1.06819 12.4311 1.34892L13.0482 1.6162L10.1824 4.56738L11.4371 5.82582L14.3809 2.94887L14.6482 3.56788C14.8735 4.08976 14.993 4.65119 14.9997 5.21961C15.0064 5.78802 14.9002 6.35211 14.6872 6.87915C14.476 7.40029 14.1623 7.87368 13.7647 8.27122C13.5394 8.49169 13.2904 8.68653 13.0222 8.85218C12.4673 9.22275 11.8324 9.45636 11.1697 9.5338C10.5069 9.61124 9.83521 9.5303 9.20982 9.29764C8.11194 10.4113 5.37142 13.1704 3.89119 14.5522C3.59426 14.8219 3.20832 14.9726 2.80723 14.9754ZM10.7448 1.92802C10.087 1.92637 9.44359 2.12018 8.89614 2.48485C8.68265 2.6152 8.48437 2.76897 8.30498 2.9433C7.82789 3.42423 7.50926 4.03953 7.39182 4.70669C7.27437 5.37385 7.36374 6.06098 7.64792 6.67591L7.78342 6.97288L7.55048 7.20025C5.81224 8.89672 3.28146 11.4201 2.06479 12.7045C1.95646 12.8658 1.91012 13.0608 1.93435 13.2535C1.95857 13.4463 2.05171 13.6238 2.19657 13.7532C2.28005 13.8462 2.38177 13.9211 2.49541 13.9731C2.59557 14.0184 2.70383 14.043 2.81373 14.0455C2.98064 14.0413 3.14044 13.977 3.26383 13.8646C4.83687 12.3964 7.87622 9.32641 8.76807 8.42435L8.9973 8.19326L9.29242 8.32783C9.80618 8.56732 10.3731 8.66985 10.9382 8.62545C11.5033 8.58106 12.0473 8.39125 12.5174 8.07447C12.7313 7.9426 12.9296 7.78694 13.1085 7.61045C13.4183 7.30153 13.6631 6.93374 13.8286 6.52874C13.994 6.12375 14.0767 5.68974 14.0719 5.25228C14.0719 5.03662 14.0505 4.82148 14.0078 4.61007L11.4306 7.12508L8.87944 4.57759L11.3944 1.98834C11.1804 1.94674 10.9628 1.92653 10.7448 1.92802Z" fill="#C5C5C5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -1,3 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.80723 14.9754C2.57119 14.9721 2.33826 14.9211 2.12247 14.8254C1.90667 14.7297 1.71248 14.5913 1.55158 14.4186C1.2385 14.1334 1.04433 13.7408 1.00775 13.3189C0.966225 12.8828 1.09269 12.4473 1.36133 12.1013C2.56779 10.8289 4.9473 8.4494 6.67811 6.75479C6.30983 5.75887 6.32704 4.66127 6.72637 3.67739C7.05474 2.85876 7.63869 2.16805 8.39129 1.70807C8.9817 1.31706 9.66031 1.07944 10.3657 1.01673C11.0711 0.954022 11.7809 1.06819 12.4311 1.34892L13.0482 1.6162L10.1824 4.56738L11.4371 5.82582L14.3809 2.94887L14.6482 3.56788C14.8735 4.08976 14.993 4.65119 14.9997 5.21961C15.0064 5.78802 14.9002 6.35211 14.6872 6.87915C14.476 7.40029 14.1623 7.87368 13.7647 8.27122C13.5394 8.49169 13.2904 8.68653 13.0222 8.85218C12.4673 9.22275 11.8324 9.45636 11.1697 9.5338C10.5069 9.61124 9.83521 9.5303 9.20982 9.29764C8.11194 10.4113 5.37142 13.1704 3.89119 14.5522C3.59426 14.8219 3.20832 14.9726 2.80723 14.9754ZM10.7448 1.92802C10.087 1.92637 9.44359 2.12018 8.89614 2.48485C8.68265 2.6152 8.48437 2.76897 8.30498 2.9433C7.82789 3.42423 7.50926 4.03953 7.39182 4.70669C7.27438 5.37385 7.36374 6.06098 7.64792 6.67591L7.78342 6.97288L7.55048 7.20025C5.81224 8.89672 3.28146 11.4201 2.06479 12.7045C1.95646 12.8658 1.91012 13.0608 1.93435 13.2535C1.95857 13.4463 2.05171 13.6238 2.19657 13.7532C2.28005 13.8462 2.38177 13.9211 2.49541 13.9731C2.59557 14.0184 2.70383 14.043 2.81373 14.0455C2.98064 14.0413 3.14044 13.977 3.26383 13.8646C4.83687 12.3964 7.87622 9.32641 8.76807 8.42435L8.9973 8.19326L9.29242 8.32783C9.80617 8.56732 10.3731 8.66985 10.9382 8.62545C11.5033 8.58106 12.0473 8.39125 12.5174 8.07447C12.7313 7.9426 12.9296 7.78694 13.1085 7.61045C13.4183 7.30153 13.6631 6.93374 13.8286 6.52874C13.994 6.12375 14.0767 5.68974 14.0719 5.25228C14.0719 5.03662 14.0505 4.82148 14.0078 4.61007L11.4306 7.12508L8.87944 4.57759L11.3944 1.98834C11.1804 1.94674 10.9628 1.92653 10.7448 1.92802Z" fill="#424242"/>
|
||||
<g opacity="0.5">
|
||||
<path d="M2.80723 14.9754C2.57119 14.9721 2.33826 14.9211 2.12247 14.8254C1.90667 14.7297 1.71248 14.5913 1.55158 14.4186C1.2385 14.1334 1.04433 13.7408 1.00775 13.3189C0.966225 12.8828 1.09269 12.4473 1.36133 12.1013C2.56779 10.8289 4.9473 8.4494 6.67811 6.75479C6.30983 5.75887 6.32704 4.66127 6.72637 3.67739C7.05474 2.85876 7.63869 2.16805 8.39129 1.70807C8.9817 1.31706 9.66031 1.07944 10.3657 1.01673C11.0711 0.954022 11.7809 1.06819 12.4311 1.34892L13.0482 1.6162L10.1824 4.56738L11.4371 5.82582L14.3809 2.94887L14.6482 3.56788C14.8735 4.08976 14.993 4.65119 14.9997 5.21961C15.0064 5.78802 14.9002 6.35211 14.6872 6.87915C14.476 7.40029 14.1623 7.87368 13.7647 8.27122C13.5394 8.49169 13.2904 8.68653 13.0222 8.85218C12.4673 9.22275 11.8324 9.45636 11.1697 9.5338C10.5069 9.61124 9.83521 9.5303 9.20982 9.29764C8.11194 10.4113 5.37142 13.1704 3.89119 14.5522C3.59426 14.8219 3.20832 14.9726 2.80723 14.9754ZM10.7448 1.92802C10.087 1.92637 9.44359 2.12018 8.89614 2.48485C8.68265 2.6152 8.48437 2.76897 8.30498 2.9433C7.82789 3.42423 7.50926 4.03953 7.39182 4.70669C7.27437 5.37385 7.36374 6.06098 7.64792 6.67591L7.78342 6.97288L7.55048 7.20025C5.81224 8.89672 3.28146 11.4201 2.06479 12.7045C1.95646 12.8658 1.91012 13.0608 1.93435 13.2535C1.95857 13.4463 2.05171 13.6238 2.19657 13.7532C2.28005 13.8462 2.38177 13.9211 2.49541 13.9731C2.59557 14.0184 2.70383 14.043 2.81373 14.0455C2.98064 14.0413 3.14044 13.977 3.26383 13.8646C4.83687 12.3964 7.87622 9.32641 8.76807 8.42435L8.9973 8.19326L9.29242 8.32783C9.80618 8.56732 10.3731 8.66985 10.9382 8.62545C11.5033 8.58106 12.0473 8.39125 12.5174 8.07447C12.7313 7.9426 12.9296 7.78694 13.1085 7.61045C13.4183 7.30153 13.6631 6.93374 13.8286 6.52874C13.994 6.12375 14.0767 5.68974 14.0719 5.25228C14.0719 5.03662 14.0505 4.82148 14.0078 4.61007L11.4306 7.12508L8.87944 4.57759L11.3944 1.98834C11.1804 1.94674 10.9628 1.92653 10.7448 1.92802Z" fill="#424242"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -7,7 +7,7 @@ import * as httpRequest from 'request-light';
|
||||
import * as vscode from 'vscode';
|
||||
import { addJSONProviders } from './features/jsonContributions';
|
||||
import { NpmScriptsTreeDataProvider } from './npmView';
|
||||
import { invalidateTasksCache, NpmTaskProvider } from './tasks';
|
||||
import { invalidateTasksCache, NpmTaskProvider, hasPackageJson } from './tasks';
|
||||
import { invalidateHoverScriptsCache, NpmScriptHoverProvider } from './scriptHover';
|
||||
import { runSelectedScript } from './commands';
|
||||
|
||||
@@ -41,6 +41,10 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
|
||||
context.subscriptions.push(d);
|
||||
context.subscriptions.push(vscode.commands.registerCommand('npm.runSelectedScript', runSelectedScript));
|
||||
context.subscriptions.push(addJSONProviders(httpRequest.xhr));
|
||||
|
||||
if (await hasPackageJson()) {
|
||||
vscode.commands.executeCommand('setContext', 'npm:showScriptExplorer', true);
|
||||
}
|
||||
}
|
||||
|
||||
function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposable | undefined {
|
||||
|
||||
@@ -262,6 +262,22 @@ export function getPackageJsonUriFromTask(task: Task): Uri | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function hasPackageJson(): Promise<boolean> {
|
||||
let folders = workspace.workspaceFolders;
|
||||
if (!folders) {
|
||||
return false;
|
||||
}
|
||||
for (const folder of folders) {
|
||||
if (folder.uri.scheme === 'file') {
|
||||
let packageJson = path.join(folder.uri.fsPath, 'package.json');
|
||||
if (await exists(packageJson)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function exists(file: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, _reject) => {
|
||||
fs.exists(file, (value) => {
|
||||
|
||||
@@ -130,4 +130,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +314,7 @@ const preferredFixes = new Set([
|
||||
'forgottenThisPropertyAccess',
|
||||
'spelling',
|
||||
'unusedIdentifier',
|
||||
'addMissingAwait',
|
||||
]);
|
||||
function isPreferredFix(tsAction: Proto.CodeFixAction): boolean {
|
||||
return preferredFixes.has(tsAction.fixName);
|
||||
|
||||
@@ -73,10 +73,10 @@ class TscTaskProvider implements vscode.TaskProvider {
|
||||
|
||||
public resolveTask(_task: vscode.Task): vscode.Task | undefined {
|
||||
const definition = <TypeScriptTaskDefinition>_task.definition;
|
||||
const badTsconfig = '\\tsconfig.json';
|
||||
if ((definition.tsconfig.length > badTsconfig.length) && (definition.tsconfig.substring(definition.tsconfig.length - badTsconfig.length, definition.tsconfig.length) === badTsconfig)) {
|
||||
const badTsconfig = /\\tsconfig.*\.json/;
|
||||
if (badTsconfig.exec(definition.tsconfig) !== null) {
|
||||
// Warn that the task has the wrong slash type
|
||||
vscode.window.showWarningMessage(localize('badTsConfig', "Typescript Task in tasks.json contains \"\\\\\". Typescript tasks must use \"/\""));
|
||||
vscode.window.showWarningMessage(localize('badTsConfig', "Typescript Task in tasks.json contains \"\\\\\". Typescript tasks tsconfig must use \"/\""));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -113,4 +113,31 @@ suite('commands namespace tests', () => {
|
||||
|
||||
return Promise.all([a, b, c, d]);
|
||||
});
|
||||
});
|
||||
|
||||
test('onDidExecuteCommand', async function () {
|
||||
let args: any[];
|
||||
let d1 = commands.registerCommand('t1', function () {
|
||||
args = [...arguments];
|
||||
});
|
||||
|
||||
|
||||
const p = new Promise((resolve, reject) => {
|
||||
|
||||
let d2 = commands.onDidExecuteCommand(event => {
|
||||
d2.dispose();
|
||||
d1.dispose();
|
||||
|
||||
try {
|
||||
assert.equal(event.command, 't1');
|
||||
assert.deepEqual(args, event.arguments);
|
||||
resolve();
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await commands.executeCommand('t1', { foo: 1 });
|
||||
await p;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -195,4 +195,27 @@ suite('editor tests', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('throw when using invalid edit', async function () {
|
||||
|
||||
await withRandomFileEditor('foo', editor => {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
editor.edit(edit => {
|
||||
edit.insert(new Position(0, 0), 'bar');
|
||||
setTimeout(() => {
|
||||
try {
|
||||
edit.insert(new Position(0, 0), 'bar');
|
||||
reject(new Error('expected error'));
|
||||
} catch (err) {
|
||||
assert.ok(true);
|
||||
resolve();
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { window, Terminal, TerminalVirtualProcess, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode';
|
||||
import { window, Terminal, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode';
|
||||
import { doesNotThrow, equal, ok } from 'assert';
|
||||
|
||||
suite('window namespace tests', () => {
|
||||
@@ -264,14 +264,16 @@ suite('window namespace tests', () => {
|
||||
});
|
||||
term.dispose();
|
||||
});
|
||||
const virtualProcess: TerminalVirtualProcess = {
|
||||
onDidWrite: new EventEmitter<string>().event
|
||||
const pty: Pseudoterminal = {
|
||||
onDidWrite: new EventEmitter<string>().event,
|
||||
open: () => {},
|
||||
close: () => {}
|
||||
};
|
||||
window.createTerminal({ name: 'c', virtualProcess });
|
||||
window.createTerminal({ name: 'c', pty });
|
||||
});
|
||||
|
||||
test('should fire Terminal.onData on write', (done) => {
|
||||
const reg1 = window.onDidOpenTerminal(term => {
|
||||
const reg1 = window.onDidOpenTerminal(async term => {
|
||||
equal(terminal, term);
|
||||
reg1.dispose();
|
||||
const reg2 = terminal.onDidWriteData(data => {
|
||||
@@ -283,13 +285,18 @@ suite('window namespace tests', () => {
|
||||
});
|
||||
terminal.dispose();
|
||||
});
|
||||
await startPromise;
|
||||
writeEmitter.fire('bar');
|
||||
});
|
||||
let startResolve: () => void;
|
||||
const startPromise: Promise<void> = new Promise<void>(r => startResolve = r);
|
||||
const writeEmitter = new EventEmitter<string>();
|
||||
const virtualProcess: TerminalVirtualProcess = {
|
||||
onDidWrite: writeEmitter.event
|
||||
const pty: Pseudoterminal = {
|
||||
onDidWrite: writeEmitter.event,
|
||||
open: () => startResolve(),
|
||||
close: () => {}
|
||||
};
|
||||
const terminal = window.createTerminal({ name: 'foo', virtualProcess });
|
||||
const terminal = window.createTerminal({ name: 'foo', pty });
|
||||
});
|
||||
|
||||
test('should fire provide dimensions on start as the terminal has been shown', (done) => {
|
||||
@@ -297,9 +304,9 @@ suite('window namespace tests', () => {
|
||||
equal(terminal, term);
|
||||
reg1.dispose();
|
||||
});
|
||||
const virtualProcess: TerminalVirtualProcess = {
|
||||
const pty: Pseudoterminal = {
|
||||
onDidWrite: new EventEmitter<string>().event,
|
||||
start: (dimensions) => {
|
||||
open: (dimensions) => {
|
||||
ok(dimensions!.columns > 0);
|
||||
ok(dimensions!.rows > 0);
|
||||
const reg3 = window.onDidCloseTerminal(() => {
|
||||
@@ -307,9 +314,10 @@ suite('window namespace tests', () => {
|
||||
done();
|
||||
});
|
||||
terminal.dispose();
|
||||
}
|
||||
},
|
||||
close: () => {}
|
||||
};
|
||||
const terminal = window.createTerminal({ name: 'foo', virtualProcess });
|
||||
const terminal = window.createTerminal({ name: 'foo', pty });
|
||||
});
|
||||
|
||||
test('should respect dimension overrides', (done) => {
|
||||
@@ -332,11 +340,13 @@ suite('window namespace tests', () => {
|
||||
});
|
||||
const writeEmitter = new EventEmitter<string>();
|
||||
const overrideDimensionsEmitter = new EventEmitter<TerminalDimensions>();
|
||||
const virtualProcess: TerminalVirtualProcess = {
|
||||
const pty: Pseudoterminal = {
|
||||
onDidWrite: writeEmitter.event,
|
||||
onDidOverrideDimensions: overrideDimensionsEmitter.event
|
||||
onDidOverrideDimensions: overrideDimensionsEmitter.event,
|
||||
open: () => {},
|
||||
close: () => {}
|
||||
};
|
||||
const terminal = window.createTerminal({ name: 'foo', virtualProcess });
|
||||
const terminal = window.createTerminal({ name: 'foo', pty });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
suite('workspace-namespace', () => {
|
||||
|
||||
suite('Tasks', () => {
|
||||
|
||||
test('CustomExecution2 task should start and shutdown successfully', (done) => {
|
||||
interface CustomTestingTaskDefinition extends vscode.TaskDefinition {
|
||||
/**
|
||||
* One of the task properties. This can be used to customize the task in the tasks.json
|
||||
*/
|
||||
customProp1: string;
|
||||
}
|
||||
const taskType: string = 'customTesting';
|
||||
const taskName = 'First custom task';
|
||||
const reg1 = vscode.window.onDidOpenTerminal(term => {
|
||||
reg1.dispose();
|
||||
const reg2 = term.onDidWriteData(e => {
|
||||
reg2.dispose();
|
||||
assert.equal(e, 'testing\r\n');
|
||||
term.dispose();
|
||||
});
|
||||
});
|
||||
const taskProvider = vscode.tasks.registerTaskProvider(taskType, {
|
||||
provideTasks: () => {
|
||||
const result: vscode.Task[] = [];
|
||||
const kind: CustomTestingTaskDefinition = {
|
||||
type: taskType,
|
||||
customProp1: 'testing task one'
|
||||
};
|
||||
const writeEmitter = new vscode.EventEmitter<string>();
|
||||
const execution = new vscode.CustomExecution2((): Thenable<vscode.Pseudoterminal> => {
|
||||
const pty: vscode.Pseudoterminal = {
|
||||
onDidWrite: writeEmitter.event,
|
||||
open: () => {
|
||||
writeEmitter.fire('testing\r\n');
|
||||
},
|
||||
close: () => {
|
||||
taskProvider.dispose();
|
||||
done();
|
||||
}
|
||||
};
|
||||
return Promise.resolve(pty);
|
||||
});
|
||||
const task = new vscode.Task2(kind, vscode.TaskScope.Workspace, taskName, taskType, execution);
|
||||
result.push(task);
|
||||
return result;
|
||||
},
|
||||
resolveTask(_task: vscode.Task): vscode.Task | undefined {
|
||||
assert.fail('resolveTask should not trigger during the test');
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
vscode.commands.executeCommand('workbench.action.tasks.runTask', `${taskType}: ${taskName}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -520,6 +520,20 @@ suite('workspace-namespace', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('findFiles - null exclude', async () => {
|
||||
await vscode.workspace.findFiles('**/file.txt').then((res) => {
|
||||
// search.exclude folder is still searched, files.exclude folder is not
|
||||
assert.equal(res.length, 1);
|
||||
assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'file.txt');
|
||||
});
|
||||
|
||||
await vscode.workspace.findFiles('**/file.txt', null).then((res) => {
|
||||
// search.exclude and files.exclude folders are both searched
|
||||
assert.equal(res.length, 2);
|
||||
assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'file.txt');
|
||||
});
|
||||
});
|
||||
|
||||
test('findFiles - exclude', () => {
|
||||
return vscode.workspace.findFiles('**/*.png').then((res) => {
|
||||
assert.equal(res.length, 2);
|
||||
@@ -796,4 +810,29 @@ suite('workspace-namespace', () => {
|
||||
we.deleteFile(docUri, { ignoreIfNotExists: true });
|
||||
assert.ok(await vscode.workspace.applyEdit(we));
|
||||
});
|
||||
|
||||
test('The api workspace.applyEdit drops the TextEdit if there is a RenameFile later #77735', async function () {
|
||||
|
||||
let [f1, f2, f3] = await Promise.all([createRandomFile(), createRandomFile(), createRandomFile()]);
|
||||
|
||||
let we = new vscode.WorkspaceEdit();
|
||||
we.insert(f1, new vscode.Position(0, 0), 'f1');
|
||||
we.insert(f2, new vscode.Position(0, 0), 'f2');
|
||||
we.insert(f3, new vscode.Position(0, 0), 'f3');
|
||||
|
||||
let f1_ = nameWithUnderscore(f1);
|
||||
we.renameFile(f1, f1_);
|
||||
|
||||
assert.ok(await vscode.workspace.applyEdit(we));
|
||||
|
||||
assert.equal((await vscode.workspace.openTextDocument(f3)).getText(), 'f3');
|
||||
assert.equal((await vscode.workspace.openTextDocument(f2)).getText(), 'f2');
|
||||
assert.equal((await vscode.workspace.openTextDocument(f1_)).getText(), 'f1');
|
||||
try {
|
||||
await vscode.workspace.fs.stat(f1);
|
||||
assert.ok(false);
|
||||
} catch {
|
||||
assert.ok(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"search.exclude": {
|
||||
"**/search-exclude/**": true
|
||||
},
|
||||
"files.exclude": {
|
||||
"**/files-exclude/**": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
file
|
||||
@@ -0,0 +1 @@
|
||||
file
|
||||
@@ -53,17 +53,17 @@
|
||||
"statusBar/windowIndicator": [
|
||||
{
|
||||
"command": "vscode-testresolver.newWindow",
|
||||
"when": "!remoteAuthority",
|
||||
"when": "!remoteName",
|
||||
"group": "9_local_testresolver@2"
|
||||
},
|
||||
{
|
||||
"command": "vscode-testresolver.showLog",
|
||||
"when": "remoteAuthority =~ /^test\\+.*$/",
|
||||
"when": "remoteName == test",
|
||||
"group": "1_remote_testresolver_open@3"
|
||||
},
|
||||
{
|
||||
"command": "vscode-testresolver.newWindow",
|
||||
"when": "remoteAuthority =~ /^test\\+.*$/",
|
||||
"when": "remoteName == test",
|
||||
"group": "1_remote_testresolver_open@1"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,31 +1,34 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "",
|
||||
"blockComment": ["<!--", "-->"]
|
||||
"blockComment": [ "<!--", "-->" ]
|
||||
},
|
||||
"brackets": [
|
||||
["<", ">"]
|
||||
["<!--", "-->"],
|
||||
["<", ">"],
|
||||
["{", "}"],
|
||||
["(", ")"]
|
||||
],
|
||||
"autoClosingPairs": [
|
||||
["<", ">"],
|
||||
["'", "'"],
|
||||
["\"", "\""]
|
||||
{ "open": "{", "close": "}"},
|
||||
{ "open": "[", "close": "]"},
|
||||
{ "open": "(", "close": ")" },
|
||||
{ "open": "'", "close": "'" },
|
||||
{ "open": "\"", "close": "\"" },
|
||||
{ "open": "<!--", "close": "-->", "notIn": [ "comment", "string" ]},
|
||||
{ "open": "<![CDATA[", "close": "]]>", "notIn": [ "comment", "string" ]}
|
||||
],
|
||||
"surroundingPairs": [
|
||||
["<", ">"],
|
||||
["'", "'"],
|
||||
["\"", "\""]
|
||||
]
|
||||
|
||||
// enhancedBrackets: [{
|
||||
// tokenType: 'tag.tag-$1.xml',
|
||||
// openTrigger: '>',
|
||||
// open: /<(\w[\w\d]*)([^\/>]*(?!\/)>)[^<>]*$/i,
|
||||
// closeComplete: '</$1>',
|
||||
// closeTrigger: '>',
|
||||
// close: /<\/(\w[\w\d]*)\s*>$/i
|
||||
// }],
|
||||
|
||||
// autoClosingPairs: [['\'', '\''], ['"', '"'] ]
|
||||
|
||||
{ "open": "'", "close": "'" },
|
||||
{ "open": "\"", "close": "\"" },
|
||||
{ "open": "{", "close": "}"},
|
||||
{ "open": "[", "close": "]"},
|
||||
{ "open": "(", "close": ")" },
|
||||
{ "open": "<", "close": ">" }
|
||||
],
|
||||
"folding": {
|
||||
"markers": {
|
||||
"start": "^\\s*<!--\\s*#region\\b.*-->",
|
||||
"end": "^\\s*<!--\\s*#endregion\\b.*-->"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.37.0",
|
||||
"distro": "dbf77e1135be7d403c9d344652fdfdb766e28517",
|
||||
"distro": "11ab6b1c5be090591adc26a81f72a16908697165",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
@@ -51,8 +51,8 @@
|
||||
"vscode-ripgrep": "^1.5.5",
|
||||
"vscode-sqlite3": "4.0.8",
|
||||
"vscode-textmate": "^4.2.2",
|
||||
"xterm": "3.15.0-beta71",
|
||||
"xterm-addon-search": "0.2.0-beta2",
|
||||
"xterm": "3.15.0-beta89",
|
||||
"xterm-addon-search": "0.2.0-beta3",
|
||||
"xterm-addon-web-links": "0.1.0-beta10",
|
||||
"yauzl": "^2.9.2",
|
||||
"yazl": "^2.4.3"
|
||||
@@ -94,7 +94,7 @@
|
||||
"gulp-gunzip": "^1.0.0",
|
||||
"gulp-json-editor": "^2.5.0",
|
||||
"gulp-plumber": "^1.2.0",
|
||||
"gulp-remote-src": "^0.4.4",
|
||||
"gulp-remote-retry-src": "^0.6.0",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-replace": "^0.5.4",
|
||||
"gulp-shell": "^0.6.5",
|
||||
@@ -158,4 +158,4 @@
|
||||
"windows-mutex": "0.3.0",
|
||||
"windows-process-tree": "0.2.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
"vscode-proxy-agent": "0.4.0",
|
||||
"vscode-ripgrep": "^1.5.5",
|
||||
"vscode-textmate": "^4.2.2",
|
||||
"xterm": "3.15.0-beta71",
|
||||
"xterm-addon-search": "0.2.0-beta2",
|
||||
"xterm": "3.15.0-beta89",
|
||||
"xterm-addon-search": "0.2.0-beta3",
|
||||
"xterm-addon-web-links": "0.1.0-beta10",
|
||||
"yauzl": "^2.9.2",
|
||||
"yazl": "^2.4.3"
|
||||
|
||||
@@ -1149,20 +1149,20 @@ vscode-windows-registry@1.0.1:
|
||||
dependencies:
|
||||
nan "^2.12.1"
|
||||
|
||||
xterm-addon-search@0.2.0-beta2:
|
||||
version "0.2.0-beta2"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta2.tgz#c3173f0a6f207ee9f1848849174ee5d6b6ce8262"
|
||||
integrity sha512-XEcwi2TeFGk2MuIFjiI/OpVXSNO5dGQBvHH3o+9KzqG3ooVqhhDqzwxs092QGNcNCGh8hGn/PWZiczaBBnKm/g==
|
||||
xterm-addon-search@0.2.0-beta3:
|
||||
version "0.2.0-beta3"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta3.tgz#710ce14658e269c5a4791f5a9e2f520883a2e62b"
|
||||
integrity sha512-KzVdkEtGbKJe9ER2TmrI7XjF/wUq1lir9U63vPJi0t2ymQvIECl1V63f9QtOp1vvpdhbZiXBxO+vGTj+y0tRow==
|
||||
|
||||
xterm-addon-web-links@0.1.0-beta10:
|
||||
version "0.1.0-beta10"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23"
|
||||
integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg==
|
||||
|
||||
xterm@3.15.0-beta71:
|
||||
version "3.15.0-beta71"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta71.tgz#2728c9800ca3b08423e835e9504bd1f4b5de6253"
|
||||
integrity sha512-8M/cLaxZ+iDopRxLPdPfKuDGaNNyYTdCeytdxjMSH0N7dZzbx6fbaEygQdCrV5pO9cGnT92MefSjVPGRXRiBLA==
|
||||
xterm@3.15.0-beta89:
|
||||
version "3.15.0-beta89"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta89.tgz#255962e2595deefb42b8c0043001256526163a3f"
|
||||
integrity sha512-rNaoUamacPRg+ejbKDGRDNqR3SZ3Uf/pUW0mO+FF25/lIgdLq8x7RgZVBgFweCZ/dijPjxoyMcgfNDTH9h8LOg==
|
||||
|
||||
yauzl@^2.9.2:
|
||||
version "2.10.0"
|
||||
|
||||
@@ -17,6 +17,7 @@ arguments=(
|
||||
'(- *)'{--telemetry}'[Shows all telemetry events which VS code collects.]'
|
||||
'--extensions-dir[set the root path for extensions]:root path:_directories'
|
||||
'--list-extensions[list the installed extensions]'
|
||||
'--category[filters instaled extension list by category, when using --list-extension]'
|
||||
'--show-versions[show versions of installed extensions, when using --list-extension]'
|
||||
'--install-extension[install an extension]:id or path:_files -g "*.vsix(-.)"'
|
||||
'--uninstall-extension[uninstall an extension]:id or path:_files -g "*.vsix(-.)"'
|
||||
|
||||
@@ -51,4 +51,4 @@ else
|
||||
CLI="$VSCODE_PATH/resources/app/out/cli.js"
|
||||
fi
|
||||
ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" "$@"
|
||||
exit $?
|
||||
exit $?
|
||||
|
||||
@@ -58,15 +58,21 @@ function code() {
|
||||
function code-wsl()
|
||||
{
|
||||
# in a wsl shell
|
||||
local WIN_CODE_CLI_CMD=$(wslpath -w "$ROOT/scripts/code-cli.bat" 2>/dev/null)
|
||||
if ! [ -z "$WIN_CODE_CLI_CMD" ]; then
|
||||
ELECTRON="$ROOT/.build/electron/Code - OSS.exe"
|
||||
if [ -f "$ELECTRON" ]; then
|
||||
local CWD=$(pwd)
|
||||
cd $ROOT
|
||||
export WSLENV=ELECTRON_RUN_AS_NODE/w:$WSLENV
|
||||
local WSL_EXT_ID="ms-vscode-remote.remote-wsl"
|
||||
local WSL_EXT_WLOC=$(cmd.exe /c "$WIN_CODE_CLI_CMD" --locate-extension $WSL_EXT_ID)
|
||||
if ! [ -z "$WSL_EXT_WLOC" ]; then
|
||||
local WSL_EXT_WLOC=$(ELECTRON_RUN_AS_NODE=1 "$ROOT/.build/electron/Code - OSS.exe" "out/cli.js" --locate-extension $WSL_EXT_ID)
|
||||
cd $CWD
|
||||
if [ -n "$WSL_EXT_WLOC" ]; then
|
||||
# replace \r\n with \n in WSL_EXT_WLOC
|
||||
local WSL_CODE=$(wslpath -u "${WSL_EXT_WLOC%%[[:cntrl:]]}")/scripts/wslCode-dev.sh
|
||||
$WSL_CODE "$ROOT" "$@"
|
||||
exit $?
|
||||
else
|
||||
echo "Remote WSL not installed, trying to run VSCode in WSL."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -74,4 +80,4 @@ function code-wsl()
|
||||
if ! [ -z ${IN_WSL+x} ]; then
|
||||
code-wsl "$@"
|
||||
fi
|
||||
code "$@"
|
||||
code "$@"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Type definitions for Electron 4.2.5
|
||||
// Type definitions for Electron 4.2.7
|
||||
// Project: http://electronjs.org/
|
||||
// Definitions by: The Electron Team <https://github.com/electron/electron>
|
||||
// Definitions: https://github.com/electron/electron-typescript-definitions
|
||||
@@ -3479,14 +3479,14 @@ declare namespace Electron {
|
||||
* Creates a new NativeImage instance from the NSImage that maps to the given image
|
||||
* name. See NSImageName for a list of possible values. The hslShift is applied to
|
||||
* the image with the following rules This means that [-1, 0, 1] will make the
|
||||
* image completely white and [-1, 1, 0] will make the image completely black. In
|
||||
* some cases, the NSImageName doesn't match its string representation; one example
|
||||
* of this is NSFolderImageName, whose string representation would actually be
|
||||
* NSFolder. Therefore, you'll need to determine the correct string representation
|
||||
* for your image before passing it in. This can be done with the following: echo
|
||||
* -e '#import <Cocoa/Cocoa.h>\nint main() { NSLog(@"%@", SYSTEM_IMAGE_NAME); }' |
|
||||
* clang -otest -x objective-c -framework Cocoa - && ./test where SYSTEM_IMAGE_NAME
|
||||
* should be replaced with any value from this list.
|
||||
* image completely white and [-1, 1, 0] will make the image completely black. In
|
||||
* some cases, the NSImageName doesn't match its string representation; one example
|
||||
* of this is NSFolderImageName, whose string representation would actually be
|
||||
* NSFolder. Therefore, you'll need to determine the correct string representation
|
||||
* for your image before passing it in. This can be done with the following: echo
|
||||
* -e '#import <Cocoa/Cocoa.h>\nint main() { NSLog(@"%@", SYSTEM_IMAGE_NAME); }' |
|
||||
* clang -otest -x objective-c -framework Cocoa - && ./test where SYSTEM_IMAGE_NAME
|
||||
* should be replaced with any value from this list.
|
||||
*/
|
||||
static createFromNamedImage(imageName: string, hslShift: number[]): NativeImage;
|
||||
/**
|
||||
@@ -3737,6 +3737,17 @@ declare namespace Electron {
|
||||
once(event: 'unlock-screen', listener: Function): this;
|
||||
addListener(event: 'unlock-screen', listener: Function): this;
|
||||
removeListener(event: 'unlock-screen', listener: Function): this;
|
||||
/**
|
||||
* Calculate the system idle state. idleThreshold is the amount of time (in
|
||||
* seconds) before considered idle. callback will be called synchronously on some
|
||||
* systems and with an idleState argument that describes the system's state. locked
|
||||
* is available on supported systems only.
|
||||
*/
|
||||
querySystemIdleState(idleThreshold: number, callback: (idleState: 'active' | 'idle' | 'locked' | 'unknown') => void): void;
|
||||
/**
|
||||
* Calculate system idle time in seconds.
|
||||
*/
|
||||
querySystemIdleTime(callback: (idleTime: number) => void): void;
|
||||
}
|
||||
|
||||
interface PowerSaveBlocker extends EventEmitter {
|
||||
@@ -4418,30 +4429,6 @@ declare namespace Electron {
|
||||
* The new RGBA color the user assigned to be their system accent color.
|
||||
*/
|
||||
newColor: string) => void): this;
|
||||
/**
|
||||
* NOTE: This event is only emitted after you have called
|
||||
* startAppLevelAppearanceTrackingOS
|
||||
*/
|
||||
on(event: 'appearance-changed', listener: (
|
||||
/**
|
||||
* Can be `dark` or `light`
|
||||
*/
|
||||
newAppearance: ('dark' | 'light')) => void): this;
|
||||
once(event: 'appearance-changed', listener: (
|
||||
/**
|
||||
* Can be `dark` or `light`
|
||||
*/
|
||||
newAppearance: ('dark' | 'light')) => void): this;
|
||||
addListener(event: 'appearance-changed', listener: (
|
||||
/**
|
||||
* Can be `dark` or `light`
|
||||
*/
|
||||
newAppearance: ('dark' | 'light')) => void): this;
|
||||
removeListener(event: 'appearance-changed', listener: (
|
||||
/**
|
||||
* Can be `dark` or `light`
|
||||
*/
|
||||
newAppearance: ('dark' | 'light')) => void): this;
|
||||
on(event: 'color-changed', listener: (event: Event) => void): this;
|
||||
once(event: 'color-changed', listener: (event: Event) => void): this;
|
||||
addListener(event: 'color-changed', listener: (event: Event) => void): this;
|
||||
@@ -8789,17 +8776,33 @@ declare namespace Electron {
|
||||
* The type of media access being requested, can be video, audio or unknown
|
||||
*/
|
||||
mediaType: ('video' | 'audio' | 'unknown');
|
||||
/**
|
||||
* The last URL the requesting frame loaded
|
||||
*/
|
||||
requestingUrl: string;
|
||||
/**
|
||||
* Whether the frame making the request is the main frame
|
||||
*/
|
||||
isMainFrame: boolean;
|
||||
}
|
||||
|
||||
interface PermissionRequestHandlerDetails {
|
||||
/**
|
||||
* The url of the openExternal request.
|
||||
*/
|
||||
externalURL: string;
|
||||
externalURL?: string;
|
||||
/**
|
||||
* The types of media access being requested, elements can be video or audio
|
||||
*/
|
||||
mediaTypes: Array<'video' | 'audio'>;
|
||||
mediaTypes?: Array<'video' | 'audio'>;
|
||||
/**
|
||||
* The last URL the requesting frame loaded
|
||||
*/
|
||||
requestingUrl: string;
|
||||
/**
|
||||
* Whether the frame making the request is the main frame
|
||||
*/
|
||||
isMainFrame: boolean;
|
||||
}
|
||||
|
||||
interface PluginCrashedEvent extends Event {
|
||||
|
||||
@@ -15,6 +15,11 @@ declare module 'xterm' {
|
||||
*/
|
||||
export type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
|
||||
|
||||
/**
|
||||
* A string representing log level.
|
||||
*/
|
||||
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'off';
|
||||
|
||||
/**
|
||||
* A string representing a renderer type.
|
||||
*/
|
||||
@@ -107,6 +112,18 @@ declare module 'xterm' {
|
||||
*/
|
||||
lineHeight?: number;
|
||||
|
||||
/**
|
||||
* What log level to use, this will log for all levels below and including
|
||||
* what is set:
|
||||
*
|
||||
* 1. debug
|
||||
* 2. info (default)
|
||||
* 3. warn
|
||||
* 4. error
|
||||
* 5. off
|
||||
*/
|
||||
logLevel?: LogLevel;
|
||||
|
||||
/**
|
||||
* Whether to treat option as the meta key.
|
||||
*/
|
||||
@@ -177,6 +194,12 @@ declare module 'xterm' {
|
||||
* not whitespace.
|
||||
*/
|
||||
windowsMode?: boolean;
|
||||
|
||||
/**
|
||||
* A string containing all characters that are considered word separated by the
|
||||
* double click to select work logic.
|
||||
*/
|
||||
wordSeparator?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,7 +214,7 @@ declare module 'xterm' {
|
||||
cursor?: string,
|
||||
/** The accent color of the cursor (fg color for a block cursor) */
|
||||
cursorAccent?: string,
|
||||
/** The selection color (can be transparent) */
|
||||
/** The selection background color (can be transparent) */
|
||||
selection?: string,
|
||||
/** ANSI black (eg. `\x1b[30m`) */
|
||||
black?: string,
|
||||
@@ -483,12 +506,14 @@ declare module 'xterm' {
|
||||
* final character (e.g "m" for SGR) of the CSI sequence.
|
||||
* @param callback The function to handle the escape sequence. The callback
|
||||
* is called with the numerical params, as well as the special characters
|
||||
* (e.g. "$" for DECSCPP). Return true if the sequence was handled; false if
|
||||
* (e.g. "$" for DECSCPP). If the sequence has subparams the array will
|
||||
* contain subarrays with their numercial values.
|
||||
* Return true if the sequence was handled; false if
|
||||
* we should try a previous handler (set by addCsiHandler or setCsiHandler).
|
||||
* The most recently-added handler is tried first.
|
||||
* @return An IDisposable you can call to remove this handler.
|
||||
*/
|
||||
addCsiHandler(flag: string, callback: (params: number[], collect: string) => boolean): IDisposable;
|
||||
addCsiHandler(flag: string, callback: (params: (number | number[])[], collect: string) => boolean): IDisposable;
|
||||
|
||||
/**
|
||||
* (EXPERIMENTAL) Adds a handler for OSC escape sequences.
|
||||
@@ -668,12 +693,12 @@ declare module 'xterm' {
|
||||
* Retrieves an option's value from the terminal.
|
||||
* @param key The option key.
|
||||
*/
|
||||
getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'fontFamily' | 'fontWeight' | 'fontWeightBold' | 'rendererType' | 'termName'): string;
|
||||
getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'fontFamily' | 'fontWeight' | 'fontWeightBold' | 'logLevel' | 'rendererType' | 'termName' | 'wordSeparator'): string;
|
||||
/**
|
||||
* Retrieves an option's value from the terminal.
|
||||
* @param key The option key.
|
||||
*/
|
||||
getOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'windowsMode'): boolean;
|
||||
getOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'disableStdin' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'windowsMode'): boolean;
|
||||
/**
|
||||
* Retrieves an option's value from the terminal.
|
||||
* @param key The option key.
|
||||
@@ -700,13 +725,19 @@ declare module 'xterm' {
|
||||
* @param key The option key.
|
||||
* @param value The option value.
|
||||
*/
|
||||
setOption(key: 'fontFamily' | 'termName' | 'bellSound', value: string): void;
|
||||
setOption(key: 'fontFamily' | 'termName' | 'bellSound' | 'wordSeparator', value: string): void;
|
||||
/**
|
||||
* Sets an option on the terminal.
|
||||
* @param key The option key.
|
||||
* @param value The option value.
|
||||
*/
|
||||
setOption(key: 'fontWeight' | 'fontWeightBold', value: null | 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'): void;
|
||||
/**
|
||||
* Sets an option on the terminal.
|
||||
* @param key The option key.
|
||||
* @param value The option value.
|
||||
*/
|
||||
setOption(key: 'logLevel', value: LogLevel): void;
|
||||
/**
|
||||
* Sets an option on the terminal.
|
||||
* @param key The option key.
|
||||
@@ -724,7 +755,7 @@ declare module 'xterm' {
|
||||
* @param key The option key.
|
||||
* @param value The option value.
|
||||
*/
|
||||
setOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'debug' | 'disableStdin' | 'macOptionIsMeta' | 'popOnBell' | 'rightClickSelectsWord' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'windowsMode', value: boolean): void;
|
||||
setOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'disableStdin' | 'macOptionIsMeta' | 'popOnBell' | 'rightClickSelectsWord' | 'screenKeys' | 'useFlowControl' | 'visualBell' | 'windowsMode', value: boolean): void;
|
||||
/**
|
||||
* Sets an option on the terminal.
|
||||
* @param key The option key.
|
||||
@@ -929,16 +960,16 @@ declare module 'xterm' {
|
||||
// Modifications to official .d.ts below
|
||||
declare module 'xterm' {
|
||||
interface TerminalCore {
|
||||
debug: boolean;
|
||||
|
||||
handler(text: string): void;
|
||||
|
||||
_onScroll: IEventEmitter<number>;
|
||||
_onKey: IEventEmitter<{ key: string }>;
|
||||
|
||||
_charSizeService: {
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
_coreService: {
|
||||
triggerDataEvent(data: string, wasUserInput?: boolean): void;
|
||||
}
|
||||
|
||||
_renderService: {
|
||||
|
||||
@@ -122,7 +122,7 @@ export const isSafari = (!isChrome && (userAgent.indexOf('Safari') >= 0));
|
||||
export const isWebkitWebView = (!isChrome && !isSafari && isWebKit);
|
||||
export const isIPad = (userAgent.indexOf('iPad') >= 0);
|
||||
export const isEdgeWebView = isEdge && (userAgent.indexOf('WebView/') >= 0);
|
||||
export const isStandalone = (window.matchMedia('(display-mode: standalone)').matches);
|
||||
export const isStandalone = (window.matchMedia && window.matchMedia('(display-mode: standalone)').matches);
|
||||
|
||||
export function hasClipboardSupport() {
|
||||
if (isIE) {
|
||||
|
||||
@@ -1200,7 +1200,7 @@ export function asDomUri(uri: URI): URI {
|
||||
if (Schemas.vscodeRemote === uri.scheme) {
|
||||
// rewrite vscode-remote-uris to uris of the window location
|
||||
// so that they can be intercepted by the service worker
|
||||
return _location.with({ path: '/vscode-resources/fetch', query: JSON.stringify({ u: uri.toJSON(), i: 1 }) });
|
||||
return _location.with({ path: '/vscode-resources/fetch', query: `u=${JSON.stringify(uri)}` });
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
@@ -160,6 +160,8 @@ export class StandardWheelEvent {
|
||||
this.deltaY = e1.wheelDeltaY / 120;
|
||||
} else if (typeof e2.VERTICAL_AXIS !== 'undefined' && e2.axis === e2.VERTICAL_AXIS) {
|
||||
this.deltaY = -e2.detail / 3;
|
||||
} else {
|
||||
this.deltaY = -e.deltaY / 40;
|
||||
}
|
||||
|
||||
// horizontal delta scroll
|
||||
@@ -171,6 +173,8 @@ export class StandardWheelEvent {
|
||||
}
|
||||
} else if (typeof e2.HORIZONTAL_AXIS !== 'undefined' && e2.axis === e2.HORIZONTAL_AXIS) {
|
||||
this.deltaX = -e.detail / 3;
|
||||
} else {
|
||||
this.deltaX = -e.deltaX / 40;
|
||||
}
|
||||
|
||||
// Assume a vertical scroll if nothing else worked
|
||||
@@ -195,4 +199,4 @@ export class StandardWheelEvent {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { SplitView, Orientation, ISplitViewStyles, IView as ISplitViewView } from 'vs/base/browser/ui/splitview/splitview';
|
||||
import { $ } from 'vs/base/browser/dom';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IView, IViewSize } from 'vs/base/browser/ui/grid/gridview';
|
||||
import { IView, IViewSize } from 'vs/base/browser/ui/grid/grid';
|
||||
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ export class CheckboxActionViewItem extends BaseActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
dipsose(): void {
|
||||
dispose(): void {
|
||||
this.disposables.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,19 @@
|
||||
background: url('case-sensitive-hc.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs .monaco-custom-checkbox.monaco-preserve-case {
|
||||
background: url('preserve-case-light.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-custom-checkbox.monaco-preserve-case {
|
||||
background: url('preserve-case-dark.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.hc-black .monaco-custom-checkbox.monaco-preserve-case,
|
||||
.hc-black .monaco-custom-checkbox.monaco-preserve-case:hover {
|
||||
background: url('preserve-case-hc.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs .monaco-custom-checkbox.monaco-whole-word {
|
||||
background: url('whole-word-light.svg') center center no-repeat;
|
||||
}
|
||||
@@ -40,4 +53,4 @@
|
||||
.hc-black .monaco-custom-checkbox.monaco-regex,
|
||||
.hc-black .monaco-custom-checkbox.monaco-regex:hover {
|
||||
background: url('regex-hc.svg') center center no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.53437 12.4673H7.4361L6.53859 10.0936H2.94854L2.10418 12.4673H1L4.24757 4H5.27499L8.53437 12.4673ZM6.21383 9.20202L4.88528 5.59426C4.84198 5.47617 4.79868 5.28722 4.75538 5.02741H4.73176C4.69239 5.26754 4.64713 5.45649 4.59595 5.59426L3.27921 9.20202H6.21383Z" fill="#C5C5C5"/>
|
||||
<path d="M9.78617 12.4673V4H12.1953C12.9275 4 13.5081 4.17911 13.9372 4.53733C14.3662 4.89554 14.5808 5.36201 14.5808 5.93674C14.5808 6.41698 14.4509 6.83425 14.1911 7.18853C13.9313 7.54281 13.573 7.79474 13.1164 7.94433V7.96795C13.6872 8.03487 14.1438 8.25137 14.4863 8.61746C14.8288 8.97961 15 9.45199 15 10.0346C15 10.7589 14.7402 11.3454 14.2206 11.7942C13.701 12.2429 13.0456 12.4673 12.2543 12.4673H9.78617ZM10.7782 4.89751V7.63138H11.7938C12.337 7.63138 12.7641 7.50148 13.0751 7.24167C13.3861 6.97793 13.5415 6.6079 13.5415 6.13159C13.5415 5.30887 13.0003 4.89751 11.9178 4.89751H10.7782ZM10.7782 8.52299V11.5698H12.1244C12.707 11.5698 13.1577 11.432 13.4766 11.1565C13.7994 10.8809 13.9608 10.503 13.9608 10.0228C13.9608 9.02292 13.2798 8.52299 11.9178 8.52299H10.7782Z" fill="#C5C5C5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.53437 12.4673H7.4361L6.53859 10.0936H2.94854L2.10418 12.4673H1L4.24757 4H5.27499L8.53437 12.4673ZM6.21383 9.20202L4.88528 5.59426C4.84198 5.47617 4.79868 5.28722 4.75538 5.02741H4.73176C4.69239 5.26754 4.64713 5.45649 4.59595 5.59426L3.27921 9.20202H6.21383Z" fill="white"/>
|
||||
<path d="M9.78617 12.4673V4H12.1953C12.9275 4 13.5081 4.17911 13.9372 4.53733C14.3662 4.89554 14.5808 5.36201 14.5808 5.93674C14.5808 6.41698 14.4509 6.83425 14.1911 7.18853C13.9313 7.54281 13.573 7.79474 13.1164 7.94433V7.96795C13.6872 8.03487 14.1438 8.25137 14.4863 8.61746C14.8288 8.97961 15 9.45199 15 10.0346C15 10.7589 14.7402 11.3454 14.2206 11.7942C13.701 12.2429 13.0456 12.4673 12.2543 12.4673H9.78617ZM10.7782 4.89751V7.63138H11.7938C12.337 7.63138 12.7641 7.50148 13.0751 7.24167C13.3861 6.97793 13.5415 6.6079 13.5415 6.13159C13.5415 5.30887 13.0003 4.89751 11.9178 4.89751H10.7782ZM10.7782 8.52299V11.5698H12.1244C12.707 11.5698 13.1577 11.432 13.4766 11.1565C13.7994 10.8809 13.9608 10.503 13.9608 10.0228C13.9608 9.02292 13.2798 8.52299 11.9178 8.52299H10.7782Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.53437 12.4673H7.4361L6.53859 10.0936H2.94854L2.10418 12.4673H1L4.24757 4H5.27499L8.53437 12.4673ZM6.21383 9.20202L4.88528 5.59426C4.84198 5.47617 4.79868 5.28722 4.75538 5.02741H4.73176C4.69239 5.26754 4.64713 5.45649 4.59595 5.59426L3.27921 9.20202H6.21383Z" fill="#424242"/>
|
||||
<path d="M9.78617 12.4673V4H12.1953C12.9275 4 13.5081 4.17911 13.9372 4.53733C14.3662 4.89554 14.5808 5.36201 14.5808 5.93674C14.5808 6.41698 14.4509 6.83425 14.1911 7.18853C13.9313 7.54281 13.573 7.79474 13.1164 7.94433V7.96795C13.6872 8.03487 14.1438 8.25137 14.4863 8.61746C14.8288 8.97961 15 9.45199 15 10.0346C15 10.7589 14.7402 11.3454 14.2206 11.7942C13.701 12.2429 13.0456 12.4673 12.2543 12.4673H9.78617ZM10.7782 4.89751V7.63138H11.7938C12.337 7.63138 12.7641 7.50148 13.0751 7.24167C13.3861 6.97793 13.5415 6.6079 13.5415 6.13159C13.5415 5.30887 13.0003 4.89751 11.9178 4.89751H10.7782ZM10.7782 8.52299V11.5698H12.1244C12.707 11.5698 13.1577 11.432 13.4766 11.1565C13.7994 10.8809 13.9608 10.503 13.9608 10.0228C13.9608 9.02292 13.2798 8.52299 11.9178 8.52299H10.7782Z" fill="#424242"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -7,10 +7,11 @@ import 'vs/css!./gridview';
|
||||
import { Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { tail2 as tail, equals } from 'vs/base/common/arrays';
|
||||
import { orthogonal, IView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize } from './gridview';
|
||||
import { orthogonal, IView as IGridViewView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize, ILayoutController, LayoutController } from './gridview';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { InvisibleSizing } from 'vs/base/browser/ui/splitview/splitview';
|
||||
|
||||
export { Orientation, Sizing as GridViewSizing } from './gridview';
|
||||
export { Orientation, Sizing as GridViewSizing, IViewSize, orthogonal, LayoutPriority } from './gridview';
|
||||
|
||||
export const enum Direction {
|
||||
Up,
|
||||
@@ -28,9 +29,15 @@ function oppositeDirection(direction: Direction): Direction {
|
||||
}
|
||||
}
|
||||
|
||||
export interface IView extends IGridViewView {
|
||||
readonly preferredHeight?: number;
|
||||
readonly preferredWidth?: number;
|
||||
}
|
||||
|
||||
export interface GridLeafNode<T extends IView> {
|
||||
readonly view: T;
|
||||
readonly box: Box;
|
||||
readonly cachedVisibleSize: number | undefined;
|
||||
}
|
||||
|
||||
export interface GridBranchNode<T extends IView> {
|
||||
@@ -173,16 +180,24 @@ function getGridLocation(element: HTMLElement): number[] {
|
||||
return [...getGridLocation(ancestor), index];
|
||||
}
|
||||
|
||||
export const enum Sizing {
|
||||
Distribute = 'distribute',
|
||||
Split = 'split'
|
||||
export type DistributeSizing = { type: 'distribute' };
|
||||
export type SplitSizing = { type: 'split' };
|
||||
export type InvisibleSizing = { type: 'invisible', cachedVisibleSize: number };
|
||||
export type Sizing = DistributeSizing | SplitSizing | InvisibleSizing;
|
||||
|
||||
export namespace Sizing {
|
||||
export const Distribute: DistributeSizing = { type: 'distribute' };
|
||||
export const Split: SplitSizing = { type: 'split' };
|
||||
export function Invisible(cachedVisibleSize: number): InvisibleSizing { return { type: 'invisible', cachedVisibleSize }; }
|
||||
}
|
||||
|
||||
export interface IGridStyles extends IGridViewStyles { }
|
||||
|
||||
export interface IGridOptions {
|
||||
styles?: IGridStyles;
|
||||
proportionalLayout?: boolean;
|
||||
readonly styles?: IGridStyles;
|
||||
readonly proportionalLayout?: boolean;
|
||||
readonly firstViewVisibleCachedSize?: number;
|
||||
readonly layoutController?: ILayoutController;
|
||||
}
|
||||
|
||||
export class Grid<T extends IView = IView> extends Disposable {
|
||||
@@ -203,14 +218,20 @@ export class Grid<T extends IView = IView> extends Disposable {
|
||||
|
||||
get element(): HTMLElement { return this.gridview.element; }
|
||||
|
||||
private didLayout = false;
|
||||
|
||||
constructor(view: T, options: IGridOptions = {}) {
|
||||
super();
|
||||
this.gridview = new GridView(options);
|
||||
this._register(this.gridview);
|
||||
|
||||
this._register(this.gridview.onDidSashReset(this.doResetViewSize, this));
|
||||
this._register(this.gridview.onDidSashReset(this.onDidSashReset, this));
|
||||
|
||||
this._addView(view, 0, [0]);
|
||||
const size: number | GridViewSizing = typeof options.firstViewVisibleCachedSize === 'number'
|
||||
? GridViewSizing.Invisible(options.firstViewVisibleCachedSize)
|
||||
: 0;
|
||||
|
||||
this._addView(view, size, [0]);
|
||||
}
|
||||
|
||||
style(styles: IGridStyles): void {
|
||||
@@ -219,6 +240,7 @@ export class Grid<T extends IView = IView> extends Disposable {
|
||||
|
||||
layout(width: number, height: number): void {
|
||||
this.gridview.layout(width, height);
|
||||
this.didLayout = true;
|
||||
}
|
||||
|
||||
hasView(view: T): boolean {
|
||||
@@ -241,10 +263,12 @@ export class Grid<T extends IView = IView> extends Disposable {
|
||||
|
||||
let viewSize: number | GridViewSizing;
|
||||
|
||||
if (size === Sizing.Split) {
|
||||
if (typeof size === 'number') {
|
||||
viewSize = size;
|
||||
} else if (size.type === 'split') {
|
||||
const [, index] = tail(referenceLocation);
|
||||
viewSize = GridViewSizing.Split(index);
|
||||
} else if (size === Sizing.Distribute) {
|
||||
} else if (size.type === 'distribute') {
|
||||
viewSize = GridViewSizing.Distribute;
|
||||
} else {
|
||||
viewSize = size;
|
||||
@@ -264,7 +288,7 @@ export class Grid<T extends IView = IView> extends Disposable {
|
||||
}
|
||||
|
||||
const location = this.getViewLocation(view);
|
||||
this.gridview.removeView(location, sizing === Sizing.Distribute ? GridViewSizing.Distribute : undefined);
|
||||
this.gridview.removeView(location, (sizing && sizing.type === 'distribute') ? GridViewSizing.Distribute : undefined);
|
||||
this.views.delete(view);
|
||||
}
|
||||
|
||||
@@ -320,10 +344,14 @@ export class Grid<T extends IView = IView> extends Disposable {
|
||||
}
|
||||
|
||||
getViews(): GridBranchNode<T> {
|
||||
return this.gridview.getViews() as GridBranchNode<T>;
|
||||
return this.gridview.getView() as GridBranchNode<T>;
|
||||
}
|
||||
|
||||
getNeighborViews(view: T, direction: Direction, wrap: boolean = false): T[] {
|
||||
if (!this.didLayout) {
|
||||
throw new Error('Can\'t call getNeighborViews before first layout');
|
||||
}
|
||||
|
||||
const location = this.getViewLocation(view);
|
||||
const root = this.getViews();
|
||||
const node = getGridNode(root, location);
|
||||
@@ -355,8 +383,36 @@ export class Grid<T extends IView = IView> extends Disposable {
|
||||
return getGridLocation(element);
|
||||
}
|
||||
|
||||
private doResetViewSize(location: number[]): void {
|
||||
const [parentLocation,] = tail(location);
|
||||
private onDidSashReset(location: number[]): void {
|
||||
const resizeToPreferredSize = (location: number[]): boolean => {
|
||||
const node = this.gridview.getView(location) as GridNode<T>;
|
||||
|
||||
if (isGridBranchNode(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const direction = getLocationOrientation(this.orientation, location);
|
||||
const size = direction === Orientation.HORIZONTAL ? node.view.preferredWidth : node.view.preferredHeight;
|
||||
|
||||
if (typeof size !== 'number') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const viewSize = direction === Orientation.HORIZONTAL ? { width: Math.round(size) } : { height: Math.round(size) };
|
||||
this.gridview.resizeView(location, viewSize);
|
||||
return true;
|
||||
};
|
||||
|
||||
if (resizeToPreferredSize(location)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [parentLocation, index] = tail(location);
|
||||
|
||||
if (resizeToPreferredSize([...parentLocation, index + 1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.gridview.distributeViewSizes(parentLocation);
|
||||
}
|
||||
}
|
||||
@@ -379,6 +435,7 @@ export interface ISerializedLeafNode {
|
||||
type: 'leaf';
|
||||
data: object | null;
|
||||
size: number;
|
||||
visible?: boolean;
|
||||
}
|
||||
|
||||
export interface ISerializedBranchNode {
|
||||
@@ -402,6 +459,10 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
|
||||
const size = orientation === Orientation.VERTICAL ? node.box.width : node.box.height;
|
||||
|
||||
if (!isGridBranchNode(node)) {
|
||||
if (typeof node.cachedVisibleSize === 'number') {
|
||||
return { type: 'leaf', data: node.view.toJSON(), size: node.cachedVisibleSize, visible: false };
|
||||
}
|
||||
|
||||
return { type: 'leaf', data: node.view.toJSON(), size };
|
||||
}
|
||||
|
||||
@@ -426,25 +487,26 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
|
||||
throw new Error('Invalid JSON: \'size\' property of node must be a number.');
|
||||
}
|
||||
|
||||
const childSize = child.type === 'leaf' && child.visible === false ? 0 : child.size;
|
||||
const childBox: Box = orientation === Orientation.HORIZONTAL
|
||||
? { top: box.top, left: box.left + offset, width: child.size, height: box.height }
|
||||
: { top: box.top + offset, left: box.left, width: box.width, height: child.size };
|
||||
? { top: box.top, left: box.left + offset, width: childSize, height: box.height }
|
||||
: { top: box.top + offset, left: box.left, width: box.width, height: childSize };
|
||||
|
||||
children.push(SerializableGrid.deserializeNode(child, orthogonal(orientation), childBox, deserializer));
|
||||
offset += child.size;
|
||||
offset += childSize;
|
||||
}
|
||||
|
||||
return { children, box };
|
||||
|
||||
} else if (json.type === 'leaf') {
|
||||
const view: T = deserializer.fromJSON(json.data);
|
||||
return { view, box };
|
||||
return { view, box, cachedVisibleSize: json.visible === false ? json.size : undefined };
|
||||
}
|
||||
|
||||
throw new Error('Invalid JSON: \'type\' property must be either \'branch\' or \'leaf\'.');
|
||||
}
|
||||
|
||||
private static getFirstLeaf<T extends IView>(node: GridNode<T>): GridLeafNode<T> | undefined {
|
||||
private static getFirstLeaf<T extends IView>(node: GridNode<T>): GridLeafNode<T> {
|
||||
if (!isGridBranchNode(node)) {
|
||||
return node;
|
||||
}
|
||||
@@ -473,11 +535,19 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
|
||||
throw new Error('Invalid serialized state, first leaf not found');
|
||||
}
|
||||
|
||||
const layoutController = new LayoutController(false);
|
||||
options = { ...options, layoutController };
|
||||
|
||||
if (typeof firstLeaf.cachedVisibleSize === 'number') {
|
||||
options = { ...options, firstViewVisibleCachedSize: firstLeaf.cachedVisibleSize };
|
||||
}
|
||||
|
||||
const result = new SerializableGrid<T>(firstLeaf.view, options);
|
||||
result.orientation = orientation;
|
||||
result.restoreViews(firstLeaf.view, orientation, root);
|
||||
result.initialLayoutContext = { width, height, root };
|
||||
|
||||
layoutController.isLayoutEnabled = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -522,13 +592,16 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
|
||||
const firstLeaves = node.children.map(c => SerializableGrid.getFirstLeaf(c));
|
||||
|
||||
for (let i = 1; i < firstLeaves.length; i++) {
|
||||
const size = orientation === Orientation.VERTICAL ? firstLeaves[i]!.box.height : firstLeaves[i]!.box.width;
|
||||
this.addView(firstLeaves[i]!.view, size, referenceView, direction);
|
||||
referenceView = firstLeaves[i]!.view;
|
||||
const node = firstLeaves[i];
|
||||
const size: number | InvisibleSizing = typeof node.cachedVisibleSize === 'number'
|
||||
? GridViewSizing.Invisible(node.cachedVisibleSize)
|
||||
: (orientation === Orientation.VERTICAL ? node.box.height : node.box.width);
|
||||
this.addView(node.view, size, referenceView, direction);
|
||||
referenceView = node.view;
|
||||
}
|
||||
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
this.restoreViews(firstLeaves[i]!.view, orthogonal(orientation), node.children[i]);
|
||||
this.restoreViews(firstLeaves[i].view, orthogonal(orientation), node.children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ export interface Box {
|
||||
export interface GridLeafNode {
|
||||
readonly view: IView;
|
||||
readonly box: Box;
|
||||
readonly cachedVisibleSize: number | undefined;
|
||||
}
|
||||
|
||||
export interface GridBranchNode {
|
||||
@@ -66,9 +67,18 @@ const defaultStyles: IGridViewStyles = {
|
||||
separatorBorder: Color.transparent
|
||||
};
|
||||
|
||||
export interface ILayoutController {
|
||||
readonly isLayoutEnabled: boolean;
|
||||
}
|
||||
|
||||
export class LayoutController implements ILayoutController {
|
||||
constructor(public isLayoutEnabled: boolean) { }
|
||||
}
|
||||
|
||||
export interface IGridViewOptions {
|
||||
styles?: IGridViewStyles;
|
||||
proportionalLayout?: boolean; // default true
|
||||
readonly styles?: IGridViewStyles;
|
||||
readonly proportionalLayout?: boolean; // default true
|
||||
readonly layoutController?: ILayoutController;
|
||||
}
|
||||
|
||||
class BranchNode implements ISplitView, IDisposable {
|
||||
@@ -343,6 +353,14 @@ class BranchNode implements ISplitView, IDisposable {
|
||||
this.splitview.setViewVisible(index, visible);
|
||||
}
|
||||
|
||||
getChildCachedVisibleSize(index: number): number | undefined {
|
||||
if (index < 0 || index >= this.children.length) {
|
||||
throw new Error('Invalid index');
|
||||
}
|
||||
|
||||
return this.splitview.getViewCachedVisibleSize(index);
|
||||
}
|
||||
|
||||
private onDidChildrenChange(): void {
|
||||
const onDidChildrenChange = Event.map(Event.any(...this.children.map(c => c.onDidChange)), () => undefined);
|
||||
this.childrenChangeDisposable.dispose();
|
||||
@@ -424,6 +442,9 @@ class LeafNode implements ISplitView, IDisposable {
|
||||
private _size: number = 0;
|
||||
get size(): number { return this._size; }
|
||||
|
||||
private _cachedVisibleSize: number | undefined;
|
||||
get cachedVisibleSize(): number | undefined { return this._cachedVisibleSize; }
|
||||
|
||||
private _orthogonalSize: number;
|
||||
get orthogonalSize(): number { return this._orthogonalSize; }
|
||||
|
||||
@@ -454,7 +475,8 @@ class LeafNode implements ISplitView, IDisposable {
|
||||
constructor(
|
||||
readonly view: IView,
|
||||
readonly orientation: Orientation,
|
||||
orthogonalSize: number = 0
|
||||
readonly layoutController: ILayoutController,
|
||||
orthogonalSize: number
|
||||
) {
|
||||
this._orthogonalSize = orthogonalSize;
|
||||
|
||||
@@ -524,10 +546,19 @@ class LeafNode implements ISplitView, IDisposable {
|
||||
|
||||
layout(size: number): void {
|
||||
this._size = size;
|
||||
return this.view.layout(this.width, this.height, orthogonal(this.orientation));
|
||||
|
||||
if (this.layoutController.isLayoutEnabled) {
|
||||
this.view.layout(this.width, this.height, orthogonal(this.orientation));
|
||||
}
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
if (visible) {
|
||||
this._cachedVisibleSize = undefined;
|
||||
} else {
|
||||
this._cachedVisibleSize = this._size;
|
||||
}
|
||||
|
||||
if (this.view.setVisible) {
|
||||
this.view.setVisible(visible);
|
||||
}
|
||||
@@ -535,7 +566,10 @@ class LeafNode implements ISplitView, IDisposable {
|
||||
|
||||
orthogonalLayout(size: number): void {
|
||||
this._orthogonalSize = size;
|
||||
return this.view.layout(this.width, this.height, orthogonal(this.orientation));
|
||||
|
||||
if (this.layoutController.isLayoutEnabled) {
|
||||
this.view.layout(this.width, this.height, orthogonal(this.orientation));
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void { }
|
||||
@@ -566,7 +600,7 @@ function flipNode<T extends Node>(node: T, size: number, orthogonalSize: number)
|
||||
|
||||
return result as T;
|
||||
} else {
|
||||
return new LeafNode((node as LeafNode).view, orthogonal(node.orientation), orthogonalSize) as T;
|
||||
return new LeafNode((node as LeafNode).view, orthogonal(node.orientation), (node as LeafNode).layoutController, orthogonalSize) as T;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,11 +660,14 @@ export class GridView implements IDisposable {
|
||||
private _onDidChange = new Relay<IViewSize | undefined>();
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
private layoutController: LayoutController;
|
||||
|
||||
constructor(options: IGridViewOptions = {}) {
|
||||
this.element = $('.monaco-grid-view');
|
||||
this.styles = options.styles || defaultStyles;
|
||||
this.proportionalLayout = typeof options.proportionalLayout !== 'undefined' ? !!options.proportionalLayout : true;
|
||||
this.root = new BranchNode(Orientation.VERTICAL, this.styles, this.proportionalLayout);
|
||||
this.layoutController = options.layoutController || new LayoutController(true);
|
||||
}
|
||||
|
||||
style(styles: IGridViewStyles): void {
|
||||
@@ -652,26 +689,34 @@ export class GridView implements IDisposable {
|
||||
const [pathToParent, parent] = this.getNode(rest);
|
||||
|
||||
if (parent instanceof BranchNode) {
|
||||
const node = new LeafNode(view, orthogonal(parent.orientation), parent.orthogonalSize);
|
||||
const node = new LeafNode(view, orthogonal(parent.orientation), this.layoutController, parent.orthogonalSize);
|
||||
parent.addChild(node, size, index);
|
||||
|
||||
} else {
|
||||
const [, grandParent] = tail(pathToParent);
|
||||
const [, parentIndex] = tail(rest);
|
||||
|
||||
let newSiblingSize: number | Sizing = 0;
|
||||
|
||||
const newSiblingCachedVisibleSize = grandParent.getChildCachedVisibleSize(parentIndex);
|
||||
if (typeof newSiblingCachedVisibleSize === 'number') {
|
||||
newSiblingSize = Sizing.Invisible(newSiblingCachedVisibleSize);
|
||||
}
|
||||
|
||||
grandParent.removeChild(parentIndex);
|
||||
|
||||
const newParent = new BranchNode(parent.orientation, this.styles, this.proportionalLayout, parent.size, parent.orthogonalSize);
|
||||
grandParent.addChild(newParent, parent.size, parentIndex);
|
||||
newParent.orthogonalLayout(parent.orthogonalSize);
|
||||
|
||||
const newSibling = new LeafNode(parent.view, grandParent.orientation, parent.size);
|
||||
newParent.addChild(newSibling, 0, 0);
|
||||
const newSibling = new LeafNode(parent.view, grandParent.orientation, this.layoutController, parent.size);
|
||||
newParent.addChild(newSibling, newSiblingSize, 0);
|
||||
|
||||
if (typeof size !== 'number' && size.type === 'split') {
|
||||
size = Sizing.Split(0);
|
||||
}
|
||||
|
||||
const node = new LeafNode(view, grandParent.orientation, parent.size);
|
||||
const node = new LeafNode(view, grandParent.orientation, this.layoutController, parent.size);
|
||||
newParent.addChild(node, size, index);
|
||||
}
|
||||
}
|
||||
@@ -733,7 +778,7 @@ export class GridView implements IDisposable {
|
||||
grandParent.addChild(child, child.size, parentIndex + i);
|
||||
}
|
||||
} else {
|
||||
const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), sibling.size);
|
||||
const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), this.layoutController, sibling.size);
|
||||
grandParent.addChild(newSibling, sibling.orthogonalSize, parentIndex);
|
||||
}
|
||||
|
||||
@@ -877,13 +922,16 @@ export class GridView implements IDisposable {
|
||||
parent.setChildVisible(index, visible);
|
||||
}
|
||||
|
||||
getViews(): GridBranchNode {
|
||||
return this._getViews(this.root, this.orientation, { top: 0, left: 0, width: this.width, height: this.height }) as GridBranchNode;
|
||||
getView(): GridBranchNode;
|
||||
getView(location?: number[]): GridNode;
|
||||
getView(location?: number[]): GridNode {
|
||||
const node = location ? this.getNode(location)[1] : this._root;
|
||||
return this._getViews(node, this.orientation, { top: 0, left: 0, width: this.width, height: this.height });
|
||||
}
|
||||
|
||||
private _getViews(node: Node, orientation: Orientation, box: Box): GridNode {
|
||||
if (node instanceof LeafNode) {
|
||||
return { view: node.view, box };
|
||||
return { view: node.view, box, cachedVisibleSize: node.cachedVisibleSize };
|
||||
}
|
||||
|
||||
const children: GridNode[] = [];
|
||||
|
||||
@@ -236,7 +236,7 @@ class KeyboardController<T> implements IDisposable {
|
||||
private view: ListView<T>,
|
||||
options: IListOptions<T>
|
||||
) {
|
||||
const multipleSelectionSupport = !(options.multipleSelectionSupport === false);
|
||||
const multipleSelectionSupport = options.multipleSelectionSupport !== false;
|
||||
|
||||
this.openController = options.openController || DefaultOpenController;
|
||||
|
||||
|
||||
@@ -190,4 +190,4 @@ export class RangeMap {
|
||||
dispose() {
|
||||
this.groups = null!; // StrictNullOverride: nulling out ok in dispose
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/scrollbars';
|
||||
import { isEdgeOrIE } from 'vs/base/browser/browser';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IMouseEvent, StandardWheelEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
@@ -312,7 +313,7 @@ export abstract class AbstractScrollableElement extends Widget {
|
||||
this._onMouseWheel(new StandardWheelEvent(browserEvent));
|
||||
};
|
||||
|
||||
this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, 'mousewheel', onMouseWheel));
|
||||
this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, isEdgeOrIE ? 'mousewheel' : 'wheel', onMouseWheel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,8 +59,11 @@ interface ISashEvent {
|
||||
alt: boolean;
|
||||
}
|
||||
|
||||
type ViewItemSize = number | { cachedVisibleSize: number };
|
||||
|
||||
abstract class ViewItem {
|
||||
|
||||
private _size: number;
|
||||
set size(size: number) {
|
||||
this._size = size;
|
||||
}
|
||||
@@ -69,10 +72,11 @@ abstract class ViewItem {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
private cachedSize: number | undefined = undefined;
|
||||
private _cachedVisibleSize: number | undefined = undefined;
|
||||
get cachedVisibleSize(): number | undefined { return this._cachedVisibleSize; }
|
||||
|
||||
get visible(): boolean {
|
||||
return typeof this.cachedSize === 'undefined';
|
||||
return typeof this._cachedVisibleSize === 'undefined';
|
||||
}
|
||||
|
||||
set visible(visible: boolean) {
|
||||
@@ -81,10 +85,10 @@ abstract class ViewItem {
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
this.size = this.cachedSize!;
|
||||
this.cachedSize = undefined;
|
||||
this.size = clamp(this._cachedVisibleSize!, this.viewMinimumSize, this.viewMaximumSize);
|
||||
this._cachedVisibleSize = undefined;
|
||||
} else {
|
||||
this.cachedSize = this.size;
|
||||
this._cachedVisibleSize = this.size;
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
@@ -104,7 +108,20 @@ abstract class ViewItem {
|
||||
get priority(): LayoutPriority | undefined { return this.view.priority; }
|
||||
get snap(): boolean { return !!this.view.snap; }
|
||||
|
||||
constructor(protected container: HTMLElement, private view: IView, private _size: number, private disposable: IDisposable) {
|
||||
constructor(
|
||||
protected container: HTMLElement,
|
||||
private view: IView,
|
||||
size: ViewItemSize,
|
||||
private disposable: IDisposable
|
||||
) {
|
||||
if (typeof size === 'number') {
|
||||
this._size = size;
|
||||
this._cachedVisibleSize = undefined;
|
||||
} else {
|
||||
this._size = 0;
|
||||
this._cachedVisibleSize = size.cachedVisibleSize;
|
||||
}
|
||||
|
||||
dom.addClass(container, 'visible');
|
||||
}
|
||||
|
||||
@@ -166,11 +183,13 @@ enum State {
|
||||
|
||||
export type DistributeSizing = { type: 'distribute' };
|
||||
export type SplitSizing = { type: 'split', index: number };
|
||||
export type Sizing = DistributeSizing | SplitSizing;
|
||||
export type InvisibleSizing = { type: 'invisible', cachedVisibleSize: number };
|
||||
export type Sizing = DistributeSizing | SplitSizing | InvisibleSizing;
|
||||
|
||||
export namespace Sizing {
|
||||
export const Distribute: DistributeSizing = { type: 'distribute' };
|
||||
export function Split(index: number): SplitSizing { return { type: 'split', index }; }
|
||||
export function Invisible(cachedVisibleSize: number): InvisibleSizing { return { type: 'invisible', cachedVisibleSize }; }
|
||||
}
|
||||
|
||||
export class SplitView extends Disposable {
|
||||
@@ -279,12 +298,14 @@ export class SplitView extends Disposable {
|
||||
const containerDisposable = toDisposable(() => this.viewContainer.removeChild(container));
|
||||
const disposable = combinedDisposable(onChangeDisposable, containerDisposable);
|
||||
|
||||
let viewSize: number;
|
||||
let viewSize: ViewItemSize;
|
||||
|
||||
if (typeof size === 'number') {
|
||||
viewSize = size;
|
||||
} else if (size.type === 'split') {
|
||||
viewSize = this.getViewSize(size.index) / 2;
|
||||
} else if (size.type === 'invisible') {
|
||||
viewSize = { cachedVisibleSize: size.cachedVisibleSize };
|
||||
} else {
|
||||
viewSize = view.minimumSize;
|
||||
}
|
||||
@@ -315,7 +336,24 @@ export class SplitView extends Disposable {
|
||||
const onChangeDisposable = onChange(this.onSashChange, this);
|
||||
const onEnd = Event.map(sash.onDidEnd, () => firstIndex(this.sashItems, item => item.sash === sash));
|
||||
const onEndDisposable = onEnd(this.onSashEnd, this);
|
||||
const onDidResetDisposable = sash.onDidReset(() => this._onDidSashReset.fire(firstIndex(this.sashItems, item => item.sash === sash)));
|
||||
|
||||
const onDidResetDisposable = sash.onDidReset(() => {
|
||||
const index = firstIndex(this.sashItems, item => item.sash === sash);
|
||||
const upIndexes = range(index, -1);
|
||||
const downIndexes = range(index + 1, this.viewItems.length);
|
||||
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
|
||||
const snapAfterIndex = this.findFirstSnapIndex(downIndexes);
|
||||
|
||||
if (typeof snapBeforeIndex === 'number' && !this.viewItems[snapBeforeIndex].visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof snapAfterIndex === 'number' && !this.viewItems[snapAfterIndex].visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidSashReset.fire(index);
|
||||
});
|
||||
|
||||
const disposable = combinedDisposable(onStartDisposable, onChangeDisposable, onEndDisposable, onDidResetDisposable, sash);
|
||||
const sashItem: ISashItem = { sash, disposable };
|
||||
@@ -325,13 +363,13 @@ export class SplitView extends Disposable {
|
||||
|
||||
container.appendChild(view.element);
|
||||
|
||||
let highPriorityIndex: number | undefined;
|
||||
let highPriorityIndexes: number[] | undefined;
|
||||
|
||||
if (typeof size !== 'number' && size.type === 'split') {
|
||||
highPriorityIndex = size.index;
|
||||
highPriorityIndexes = [size.index];
|
||||
}
|
||||
|
||||
this.relayout(index, highPriorityIndex);
|
||||
this.relayout([index], highPriorityIndexes);
|
||||
this.state = State.Idle;
|
||||
|
||||
if (typeof size !== 'number' && size.type === 'distribute') {
|
||||
@@ -420,15 +458,13 @@ export class SplitView extends Disposable {
|
||||
this.layoutViews();
|
||||
}
|
||||
|
||||
private relayout(lowPriorityIndex?: number, highPriorityIndex?: number): void {
|
||||
const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
|
||||
const lowPriorityIndexes = typeof lowPriorityIndex === 'number' ? [lowPriorityIndex] : undefined;
|
||||
const highPriorityIndexes = typeof highPriorityIndex === 'number' ? [highPriorityIndex] : undefined;
|
||||
getViewCachedVisibleSize(index: number): number | undefined {
|
||||
if (index < 0 || index >= this.viewItems.length) {
|
||||
throw new Error('Index out of bounds');
|
||||
}
|
||||
|
||||
this.resize(this.viewItems.length - 1, this.size - contentSize, undefined, lowPriorityIndexes, highPriorityIndexes);
|
||||
this.distributeEmptySpace();
|
||||
this.layoutViews();
|
||||
this.saveProportions();
|
||||
const viewItem = this.viewItems[index];
|
||||
return viewItem.cachedVisibleSize;
|
||||
}
|
||||
|
||||
layout(size: number): void {
|
||||
@@ -582,7 +618,7 @@ export class SplitView extends Disposable {
|
||||
this.layoutViews();
|
||||
} else {
|
||||
item.size = size;
|
||||
this.relayout(index, undefined);
|
||||
this.relayout([index], undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,42 +633,41 @@ export class SplitView extends Disposable {
|
||||
return;
|
||||
}
|
||||
|
||||
const indexes = range(this.viewItems.length).filter(i => i !== index);
|
||||
const lowPriorityIndexes = [...indexes.filter(i => this.viewItems[i].priority === LayoutPriority.Low), index];
|
||||
const highPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.High);
|
||||
|
||||
const item = this.viewItems[index];
|
||||
size = Math.round(size);
|
||||
size = clamp(size, item.minimumSize, item.maximumSize);
|
||||
let delta = size - item.size;
|
||||
size = clamp(size, item.minimumSize, Math.min(item.maximumSize, this.size));
|
||||
|
||||
if (delta !== 0 && index < this.viewItems.length - 1) {
|
||||
const downIndexes = range(index + 1, this.viewItems.length);
|
||||
const collapseDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].minimumSize), 0);
|
||||
const expandDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - this.viewItems[i].size), 0);
|
||||
const deltaDown = clamp(delta, -expandDown, collapseDown);
|
||||
|
||||
this.resize(index, deltaDown);
|
||||
delta -= deltaDown;
|
||||
}
|
||||
|
||||
if (delta !== 0 && index > 0) {
|
||||
const upIndexes = range(index - 1, -1);
|
||||
const collapseUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].minimumSize), 0);
|
||||
const expandUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - this.viewItems[i].size), 0);
|
||||
const deltaUp = clamp(-delta, -collapseUp, expandUp);
|
||||
|
||||
this.resize(index - 1, deltaUp);
|
||||
}
|
||||
|
||||
this.distributeEmptySpace();
|
||||
this.layoutViews();
|
||||
this.saveProportions();
|
||||
item.size = size;
|
||||
this.relayout(lowPriorityIndexes, highPriorityIndexes);
|
||||
this.state = State.Idle;
|
||||
}
|
||||
|
||||
distributeViewSizes(): void {
|
||||
const size = Math.floor(this.size / this.viewItems.length);
|
||||
const flexibleViewItems: ViewItem[] = [];
|
||||
let flexibleSize = 0;
|
||||
|
||||
for (let i = 0; i < this.viewItems.length - 1; i++) {
|
||||
this.resizeView(i, size);
|
||||
for (const item of this.viewItems) {
|
||||
if (item.maximumSize - item.minimumSize > 0) {
|
||||
flexibleViewItems.push(item);
|
||||
flexibleSize += item.size;
|
||||
}
|
||||
}
|
||||
|
||||
const size = Math.floor(flexibleSize / flexibleViewItems.length);
|
||||
|
||||
for (const item of flexibleViewItems) {
|
||||
item.size = clamp(size, item.minimumSize, item.maximumSize);
|
||||
}
|
||||
|
||||
const indexes = range(this.viewItems.length);
|
||||
const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.Low);
|
||||
const highPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.High);
|
||||
|
||||
this.relayout(lowPriorityIndexes, highPriorityIndexes);
|
||||
}
|
||||
|
||||
getViewSize(index: number): number {
|
||||
@@ -643,6 +678,15 @@ export class SplitView extends Disposable {
|
||||
return this.viewItems[index].size;
|
||||
}
|
||||
|
||||
private relayout(lowPriorityIndexes?: number[], highPriorityIndexes?: number[]): void {
|
||||
const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
|
||||
|
||||
this.resize(this.viewItems.length - 1, this.size - contentSize, undefined, lowPriorityIndexes, highPriorityIndexes);
|
||||
this.distributeEmptySpace();
|
||||
this.layoutViews();
|
||||
this.saveProportions();
|
||||
}
|
||||
|
||||
private resize(
|
||||
index: number,
|
||||
delta: number,
|
||||
|
||||
@@ -1183,7 +1183,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
delegate: IListVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
|
||||
renderers: ITreeRenderer<T, TFilterData, any>[],
|
||||
private _options: IAbstractTreeOptions<T, TFilterData> = {}
|
||||
) {
|
||||
const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate);
|
||||
|
||||
@@ -320,7 +320,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
get onDidFocus(): Event<void> { return this.tree.onDidFocus; }
|
||||
get onDidBlur(): Event<void> { return this.tree.onDidBlur; }
|
||||
|
||||
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<IAsyncDataTreeNode<TInput, T>, TFilterData>> { return this.tree.onDidChangeCollapseState; }
|
||||
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<IAsyncDataTreeNode<TInput, T> | null, TFilterData>> { return this.tree.onDidChangeCollapseState; }
|
||||
|
||||
get onDidUpdateOptions(): Event<IAsyncDataTreeOptionsUpdate> { return this.tree.onDidUpdateOptions; }
|
||||
|
||||
@@ -340,7 +340,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
delegate: IListVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
|
||||
renderers: ITreeRenderer<T, TFilterData, any>[],
|
||||
private dataSource: IAsyncDataSource<TInput, T>,
|
||||
options: IAsyncDataTreeOptions<T, TFilterData> = {}
|
||||
) {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Iterator, ISequence } from 'vs/base/common/iterator';
|
||||
import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ISpliceable } from 'vs/base/common/sequence';
|
||||
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, ICollapseStateChangeEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { CompressedTreeModel, ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
|
||||
|
||||
export interface IObjectTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> {
|
||||
sorter?: ITreeSorter<T>;
|
||||
}
|
||||
|
||||
export class CompressedObjectTree<T extends NonNullable<any>, TFilterData = void> extends AbstractTree<ICompressedTreeNode<T> | null, TFilterData, T | null> {
|
||||
|
||||
protected model: CompressedTreeModel<T, TFilterData>;
|
||||
|
||||
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<ICompressedTreeNode<T> | null, TFilterData>> { return this.model.onDidChangeCollapseState; }
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
delegate: IListVirtualDelegate<ICompressedTreeNode<T>>,
|
||||
renderers: ITreeRenderer<ICompressedTreeNode<T>, TFilterData, any>[],
|
||||
options: IObjectTreeOptions<ICompressedTreeNode<T>, TFilterData> = {}
|
||||
) {
|
||||
super(container, delegate, renderers, options);
|
||||
}
|
||||
|
||||
setChildren(
|
||||
element: T | null,
|
||||
children?: ISequence<ITreeElement<T>>
|
||||
): Iterator<ITreeElement<T | null>> {
|
||||
return this.model.setChildren(element, children);
|
||||
}
|
||||
|
||||
rerender(element?: T): void {
|
||||
if (element === undefined) {
|
||||
this.view.rerender();
|
||||
return;
|
||||
}
|
||||
|
||||
this.model.rerender(element);
|
||||
}
|
||||
|
||||
resort(element: T, recursive = true): void {
|
||||
this.model.resort(element, recursive);
|
||||
}
|
||||
|
||||
protected createModel(view: ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>>, options: IObjectTreeOptions<ICompressedTreeNode<T>, TFilterData>): ITreeModel<ICompressedTreeNode<T> | null, TFilterData, T | null> {
|
||||
return new CompressedTreeModel(view, options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,418 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ISpliceable } from 'vs/base/common/sequence';
|
||||
import { Iterator, ISequence } from 'vs/base/common/iterator';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ITreeModel, ITreeNode, ITreeElement, ICollapseStateChangeEvent, ITreeModelSpliceEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IObjectTreeModelOptions, ObjectTreeModel, IObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
|
||||
export interface ICompressedTreeElement<T> extends ITreeElement<T> {
|
||||
readonly children?: Iterator<ICompressedTreeElement<T>> | ICompressedTreeElement<T>[];
|
||||
readonly incompressible?: boolean;
|
||||
}
|
||||
|
||||
export interface ICompressedTreeNode<T> {
|
||||
readonly elements: T[];
|
||||
readonly incompressible: boolean;
|
||||
}
|
||||
|
||||
export function compress<T>(element: ICompressedTreeElement<T>): ITreeElement<ICompressedTreeNode<T>> {
|
||||
const elements = [element.element];
|
||||
const incompressible = element.incompressible || false;
|
||||
|
||||
let childrenIterator: Iterator<ITreeElement<T>>;
|
||||
let children: ITreeElement<T>[];
|
||||
|
||||
while (true) {
|
||||
childrenIterator = Iterator.from(element.children);
|
||||
children = Iterator.collect(childrenIterator, 2);
|
||||
|
||||
if (children.length !== 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
element = children[0];
|
||||
|
||||
if (element.incompressible) {
|
||||
break;
|
||||
}
|
||||
|
||||
elements.push(element.element);
|
||||
}
|
||||
|
||||
return {
|
||||
element: { elements, incompressible },
|
||||
children: Iterator.map(Iterator.concat(Iterator.fromArray(children), childrenIterator), compress)
|
||||
};
|
||||
}
|
||||
|
||||
export function _decompress<T>(element: ITreeElement<ICompressedTreeNode<T>>, index = 0): ICompressedTreeElement<T> {
|
||||
let children: Iterator<ICompressedTreeElement<T>>;
|
||||
|
||||
if (index < element.element.elements.length - 1) {
|
||||
children = Iterator.single(_decompress(element, index + 1));
|
||||
} else {
|
||||
children = Iterator.map(Iterator.from(element.children), el => _decompress(el, 0));
|
||||
}
|
||||
|
||||
if (index === 0 && element.element.incompressible) {
|
||||
return { element: element.element.elements[index], children, incompressible: true };
|
||||
}
|
||||
|
||||
return { element: element.element.elements[index], children };
|
||||
}
|
||||
|
||||
export function decompress<T>(element: ITreeElement<ICompressedTreeNode<T>>): ICompressedTreeElement<T> {
|
||||
return _decompress(element, 0);
|
||||
}
|
||||
|
||||
export function splice<T>(treeElement: ICompressedTreeElement<T>, element: T, children: Iterator<ICompressedTreeElement<T>>): ICompressedTreeElement<T> {
|
||||
if (treeElement.element === element) {
|
||||
return { element, children };
|
||||
}
|
||||
|
||||
return {
|
||||
...treeElement,
|
||||
children: Iterator.map(Iterator.from(treeElement.children), e => splice(e, element, children))
|
||||
};
|
||||
}
|
||||
|
||||
export interface ICompressedTreeModelOptions<T, TFilterData> extends IObjectTreeModelOptions<ICompressedTreeNode<T>, TFilterData> { }
|
||||
|
||||
export class CompressedTreeModel<T extends NonNullable<any>, TFilterData extends NonNullable<any> = void> implements ITreeModel<ICompressedTreeNode<T> | null, TFilterData, T | null> {
|
||||
|
||||
readonly rootRef = null;
|
||||
|
||||
get onDidSplice(): Event<ITreeModelSpliceEvent<ICompressedTreeNode<T> | null, TFilterData>> { return this.model.onDidSplice; }
|
||||
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<ICompressedTreeNode<T>, TFilterData>> { return this.model.onDidChangeCollapseState; }
|
||||
get onDidChangeRenderNodeCount(): Event<ITreeNode<ICompressedTreeNode<T>, TFilterData>> { return this.model.onDidChangeRenderNodeCount; }
|
||||
|
||||
private model: ObjectTreeModel<ICompressedTreeNode<T>, TFilterData>;
|
||||
private nodes = new Map<T | null, ICompressedTreeNode<T>>();
|
||||
|
||||
get size(): number { return this.nodes.size; }
|
||||
|
||||
constructor(list: ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>>, options: ICompressedTreeModelOptions<T, TFilterData> = {}) {
|
||||
this.model = new ObjectTreeModel(list, options);
|
||||
}
|
||||
|
||||
setChildren(
|
||||
element: T | null,
|
||||
children: ISequence<ICompressedTreeElement<T>> | undefined,
|
||||
onDidCreateNode?: (node: ITreeNode<ICompressedTreeNode<T>, TFilterData>) => void,
|
||||
onDidDeleteNode?: (node: ITreeNode<ICompressedTreeNode<T>, TFilterData>) => void
|
||||
): Iterator<ITreeElement<T | null>> {
|
||||
const insertedElements = new Set<T | null>();
|
||||
const _onDidCreateNode = (node: ITreeNode<ICompressedTreeNode<T>, TFilterData>) => {
|
||||
for (const element of node.element.elements) {
|
||||
insertedElements.add(element);
|
||||
this.nodes.set(element, node.element);
|
||||
}
|
||||
|
||||
// if (this.identityProvider) {
|
||||
// const id = this.identityProvider.getId(node.element).toString();
|
||||
// insertedElementIds.add(id);
|
||||
// this.nodesByIdentity.set(id, node);
|
||||
// }
|
||||
|
||||
if (onDidCreateNode) {
|
||||
onDidCreateNode(node);
|
||||
}
|
||||
};
|
||||
|
||||
const _onDidDeleteNode = (node: ITreeNode<ICompressedTreeNode<T>, TFilterData>) => {
|
||||
for (const element of node.element.elements) {
|
||||
if (!insertedElements.has(element)) {
|
||||
this.nodes.delete(element);
|
||||
}
|
||||
}
|
||||
|
||||
// if (this.identityProvider) {
|
||||
// const id = this.identityProvider.getId(node.element).toString();
|
||||
// if (!insertedElementIds.has(id)) {
|
||||
// this.nodesByIdentity.delete(id);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (onDidDeleteNode) {
|
||||
onDidDeleteNode(node);
|
||||
}
|
||||
};
|
||||
|
||||
if (element === null) {
|
||||
const compressedChildren = Iterator.map(Iterator.from(children), compress);
|
||||
const result = this.model.setChildren(null, compressedChildren, _onDidCreateNode, _onDidDeleteNode);
|
||||
return Iterator.map(result, decompress);
|
||||
}
|
||||
|
||||
const compressedNode = this.nodes.get(element);
|
||||
const node = this.model.getNode(compressedNode) as ITreeNode<ICompressedTreeNode<T>, TFilterData>;
|
||||
const parent = node.parent!;
|
||||
|
||||
const decompressedElement = decompress(node);
|
||||
const splicedElement = splice(decompressedElement, element, Iterator.from(children));
|
||||
const recompressedElement = compress(splicedElement);
|
||||
|
||||
const parentChildren = parent.children
|
||||
.map(child => child === node ? recompressedElement : child);
|
||||
|
||||
this.model.setChildren(parent.element, parentChildren, _onDidCreateNode, _onDidDeleteNode);
|
||||
|
||||
// TODO
|
||||
return Iterator.empty();
|
||||
}
|
||||
|
||||
getListIndex(location: T | null): number {
|
||||
const node = this.getCompressedNode(location);
|
||||
return this.model.getListIndex(node);
|
||||
}
|
||||
|
||||
getListRenderCount(location: T | null): number {
|
||||
const node = this.getCompressedNode(location);
|
||||
return this.model.getListRenderCount(node);
|
||||
}
|
||||
|
||||
getNode(location?: T | null | undefined): ITreeNode<ICompressedTreeNode<T> | null, TFilterData> {
|
||||
if (typeof location === 'undefined') {
|
||||
return this.model.getNode();
|
||||
}
|
||||
|
||||
const node = this.getCompressedNode(location);
|
||||
return this.model.getNode(node);
|
||||
}
|
||||
|
||||
// TODO: review this
|
||||
getNodeLocation(node: ITreeNode<ICompressedTreeNode<T>, TFilterData>): T | null {
|
||||
const compressedNode = this.model.getNodeLocation(node);
|
||||
|
||||
if (compressedNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return compressedNode.elements[compressedNode.elements.length - 1];
|
||||
}
|
||||
|
||||
// TODO: review this
|
||||
getParentNodeLocation(location: T | null): T | null {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
const parentNode = this.model.getParentNodeLocation(compressedNode);
|
||||
|
||||
if (parentNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parentNode.elements[parentNode.elements.length - 1];
|
||||
}
|
||||
|
||||
getParentElement(location: T | null): ICompressedTreeNode<T> | null {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
return this.model.getParentElement(compressedNode);
|
||||
}
|
||||
|
||||
getFirstElementChild(location: T | null): ICompressedTreeNode<T> | null | undefined {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
return this.model.getFirstElementChild(compressedNode);
|
||||
}
|
||||
|
||||
getLastElementAncestor(location?: T | null | undefined): ICompressedTreeNode<T> | null | undefined {
|
||||
const compressedNode = typeof location === 'undefined' ? undefined : this.getCompressedNode(location);
|
||||
return this.model.getLastElementAncestor(compressedNode);
|
||||
}
|
||||
|
||||
isCollapsible(location: T | null): boolean {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
return this.model.isCollapsible(compressedNode);
|
||||
}
|
||||
|
||||
isCollapsed(location: T | null): boolean {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
return this.model.isCollapsed(compressedNode);
|
||||
}
|
||||
|
||||
setCollapsed(location: T | null, collapsed?: boolean | undefined, recursive?: boolean | undefined): boolean {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
return this.model.setCollapsed(compressedNode, collapsed, recursive);
|
||||
}
|
||||
|
||||
expandTo(location: T | null): void {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
this.model.expandTo(compressedNode);
|
||||
}
|
||||
|
||||
rerender(location: T | null): void {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
this.model.rerender(compressedNode);
|
||||
}
|
||||
|
||||
refilter(): void {
|
||||
this.model.refilter();
|
||||
}
|
||||
|
||||
resort(location: T | null = null, recursive = true): void {
|
||||
const compressedNode = this.getCompressedNode(location);
|
||||
this.model.resort(compressedNode, recursive);
|
||||
}
|
||||
|
||||
private getCompressedNode(element: T | null): ICompressedTreeNode<T> | null {
|
||||
if (element === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const node = this.nodes.get(element);
|
||||
|
||||
if (!node) {
|
||||
throw new Error(`Tree element not found: ${element}`);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
export type ElementMapper<T> = (elements: T[]) => T;
|
||||
export const DefaultElementMapper: ElementMapper<any> = elements => elements[elements.length - 1];
|
||||
|
||||
export type NodeMapper<T, TFilterData> = (node: ITreeNode<ICompressedTreeNode<T> | null, TFilterData>) => ITreeNode<T | null, TFilterData>;
|
||||
|
||||
function mapNode<T, TFilterData>(elementMapper: ElementMapper<T>, node: ITreeNode<ICompressedTreeNode<T> | null, TFilterData>): ITreeNode<T | null, TFilterData> {
|
||||
return {
|
||||
...node,
|
||||
element: node.element === null ? null : elementMapper(node.element.elements),
|
||||
children: node.children.map(child => mapNode(elementMapper, child)),
|
||||
parent: typeof node.parent === 'undefined' ? node.parent : mapNode(elementMapper, node.parent)
|
||||
};
|
||||
}
|
||||
|
||||
function createNodeMapper<T, TFilterData>(elementMapper: ElementMapper<T>): NodeMapper<T, TFilterData> {
|
||||
return node => mapNode(elementMapper, node);
|
||||
}
|
||||
|
||||
export interface ICompressedObjectTreeModelOptions<T, TFilterData> extends ICompressedTreeModelOptions<T, TFilterData> {
|
||||
readonly elementMapper?: ElementMapper<T>;
|
||||
}
|
||||
|
||||
export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData extends NonNullable<any> = void> implements IObjectTreeModel<T, TFilterData> {
|
||||
|
||||
readonly rootRef = null;
|
||||
|
||||
get onDidSplice(): Event<ITreeModelSpliceEvent<T | null, TFilterData>> {
|
||||
return Event.map(this.model.onDidSplice, ({ insertedNodes, deletedNodes }) => ({
|
||||
insertedNodes: insertedNodes.map(this.mapNode),
|
||||
deletedNodes: deletedNodes.map(this.mapNode),
|
||||
}));
|
||||
}
|
||||
|
||||
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<T | null, TFilterData>> {
|
||||
return Event.map(this.model.onDidChangeCollapseState, ({ node, deep }) => ({
|
||||
node: this.mapNode(node),
|
||||
deep
|
||||
}));
|
||||
}
|
||||
|
||||
get onDidChangeRenderNodeCount(): Event<ITreeNode<T | null, TFilterData>> {
|
||||
return Event.map(this.model.onDidChangeRenderNodeCount, this.mapNode);
|
||||
}
|
||||
|
||||
private mapElement: ElementMapper<T | null>;
|
||||
private mapNode: NodeMapper<T | null, TFilterData>;
|
||||
private model: CompressedTreeModel<T, TFilterData>;
|
||||
|
||||
constructor(
|
||||
list: ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>>,
|
||||
options: ICompressedObjectTreeModelOptions<T, TFilterData> = {}
|
||||
) {
|
||||
this.mapElement = options.elementMapper || DefaultElementMapper;
|
||||
this.mapNode = createNodeMapper(this.mapElement);
|
||||
this.model = new CompressedTreeModel(list, options);
|
||||
}
|
||||
|
||||
setChildren(
|
||||
element: T | null,
|
||||
children: ISequence<ITreeElement<T>> | undefined
|
||||
): Iterator<ITreeElement<T>> {
|
||||
this.model.setChildren(element, children);
|
||||
|
||||
// TODO
|
||||
return Iterator.empty();
|
||||
}
|
||||
|
||||
getListIndex(location: T | null): number {
|
||||
return this.model.getListIndex(location);
|
||||
}
|
||||
|
||||
getListRenderCount(location: T | null): number {
|
||||
return this.model.getListRenderCount(location);
|
||||
}
|
||||
|
||||
getNode(location?: T | null | undefined): ITreeNode<T | null, any> {
|
||||
return this.mapNode(this.model.getNode(location));
|
||||
}
|
||||
|
||||
getNodeLocation(node: ITreeNode<T | null, any>): T | null {
|
||||
return node.element;
|
||||
}
|
||||
|
||||
getParentNodeLocation(location: T | null): T | null {
|
||||
return this.model.getParentNodeLocation(location);
|
||||
}
|
||||
|
||||
getParentElement(location: T | null): T | null {
|
||||
const result = this.model.getParentElement(location);
|
||||
|
||||
if (result === null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return this.mapElement(result.elements);
|
||||
}
|
||||
|
||||
getFirstElementChild(location: T | null): T | null | undefined {
|
||||
const result = this.model.getFirstElementChild(location);
|
||||
|
||||
if (result === null || typeof result === 'undefined') {
|
||||
return result;
|
||||
}
|
||||
|
||||
return this.mapElement(result.elements);
|
||||
}
|
||||
|
||||
getLastElementAncestor(location?: T | null | undefined): T | null | undefined {
|
||||
const result = this.model.getLastElementAncestor(location);
|
||||
|
||||
if (result === null || typeof result === 'undefined') {
|
||||
return result;
|
||||
}
|
||||
|
||||
return this.mapElement(result.elements);
|
||||
}
|
||||
|
||||
isCollapsible(location: T | null): boolean {
|
||||
return this.model.isCollapsible(location);
|
||||
}
|
||||
|
||||
isCollapsed(location: T | null): boolean {
|
||||
return this.model.isCollapsed(location);
|
||||
}
|
||||
|
||||
setCollapsed(location: T | null, collapsed?: boolean | undefined, recursive?: boolean | undefined): boolean {
|
||||
return this.model.setCollapsed(location, collapsed, recursive);
|
||||
}
|
||||
|
||||
expandTo(location: T | null): void {
|
||||
return this.model.expandTo(location);
|
||||
}
|
||||
|
||||
rerender(location: T | null): void {
|
||||
return this.model.rerender(location);
|
||||
}
|
||||
|
||||
refilter(): void {
|
||||
return this.model.refilter();
|
||||
}
|
||||
|
||||
resort(element: T | null = null, recursive = true): void {
|
||||
return this.model.resort(element, recursive);
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ export class DataTree<TInput, T, TFilterData = void> extends AbstractTree<T | nu
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
delegate: IListVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
|
||||
renderers: ITreeRenderer<T, TFilterData, any>[],
|
||||
private dataSource: IDataSource<TInput, T>,
|
||||
options: IDataTreeOptions<T, TFilterData> = {}
|
||||
) {
|
||||
|
||||
@@ -20,7 +20,7 @@ export class IndexTree<T, TFilterData = void> extends AbstractTree<T, TFilterDat
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
delegate: IListVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
|
||||
renderers: ITreeRenderer<T, TFilterData, any>[],
|
||||
private rootElement: T,
|
||||
options: IIndexTreeOptions<T, TFilterData> = {}
|
||||
) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Iterator, ISequence } from 'vs/base/common/iterator';
|
||||
import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ISpliceable } from 'vs/base/common/sequence';
|
||||
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, ICollapseStateChangeEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
import { ObjectTreeModel, IObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
@@ -17,14 +17,14 @@ export interface IObjectTreeOptions<T, TFilterData = void> extends IAbstractTree
|
||||
|
||||
export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends AbstractTree<T | null, TFilterData, T | null> {
|
||||
|
||||
protected model: ObjectTreeModel<T, TFilterData>;
|
||||
protected model: IObjectTreeModel<T, TFilterData>;
|
||||
|
||||
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<T, TFilterData>> { return this.model.onDidChangeCollapseState; }
|
||||
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<T | null, TFilterData>> { return this.model.onDidChangeCollapseState; }
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
delegate: IListVirtualDelegate<T>,
|
||||
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
|
||||
renderers: ITreeRenderer<T, TFilterData, any>[],
|
||||
options: IObjectTreeOptions<T, TFilterData> = {}
|
||||
) {
|
||||
super(container, delegate, renderers, options);
|
||||
@@ -32,11 +32,9 @@ export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends
|
||||
|
||||
setChildren(
|
||||
element: T | null,
|
||||
children?: ISequence<ITreeElement<T>>,
|
||||
onDidCreateNode?: (node: ITreeNode<T, TFilterData>) => void,
|
||||
onDidDeleteNode?: (node: ITreeNode<T, TFilterData>) => void
|
||||
children?: ISequence<ITreeElement<T>>
|
||||
): Iterator<ITreeElement<T | null>> {
|
||||
return this.model.setChildren(element, children, onDidCreateNode, onDidDeleteNode);
|
||||
return this.model.setChildren(element, children);
|
||||
}
|
||||
|
||||
rerender(element?: T): void {
|
||||
|
||||
@@ -10,12 +10,19 @@ import { Event } from 'vs/base/common/event';
|
||||
import { ITreeModel, ITreeNode, ITreeElement, ITreeSorter, ICollapseStateChangeEvent, ITreeModelSpliceEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
|
||||
export type ITreeNodeCallback<T, TFilterData> = (node: ITreeNode<T, TFilterData>) => void;
|
||||
|
||||
export interface IObjectTreeModel<T extends NonNullable<any>, TFilterData extends NonNullable<any> = void> extends ITreeModel<T | null, TFilterData, T | null> {
|
||||
setChildren(element: T | null, children: ISequence<ITreeElement<T>> | undefined): Iterator<ITreeElement<T>>;
|
||||
resort(element?: T | null, recursive?: boolean): void;
|
||||
}
|
||||
|
||||
export interface IObjectTreeModelOptions<T, TFilterData> extends IIndexTreeModelOptions<T, TFilterData> {
|
||||
readonly sorter?: ITreeSorter<T>;
|
||||
readonly identityProvider?: IIdentityProvider<T>;
|
||||
}
|
||||
|
||||
export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends NonNullable<any> = void> implements ITreeModel<T | null, TFilterData, T | null> {
|
||||
export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends NonNullable<any> = void> implements IObjectTreeModel<T, TFilterData> {
|
||||
|
||||
readonly rootRef = null;
|
||||
|
||||
@@ -51,9 +58,9 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
setChildren(
|
||||
element: T | null,
|
||||
children: ISequence<ITreeElement<T>> | undefined,
|
||||
onDidCreateNode?: (node: ITreeNode<T, TFilterData>) => void,
|
||||
onDidDeleteNode?: (node: ITreeNode<T, TFilterData>) => void
|
||||
): Iterator<ITreeElement<T | null>> {
|
||||
onDidCreateNode?: ITreeNodeCallback<T, TFilterData>,
|
||||
onDidDeleteNode?: ITreeNodeCallback<T, TFilterData>
|
||||
): Iterator<ITreeElement<T>> {
|
||||
const location = this.getElementLocation(element);
|
||||
return this._setChildren(location, this.preserveCollapseState(children), onDidCreateNode, onDidDeleteNode);
|
||||
}
|
||||
@@ -61,9 +68,9 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
private _setChildren(
|
||||
location: number[],
|
||||
children: ISequence<ITreeElement<T>> | undefined,
|
||||
onDidCreateNode?: (node: ITreeNode<T, TFilterData>) => void,
|
||||
onDidDeleteNode?: (node: ITreeNode<T, TFilterData>) => void
|
||||
): Iterator<ITreeElement<T | null>> {
|
||||
onDidCreateNode?: ITreeNodeCallback<T, TFilterData>,
|
||||
onDidDeleteNode?: ITreeNodeCallback<T, TFilterData>
|
||||
): Iterator<ITreeElement<T>> {
|
||||
const insertedElements = new Set<T | null>();
|
||||
const insertedElementIds = new Set<string>();
|
||||
|
||||
@@ -107,7 +114,7 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
_onDidDeleteNode
|
||||
);
|
||||
|
||||
return result;
|
||||
return result as Iterator<ITreeElement<T>>;
|
||||
}
|
||||
|
||||
private preserveCollapseState(elements: ISequence<ITreeElement<T>> | undefined): ISequence<ITreeElement<T>> {
|
||||
@@ -144,7 +151,7 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
});
|
||||
}
|
||||
|
||||
rerender(element: T): void {
|
||||
rerender(element: T | null): void {
|
||||
const location = this.getElementLocation(element);
|
||||
this.model.rerender(location);
|
||||
}
|
||||
@@ -190,32 +197,32 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
return this.model.getLastElementAncestor(location);
|
||||
}
|
||||
|
||||
getListIndex(element: T): number {
|
||||
getListIndex(element: T | null): number {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.getListIndex(location);
|
||||
}
|
||||
|
||||
getListRenderCount(element: T): number {
|
||||
getListRenderCount(element: T | null): number {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.getListRenderCount(location);
|
||||
}
|
||||
|
||||
isCollapsible(element: T): boolean {
|
||||
isCollapsible(element: T | null): boolean {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.isCollapsible(location);
|
||||
}
|
||||
|
||||
isCollapsed(element: T): boolean {
|
||||
isCollapsed(element: T | null): boolean {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.isCollapsed(location);
|
||||
}
|
||||
|
||||
setCollapsed(element: T, collapsed?: boolean, recursive?: boolean): boolean {
|
||||
setCollapsed(element: T | null, collapsed?: boolean, recursive?: boolean): boolean {
|
||||
const location = this.getElementLocation(element);
|
||||
return this.model.setCollapsed(location, collapsed, recursive);
|
||||
}
|
||||
|
||||
expandTo(element: T): void {
|
||||
expandTo(element: T | null): void {
|
||||
const location = this.getElementLocation(element);
|
||||
this.model.expandTo(location);
|
||||
}
|
||||
@@ -238,11 +245,15 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
return node;
|
||||
}
|
||||
|
||||
getNodeLocation(node: ITreeNode<T, TFilterData>): T {
|
||||
getNodeLocation(node: ITreeNode<T, TFilterData>): T | null {
|
||||
return node.element;
|
||||
}
|
||||
|
||||
getParentNodeLocation(element: T): T | null {
|
||||
getParentNodeLocation(element: T | null): T | null {
|
||||
if (element === null) {
|
||||
throw new Error(`Invalid getParentNodeLocation call`);
|
||||
}
|
||||
|
||||
const node = this.nodes.get(element);
|
||||
|
||||
if (!node) {
|
||||
|
||||