mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
Merge from vscode 3c6f6af7347d38e87bc6406024e8dcf9e9bce229 (#8962)
* Merge from vscode 3c6f6af7347d38e87bc6406024e8dcf9e9bce229 * skip failing tests * update mac build image
This commit is contained in:
committed by
Karl Burtram
parent
0eaee18dc4
commit
fefe1454de
2
.yarnrc
2
.yarnrc
@@ -1,3 +1,3 @@
|
||||
disturl "https://atom.io/download/electron"
|
||||
target "7.1.7"
|
||||
target "6.1.6"
|
||||
runtime "electron"
|
||||
|
||||
@@ -17,6 +17,6 @@ jobs:
|
||||
|
||||
- job: macOS
|
||||
pool:
|
||||
vmImage: macOS 10.13
|
||||
vmImage: macOS-latest
|
||||
steps:
|
||||
- template: build/azure-pipelines/darwin/continuous-build-darwin.yml
|
||||
|
||||
@@ -102,7 +102,7 @@ jobs:
|
||||
- job: macOS
|
||||
condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_MACOS'], 'true'))
|
||||
pool:
|
||||
vmImage: macOS 10.13
|
||||
vmImage: macOS-latest
|
||||
dependsOn:
|
||||
- Compile
|
||||
steps:
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
- job: macOS
|
||||
condition: eq(variables['VSCODE_BUILD_MACOS'], 'true')
|
||||
pool:
|
||||
vmImage: macOS 10.13
|
||||
vmImage: macOS-latest
|
||||
dependsOn:
|
||||
- Compile
|
||||
steps:
|
||||
|
||||
@@ -10,6 +10,7 @@ const os = require('os');
|
||||
const { remote } = require('electron');
|
||||
const dialog = remote.dialog;
|
||||
|
||||
const productJsonPath = path.join(__dirname, '..', '..', 'product.json');
|
||||
const builtInExtensionsPath = path.join(__dirname, '..', 'builtInExtensions.json');
|
||||
const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json');
|
||||
|
||||
@@ -51,6 +52,7 @@ function render(el, state) {
|
||||
}
|
||||
|
||||
const ul = document.createElement('ul');
|
||||
const { quality } = readJson(productJsonPath);
|
||||
const { builtin, control } = state;
|
||||
|
||||
for (const ext of builtin) {
|
||||
@@ -61,6 +63,10 @@ function render(el, state) {
|
||||
|
||||
const name = document.createElement('code');
|
||||
name.textContent = ext.name;
|
||||
if (quality && ext.forQualities && !ext.forQualities.includes(quality)) {
|
||||
name.textContent += ` (only on ${ext.forQualities.join(', ')})`;
|
||||
}
|
||||
|
||||
li.appendChild(name);
|
||||
|
||||
const form = document.createElement('form');
|
||||
@@ -123,4 +129,4 @@ function main() {
|
||||
render(el, { builtin, control });
|
||||
}
|
||||
|
||||
window.onload = main;
|
||||
window.onload = main;
|
||||
|
||||
@@ -27,6 +27,7 @@ const util = require('./util');
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
const commit = util.getVersion(root);
|
||||
const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`;
|
||||
const product = require('../../product.json');
|
||||
function fromLocal(extensionPath) {
|
||||
const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
|
||||
const input = fs.existsSync(webpackFilename)
|
||||
@@ -185,8 +186,8 @@ const excludedExtensions = [
|
||||
'vscode-test-resolver',
|
||||
'ms-vscode.node-debug',
|
||||
'ms-vscode.node-debug2',
|
||||
// {{SQL CARBON EDIT}}
|
||||
'integration-tests'
|
||||
'integration-tests',
|
||||
'ms.vscode.js-debug-nightly'
|
||||
];
|
||||
// {{SQL CARBON EDIT}}
|
||||
const externalExtensions = [
|
||||
@@ -212,7 +213,8 @@ const rebuildExtensions = [
|
||||
'big-data-cluster',
|
||||
'mssql'
|
||||
];
|
||||
const builtInExtensions = require('../builtInExtensions.json');
|
||||
const builtInExtensions = require('../builtInExtensions.json')
|
||||
.filter(({ forQualities }) => { var _a; return !product.quality || ((_a = forQualities === null || forQualities === void 0 ? void 0 : forQualities.includes) === null || _a === void 0 ? void 0 : _a.call(forQualities, product.quality)) !== false; });
|
||||
function packageLocalExtensionsStream() {
|
||||
const localExtensionDescriptions = glob.sync('extensions/*/package.json')
|
||||
.map(manifestPath => {
|
||||
|
||||
@@ -27,6 +27,7 @@ const util = require('./util');
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
const commit = util.getVersion(root);
|
||||
const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`;
|
||||
const product = require('../../product.json');
|
||||
|
||||
function fromLocal(extensionPath: string): Stream {
|
||||
const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
|
||||
@@ -220,8 +221,8 @@ const excludedExtensions = [
|
||||
'vscode-test-resolver',
|
||||
'ms-vscode.node-debug',
|
||||
'ms-vscode.node-debug2',
|
||||
// {{SQL CARBON EDIT}}
|
||||
'integration-tests'
|
||||
'integration-tests', // {{SQL CARBON EDIT}}
|
||||
'ms.vscode.js-debug-nightly'
|
||||
];
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
@@ -254,10 +255,12 @@ interface IBuiltInExtension {
|
||||
name: string;
|
||||
version: string;
|
||||
repo: string;
|
||||
forQualities?: ReadonlyArray<string>;
|
||||
metadata: any;
|
||||
}
|
||||
|
||||
const builtInExtensions: IBuiltInExtension[] = require('../builtInExtensions.json');
|
||||
const builtInExtensions = (<IBuiltInExtension[]>require('../builtInExtensions.json'))
|
||||
.filter(({ forQualities }) => !product.quality || forQualities?.includes?.(product.quality) !== false);
|
||||
|
||||
export function packageLocalExtensionsStream(): NodeJS.ReadWriteStream {
|
||||
const localExtensionDescriptions = (<string[]>glob.sync('extensions/*/package.json'))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "chromium",
|
||||
"repositoryUrl": "https://chromium.googlesource.com/chromium/src",
|
||||
"commitHash": "e4745133a1d3745f066e068b8033c6a269b59caf"
|
||||
"commitHash": "91f08db83c2ce8c722ddf0911ead8f7c473bedfa"
|
||||
}
|
||||
},
|
||||
"licenseDetail": [
|
||||
@@ -40,7 +40,7 @@
|
||||
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
],
|
||||
"isOnlyProductionDependency": true,
|
||||
"version": "78.0.3904.130"
|
||||
"version": "76.0.3809.146"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
@@ -48,11 +48,11 @@
|
||||
"git": {
|
||||
"name": "nodejs",
|
||||
"repositoryUrl": "https://github.com/nodejs/node",
|
||||
"commitHash": "787378879acfb212ed4ff824bf9f767a24a5cb43a"
|
||||
"commitHash": "64219741218aa87e259cf8257596073b8e747f0a"
|
||||
}
|
||||
},
|
||||
"isOnlyProductionDependency": true,
|
||||
"version": "12.8.1"
|
||||
"version": "12.4.0"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
@@ -60,12 +60,12 @@
|
||||
"git": {
|
||||
"name": "electron",
|
||||
"repositoryUrl": "https://github.com/electron/electron",
|
||||
"commitHash": "bef0dd868b7d6d32716c319664ed480f2ae17396"
|
||||
"commitHash": "19c705ab80cd6fdccca3d65803ec2c4addb9540a"
|
||||
}
|
||||
},
|
||||
"isOnlyProductionDependency": true,
|
||||
"license": "MIT",
|
||||
"version": "7.1.7"
|
||||
"version": "6.1.6"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"],
|
||||
["%", "%"],
|
||||
["\"", "\""]
|
||||
],
|
||||
"folding": {
|
||||
|
||||
@@ -24,6 +24,13 @@
|
||||
"$ref": "vscode://schemas/settings/machine",
|
||||
"description": "Machine specific settings that should be copied into the container."
|
||||
},
|
||||
"forwardPorts": {
|
||||
"type": "array",
|
||||
"description": "Ports that are forwarded from the container to the local machine.",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"remoteEnv": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
|
||||
@@ -1194,7 +1194,7 @@
|
||||
{
|
||||
"command": "git.openFile",
|
||||
"group": "navigation",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.openChange",
|
||||
@@ -1204,44 +1204,44 @@
|
||||
{
|
||||
"command": "git.stageSelectedRanges",
|
||||
"group": "2_git@1",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.unstageSelectedRanges",
|
||||
"group": "2_git@2",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.revertSelectedRanges",
|
||||
"group": "2_git@3",
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
}
|
||||
],
|
||||
"editor/context": [
|
||||
{
|
||||
"command": "git.stageSelectedRanges",
|
||||
"group": "2_git@1",
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.unstageSelectedRanges",
|
||||
"group": "2_git@2",
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.revertSelectedRanges",
|
||||
"group": "2_git@3",
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^gitfs$|^file$/"
|
||||
"when": "isInDiffRightEditor && config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
}
|
||||
],
|
||||
"scm/change/title": [
|
||||
{
|
||||
"command": "git.stageChange",
|
||||
"when": "originalResourceScheme == gitfs"
|
||||
"when": "originalResourceScheme == git"
|
||||
},
|
||||
{
|
||||
"command": "git.revertChange",
|
||||
"when": "originalResourceScheme == gitfs"
|
||||
"when": "originalResourceScheme == git"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -239,5 +239,10 @@ export class ApiImpl implements API {
|
||||
return toGitUri(uri, ref);
|
||||
}
|
||||
|
||||
getRepository(uri: Uri): Repository | null {
|
||||
const result = this._model.getRepository(uri);
|
||||
return result ? new ApiRepository(result) : null;
|
||||
}
|
||||
|
||||
constructor(private _model: Model) { }
|
||||
}
|
||||
|
||||
1
extensions/git/src/api/git.d.ts
vendored
1
extensions/git/src/api/git.d.ts
vendored
@@ -187,6 +187,7 @@ export interface API {
|
||||
readonly onDidCloseRepository: Event<Repository>;
|
||||
|
||||
toGitUri(uri: Uri, ref: string): Uri;
|
||||
getRepository(uri: Uri): Repository | null;
|
||||
}
|
||||
|
||||
export interface GitExtension {
|
||||
|
||||
@@ -47,9 +47,9 @@ export class GitFileSystemProvider implements FileSystemProvider {
|
||||
this.disposables.push(
|
||||
model.onDidChangeRepository(this.onDidChangeRepository, this),
|
||||
model.onDidChangeOriginalResource(this.onDidChangeOriginalResource, this),
|
||||
workspace.registerFileSystemProvider('gitfs', this, { isReadonly: true, isCaseSensitive: true }),
|
||||
workspace.registerFileSystemProvider('git', this, { isReadonly: true, isCaseSensitive: true }),
|
||||
workspace.registerResourceLabelFormatter({
|
||||
scheme: 'gitfs',
|
||||
scheme: 'git',
|
||||
formatting: {
|
||||
label: '${path} (git)',
|
||||
separator: '/'
|
||||
|
||||
@@ -392,7 +392,7 @@ export class Model {
|
||||
if (hint instanceof Uri) {
|
||||
let resourcePath: string;
|
||||
|
||||
if (hint.scheme === 'git' || hint.scheme === 'gitfs') {
|
||||
if (hint.scheme === 'git') {
|
||||
resourcePath = fromGitUri(hint).path;
|
||||
} else {
|
||||
resourcePath = hint.fsPath;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri } from 'vscode';
|
||||
import * as qs from 'querystring';
|
||||
|
||||
export interface GitUriParams {
|
||||
path: string;
|
||||
@@ -13,25 +12,11 @@ export interface GitUriParams {
|
||||
}
|
||||
|
||||
export function isGitUri(uri: Uri): boolean {
|
||||
return /^git(fs)?$/.test(uri.scheme);
|
||||
return /^git$/.test(uri.scheme);
|
||||
}
|
||||
|
||||
export function fromGitUri(uri: Uri): GitUriParams {
|
||||
const result = qs.parse(uri.query) as any;
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Invalid git URI: empty query');
|
||||
}
|
||||
|
||||
if (typeof result.path !== 'string') {
|
||||
throw new Error('Invalid git URI: missing path');
|
||||
}
|
||||
|
||||
if (typeof result.ref !== 'string') {
|
||||
throw new Error('Invalid git URI: missing ref');
|
||||
}
|
||||
|
||||
return result;
|
||||
return JSON.parse(uri.query);
|
||||
}
|
||||
|
||||
export interface GitUriOptions {
|
||||
@@ -61,8 +46,8 @@ export function toGitUri(uri: Uri, ref: string, options: GitUriOptions = {}): Ur
|
||||
}
|
||||
|
||||
return uri.with({
|
||||
scheme: 'gitfs',
|
||||
scheme: 'git',
|
||||
path,
|
||||
query: qs.stringify(params as any)
|
||||
query: JSON.stringify(params)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -235,9 +235,9 @@
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit markup.inserted.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "markup.inserted: #B5CEA8",
|
||||
"light_plus": "markup.inserted: #09885A",
|
||||
"light_plus": "markup.inserted: #098658",
|
||||
"dark_vs": "markup.inserted: #B5CEA8",
|
||||
"light_vs": "markup.inserted: #09885A",
|
||||
"light_vs": "markup.inserted: #098658",
|
||||
"hc_black": "markup.inserted: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -252,4 +252,4 @@
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -147,9 +147,9 @@
|
||||
"t": "source.diff markup.inserted.diff punctuation.definition.inserted.diff",
|
||||
"r": {
|
||||
"dark_plus": "markup.inserted: #B5CEA8",
|
||||
"light_plus": "markup.inserted: #09885A",
|
||||
"light_plus": "markup.inserted: #098658",
|
||||
"dark_vs": "markup.inserted: #B5CEA8",
|
||||
"light_vs": "markup.inserted: #09885A",
|
||||
"light_vs": "markup.inserted: #098658",
|
||||
"hc_black": "markup.inserted: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -158,10 +158,10 @@
|
||||
"t": "source.diff markup.inserted.diff",
|
||||
"r": {
|
||||
"dark_plus": "markup.inserted: #B5CEA8",
|
||||
"light_plus": "markup.inserted: #09885A",
|
||||
"light_plus": "markup.inserted: #098658",
|
||||
"dark_vs": "markup.inserted: #B5CEA8",
|
||||
"light_vs": "markup.inserted: #09885A",
|
||||
"light_vs": "markup.inserted: #098658",
|
||||
"hc_black": "markup.inserted: #B5CEA8"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"light_plus": "constant.sha.git-rebase: #098658",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"light_vs": "constant.sha.git-rebase: #098658",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -81,9 +81,9 @@
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"light_plus": "constant.sha.git-rebase: #098658",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"light_vs": "constant.sha.git-rebase: #098658",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -136,9 +136,9 @@
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"light_plus": "constant.sha.git-rebase: #098658",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"light_vs": "constant.sha.git-rebase: #098658",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -191,9 +191,9 @@
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"light_plus": "constant.sha.git-rebase: #098658",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"light_vs": "constant.sha.git-rebase: #098658",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -246,9 +246,9 @@
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"light_plus": "constant.sha.git-rebase: #098658",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"light_vs": "constant.sha.git-rebase: #098658",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -301,9 +301,9 @@
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"light_plus": "constant.sha.git-rebase: #098658",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"light_vs": "constant.sha.git-rebase: #098658",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -356,9 +356,9 @@
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"light_plus": "constant.sha.git-rebase: #098658",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"light_vs": "constant.sha.git-rebase: #098658",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -538,4 +538,4 @@
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -236,7 +236,7 @@ class Preview extends Disposable {
|
||||
}
|
||||
|
||||
private async getResourcePath(webviewEditor: vscode.WebviewPanel, resource: vscode.Uri, version: string): Promise<string> {
|
||||
if (resource.scheme === 'gitfs') {
|
||||
if (resource.scheme === 'git') {
|
||||
const stat = await vscode.workspace.fs.stat(resource);
|
||||
if (stat.size === 0) {
|
||||
return this.emptyPngDataUri;
|
||||
|
||||
@@ -117,7 +117,8 @@ export function activate(context: ExtensionContext) {
|
||||
documentSelector,
|
||||
initializationOptions: {
|
||||
handledSchemaProtocols: ['file'], // language server only loads file-URI. Fetching schemas with other protocols ('http'...) are made on the client.
|
||||
provideFormatter: false // tell the server to not provide formatting capability and ignore the `json.format.enable` setting.
|
||||
provideFormatter: false, // tell the server to not provide formatting capability and ignore the `json.format.enable` setting.
|
||||
customCapabilities: { rangeFormatting: { editLimit: 1000 } }
|
||||
},
|
||||
synchronize: {
|
||||
// Synchronize the setting section 'json' to the server
|
||||
|
||||
@@ -111,12 +111,16 @@
|
||||
},
|
||||
"editor.suggest.insertMode": "replace"
|
||||
}
|
||||
}
|
||||
},
|
||||
"jsonValidation": [{
|
||||
"fileMatch": "*.schema.json",
|
||||
"url": "http://json-schema.org/draft-07/schema#"
|
||||
}]
|
||||
},
|
||||
"dependencies": {
|
||||
"request-light": "^0.2.5",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-languageclient": "^6.0.0-next.3",
|
||||
"vscode-languageclient": "^6.0.1",
|
||||
"vscode-nls": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -46,6 +46,8 @@ The client can send the following initialization options to the server:
|
||||
|
||||
- `provideFormatter: boolean | undefined`. If defined, the value defines whether the server provides the `documentRangeFormattingProvider` capability on initialization. If undefined, the setting `json.format.enable` is used to determine whether formatting is provided. The formatter will then be registered through dynamic registration. If the client does not support dynamic registration, no formatter will be available.
|
||||
- `handledSchemaProtocols`: The URI schemas handles by the server. See section `Schema configuration` below.
|
||||
- `customCapabilities`: Additional non-LSP client capabilities:
|
||||
- `rangeFormatting: { editLimit: x } }`: For performance reasons, limit the number of edits returned by the range formatter to `x`.
|
||||
|
||||
### Settings
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^2.2.0",
|
||||
"request-light": "^0.2.5",
|
||||
"vscode-json-languageservice": "^3.4.9",
|
||||
"vscode-languageserver": "^6.0.0-next.3",
|
||||
"vscode-json-languageservice": "^3.4.12",
|
||||
"vscode-languageserver": "^6.0.1",
|
||||
"vscode-uri": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import {
|
||||
createConnection, IConnection,
|
||||
TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit
|
||||
} from 'vscode-languageserver';
|
||||
|
||||
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
|
||||
@@ -16,7 +16,7 @@ import * as URL from 'url';
|
||||
import { posix } from 'path';
|
||||
import { setTimeout, clearTimeout } from 'timers';
|
||||
import { formatError, runSafe, runSafeAsync } from './utils/runner';
|
||||
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, SchemaRequestService, Diagnostic } from 'vscode-json-languageservice';
|
||||
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, SchemaRequestService, Diagnostic, Range, Position } from 'vscode-json-languageservice';
|
||||
import { getLanguageModelCache } from './languageModelCache';
|
||||
|
||||
interface ISchemaAssociations {
|
||||
@@ -126,12 +126,13 @@ let hierarchicalDocumentSymbolSupport = false;
|
||||
let foldingRangeLimitDefault = Number.MAX_VALUE;
|
||||
let foldingRangeLimit = Number.MAX_VALUE;
|
||||
let resultLimit = Number.MAX_VALUE;
|
||||
let formatterMaxNumberOfEdits = Number.MAX_VALUE;
|
||||
|
||||
// After the server has started the client sends an initialize request. The server receives
|
||||
// in the passed params the rootPath of the workspace plus the client capabilities.
|
||||
connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
|
||||
const handledProtocols = params.initializationOptions && params.initializationOptions['handledSchemaProtocols'];
|
||||
const handledProtocols = params.initializationOptions?.handledSchemaProtocols;
|
||||
|
||||
languageService = getLanguageService({
|
||||
schemaRequestService: getSchemaRequestService(handledProtocols),
|
||||
@@ -153,9 +154,10 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
}
|
||||
|
||||
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
|
||||
dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof params.initializationOptions.provideFormatter !== 'boolean');
|
||||
dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof params.initializationOptions?.provideFormatter !== 'boolean');
|
||||
foldingRangeLimitDefault = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false);
|
||||
formatterMaxNumberOfEdits = params.initializationOptions?.customCapabilities?.rangeFormatting?.editLimit || Number.MAX_VALUE;
|
||||
const capabilities: ServerCapabilities = {
|
||||
textDocumentSync: TextDocumentSyncKind.Incremental,
|
||||
completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['"', ':'] } : undefined,
|
||||
@@ -445,7 +447,12 @@ connection.onDocumentRangeFormatting((formatParams, token) => {
|
||||
return runSafe(() => {
|
||||
const document = documents.get(formatParams.textDocument.uri);
|
||||
if (document) {
|
||||
return languageService.format(document, formatParams.range, formatParams.options);
|
||||
const edits = languageService.format(document, formatParams.range, formatParams.options);
|
||||
if (edits.length > formatterMaxNumberOfEdits) {
|
||||
const newText = TextDocument.applyEdits(document, edits);
|
||||
return [TextEdit.replace(Range.create(Position.create(0, 0), document.positionAt(document.getText().length - 1)), newText)];
|
||||
}
|
||||
return edits;
|
||||
}
|
||||
return [];
|
||||
}, [], `Error while formatting range for ${formatParams.textDocument.uri}`, token);
|
||||
|
||||
@@ -80,57 +80,52 @@ request-light@^0.2.5:
|
||||
https-proxy-agent "^2.2.3"
|
||||
vscode-nls "^4.1.1"
|
||||
|
||||
vscode-json-languageservice@^3.4.9:
|
||||
version "3.4.9"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.9.tgz#7ce485bb0f9a07b4d879c988baac9be2222909ad"
|
||||
integrity sha512-4VCpZ9ooea/Zc/MTnj1ccc9C7rqcoinKVQLhLoi6jw6yueSf4y4tg/YIUiPPVMlEAG7ZCPS+NVmqxisQ+mOsSw==
|
||||
vscode-json-languageservice@^3.4.12:
|
||||
version "3.4.12"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.12.tgz#e7c96a1824896a624cc7bb14f46fbf9cb7e6c5a3"
|
||||
integrity sha512-+tA0KPVM1pDfORZqsQen7bY5buBpQGDTVYEobm5MoGtXNeZY2Kn0iy5wIQqXveb28LRv/I5xKE87dmNJTEaijQ==
|
||||
dependencies:
|
||||
jsonc-parser "^2.2.0"
|
||||
vscode-languageserver-textdocument "^1.0.0-next.4"
|
||||
vscode-languageserver-types "^3.15.0-next.6"
|
||||
vscode-languageserver-textdocument "^1.0.1-next.1"
|
||||
vscode-languageserver-types "^3.15.0"
|
||||
vscode-nls "^4.1.1"
|
||||
vscode-uri "^2.1.0"
|
||||
vscode-uri "^2.1.1"
|
||||
|
||||
vscode-jsonrpc@^5.0.0-next.2:
|
||||
version "5.0.0-next.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.0-next.2.tgz#a44bc03f67069e53f8d8beb88b96c0cacbfefbca"
|
||||
integrity sha512-Q3/jabZUNviCG9hhF6hHWjhrABevPF9mv0aiE2j8BYCAP2k+aHTpjMyk+04MzaAqWYwXdQuZkLSbcYCCqbzJLg==
|
||||
vscode-jsonrpc@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794"
|
||||
integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==
|
||||
|
||||
vscode-languageserver-protocol@^3.15.0-next.10:
|
||||
version "3.15.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.10.tgz#f1382f0c270ae5d0c2c7e552483285fb75810914"
|
||||
integrity sha512-TmbBhKrBoYNX+/pQGwoXmy2qlOfjGBUhwUGIzQoWpj8qtDzYuLof8bi19rGLZ9sVuSHh3anvIyVpGJEqT0QODQ==
|
||||
vscode-languageserver-protocol@^3.15.1:
|
||||
version "3.15.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.1.tgz#7555e595f0058b9a166f14605ad039e97fab320a"
|
||||
integrity sha512-wJAo06VM9ZBnRqslplDjfz6Tdive0O7z44yNxBFA3x0/YZkXBIL6I+9rwQ/9Y//0X0eCh12FQrj+KmEXf2L5eA==
|
||||
dependencies:
|
||||
vscode-jsonrpc "^5.0.0-next.2"
|
||||
vscode-languageserver-types "^3.15.0-next.6"
|
||||
vscode-jsonrpc "^5.0.1"
|
||||
vscode-languageserver-types "3.15.0"
|
||||
|
||||
vscode-languageserver-textdocument@^1.0.0-next.4:
|
||||
version "1.0.0-next.4"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.0-next.4.tgz#8f7afdfe3e81411f57baaa29bb3214d1907160cd"
|
||||
integrity sha512-LJ5WfoBO54nqinjlLJKnjoo2Im4bIvPJ8bFT7R0C84ZI36iK8M29ddslfe5jUeWNSTtCda7YuKdKsDIq38HpgA==
|
||||
vscode-languageserver-textdocument@^1.0.1-next.1:
|
||||
version "1.0.1-next.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1-next.1.tgz#c8f2f792c7c88d33ea8441ca04bfb8376896b671"
|
||||
integrity sha512-Cmt0KsNxouns+d7/Kw/jWtWU9Z3h56z1qAA8utjDOEqrDcrTs2rDXv3EJRa99nuKM3wVf6DbWym1VqL9q71XPA==
|
||||
|
||||
vscode-languageserver-types@^3.15.0-next.6:
|
||||
version "3.15.0-next.6"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.6.tgz#7a990d00c39ad4e744335afb4cc422a3e687ff25"
|
||||
integrity sha512-+4jfvmZ26oFMSX6EgPRB75PWHoT8pzyWuSSWk0erC4hTzmJq2gWxVLh20bZutZjMmiivawvPshtM3XZhX2SttA==
|
||||
vscode-languageserver-types@3.15.0, vscode-languageserver-types@^3.15.0:
|
||||
version "3.15.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0.tgz#c45a23308ec0967135c483b759dfaf97978d9e0a"
|
||||
integrity sha512-AXteNagMhBWnZ6gNN0UB4HTiD/7TajgfHl6jaM6O7qz3zDJw0H3Jf83w05phihnBRCML+K6Ockh8f8bL0OObPw==
|
||||
|
||||
vscode-languageserver@^6.0.0-next.3:
|
||||
version "6.0.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-6.0.0-next.3.tgz#41e2fda6417939792f6a19fc19ecbb2f080e2072"
|
||||
integrity sha512-Q6T+KwYuoXV9KRHD6x7RfTU13pV0xAX2BtcuvSC/LBCiVAnEIOe7jKZjzya+B9gDvSk4hpfvhPefy5IdQK1mpQ==
|
||||
vscode-languageserver@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-6.0.1.tgz#4f499d245f1baf83bd607dd79c4c3fd19e8cefc0"
|
||||
integrity sha512-Wk4I/Dn5KNARWockdCrYuuImJz6bpYG8n2G3Kk5AU6Xy9nWNHD6YjB9/Rd99p4goViZOyETM+hYE81LnEzQZUA==
|
||||
dependencies:
|
||||
vscode-languageserver-protocol "^3.15.0-next.10"
|
||||
vscode-languageserver-protocol "^3.15.1"
|
||||
|
||||
vscode-nls@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c"
|
||||
integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==
|
||||
|
||||
vscode-uri@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.0.tgz#475a4269e63edbc13914b40c84bc1416e3398156"
|
||||
integrity sha512-3voe44nOhb6OdKlpZShVsmVvY2vFQHMe6REP3Ky9RVJuPyM/XidsjH6HncCIDdSmbcF5YQHrTC/Q+Q2loJGkOw==
|
||||
|
||||
vscode-uri@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.1.tgz#5aa1803391b6ebdd17d047f51365cf62c38f6e90"
|
||||
|
||||
@@ -120,31 +120,31 @@ vscode-extension-telemetry@0.1.1:
|
||||
dependencies:
|
||||
applicationinsights "1.0.8"
|
||||
|
||||
vscode-jsonrpc@^5.0.0-next.2:
|
||||
version "5.0.0-next.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.0-next.2.tgz#a44bc03f67069e53f8d8beb88b96c0cacbfefbca"
|
||||
integrity sha512-Q3/jabZUNviCG9hhF6hHWjhrABevPF9mv0aiE2j8BYCAP2k+aHTpjMyk+04MzaAqWYwXdQuZkLSbcYCCqbzJLg==
|
||||
vscode-jsonrpc@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794"
|
||||
integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==
|
||||
|
||||
vscode-languageclient@^6.0.0-next.3:
|
||||
version "6.0.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-6.0.0-next.3.tgz#41b701d963fc7affc01e9279532a747fcd4f3810"
|
||||
integrity sha512-SuSaG9xjqkROm4Ie0jQig0CFDuU/WxHERegl3kRsFHDbhMSK4dH45ZeBY5zMWUgZ+LrIrEbwf8qWNlrTRBlUgg==
|
||||
vscode-languageclient@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-6.0.1.tgz#acd138e0a19a40c5788365e882ae11c164d9a460"
|
||||
integrity sha512-7yZaSHichTJEyOJykI2RLQEECf9MqNLoklzC/1OVi/M8ioIsWQ1+lkN1nTsUhd6+F7p9ar9dNmPiEhL0i5uUBA==
|
||||
dependencies:
|
||||
semver "^6.3.0"
|
||||
vscode-languageserver-protocol "^3.15.0-next.10"
|
||||
vscode-languageserver-protocol "^3.15.1"
|
||||
|
||||
vscode-languageserver-protocol@^3.15.0-next.10:
|
||||
version "3.15.0-next.10"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.10.tgz#f1382f0c270ae5d0c2c7e552483285fb75810914"
|
||||
integrity sha512-TmbBhKrBoYNX+/pQGwoXmy2qlOfjGBUhwUGIzQoWpj8qtDzYuLof8bi19rGLZ9sVuSHh3anvIyVpGJEqT0QODQ==
|
||||
vscode-languageserver-protocol@^3.15.1:
|
||||
version "3.15.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.1.tgz#7555e595f0058b9a166f14605ad039e97fab320a"
|
||||
integrity sha512-wJAo06VM9ZBnRqslplDjfz6Tdive0O7z44yNxBFA3x0/YZkXBIL6I+9rwQ/9Y//0X0eCh12FQrj+KmEXf2L5eA==
|
||||
dependencies:
|
||||
vscode-jsonrpc "^5.0.0-next.2"
|
||||
vscode-languageserver-types "^3.15.0-next.6"
|
||||
vscode-jsonrpc "^5.0.1"
|
||||
vscode-languageserver-types "3.15.0"
|
||||
|
||||
vscode-languageserver-types@^3.15.0-next.6:
|
||||
version "3.15.0-next.6"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.6.tgz#7a990d00c39ad4e744335afb4cc422a3e687ff25"
|
||||
integrity sha512-+4jfvmZ26oFMSX6EgPRB75PWHoT8pzyWuSSWk0erC4hTzmJq2gWxVLh20bZutZjMmiivawvPshtM3XZhX2SttA==
|
||||
vscode-languageserver-types@3.15.0:
|
||||
version "3.15.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0.tgz#c45a23308ec0967135c483b759dfaf97978d9e0a"
|
||||
integrity sha512-AXteNagMhBWnZ6gNN0UB4HTiD/7TajgfHl6jaM6O7qz3zDJw0H3Jf83w05phihnBRCML+K6Ockh8f8bL0OObPw==
|
||||
|
||||
vscode-nls@^4.1.1:
|
||||
version "4.1.1"
|
||||
|
||||
@@ -67,12 +67,6 @@
|
||||
"scopeName": "source.json.comments",
|
||||
"path": "./syntaxes/JSONC.tmLanguage.json"
|
||||
}
|
||||
],
|
||||
"jsonValidation": [
|
||||
{
|
||||
"fileMatch": "*.schema.json",
|
||||
"url": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,9 +279,9 @@
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json constant.numeric.json",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -488,9 +488,9 @@
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json constant.numeric.json",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -686,9 +686,9 @@
|
||||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.array.json constant.numeric.json",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1165,4 +1165,4 @@
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -950,9 +950,9 @@
|
||||
"t": "source.powershell meta.scriptblock.powershell interpolated.simple.source.powershell meta.attribute.powershell constant.numeric.integer.powershell",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1522,9 +1522,9 @@
|
||||
"t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell constant.numeric.integer.powershell",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1599,9 +1599,9 @@
|
||||
"t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell meta.scriptblock.powershell interpolated.simple.source.powershell constant.numeric.integer.powershell",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -2892,4 +2892,4 @@
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -169,9 +169,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -565,9 +565,9 @@
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python constant.numeric.float.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1137,9 +1137,9 @@
|
||||
"t": "source.python meta.function.python meta.function.parameters.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1214,9 +1214,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1280,9 +1280,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1324,9 +1324,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1390,9 +1390,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1456,9 +1456,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1522,9 +1522,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1566,9 +1566,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1632,9 +1632,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1698,9 +1698,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1764,9 +1764,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1808,9 +1808,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1874,9 +1874,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1962,9 +1962,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -2424,9 +2424,9 @@
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -2446,9 +2446,9 @@
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -2468,9 +2468,9 @@
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -2490,9 +2490,9 @@
|
||||
"t": "source.python meta.function-call.python meta.function-call.arguments.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -2985,9 +2985,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3359,9 +3359,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3414,9 +3414,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3480,9 +3480,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3568,9 +3568,9 @@
|
||||
"t": "source.python constant.numeric.float.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3601,9 +3601,9 @@
|
||||
"t": "source.python constant.numeric.float.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3656,9 +3656,9 @@
|
||||
"t": "source.python constant.numeric.float.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3722,9 +3722,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3854,9 +3854,9 @@
|
||||
"t": "source.python constant.numeric.float.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -3898,9 +3898,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -6252,9 +6252,9 @@
|
||||
"t": "source.python constant.numeric.dec.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -6797,4 +6797,4 @@
|
||||
"hc_black": "string: #CE9178"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -554,9 +554,9 @@
|
||||
"t": "source.r meta.function-call.r meta.function-call.arguments.r constant.numeric.float.decimal.r",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -598,9 +598,9 @@
|
||||
"t": "source.r meta.function-call.r meta.function-call.arguments.r constant.numeric.float.decimal.r",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -631,9 +631,9 @@
|
||||
"t": "source.r meta.function-call.r meta.function-call.arguments.r constant.numeric.float.decimal.r",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -675,9 +675,9 @@
|
||||
"t": "source.r meta.function-call.r meta.function-call.arguments.r constant.numeric.float.decimal.r",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -708,9 +708,9 @@
|
||||
"t": "source.r meta.function-call.r meta.function-call.arguments.r constant.numeric.float.decimal.r",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1044,4 +1044,4 @@
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -25,46 +25,6 @@
|
||||
"editor.lineNumbers": "off"
|
||||
}
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"title": "%searchResult.rerunSearch.title%",
|
||||
"category": "Search Result",
|
||||
"icon": {
|
||||
"light": "./src/media/refresh-light.svg",
|
||||
"dark": "./src/media/refresh-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "searchResult.rerunSearchWithContext",
|
||||
"title": "%searchResult.rerunSearchWithContext.title%",
|
||||
"category": "Search Result",
|
||||
"icon": {
|
||||
"light": "./src/media/refresh-light.svg",
|
||||
"dark": "./src/media/refresh-dark.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "searchResult.rerunSearchWithContext",
|
||||
"when": "false"
|
||||
}
|
||||
],
|
||||
"editor/title": [
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"when": "editorLangId == search-result",
|
||||
"alt": "searchResult.rerunSearchWithContext",
|
||||
"group": "navigation"
|
||||
}
|
||||
]
|
||||
},
|
||||
"languages": [
|
||||
{
|
||||
"id": "search-result",
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
{
|
||||
"displayName": "Search Result",
|
||||
"description": "Provides syntax highlighting and language features for tabbed search results.",
|
||||
"searchResult.rerunSearch.title": "Search Again",
|
||||
"searchResult.rerunSearchWithContext.title": "Search Again (With Context)"
|
||||
"description": "Provides syntax highlighting and language features for tabbed search results."
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('searchResult.rerunSearch', () => vscode.commands.executeCommand('search.action.rerunEditorSearch')),
|
||||
vscode.commands.registerCommand('searchResult.rerunSearchWithContext', () => vscode.commands.executeCommand('search.action.rerunEditorSearchWithContext')),
|
||||
|
||||
vscode.languages.registerDocumentSymbolProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.DocumentSymbol[] {
|
||||
|
||||
@@ -136,9 +136,9 @@
|
||||
"t": "source.sql constant.numeric.sql",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -180,9 +180,9 @@
|
||||
"t": "source.sql constant.numeric.sql",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -213,9 +213,9 @@
|
||||
"t": "source.sql constant.numeric.sql",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -268,9 +268,9 @@
|
||||
"t": "source.sql constant.numeric.sql",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -290,9 +290,9 @@
|
||||
"t": "source.sql constant.numeric.sql",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -318,4 +318,4 @@
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
"keyword.operator.minus.exponent"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#09885a"
|
||||
"foreground": "#098658"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -130,7 +130,7 @@
|
||||
{
|
||||
"scope": "markup.inserted",
|
||||
"settings": {
|
||||
"foreground": "#09885a"
|
||||
"foreground": "#098658"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -185,7 +185,7 @@
|
||||
{
|
||||
"scope": "meta.preprocessor.numeric",
|
||||
"settings": {
|
||||
"foreground": "#09885a"
|
||||
"foreground": "#098658"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -346,7 +346,7 @@
|
||||
{
|
||||
"scope": "keyword.other.unit",
|
||||
"settings": {
|
||||
"foreground": "#09885a"
|
||||
"foreground": "#098658"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -367,7 +367,7 @@
|
||||
{
|
||||
"scope": "constant.sha.git-rebase",
|
||||
"settings": {
|
||||
"foreground": "#09885a"
|
||||
"foreground": "#098658"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,52 +4,131 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as crypto from 'crypto';
|
||||
import * as vscode from 'vscode';
|
||||
import * as https from 'https';
|
||||
import * as querystring from 'querystring';
|
||||
import { keychain } from './keychain';
|
||||
import { toBase64UrlEncoding } from './utils';
|
||||
import * as vscode from 'vscode';
|
||||
import { createServer, startServer } from './authServer';
|
||||
import { keychain } from './keychain';
|
||||
import Logger from './logger';
|
||||
import { toBase64UrlEncoding } from './utils';
|
||||
|
||||
const redirectUrl = 'https://vscode-redirect.azurewebsites.net/';
|
||||
const loginEndpointUrl = 'https://login.microsoftonline.com/';
|
||||
const clientId = 'aebc6443-996d-45c2-90f0-388ff96faa56';
|
||||
const scope = 'https://management.core.windows.net/.default offline_access';
|
||||
const tenant = 'common';
|
||||
const tenant = 'organizations';
|
||||
|
||||
interface IToken {
|
||||
expiresIn: string; // How long access token is valid, in seconds
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
|
||||
displayName: string;
|
||||
scope: string;
|
||||
sessionId: string; // The account id + the scope
|
||||
}
|
||||
|
||||
interface ITokenClaims {
|
||||
tid: string;
|
||||
email?: string;
|
||||
unique_name?: string;
|
||||
oid?: string;
|
||||
altsecid?: string;
|
||||
scp: string;
|
||||
}
|
||||
|
||||
interface IStoredSession {
|
||||
id: string;
|
||||
refreshToken: string;
|
||||
scope: string; // Scopes are alphabetized and joined with a space
|
||||
}
|
||||
|
||||
export const onDidChangeSessions = new vscode.EventEmitter<void>();
|
||||
|
||||
export class AzureActiveDirectoryService {
|
||||
private _token: IToken | undefined;
|
||||
private _refreshTimeout: NodeJS.Timeout | undefined;
|
||||
private _tokens: IToken[] = [];
|
||||
private _refreshTimeouts: Map<string, NodeJS.Timeout> = new Map<string, NodeJS.Timeout>();
|
||||
|
||||
public async initialize(): Promise<void> {
|
||||
const existingRefreshToken = await keychain.getToken();
|
||||
if (existingRefreshToken) {
|
||||
await this.refreshToken(existingRefreshToken);
|
||||
const storedData = await keychain.getToken();
|
||||
if (storedData) {
|
||||
try {
|
||||
const sessions = this.parseStoredData(storedData);
|
||||
const refreshes = sessions.map(async session => {
|
||||
try {
|
||||
await this.refreshToken(session.refreshToken, session.scope);
|
||||
} catch (e) {
|
||||
await this.logout(session.id);
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(refreshes);
|
||||
} catch (e) {
|
||||
await this.clearSessions();
|
||||
}
|
||||
}
|
||||
|
||||
this.pollForChange();
|
||||
}
|
||||
|
||||
private parseStoredData(data: string): IStoredSession[] {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
|
||||
private async storeTokenData(): Promise<void> {
|
||||
const serializedData: IStoredSession[] = this._tokens.map(token => {
|
||||
return {
|
||||
id: token.sessionId,
|
||||
refreshToken: token.refreshToken,
|
||||
scope: token.scope
|
||||
};
|
||||
});
|
||||
|
||||
await keychain.setToken(JSON.stringify(serializedData));
|
||||
}
|
||||
|
||||
private pollForChange() {
|
||||
setTimeout(async () => {
|
||||
const refreshToken = await keychain.getToken();
|
||||
// Another window has logged in, generate access token for this instance.
|
||||
if (refreshToken && !this._token) {
|
||||
await this.refreshToken(refreshToken);
|
||||
onDidChangeSessions.fire();
|
||||
let didChange = false;
|
||||
const storedData = await keychain.getToken();
|
||||
if (storedData) {
|
||||
try {
|
||||
const sessions = this.parseStoredData(storedData);
|
||||
let promises = sessions.map(async session => {
|
||||
const matchesExisting = this._tokens.some(token => token.scope === session.scope && token.sessionId === session.id);
|
||||
if (!matchesExisting) {
|
||||
try {
|
||||
await this.refreshToken(session.refreshToken, session.scope);
|
||||
didChange = true;
|
||||
} catch (e) {
|
||||
await this.logout(session.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
promises = promises.concat(this._tokens.map(async token => {
|
||||
const matchesExisting = sessions.some(session => token.scope === session.scope && token.sessionId === session.id);
|
||||
if (!matchesExisting) {
|
||||
await this.logout(token.sessionId);
|
||||
didChange = true;
|
||||
}
|
||||
}));
|
||||
|
||||
await Promise.all(promises);
|
||||
} catch (e) {
|
||||
Logger.error(e.message);
|
||||
// if data is improperly formatted, remove all of it and send change event
|
||||
this.clearSessions();
|
||||
didChange = true;
|
||||
}
|
||||
} else {
|
||||
if (this._tokens.length) {
|
||||
// Log out all
|
||||
await this.clearSessions();
|
||||
didChange = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Another window has logged out
|
||||
if (!refreshToken && this._token) {
|
||||
await this.logout();
|
||||
if (didChange) {
|
||||
onDidChangeSessions.fire();
|
||||
}
|
||||
|
||||
@@ -57,31 +136,30 @@ export class AzureActiveDirectoryService {
|
||||
}, 1000 * 30);
|
||||
}
|
||||
|
||||
private tokenToAccount(token: IToken): vscode.Session {
|
||||
private convertToSession(token: IToken): vscode.Session {
|
||||
return {
|
||||
id: '',
|
||||
id: token.sessionId,
|
||||
accessToken: token.accessToken,
|
||||
displayName: this.getDisplayNameFromToken(token.accessToken)
|
||||
displayName: token.displayName,
|
||||
scopes: token.scope.split(' ')
|
||||
};
|
||||
}
|
||||
|
||||
private getDisplayNameFromToken(accessToken: string): string {
|
||||
let displayName = 'user@example.com';
|
||||
private getTokenClaims(accessToken: string): ITokenClaims {
|
||||
try {
|
||||
// TODO fixme
|
||||
displayName = JSON.parse(atob(accessToken.split('.')[1]));
|
||||
return JSON.parse(Buffer.from(accessToken.split('.')[1], 'base64').toString());
|
||||
} catch (e) {
|
||||
// Fall back to example display name
|
||||
Logger.error(e.message);
|
||||
throw new Error('Unable to read token claims');
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
get sessions(): vscode.Session[] {
|
||||
return this._token ? [this.tokenToAccount(this._token)] : [];
|
||||
return this._tokens.map(token => this.convertToSession(token));
|
||||
}
|
||||
|
||||
public async login(): Promise<void> {
|
||||
public async login(scope: string): Promise<void> {
|
||||
Logger.info('Logging in...');
|
||||
const nonce = crypto.randomBytes(16).toString('base64');
|
||||
const { server, redirectPromise, codePromise } = createServer(nonce);
|
||||
|
||||
@@ -118,11 +196,13 @@ export class AzureActiveDirectoryService {
|
||||
if ('err' in codeRes) {
|
||||
throw codeRes.err;
|
||||
}
|
||||
token = await this.exchangeCodeForToken(codeRes.code, codeVerifier);
|
||||
this.setToken(token);
|
||||
token = await this.exchangeCodeForToken(codeRes.code, codeVerifier, scope);
|
||||
this.setToken(token, scope);
|
||||
Logger.info('Login successful');
|
||||
res.writeHead(302, { Location: '/' });
|
||||
res.end();
|
||||
} catch (err) {
|
||||
Logger.error(err.message);
|
||||
res.writeHead(302, { Location: `/?error=${encodeURIComponent(err && err.message || 'Unknown error')}` });
|
||||
res.end();
|
||||
}
|
||||
@@ -133,28 +213,48 @@ export class AzureActiveDirectoryService {
|
||||
}
|
||||
}
|
||||
|
||||
private async setToken(token: IToken): Promise<void> {
|
||||
this._token = token;
|
||||
|
||||
if (this._refreshTimeout) {
|
||||
clearTimeout(this._refreshTimeout);
|
||||
private async setToken(token: IToken, scope: string): Promise<void> {
|
||||
const existingToken = this._tokens.findIndex(t => t.sessionId === token.sessionId);
|
||||
if (existingToken) {
|
||||
this._tokens.splice(existingToken, 1, token);
|
||||
} else {
|
||||
this._tokens.push(token);
|
||||
}
|
||||
|
||||
this._refreshTimeout = setTimeout(async () => {
|
||||
const existingTimeout = this._refreshTimeouts.get(token.sessionId);
|
||||
if (existingTimeout) {
|
||||
clearTimeout(existingTimeout);
|
||||
}
|
||||
|
||||
this._refreshTimeouts.set(token.sessionId, setTimeout(async () => {
|
||||
try {
|
||||
await this.refreshToken(token.refreshToken);
|
||||
await this.refreshToken(token.refreshToken, scope);
|
||||
} catch (e) {
|
||||
await this.logout();
|
||||
await this.logout(token.sessionId);
|
||||
} finally {
|
||||
onDidChangeSessions.fire();
|
||||
}
|
||||
}, 1000 * (parseInt(token.expiresIn) - 10));
|
||||
}, 1000 * (parseInt(token.expiresIn) - 10)));
|
||||
|
||||
await keychain.setToken(token.refreshToken);
|
||||
this.storeTokenData();
|
||||
}
|
||||
|
||||
private async exchangeCodeForToken(code: string, codeVerifier: string): Promise<IToken> {
|
||||
private getTokenFromResponse(buffer: Buffer[], scope: string): IToken {
|
||||
const json = JSON.parse(Buffer.concat(buffer).toString());
|
||||
const claims = this.getTokenClaims(json.access_token);
|
||||
return {
|
||||
expiresIn: json.expires_in,
|
||||
accessToken: json.access_token,
|
||||
refreshToken: json.refresh_token,
|
||||
scope,
|
||||
sessionId: claims.tid + (claims.oid || claims.altsecid) + scope,
|
||||
displayName: claims.email || claims.unique_name || 'user@example.com'
|
||||
};
|
||||
}
|
||||
|
||||
private async exchangeCodeForToken(code: string, codeVerifier: string, scope: string): Promise<IToken> {
|
||||
return new Promise((resolve: (value: IToken) => void, reject) => {
|
||||
Logger.info('Exchanging login code for token');
|
||||
try {
|
||||
const postData = querystring.stringify({
|
||||
grant_type: 'authorization_code',
|
||||
@@ -182,12 +282,7 @@ export class AzureActiveDirectoryService {
|
||||
});
|
||||
result.on('end', () => {
|
||||
if (result.statusCode === 200) {
|
||||
const json = JSON.parse(Buffer.concat(buffer).toString());
|
||||
resolve({
|
||||
expiresIn: json.expires_in,
|
||||
accessToken: json.access_token,
|
||||
refreshToken: json.refresh_token
|
||||
});
|
||||
resolve(this.getTokenFromResponse(buffer, scope));
|
||||
} else {
|
||||
reject(new Error('Unable to login.'));
|
||||
}
|
||||
@@ -202,13 +297,15 @@ export class AzureActiveDirectoryService {
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
Logger.error(e.message);
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async refreshToken(refreshToken: string): Promise<IToken> {
|
||||
private async refreshToken(refreshToken: string, scope: string): Promise<IToken> {
|
||||
return new Promise((resolve: (value: IToken) => void, reject) => {
|
||||
Logger.info('Refreshing token...');
|
||||
const postData = querystring.stringify({
|
||||
refresh_token: refreshToken,
|
||||
client_id: clientId,
|
||||
@@ -231,16 +328,12 @@ export class AzureActiveDirectoryService {
|
||||
});
|
||||
result.on('end', async () => {
|
||||
if (result.statusCode === 200) {
|
||||
const json = JSON.parse(Buffer.concat(buffer).toString());
|
||||
const token = {
|
||||
expiresIn: json.expires_in,
|
||||
accessToken: json.access_token,
|
||||
refreshToken: json.refresh_token
|
||||
};
|
||||
this.setToken(token);
|
||||
const token = this.getTokenFromResponse(buffer, scope);
|
||||
this.setToken(token, scope);
|
||||
Logger.info('Token refresh success');
|
||||
resolve(token);
|
||||
} else {
|
||||
await this.logout();
|
||||
Logger.error('Refreshing token failed');
|
||||
reject(new Error('Refreshing token failed.'));
|
||||
}
|
||||
});
|
||||
@@ -250,16 +343,41 @@ export class AzureActiveDirectoryService {
|
||||
|
||||
post.end();
|
||||
post.on('error', err => {
|
||||
Logger.error(err.message);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async logout() {
|
||||
delete this._token;
|
||||
await keychain.deleteToken();
|
||||
if (this._refreshTimeout) {
|
||||
clearTimeout(this._refreshTimeout);
|
||||
public async logout(sessionId: string) {
|
||||
Logger.info(`Logging out of session '${sessionId}'`);
|
||||
const tokenIndex = this._tokens.findIndex(token => token.sessionId === sessionId);
|
||||
if (tokenIndex > -1) {
|
||||
this._tokens.splice(tokenIndex, 1);
|
||||
}
|
||||
|
||||
if (this._tokens.length === 0) {
|
||||
await keychain.deleteToken();
|
||||
} else {
|
||||
this.storeTokenData();
|
||||
}
|
||||
|
||||
const timeout = this._refreshTimeouts.get(sessionId);
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
this._refreshTimeouts.delete(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
public async clearSessions() {
|
||||
Logger.info('Logging out of all sessions');
|
||||
this._tokens = [];
|
||||
await keychain.deleteToken();
|
||||
|
||||
this._refreshTimeouts.forEach(timeout => {
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
|
||||
this._refreshTimeouts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
vscode.authentication.registerAuthenticationProvider({
|
||||
id: 'MSA',
|
||||
displayName: 'Microsoft Account', // TODO localize
|
||||
displayName: 'Microsoft',
|
||||
onDidChangeSessions: onDidChangeSessions.event,
|
||||
getSessions: () => Promise.resolve(loginService.sessions),
|
||||
login: async () => {
|
||||
login: async (scopes: string[]) => {
|
||||
try {
|
||||
await loginService.login();
|
||||
await loginService.login(scopes.sort().join(' '));
|
||||
return loginService.sessions[0]!;
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(`Logging in failed: ${e}`);
|
||||
@@ -27,7 +27,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
},
|
||||
logout: async (id: string) => {
|
||||
return loginService.logout();
|
||||
return loginService.logout(id);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
55
extensions/vscode-account/src/logger.ts
Normal file
55
extensions/vscode-account/src/logger.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
type LogLevel = 'Trace' | 'Info' | 'Error';
|
||||
|
||||
class Log {
|
||||
private output: vscode.OutputChannel;
|
||||
|
||||
constructor() {
|
||||
this.output = vscode.window.createOutputChannel('Account');
|
||||
}
|
||||
|
||||
private data2String(data: any): string {
|
||||
if (data instanceof Error) {
|
||||
return data.stack || data.message;
|
||||
}
|
||||
if (data.success === false && data.message) {
|
||||
return data.message;
|
||||
}
|
||||
return data.toString();
|
||||
}
|
||||
|
||||
public info(message: string, data?: any): void {
|
||||
this.logLevel('Info', message, data);
|
||||
}
|
||||
|
||||
public error(message: string, data?: any): void {
|
||||
this.logLevel('Error', message, data);
|
||||
}
|
||||
|
||||
public logLevel(level: LogLevel, message: string, data?: any): void {
|
||||
this.output.appendLine(`[${level} - ${this.now()}] ${message}`);
|
||||
if (data) {
|
||||
this.output.appendLine(this.data2String(data));
|
||||
}
|
||||
}
|
||||
|
||||
private now(): string {
|
||||
const now = new Date();
|
||||
return padLeft(now.getUTCHours() + '', 2, '0')
|
||||
+ ':' + padLeft(now.getMinutes() + '', 2, '0')
|
||||
+ ':' + padLeft(now.getUTCSeconds() + '', 2, '0') + '.' + now.getMilliseconds();
|
||||
}
|
||||
}
|
||||
|
||||
function padLeft(s: string, n: number, pad = ' ') {
|
||||
return pad.repeat(Math.max(0, n - s.length)) + s;
|
||||
}
|
||||
|
||||
const Logger = new Log();
|
||||
export default Logger;
|
||||
@@ -20,6 +20,7 @@ declare module 'vscode' {
|
||||
id: string;
|
||||
accessToken: string;
|
||||
displayName: string;
|
||||
scopes: string[]
|
||||
}
|
||||
|
||||
export interface AuthenticationProvider {
|
||||
@@ -35,7 +36,7 @@ declare module 'vscode' {
|
||||
/**
|
||||
* Prompts a user to login.
|
||||
*/
|
||||
login(): Promise<Session>;
|
||||
login(scopes: string[]): Promise<Session>;
|
||||
logout(sessionId: string): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -48,13 +49,7 @@ declare module 'vscode' {
|
||||
export const onDidRegisterAuthenticationProvider: Event<string>;
|
||||
export const onDidUnregisterAuthenticationProvider: Event<string>;
|
||||
|
||||
/**
|
||||
* Fires with the provider id that changed sessions.
|
||||
*/
|
||||
export const onDidChangeSessions: Event<string>;
|
||||
export function login(providerId: string): Promise<Session>;
|
||||
export function logout(providerId: string, accountId: string): Promise<void>;
|
||||
export function getSessions(providerId: string): Promise<ReadonlyArray<Session> | undefined>;
|
||||
export const providers: ReadonlyArray<AuthenticationProvider>;
|
||||
}
|
||||
|
||||
// #region Ben - extension auth flow (desktop+web)
|
||||
|
||||
@@ -257,10 +257,10 @@
|
||||
"t": "source.yaml constant.numeric.integer.yaml",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -246,9 +246,9 @@
|
||||
"t": "source.yaml constant.numeric.float.yaml",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -774,9 +774,9 @@
|
||||
"t": "source.yaml meta.flow-mapping.yaml meta.flow-pair.yaml meta.flow-pair.value.yaml constant.numeric.integer.yaml",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -906,9 +906,9 @@
|
||||
"t": "source.yaml constant.numeric.integer.yaml",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"light_plus": "constant.numeric: #098658",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"light_vs": "constant.numeric: #098658",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
@@ -1132,4 +1132,4 @@
|
||||
"hc_black": "string: #CE9178"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
"coveralls": "^2.11.11",
|
||||
"cson-parser": "^1.3.3",
|
||||
"debounce": "^1.0.0",
|
||||
"electron": "7.1.7",
|
||||
"electron": "6.1.6",
|
||||
"eslint": "6.8.0",
|
||||
"eslint-plugin-jsdoc": "^19.1.0",
|
||||
"event-stream": "3.3.4",
|
||||
|
||||
@@ -95,7 +95,7 @@ class MainThreadNotebookEditor extends Disposable {
|
||||
}
|
||||
|
||||
public save(): Thenable<boolean> {
|
||||
return this.textFileService.save(this.uri);
|
||||
return this.textFileService.save(this.uri).then(uri => !!uri);
|
||||
}
|
||||
|
||||
public matches(input: NotebookInput): boolean {
|
||||
@@ -351,7 +351,7 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
|
||||
let uriString = URI.revive(uri).toString();
|
||||
let editor = this._notebookEditors.get(uriString);
|
||||
if (editor) {
|
||||
return editor.save();
|
||||
return editor.save().then(uri => !!uri);
|
||||
} else {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la
|
||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
||||
|
||||
export class CategoryView extends ViewPane {
|
||||
|
||||
@@ -45,9 +46,10 @@ export class CategoryView extends ViewPane {
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
|
||||
) {
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, instantiationService);
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
|
||||
}
|
||||
|
||||
// we want a fixed size, so when we render to will measure our content and set that to be our
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as azdata from 'azdata';
|
||||
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { EditorInput, EditorModel } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorModel, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
@@ -139,8 +139,8 @@ export class ModelViewInput extends EditorInput {
|
||||
/**
|
||||
* Saves the editor if it is dirty. Subclasses return a promise with a boolean indicating the success of the operation.
|
||||
*/
|
||||
save(): Promise<boolean> {
|
||||
return this._model.save();
|
||||
save(): Promise<IEditorInput | undefined> {
|
||||
return this._model.save().then(saved => saved ? this : undefined);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
|
||||
@@ -196,7 +196,7 @@ export class QueryTextEditor extends BaseTextEditor {
|
||||
this.refreshEditorConfiguration();
|
||||
}
|
||||
|
||||
private refreshEditorConfiguration(configuration = this.configurationService.getValue<IEditorConfiguration>(this.getResource())): void {
|
||||
private refreshEditorConfiguration(configuration = this.textResourceConfigurationService.getValue<IEditorConfiguration>(this.input.getResource())): void {
|
||||
if (!this.getControl()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { ContextAwareMenuEntryActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ViewContainer, ITreeItemLabel, Extensions } from 'vs/workbench/common/views';
|
||||
import { TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ViewContainer, ITreeItemLabel, Extensions, IViewDescriptorService } from 'vs/workbench/common/views';
|
||||
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -27,7 +27,7 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { dirname, basename } from 'vs/base/common/resources';
|
||||
import { LIGHT, FileThemeIcon, FolderThemeIcon, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { WorkbenchAsyncDataTree, TreeResourceNavigator2 } from 'vs/platform/list/browser/listService';
|
||||
import { WorkbenchAsyncDataTree, TreeResourceNavigator } from 'vs/platform/list/browser/listService';
|
||||
import { localize } from 'vs/nls';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { editorFindMatchHighlight, editorFindMatchHighlightBorder, textLinkForeground, textCodeBlockBackground, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
@@ -62,9 +62,10 @@ export class CustomTreeViewPanel extends ViewPane {
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
|
||||
) {
|
||||
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService, instantiationService);
|
||||
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
|
||||
const { treeView } = (<ITreeViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(options.id));
|
||||
this.treeView = treeView as ITreeView;
|
||||
this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this));
|
||||
@@ -443,7 +444,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
}));
|
||||
this.tree.setInput(this.root).then(() => this.updateContentAreas());
|
||||
|
||||
const customTreeNavigator = new TreeResourceNavigator2(this.tree);
|
||||
const customTreeNavigator = new TreeResourceNavigator(this.tree);
|
||||
this._register(customTreeNavigator);
|
||||
this._register(customTreeNavigator.onDidOpenResource(e => {
|
||||
if (!e.browserEvent) {
|
||||
|
||||
@@ -36,6 +36,7 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la
|
||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
||||
|
||||
class AccountPanel extends ViewPane {
|
||||
public index: number;
|
||||
@@ -48,9 +49,10 @@ class AccountPanel extends ViewPane {
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
|
||||
) {
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, instantiationService);
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
|
||||
}
|
||||
|
||||
protected renderBody(container: HTMLElement): void {
|
||||
@@ -126,6 +128,7 @@ export class AccountDialog extends Modal {
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IClipboardService clipboardService: IClipboardService,
|
||||
@ILogService logService: ILogService,
|
||||
@IViewDescriptorService private viewDescriptorService: IViewDescriptorService,
|
||||
@ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService
|
||||
) {
|
||||
super(
|
||||
@@ -296,7 +299,8 @@ export class AccountDialog extends Modal {
|
||||
this._configurationService,
|
||||
this._themeService,
|
||||
this.contextKeyService,
|
||||
this._instantiationService
|
||||
this._instantiationService,
|
||||
this.viewDescriptorService
|
||||
);
|
||||
|
||||
attachPanelStyler(providerView, this._themeService);
|
||||
|
||||
@@ -86,7 +86,7 @@ function createInstantiationService(addAccountFailureEmitter?: Emitter<string>):
|
||||
.returns(() => undefined);
|
||||
|
||||
// Create a mock account dialog
|
||||
let accountDialog = new AccountDialog(undefined!, undefined!, instantiationService.object, undefined!, undefined!, undefined!, undefined!, new MockContextKeyService(), undefined!, undefined!, undefined!);
|
||||
let accountDialog = new AccountDialog(undefined!, undefined!, instantiationService.object, undefined!, undefined!, undefined!, undefined!, new MockContextKeyService(), undefined!, undefined!, undefined!, undefined!);
|
||||
let mockAccountDialog = TypeMoq.Mock.ofInstance(accountDialog);
|
||||
mockAccountDialog.setup(x => x.onAddAccountErrorEvent)
|
||||
.returns(() => { return addAccountFailureEmitter ? addAccountFailureEmitter.event : mockEvent.event; });
|
||||
|
||||
@@ -393,7 +393,7 @@ suite('commandLineService tests', () => {
|
||||
querymodelService.setup(c => c.onRunQueryComplete).returns(() => Event.None);
|
||||
const instantiationService = new TestInstantiationService();
|
||||
let uri = URI.file(args._[0]);
|
||||
const untitledEditorInput = new UntitledTextEditorInput(uri, false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined, undefined);
|
||||
const untitledEditorInput = new UntitledTextEditorInput(uri, false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined);
|
||||
const queryInput = new UntitledQueryEditorInput(undefined, untitledEditorInput, undefined, connectionManagementService.object, querymodelService.object, configurationService.object, undefined);
|
||||
queryInput.state.connected = true;
|
||||
const editorService: TypeMoq.Mock<IEditorService> = TypeMoq.Mock.ofType<IEditorService>(TestEditorService, TypeMoq.MockBehavior.Strict);
|
||||
|
||||
@@ -20,6 +20,7 @@ import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/br
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
||||
|
||||
export class ConnectionViewletPanel extends ViewPane {
|
||||
|
||||
@@ -38,9 +39,10 @@ export class ConnectionViewletPanel extends ViewPane {
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IObjectExplorerService private readonly objectExplorerService: IObjectExplorerService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
|
||||
) {
|
||||
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService, instantiationService);
|
||||
super({ ...(options as IViewPaneOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
|
||||
this._addServerAction = this.instantiationService.createInstance(AddServerAction,
|
||||
AddServerAction.ID,
|
||||
AddServerAction.LABEL);
|
||||
|
||||
@@ -17,7 +17,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IAddedViewDescriptorRef } from 'vs/workbench/browser/parts/views/views';
|
||||
import { ConnectionViewletPanel } from 'sql/workbench/contrib/dataExplorer/browser/connectionViewletPanel';
|
||||
import { Extensions as ViewContainerExtensions, IViewDescriptor, IViewsRegistry, IViewContainersRegistry, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { Extensions as ViewContainerExtensions, IViewDescriptor, IViewsRegistry, IViewContainersRegistry, ViewContainerLocation, IViewDescriptorService } from 'vs/workbench/common/views';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
@@ -103,9 +103,10 @@ export class DataExplorerViewPaneContainer extends ViewPaneContainer {
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IMenuService private menuService: IMenuService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
|
||||
) {
|
||||
super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService);
|
||||
super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService);
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): void {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EditorInput, EditorModel, EncodingMode } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorModel, EncodingMode, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IConnectionManagementService, IConnectableInput, INewConnectionParams } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
@@ -107,7 +107,7 @@ export class EditDataInput extends EditorInput implements IConnectableInput {
|
||||
public get objectType(): string { return this._objectType; }
|
||||
public showResultsEditor(): void { this._showResultsEditor.fire(undefined); }
|
||||
public isDirty(): boolean { return false; }
|
||||
public save(): Promise<boolean> { return Promise.resolve(false); }
|
||||
public save(): Promise<IEditorInput | undefined> { return Promise.resolve(undefined); }
|
||||
public getTypeId(): string { return EditDataInput.ID; }
|
||||
public setBootstrappedTrue(): void { this._hasBootstrapped = true; }
|
||||
public getResource(): URI { return this._uri; }
|
||||
@@ -220,7 +220,6 @@ export class EditDataInput extends EditorInput implements IConnectableInput {
|
||||
public get onDidModelChangeEncoding(): Event<void> { return this._sql.onDidModelChangeEncoding; }
|
||||
public resolve(refresh?: boolean): Promise<EditorModel> { return this._sql.resolve(); }
|
||||
public getEncoding(): string { return this._sql.getEncoding(); }
|
||||
public suggestFileName(): string { return this._sql.suggestFileName(); }
|
||||
public getName(): string { return this._sql.getName(); }
|
||||
public get hasAssociatedFilePath(): boolean { return this._sql.hasAssociatedFilePath; }
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EditorInput, EditorModel } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorModel, IRevertOptions, GroupIdentifier, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
@@ -230,8 +230,8 @@ export abstract class NotebookInput extends EditorInput {
|
||||
return this._textInput;
|
||||
}
|
||||
|
||||
public revert(): Promise<boolean> {
|
||||
return this._textInput.revert();
|
||||
public revert(group: GroupIdentifier, options?: IRevertOptions): Promise<boolean> {
|
||||
return this._textInput.revert(group, options);
|
||||
}
|
||||
|
||||
public get notebookUri(): URI {
|
||||
@@ -283,11 +283,11 @@ export abstract class NotebookInput extends EditorInput {
|
||||
return this._standardKernels;
|
||||
}
|
||||
|
||||
save(groupId: number, options?: ITextFileSaveOptions): Promise<boolean> {
|
||||
save(groupId: number, options?: ITextFileSaveOptions): Promise<IEditorInput | undefined> {
|
||||
return this.textInput.save(groupId, options);
|
||||
}
|
||||
|
||||
saveAs(group: number, options?: ITextFileSaveOptions): Promise<boolean> {
|
||||
saveAs(group: number, options?: ITextFileSaveOptions): Promise<IEditorInput | undefined> {
|
||||
return this.textInput.saveAs(group, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ suite('Notebook Input', function (): void {
|
||||
let untitledNotebookInput: UntitledNotebookInput;
|
||||
|
||||
setup(() => {
|
||||
untitledTextInput = new UntitledTextEditorInput(untitledUri, false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined, undefined);
|
||||
untitledTextInput = new UntitledTextEditorInput(untitledUri, false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined);
|
||||
untitledNotebookInput = new UntitledNotebookInput(
|
||||
testTitle, untitledUri, untitledTextInput,
|
||||
undefined, instantiationService, mockNotebookService.object, mockExtensionService.object);
|
||||
@@ -169,7 +169,7 @@ suite('Notebook Input', function (): void {
|
||||
assert.ok(untitledNotebookInput.matches(untitledNotebookInput), 'Input should match itself.');
|
||||
|
||||
let otherTestUri = URI.from({ scheme: Schemas.untitled, path: 'OtherTestPath' });
|
||||
let otherTextInput = new UntitledTextEditorInput(otherTestUri, false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined, undefined);
|
||||
let otherTextInput = new UntitledTextEditorInput(otherTestUri, false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined);
|
||||
let otherInput = instantiationService.createInstance(UntitledNotebookInput, 'OtherTestInput', otherTestUri, otherTextInput);
|
||||
|
||||
assert.strictEqual(untitledNotebookInput.matches(otherInput), false, 'Input should not match different input.');
|
||||
|
||||
@@ -109,6 +109,9 @@ suite('SQL Connection Tree Action tests', () => {
|
||||
});
|
||||
|
||||
const viewsService = new class implements IViewsService {
|
||||
getActiveViewWithId(id: string): IView {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
_serviceBrand: undefined;
|
||||
openView(id: string, focus?: boolean): Promise<IView> {
|
||||
return Promise.resolve({
|
||||
|
||||
@@ -7,7 +7,7 @@ import { localize } from 'vs/nls';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { EditorInput } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, GroupIdentifier, IRevertOptions, ISaveOptions, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
|
||||
@@ -17,7 +17,6 @@ import { IQueryModelService } from 'sql/platform/query/common/queryModel';
|
||||
|
||||
import { ISelectionData, ExecutionPlanOptions } from 'azdata';
|
||||
import { startsWith } from 'vs/base/common/strings';
|
||||
import { ITextFileSaveOptions } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
|
||||
const MAX_SIZE = 13;
|
||||
|
||||
@@ -175,7 +174,9 @@ export abstract class QueryEditorInput extends EditorInput implements IConnectab
|
||||
// Description is shown beside the tab name in the combobox of open editors
|
||||
public getDescription(): string { return this._description; }
|
||||
public supportsSplitEditor(): boolean { return false; }
|
||||
public revert(): Promise<boolean> { return this._text.revert(); }
|
||||
public revert(group: GroupIdentifier, options?: IRevertOptions): Promise<boolean> {
|
||||
return this._text.revert(group, options);
|
||||
}
|
||||
|
||||
public isReadonly(): boolean {
|
||||
return false;
|
||||
@@ -224,11 +225,11 @@ export abstract class QueryEditorInput extends EditorInput implements IConnectab
|
||||
}
|
||||
}
|
||||
|
||||
save(groupId: number, options?: ITextFileSaveOptions): Promise<boolean> {
|
||||
return this.text.save(groupId, options);
|
||||
save(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
|
||||
return this.text.save(group, options);
|
||||
}
|
||||
|
||||
saveAs(group: number, options?: ITextFileSaveOptions): Promise<boolean> {
|
||||
saveAs(group: GroupIdentifier, options?: ISaveOptions): Promise<IEditorInput | undefined> {
|
||||
return this.text.saveAs(group, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,10 +47,6 @@ export class UntitledQueryEditorInput extends QueryEditorInput implements IEncod
|
||||
return this.text.hasAssociatedFilePath;
|
||||
}
|
||||
|
||||
public suggestFileName(): string {
|
||||
return this.text.suggestFileName();
|
||||
}
|
||||
|
||||
public setMode(mode: string): void {
|
||||
this.text.setMode(mode);
|
||||
}
|
||||
@@ -75,12 +71,4 @@ export class UntitledQueryEditorInput extends QueryEditorInput implements IEncod
|
||||
// Subclasses need to explicitly opt-in to being untitled.
|
||||
return true;
|
||||
}
|
||||
|
||||
hasBackup(): boolean {
|
||||
if (this.text) {
|
||||
return this.text.hasBackup();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
connectionManagementService = TypeMoq.Mock.ofType<TestConnectionManagementService>(TestConnectionManagementService);
|
||||
connectionManagementService.setup(q => q.onDisconnect).returns(() => Event.None);
|
||||
const instantiationService = new TestInstantiationService();
|
||||
let fileInput = new UntitledTextEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined, undefined);
|
||||
let fileInput = new UntitledTextEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined);
|
||||
// Setup a reusable mock QueryInput
|
||||
testQueryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Strict, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||
testQueryInput.setup(x => x.uri).returns(() => testUri);
|
||||
@@ -175,7 +175,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
queryModelService.setup(x => x.onRunQueryStart).returns(() => Event.None);
|
||||
queryModelService.setup(x => x.onRunQueryComplete).returns(() => Event.None);
|
||||
const instantiationService = new TestInstantiationService();
|
||||
let fileInput = new UntitledTextEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined, undefined);
|
||||
let fileInput = new UntitledTextEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined);
|
||||
|
||||
// ... Mock "isSelectionEmpty" in QueryEditor
|
||||
let queryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Strict, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||
@@ -224,7 +224,7 @@ suite('SQL QueryAction Tests', () => {
|
||||
|
||||
// ... Mock "getSelection" in QueryEditor
|
||||
const instantiationService = new TestInstantiationService();
|
||||
let fileInput = new UntitledTextEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined, undefined);
|
||||
let fileInput = new UntitledTextEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService, undefined, new LabelService(undefined, undefined), undefined, undefined);
|
||||
|
||||
let queryInput = TypeMoq.Mock.ofType(UntitledQueryEditorInput, TypeMoq.MockBehavior.Loose, undefined, fileInput, undefined, connectionManagementService.object, queryModelService.object, configurationService.object);
|
||||
queryInput.setup(x => x.uri).returns(() => testUri);
|
||||
|
||||
@@ -285,7 +285,7 @@ suite('SQL QueryEditor Tests', () => {
|
||||
return new RunQueryAction(undefined, undefined, undefined);
|
||||
});
|
||||
|
||||
let fileInput = new UntitledTextEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService.object, undefined, new LabelService(undefined, undefined), undefined, undefined, undefined);
|
||||
let fileInput = new UntitledTextEditorInput(URI.parse('file://testUri'), false, '', '', '', instantiationService.object, undefined, new LabelService(undefined, undefined), undefined, undefined);
|
||||
queryModelService = TypeMoq.Mock.ofType(TestQueryModelService, TypeMoq.MockBehavior.Strict);
|
||||
queryModelService.setup(x => x.disposeQuery(TypeMoq.It.isAny()));
|
||||
queryModelService.setup(x => x.onRunQueryComplete).returns(() => Event.None);
|
||||
|
||||
@@ -43,6 +43,7 @@ import { ITextResourcePropertiesService } from 'vs/editor/common/services/textRe
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
||||
|
||||
const labelDisplay = nls.localize("insights.item", "Item");
|
||||
const valueDisplay = nls.localize("insights.value", "Value");
|
||||
@@ -63,9 +64,10 @@ class InsightTableView<T> extends ViewPane {
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
|
||||
) {
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, instantiationService);
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService);
|
||||
}
|
||||
|
||||
protected renderBody(container: HTMLElement): void {
|
||||
|
||||
@@ -25,6 +25,7 @@ import { getRandomTestPath } from 'vs/base/test/node/testUtils';
|
||||
import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api';
|
||||
|
||||
class TestEnvironmentService implements IWorkbenchEnvironmentService {
|
||||
userDataSyncHome: URI;
|
||||
keybindingsSyncPreviewResource: URI;
|
||||
argvResource: URI;
|
||||
userDataSyncLogResource: URI;
|
||||
|
||||
@@ -287,7 +287,7 @@ export function addDisposableGenericMouseUpListner(node: EventTarget, handler: (
|
||||
export function addDisposableNonBubblingMouseOutListener(node: Element, handler: (event: MouseEvent) => void): IDisposable {
|
||||
return addDisposableListener(node, 'mouseout', (e: MouseEvent) => {
|
||||
// Mouse out bubbles, so this is an attempt to ignore faux mouse outs coming from children elements
|
||||
let toElement: Node | null = <Node>(e.relatedTarget || e.target);
|
||||
let toElement: Node | null = <Node>(e.relatedTarget);
|
||||
while (toElement && toElement !== node) {
|
||||
toElement = toElement.parentNode;
|
||||
}
|
||||
@@ -302,7 +302,7 @@ export function addDisposableNonBubblingMouseOutListener(node: Element, handler:
|
||||
export function addDisposableNonBubblingPointerOutListener(node: Element, handler: (event: MouseEvent) => void): IDisposable {
|
||||
return addDisposableListener(node, 'pointerout', (e: MouseEvent) => {
|
||||
// Mouse out bubbles, so this is an attempt to ignore faux mouse outs coming from children elements
|
||||
let toElement: Node | null = <Node>(e.relatedTarget || e.target);
|
||||
let toElement: Node | null = <Node>(e.relatedTarget);
|
||||
while (toElement && toElement !== node) {
|
||||
toElement = toElement.parentNode;
|
||||
}
|
||||
@@ -628,11 +628,17 @@ export function getTopLeftOffset(element: HTMLElement): { left: number; top: num
|
||||
// Adapted from WinJS.Utilities.getPosition
|
||||
// and added borders to the mix
|
||||
|
||||
let offsetParent = element.offsetParent, top = element.offsetTop, left = element.offsetLeft;
|
||||
let offsetParent = element.offsetParent;
|
||||
let top = element.offsetTop;
|
||||
let left = element.offsetLeft;
|
||||
|
||||
while ((element = <HTMLElement>element.parentNode) !== null && element !== document.body && element !== document.documentElement) {
|
||||
while (
|
||||
(element = <HTMLElement>element.parentNode) !== null
|
||||
&& element !== document.body
|
||||
&& element !== document.documentElement
|
||||
) {
|
||||
top -= element.scrollTop;
|
||||
let c = getComputedStyle(element);
|
||||
const c = isShadowRoot(element) ? null : getComputedStyle(element);
|
||||
if (c) {
|
||||
left -= c.direction !== 'rtl' ? element.scrollLeft : -element.scrollLeft;
|
||||
}
|
||||
@@ -793,7 +799,7 @@ export function isAncestor(testChild: Node | null, testAncestor: Node | null): b
|
||||
}
|
||||
|
||||
export function findParentWithClass(node: HTMLElement, clazz: string, stopAtClazzOrNode?: string | HTMLElement): HTMLElement | null {
|
||||
while (node) {
|
||||
while (node && node.nodeType === node.ELEMENT_NODE) {
|
||||
if (hasClass(node, clazz)) {
|
||||
return node;
|
||||
}
|
||||
@@ -820,6 +826,27 @@ export function hasParentWithClass(node: HTMLElement, clazz: string, stopAtClazz
|
||||
return !!findParentWithClass(node, clazz, stopAtClazzOrNode);
|
||||
}
|
||||
|
||||
export function isShadowRoot(node: Node): node is ShadowRoot {
|
||||
return (
|
||||
node && !!(<ShadowRoot>node).host && !!(<ShadowRoot>node).mode
|
||||
);
|
||||
}
|
||||
|
||||
export function isInShadowDOM(domNode: Node): boolean {
|
||||
return !!getShadowRoot(domNode);
|
||||
}
|
||||
|
||||
export function getShadowRoot(domNode: Node): ShadowRoot | null {
|
||||
while (domNode.parentNode) {
|
||||
if (domNode === document.body) {
|
||||
// reached the body
|
||||
return null;
|
||||
}
|
||||
domNode = domNode.parentNode;
|
||||
}
|
||||
return isShadowRoot(domNode) ? domNode : null;
|
||||
}
|
||||
|
||||
export function createStyleSheet(container: HTMLElement = document.getElementsByTagName('head')[0]): HTMLStyleElement {
|
||||
let style = document.createElement('style');
|
||||
style.type = 'text/css';
|
||||
@@ -1167,7 +1194,7 @@ export function hide(...elements: HTMLElement[]): void {
|
||||
}
|
||||
|
||||
function findParentWithAttribute(node: Node | null, attribute: string): HTMLElement | null {
|
||||
while (node) {
|
||||
while (node && node.nodeType === node.ELEMENT_NODE) {
|
||||
if (node instanceof HTMLElement && node.hasAttribute(attribute)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ export class FastDomNode<T extends HTMLElement> {
|
||||
private _display: string;
|
||||
private _position: string;
|
||||
private _visibility: string;
|
||||
private _backgroundColor: string;
|
||||
private _layerHint: boolean;
|
||||
private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint';
|
||||
|
||||
@@ -47,6 +48,7 @@ export class FastDomNode<T extends HTMLElement> {
|
||||
this._display = '';
|
||||
this._position = '';
|
||||
this._visibility = '';
|
||||
this._backgroundColor = '';
|
||||
this._layerHint = false;
|
||||
this._contain = 'none';
|
||||
}
|
||||
@@ -200,6 +202,14 @@ export class FastDomNode<T extends HTMLElement> {
|
||||
this.domNode.style.visibility = this._visibility;
|
||||
}
|
||||
|
||||
public setBackgroundColor(backgroundColor: string): void {
|
||||
if (this._backgroundColor === backgroundColor) {
|
||||
return;
|
||||
}
|
||||
this._backgroundColor = backgroundColor;
|
||||
this.domNode.style.backgroundColor = this._backgroundColor;
|
||||
}
|
||||
|
||||
public setLayerHinting(layerHint: boolean): void {
|
||||
if (this._layerHint === layerHint) {
|
||||
return;
|
||||
|
||||
@@ -75,6 +75,7 @@ export class GlobalMouseMoveMonitor<R extends { buttons: number; }> implements I
|
||||
}
|
||||
|
||||
public startMonitoring(
|
||||
initialElement: HTMLElement,
|
||||
initialButtons: number,
|
||||
mouseMoveEventMerger: IEventMerger<R>,
|
||||
mouseMoveCallback: IMouseMoveCallback<R>,
|
||||
@@ -88,11 +89,18 @@ export class GlobalMouseMoveMonitor<R extends { buttons: number; }> implements I
|
||||
this._mouseMoveCallback = mouseMoveCallback;
|
||||
this._onStopCallback = onStopCallback;
|
||||
|
||||
let windowChain = IframeUtils.getSameOriginWindowChain();
|
||||
const windowChain = IframeUtils.getSameOriginWindowChain();
|
||||
const mouseMove = platform.isIOS && BrowserFeatures.pointerEvents ? 'pointermove' : 'mousemove';
|
||||
const mouseUp = platform.isIOS && BrowserFeatures.pointerEvents ? 'pointerup' : 'mouseup';
|
||||
for (const element of windowChain) {
|
||||
this._hooks.add(dom.addDisposableThrottledListener(element.window.document, mouseMove,
|
||||
|
||||
const listenTo: (Document | ShadowRoot)[] = windowChain.map(element => element.window.document);
|
||||
const shadowRoot = dom.getShadowRoot(initialElement);
|
||||
if (shadowRoot) {
|
||||
listenTo.unshift(shadowRoot);
|
||||
}
|
||||
|
||||
for (const element of listenTo) {
|
||||
this._hooks.add(dom.addDisposableThrottledListener(element, mouseMove,
|
||||
(data: R) => {
|
||||
if (data.buttons !== initialButtons) {
|
||||
// Buttons state has changed in the meantime
|
||||
@@ -103,7 +111,7 @@ export class GlobalMouseMoveMonitor<R extends { buttons: number; }> implements I
|
||||
},
|
||||
(lastEvent: R | null, currentEvent) => this._mouseMoveEventMerger!(lastEvent, currentEvent as MouseEvent)
|
||||
));
|
||||
this._hooks.add(dom.addDisposableListener(element.window.document, mouseUp, (e: MouseEvent) => this.stopMonitoring(true)));
|
||||
this._hooks.add(dom.addDisposableListener(element, mouseUp, (e: MouseEvent) => this.stopMonitoring(true)));
|
||||
}
|
||||
|
||||
if (IframeUtils.hasDifferentOriginAncestor()) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
@font-face {
|
||||
font-family: "codicon";
|
||||
src: url("./codicon.ttf?ed926e87ee4e27771159d875e877f74a") format("truetype");
|
||||
src: url("./codicon.ttf?be537a78617db0869caa4b4cc683a24a") format("truetype");
|
||||
}
|
||||
|
||||
.codicon[class*='codicon-'] {
|
||||
@@ -119,6 +119,7 @@
|
||||
.codicon-github:before { content: "\ea84" }
|
||||
.codicon-terminal:before { content: "\ea85" }
|
||||
.codicon-console:before { content: "\ea85" }
|
||||
.codicon-repl:before { content: "\ea85" }
|
||||
.codicon-zap:before { content: "\ea86" }
|
||||
.codicon-symbol-event:before { content: "\ea86" }
|
||||
.codicon-error:before { content: "\ea87" }
|
||||
@@ -410,4 +411,6 @@
|
||||
.codicon-menu:before { content: "\eb94" }
|
||||
.codicon-expand-all:before { content: "\eb95" }
|
||||
.codicon-feedback:before { content: "\eb96" }
|
||||
.codicon-group-by-ref-type:before { content: "\eb97" }
|
||||
.codicon-ungroup-by-ref-type:before { content: "\eb98" }
|
||||
.codicon-debug-alt:before { content: "\f101" }
|
||||
|
||||
Binary file not shown.
@@ -92,8 +92,10 @@ class FastLabelNode {
|
||||
export class IconLabel extends Disposable {
|
||||
|
||||
private domNode: FastLabelNode;
|
||||
private descriptionContainer: FastLabelNode;
|
||||
|
||||
private nameNode: Label | LabelWithHighlights;
|
||||
|
||||
private descriptionContainer: FastLabelNode;
|
||||
private descriptionNode: FastLabelNode | HighlightedLabel | undefined;
|
||||
private descriptionNodeFactory: () => FastLabelNode | HighlightedLabel;
|
||||
|
||||
|
||||
@@ -844,7 +844,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
}
|
||||
|
||||
// sanitize feedback list
|
||||
feedback = distinct(feedback).filter(i => i >= -1 && i < this.length).sort();
|
||||
feedback = distinct(feedback).filter(i => i >= -1 && i < this.length).sort((a, b) => a - b);
|
||||
feedback = feedback[0] === -1 ? [-1] : feedback;
|
||||
|
||||
if (equalsDragFeedback(this.currentDragFeedback, feedback)) {
|
||||
|
||||
@@ -61,6 +61,7 @@ export abstract class AbstractScrollbar extends Widget {
|
||||
this._scrollable = opts.scrollable;
|
||||
this._scrollbarState = opts.scrollbarState;
|
||||
this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'visible scrollbar ' + opts.extraScrollbarClassName, 'invisible scrollbar ' + opts.extraScrollbarClassName));
|
||||
this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());
|
||||
this._mouseMoveMonitor = this._register(new GlobalMouseMoveMonitor<IStandardMouseMoveEventData>());
|
||||
this._shouldRender = true;
|
||||
this.domNode = createFastDomNode(document.createElement('div'));
|
||||
@@ -216,13 +217,14 @@ export abstract class AbstractScrollbar extends Widget {
|
||||
}
|
||||
}
|
||||
|
||||
private _sliderMouseDown(e: ISimplifiedMouseEvent, onDragFinished: () => void): void {
|
||||
private _sliderMouseDown(e: IMouseEvent, onDragFinished: () => void): void {
|
||||
const initialMousePosition = this._sliderMousePosition(e);
|
||||
const initialMouseOrthogonalPosition = this._sliderOrthogonalMousePosition(e);
|
||||
const initialScrollbarState = this._scrollbarState.clone();
|
||||
this.slider.toggleClassName('active', true);
|
||||
|
||||
this._mouseMoveMonitor.startMonitoring(
|
||||
e.target,
|
||||
e.buttons,
|
||||
standardMouseMoveMerger,
|
||||
(mouseMoveData: IStandardMouseMoveEventData) => {
|
||||
|
||||
@@ -13,13 +13,18 @@ import { INewScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from
|
||||
export class HorizontalScrollbar extends AbstractScrollbar {
|
||||
|
||||
constructor(scrollable: Scrollable, options: ScrollableElementResolvedOptions, host: ScrollbarHost) {
|
||||
const scrollDimensions = scrollable.getScrollDimensions();
|
||||
const scrollPosition = scrollable.getCurrentScrollPosition();
|
||||
super({
|
||||
lazyRender: options.lazyRender,
|
||||
host: host,
|
||||
scrollbarState: new ScrollbarState(
|
||||
(options.horizontalHasArrows ? options.arrowSize : 0),
|
||||
(options.horizontal === ScrollbarVisibility.Hidden ? 0 : options.horizontalScrollbarSize),
|
||||
(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize)
|
||||
(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize),
|
||||
scrollDimensions.width,
|
||||
scrollDimensions.scrollWidth,
|
||||
scrollPosition.scrollLeft
|
||||
),
|
||||
visibility: options.horizontal,
|
||||
extraScrollbarClassName: 'horizontal',
|
||||
|
||||
@@ -93,6 +93,7 @@ export class ScrollbarArrow extends Widget {
|
||||
this._mousedownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);
|
||||
|
||||
this._mouseMoveMonitor.startMonitoring(
|
||||
e.target,
|
||||
e.buttons,
|
||||
standardMouseMoveMerger,
|
||||
(mouseMoveData: IStandardMouseMoveEventData) => {
|
||||
|
||||
@@ -62,14 +62,14 @@ export class ScrollbarState {
|
||||
private _computedSliderRatio: number;
|
||||
private _computedSliderPosition: number;
|
||||
|
||||
constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number) {
|
||||
constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {
|
||||
this._scrollbarSize = Math.round(scrollbarSize);
|
||||
this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);
|
||||
this._arrowSize = Math.round(arrowSize);
|
||||
|
||||
this._visibleSize = 0;
|
||||
this._scrollSize = 0;
|
||||
this._scrollPosition = 0;
|
||||
this._visibleSize = visibleSize;
|
||||
this._scrollSize = scrollSize;
|
||||
this._scrollPosition = scrollPosition;
|
||||
|
||||
this._computedAvailableSize = 0;
|
||||
this._computedIsNeeded = false;
|
||||
@@ -81,11 +81,7 @@ export class ScrollbarState {
|
||||
}
|
||||
|
||||
public clone(): ScrollbarState {
|
||||
let r = new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize);
|
||||
r.setVisibleSize(this._visibleSize);
|
||||
r.setScrollSize(this._scrollSize);
|
||||
r.setScrollPosition(this._scrollPosition);
|
||||
return r;
|
||||
return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);
|
||||
}
|
||||
|
||||
public setVisibleSize(visibleSize: number): boolean {
|
||||
|
||||
@@ -13,6 +13,8 @@ import { INewScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from
|
||||
export class VerticalScrollbar extends AbstractScrollbar {
|
||||
|
||||
constructor(scrollable: Scrollable, options: ScrollableElementResolvedOptions, host: ScrollbarHost) {
|
||||
const scrollDimensions = scrollable.getScrollDimensions();
|
||||
const scrollPosition = scrollable.getCurrentScrollPosition();
|
||||
super({
|
||||
lazyRender: options.lazyRender,
|
||||
host: host,
|
||||
@@ -20,7 +22,10 @@ export class VerticalScrollbar extends AbstractScrollbar {
|
||||
(options.verticalHasArrows ? options.arrowSize : 0),
|
||||
(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize),
|
||||
// give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom
|
||||
0
|
||||
0,
|
||||
scrollDimensions.height,
|
||||
scrollDimensions.scrollHeight,
|
||||
scrollPosition.scrollTop
|
||||
),
|
||||
visibility: options.vertical,
|
||||
extraScrollbarClassName: 'vertical',
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export function getPathFromAmdModule(requirefn: typeof require, relativePath: string): string {
|
||||
return URI.parse(requirefn.toUrl(relativePath)).fsPath;
|
||||
return getUriFromAmdModule(requirefn, relativePath).fsPath;
|
||||
}
|
||||
|
||||
export function getUriFromAmdModule(requirefn: typeof require, relativePath: string): URI {
|
||||
return URI.parse(requirefn.toUrl(relativePath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -481,8 +481,9 @@ export class Queue<T> extends Limiter<T> {
|
||||
* A helper to organize queues per resource. The ResourceQueue makes sure to manage queues per resource
|
||||
* by disposing them once the queue is empty.
|
||||
*/
|
||||
export class ResourceQueue {
|
||||
private queues: Map<string, Queue<void>> = new Map();
|
||||
export class ResourceQueue implements IDisposable {
|
||||
|
||||
private readonly queues = new Map<string, Queue<void>>();
|
||||
|
||||
queueFor(resource: URI): Queue<void> {
|
||||
const key = resource.toString();
|
||||
@@ -498,6 +499,11 @@ export class ResourceQueue {
|
||||
|
||||
return this.queues.get(key)!;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.queues.forEach(queue => queue.dispose());
|
||||
this.queues.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class TimeoutTimer implements IDisposable {
|
||||
|
||||
@@ -148,6 +148,7 @@ export namespace Event {
|
||||
|
||||
if (leading && !handle) {
|
||||
emitter.fire(output);
|
||||
output = undefined;
|
||||
}
|
||||
|
||||
clearTimeout(handle);
|
||||
|
||||
@@ -120,7 +120,7 @@ export function setProperty(text: string, originalPath: JSONPath, value: any, fo
|
||||
}
|
||||
}
|
||||
|
||||
function withFormatting(text: string, edit: Edit, formattingOptions: FormattingOptions): Edit[] {
|
||||
export function withFormatting(text: string, edit: Edit, formattingOptions: FormattingOptions): Edit[] {
|
||||
// apply the edit
|
||||
let newText = applyEdit(text, edit);
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ function computeIndentLevel(content: string, options: FormattingOptions): number
|
||||
return Math.floor(nChars / tabSize);
|
||||
}
|
||||
|
||||
function getEOL(options: FormattingOptions, text: string): string {
|
||||
export function getEOL(options: FormattingOptions, text: string): string {
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const ch = text.charAt(i);
|
||||
if (ch === '\r') {
|
||||
@@ -245,4 +245,4 @@ function getEOL(options: FormattingOptions, text: string): string {
|
||||
|
||||
export function isEOL(text: string, offset: number) {
|
||||
return '\r\n'.indexOf(text.charAt(offset)) !== -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,49 @@ function doFindFreePort(startPort: number, giveUpAfter: number, clb: (port: numb
|
||||
client.connect(startPort, '127.0.0.1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses listen instead of connect. Is faster, but if there is another listener on 0.0.0.0 then this will take 127.0.0.1 from that listener.
|
||||
*/
|
||||
export function findFreePortFaster(startPort: number, giveUpAfter: number, timeout: number): Promise<number> {
|
||||
let resolved: boolean = false;
|
||||
let timeoutHandle: NodeJS.Timeout | undefined = undefined;
|
||||
let countTried: number = 1;
|
||||
const server = net.createServer({ pauseOnConnect: true });
|
||||
function doResolve(port: number, resolve: (port: number) => void) {
|
||||
if (!resolved) {
|
||||
resolved = true;
|
||||
server.removeAllListeners();
|
||||
server.close();
|
||||
if (timeoutHandle) {
|
||||
clearTimeout(timeoutHandle);
|
||||
}
|
||||
resolve(port);
|
||||
}
|
||||
}
|
||||
return new Promise<number>(resolve => {
|
||||
timeoutHandle = setTimeout(() => {
|
||||
doResolve(0, resolve);
|
||||
}, timeout);
|
||||
|
||||
server.on('listening', () => {
|
||||
doResolve(startPort, resolve);
|
||||
});
|
||||
server.on('error', err => {
|
||||
if (err && ((<any>err).code === 'EADDRINUSE' || (<any>err).code === 'EACCES') && (countTried < giveUpAfter)) {
|
||||
startPort++;
|
||||
countTried++;
|
||||
server.listen(startPort, '127.0.0.1');
|
||||
} else {
|
||||
doResolve(0, resolve);
|
||||
}
|
||||
});
|
||||
server.on('close', () => {
|
||||
doResolve(0, resolve);
|
||||
});
|
||||
server.listen(startPort, '127.0.0.1');
|
||||
});
|
||||
}
|
||||
|
||||
function dispose(socket: net.Socket): void {
|
||||
try {
|
||||
socket.removeAllListeners('connect');
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -8,10 +8,7 @@ import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
|
||||
|
||||
suite('ScrollbarState', () => {
|
||||
test('inflates slider size', () => {
|
||||
let actual = new ScrollbarState(0, 14, 0);
|
||||
actual.setVisibleSize(339);
|
||||
actual.setScrollSize(42423);
|
||||
actual.setScrollPosition(32787);
|
||||
let actual = new ScrollbarState(0, 14, 0, 339, 42423, 32787);
|
||||
|
||||
assert.equal(actual.getArrowSize(), 0);
|
||||
assert.equal(actual.getScrollPosition(), 32787);
|
||||
@@ -34,10 +31,7 @@ suite('ScrollbarState', () => {
|
||||
});
|
||||
|
||||
test('inflates slider size with arrows', () => {
|
||||
let actual = new ScrollbarState(12, 14, 0);
|
||||
actual.setVisibleSize(339);
|
||||
actual.setScrollSize(42423);
|
||||
actual.setScrollPosition(32787);
|
||||
let actual = new ScrollbarState(12, 14, 0, 339, 42423, 32787);
|
||||
|
||||
assert.equal(actual.getArrowSize(), 12);
|
||||
assert.equal(actual.getScrollPosition(), 32787);
|
||||
|
||||
@@ -237,6 +237,20 @@ suite('Event', function () {
|
||||
assert.equal(calls, 2);
|
||||
});
|
||||
|
||||
test('Debounce Event - leading reset', async function () {
|
||||
const emitter = new Emitter<number>();
|
||||
let debounced = Event.debounce(emitter.event, (l, e) => l ? l + 1 : 1, 0, /*leading=*/true);
|
||||
|
||||
let calls: number[] = [];
|
||||
debounced((e) => calls.push(e));
|
||||
|
||||
emitter.fire(1);
|
||||
emitter.fire(1);
|
||||
|
||||
await timeout(1);
|
||||
assert.deepEqual(calls, [1, 1]);
|
||||
});
|
||||
|
||||
test('Emitter - In Order Delivery', function () {
|
||||
const a = new Emitter<string>();
|
||||
const listener2Events: string[] = [];
|
||||
|
||||
@@ -12,8 +12,8 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { ExtensionManagementChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
|
||||
import { IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionManagementChannel, GlobalExtensionEnablementServiceClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
|
||||
import { IExtensionManagementService, IExtensionGalleryService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -113,6 +113,9 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
|
||||
disposables.add(logService);
|
||||
logService.info('main', JSON.stringify(configuration));
|
||||
|
||||
const mainProcessService = new MainProcessService(server, mainRouter);
|
||||
services.set(IMainProcessService, mainProcessService);
|
||||
|
||||
const configurationService = new ConfigurationService(environmentService.settingsResource);
|
||||
disposables.add(configurationService);
|
||||
await configurationService.initialize();
|
||||
@@ -124,8 +127,6 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
|
||||
services.set(IRequestService, new SyncDescriptor(RequestService));
|
||||
services.set(ILoggerService, new SyncDescriptor(LoggerService));
|
||||
|
||||
const mainProcessService = new MainProcessService(server, mainRouter);
|
||||
services.set(IMainProcessService, mainProcessService);
|
||||
|
||||
const electronService = createChannelSender<IElectronService>(mainProcessService.getChannel('electron'), { context: configuration.windowId });
|
||||
services.set(IElectronService, electronService);
|
||||
@@ -184,6 +185,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
|
||||
services.set(IUserDataAuthTokenService, new SyncDescriptor(UserDataAuthTokenService));
|
||||
services.set(IUserDataSyncLogService, new SyncDescriptor(UserDataSyncLogService));
|
||||
services.set(IUserDataSyncUtilService, new UserDataSyncUtilServiceClient(server.getChannel('userDataSyncUtil', activeWindowRouter)));
|
||||
services.set(IGlobalExtensionEnablementService, new GlobalExtensionEnablementServiceClient(server.getChannel('globalExtensionEnablement', activeWindowRouter)));
|
||||
services.set(IUserDataSyncStoreService, new SyncDescriptor(UserDataSyncStoreService));
|
||||
services.set(ISettingsSyncService, new SyncDescriptor(SettingsSynchroniser));
|
||||
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService));
|
||||
|
||||
@@ -171,7 +171,7 @@ export class CodeApplication extends Disposable {
|
||||
app.on('web-contents-created', (_event: Event, contents) => {
|
||||
contents.on('will-attach-webview', (event: Event, webPreferences, params) => {
|
||||
|
||||
const isValidWebviewSource = (source: string | undefined): boolean => {
|
||||
const isValidWebviewSource = (source: string): boolean => {
|
||||
if (!source) {
|
||||
return false;
|
||||
}
|
||||
@@ -191,12 +191,11 @@ export class CodeApplication extends Disposable {
|
||||
webPreferences.nodeIntegration = false;
|
||||
|
||||
// Verify URLs being loaded
|
||||
// https://github.com/electron/electron/issues/21553
|
||||
if (isValidWebviewSource(params.src) && isValidWebviewSource((webPreferences as { preloadURL: string }).preloadURL)) {
|
||||
if (isValidWebviewSource(params.src) && isValidWebviewSource(webPreferences.preloadURL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete (webPreferences as { preloadURL: string }).preloadURL; // https://github.com/electron/electron/issues/21553
|
||||
delete webPreferences.preloadUrl;
|
||||
|
||||
// Otherwise prevent loading
|
||||
this.logService.error('webContents#web-contents-created: Prevented webview attach');
|
||||
@@ -498,27 +497,27 @@ export class CodeApplication extends Disposable {
|
||||
this.logService.info(`Tracing: waiting for windows to get ready...`);
|
||||
|
||||
let recordingStopped = false;
|
||||
const stopRecording = async (timeout: boolean) => {
|
||||
const stopRecording = (timeout: boolean) => {
|
||||
if (recordingStopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
recordingStopped = true; // only once
|
||||
|
||||
const path = await contentTracing.stopRecording(join(homedir(), `${product.applicationName}-${Math.random().toString(16).slice(-4)}.trace.txt`));
|
||||
|
||||
if (!timeout) {
|
||||
if (this.dialogMainService) {
|
||||
this.dialogMainService.showMessageBox({
|
||||
type: 'info',
|
||||
message: localize('trace.message', "Successfully created trace."),
|
||||
detail: localize('trace.detail', "Please create an issue and manually attach the following file:\n{0}", path),
|
||||
buttons: [localize('trace.ok', "Ok")]
|
||||
}, withNullAsUndefined(BrowserWindow.getFocusedWindow()));
|
||||
contentTracing.stopRecording(join(homedir(), `${product.applicationName}-${Math.random().toString(16).slice(-4)}.trace.txt`), path => {
|
||||
if (!timeout) {
|
||||
if (this.dialogMainService) {
|
||||
this.dialogMainService.showMessageBox({
|
||||
type: 'info',
|
||||
message: localize('trace.message', "Successfully created trace."),
|
||||
detail: localize('trace.detail', "Please create an issue and manually attach the following file:\n{0}", path),
|
||||
buttons: [localize('trace.ok', "Ok")]
|
||||
}, withNullAsUndefined(BrowserWindow.getFocusedWindow()));
|
||||
}
|
||||
} else {
|
||||
this.logService.info(`Tracing: data recorded (after 30s timeout) to ${path}`);
|
||||
}
|
||||
} else {
|
||||
this.logService.info(`Tracing: data recorded (after 30s timeout) to ${path}`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Wait up to 30s before creating the trace anyways
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as objects from 'vs/base/common/objects';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, nativeTheme } from 'electron';
|
||||
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment } from 'electron';
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -347,9 +347,9 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
});
|
||||
|
||||
this._win.webContents.session.webRequest.onHeadersReceived(null!, (details, callback) => {
|
||||
const responseHeaders = details.responseHeaders as Record<string, (string) | (string[])>;
|
||||
const responseHeaders = details.responseHeaders as { [key: string]: string[] };
|
||||
|
||||
const contentType = (responseHeaders['content-type'] || responseHeaders['Content-Type']);
|
||||
const contentType: string[] = (responseHeaders['content-type'] || responseHeaders['Content-Type']);
|
||||
if (contentType && Array.isArray(contentType) && contentType.some(x => x.toLowerCase().indexOf('image/svg') >= 0)) {
|
||||
return callback({ cancel: true });
|
||||
}
|
||||
@@ -441,7 +441,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
// Inject headers when requests are incoming
|
||||
const urls = ['https://marketplace.visualstudio.com/*', 'https://*.vsassets.io/*'];
|
||||
this._win.webContents.session.webRequest.onBeforeSendHeaders({ urls }, (details, cb) =>
|
||||
this.marketplaceHeadersPromise.then(headers => cb({ cancel: false, requestHeaders: objects.assign(details.requestHeaders, headers) as Record<string, string> })));
|
||||
this.marketplaceHeadersPromise.then(headers => cb({ cancel: false, requestHeaders: objects.assign(details.requestHeaders, headers) as { [key: string]: string | undefined } })));
|
||||
}
|
||||
|
||||
private onWindowError(error: WindowError): void {
|
||||
@@ -648,7 +648,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
if (windowConfig?.autoDetectHighContrast === false) {
|
||||
autoDetectHighContrast = false;
|
||||
}
|
||||
windowConfiguration.highContrast = isWindows && autoDetectHighContrast && nativeTheme.shouldUseInvertedColorScheme;
|
||||
windowConfiguration.highContrast = isWindows && autoDetectHighContrast && systemPreferences.isInvertedColorScheme();
|
||||
windowConfiguration.accessibilitySupport = app.accessibilitySupportEnabled;
|
||||
|
||||
// Title style related
|
||||
@@ -1007,22 +1007,22 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
switch (visibility) {
|
||||
case ('default'):
|
||||
this._win.setMenuBarVisibility(!isFullscreen);
|
||||
this._win.autoHideMenuBar = isFullscreen;
|
||||
this._win.setAutoHideMenuBar(isFullscreen);
|
||||
break;
|
||||
|
||||
case ('visible'):
|
||||
this._win.setMenuBarVisibility(true);
|
||||
this._win.autoHideMenuBar = false;
|
||||
this._win.setAutoHideMenuBar(false);
|
||||
break;
|
||||
|
||||
case ('toggle'):
|
||||
this._win.setMenuBarVisibility(false);
|
||||
this._win.autoHideMenuBar = true;
|
||||
this._win.setAutoHideMenuBar(true);
|
||||
break;
|
||||
|
||||
case ('hidden'):
|
||||
this._win.setMenuBarVisibility(false);
|
||||
this._win.autoHideMenuBar = false;
|
||||
this._win.setAutoHideMenuBar(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { CommonEditorConfiguration, IEnvConfiguration } from 'vs/editor/common/c
|
||||
import { EditorOption, IEditorConstructionOptions, EditorFontLigatures } from 'vs/editor/common/config/editorOptions';
|
||||
import { BareFontInfo, FontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { IDimension } from 'vs/editor/common/editorCommon';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||
|
||||
class CSSBasedConfigurationCache {
|
||||
|
||||
@@ -87,6 +87,7 @@ export interface ISerializedFontInfo {
|
||||
readonly typicalFullwidthCharacterWidth: number;
|
||||
readonly canUseHalfwidthRightwardsArrow: boolean;
|
||||
readonly spaceWidth: number;
|
||||
middotWidth: number;
|
||||
readonly maxDigitWidth: number;
|
||||
}
|
||||
|
||||
@@ -159,6 +160,7 @@ class CSSBasedConfiguration extends Disposable {
|
||||
const savedFontInfo = savedFontInfos[i];
|
||||
// compatibility with older versions of VS Code which did not store this...
|
||||
savedFontInfo.fontFeatureSettings = savedFontInfo.fontFeatureSettings || EditorFontLigatures.OFF;
|
||||
savedFontInfo.middotWidth = savedFontInfo.middotWidth || savedFontInfo.spaceWidth;
|
||||
const fontInfo = new FontInfo(savedFontInfo, false);
|
||||
this._writeToCache(fontInfo, fontInfo);
|
||||
}
|
||||
@@ -183,6 +185,7 @@ class CSSBasedConfiguration extends Disposable {
|
||||
typicalFullwidthCharacterWidth: Math.max(readConfig.typicalFullwidthCharacterWidth, 5),
|
||||
canUseHalfwidthRightwardsArrow: readConfig.canUseHalfwidthRightwardsArrow,
|
||||
spaceWidth: Math.max(readConfig.spaceWidth, 5),
|
||||
middotWidth: Math.max(readConfig.middotWidth, 5),
|
||||
maxDigitWidth: Math.max(readConfig.maxDigitWidth, 5),
|
||||
}, false);
|
||||
}
|
||||
@@ -223,7 +226,8 @@ class CSSBasedConfiguration extends Disposable {
|
||||
const rightwardsArrow = this.createRequest('→', CharWidthRequestType.Regular, all, monospace);
|
||||
const halfwidthRightwardsArrow = this.createRequest('→', CharWidthRequestType.Regular, all, null);
|
||||
|
||||
this.createRequest('·', CharWidthRequestType.Regular, all, monospace);
|
||||
// middle dot character
|
||||
const middot = this.createRequest('·', CharWidthRequestType.Regular, all, monospace);
|
||||
|
||||
// monospace test: some characters
|
||||
this.createRequest('|', CharWidthRequestType.Regular, all, monospace);
|
||||
@@ -289,6 +293,7 @@ class CSSBasedConfiguration extends Disposable {
|
||||
typicalFullwidthCharacterWidth: typicalFullwidthCharacter.width,
|
||||
canUseHalfwidthRightwardsArrow: canUseHalfwidthRightwardsArrow,
|
||||
spaceWidth: space.width,
|
||||
middotWidth: middot.width,
|
||||
maxDigitWidth: maxDigitWidth
|
||||
}, canTrustBrowserZoomLevel);
|
||||
}
|
||||
@@ -333,7 +338,7 @@ export class Configuration extends CommonEditorConfiguration {
|
||||
}
|
||||
|
||||
this._register(browser.onDidChangeZoomLevel(_ => this._recomputeOptions()));
|
||||
this._register(this.accessibilityService.onDidChangeAccessibilitySupport(() => this._recomputeOptions()));
|
||||
this._register(this.accessibilityService.onDidChangeScreenReaderOptimized(() => this._recomputeOptions()));
|
||||
|
||||
this._recomputeOptions();
|
||||
}
|
||||
@@ -374,7 +379,7 @@ export class Configuration extends CommonEditorConfiguration {
|
||||
emptySelectionClipboard: browser.isWebKit || browser.isFirefox,
|
||||
pixelRatio: browser.getPixelRatio(),
|
||||
zoomLevel: browser.getZoomLevel(),
|
||||
accessibilitySupport: this.accessibilityService.getAccessibilitySupport()
|
||||
accessibilitySupport: this.accessibilityService.isScreenReaderOptimized() ? AccessibilitySupport.Enabled : AccessibilitySupport.Disabled
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -363,6 +363,7 @@ class MouseDownOperation extends Disposable {
|
||||
this._isActive = true;
|
||||
|
||||
this._mouseMoveMonitor.startMonitoring(
|
||||
e.target,
|
||||
e.buttons,
|
||||
createMouseMoveEventMerger(null),
|
||||
(e) => this._onMouseDownThenMove(e),
|
||||
@@ -387,6 +388,7 @@ class MouseDownOperation extends Disposable {
|
||||
if (!this._isActive) {
|
||||
this._isActive = true;
|
||||
this._mouseMoveMonitor.startMonitoring(
|
||||
e.target,
|
||||
e.buttons,
|
||||
createMouseMoveEventMerger(null),
|
||||
(e) => this._onMouseDownThenMove(e),
|
||||
|
||||
@@ -17,6 +17,7 @@ import { HorizontalPosition } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { CursorColumns } from 'vs/editor/common/controller/cursorCommon';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
|
||||
export interface IViewZoneData {
|
||||
viewZoneId: string;
|
||||
@@ -835,8 +836,17 @@ export class MouseTargetFactory {
|
||||
}
|
||||
|
||||
private static _actualDoHitTestWithCaretRangeFromPoint(ctx: HitTestContext, coords: ClientCoordinates): IHitTestResult {
|
||||
|
||||
const range: Range = document.caretRangeFromPoint(coords.clientX, coords.clientY);
|
||||
const shadowRoot = dom.getShadowRoot(ctx.viewDomNode);
|
||||
let range: Range;
|
||||
if (shadowRoot) {
|
||||
if (typeof shadowRoot.caretRangeFromPoint === 'undefined') {
|
||||
range = shadowCaretRangeFromPoint(shadowRoot, coords.clientX, coords.clientY);
|
||||
} else {
|
||||
range = shadowRoot.caretRangeFromPoint(coords.clientX, coords.clientY);
|
||||
}
|
||||
} else {
|
||||
range = document.caretRangeFromPoint(coords.clientX, coords.clientY);
|
||||
}
|
||||
|
||||
if (!range || !range.startContainer) {
|
||||
return {
|
||||
@@ -1009,3 +1019,94 @@ export class MouseTargetFactory {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function shadowCaretRangeFromPoint(shadowRoot: ShadowRoot, x: number, y: number): Range {
|
||||
const range = document.createRange();
|
||||
|
||||
// Get the element under the point
|
||||
let el: Element | null = shadowRoot.elementFromPoint(x, y);
|
||||
|
||||
if (el !== null) {
|
||||
// Get the last child of the element until its firstChild is a text node
|
||||
// This assumes that the pointer is on the right of the line, out of the tokens
|
||||
// and that we want to get the offset of the last token of the line
|
||||
while (el && el.firstChild && el.firstChild.nodeType !== el.firstChild.TEXT_NODE) {
|
||||
el = <Element>el.lastChild;
|
||||
}
|
||||
|
||||
// Grab its rect
|
||||
const rect = el.getBoundingClientRect();
|
||||
|
||||
// And its font
|
||||
const font = window.getComputedStyle(el, null).getPropertyValue('font');
|
||||
|
||||
// And also its txt content
|
||||
const text = (el as any).innerText;
|
||||
|
||||
// Position the pixel cursor at the left of the element
|
||||
let pixelCursor = rect.left;
|
||||
let offset = 0;
|
||||
let step: number;
|
||||
|
||||
// If the point is on the right of the box put the cursor after the last character
|
||||
if (x > rect.left + rect.width) {
|
||||
offset = text.length;
|
||||
} else {
|
||||
const charWidthReader = CharWidthReader.getInstance();
|
||||
// Goes through all the characters of the innerText, and checks if the x of the point
|
||||
// belongs to the character.
|
||||
for (let i = 0; i < text.length + 1; i++) {
|
||||
// The step is half the width of the character
|
||||
step = charWidthReader.getCharWidth(text.charAt(i), font) / 2;
|
||||
// Move to the center of the character
|
||||
pixelCursor += step;
|
||||
// If the x of the point is smaller that the position of the cursor, the point is over that character
|
||||
if (x < pixelCursor) {
|
||||
offset = i;
|
||||
break;
|
||||
}
|
||||
// Move between the current character and the next
|
||||
pixelCursor += step;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a range with the text node of the element and set the offset found
|
||||
range.setStart(el.firstChild!, offset);
|
||||
range.setEnd(el.firstChild!, offset);
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
class CharWidthReader {
|
||||
private static _INSTANCE: CharWidthReader | null = null;
|
||||
|
||||
public static getInstance(): CharWidthReader {
|
||||
if (!CharWidthReader._INSTANCE) {
|
||||
CharWidthReader._INSTANCE = new CharWidthReader();
|
||||
}
|
||||
return CharWidthReader._INSTANCE;
|
||||
}
|
||||
|
||||
private readonly _cache: { [cacheKey: string]: number; };
|
||||
private readonly _canvas: HTMLCanvasElement;
|
||||
|
||||
private constructor() {
|
||||
this._cache = {};
|
||||
this._canvas = document.createElement('canvas');
|
||||
}
|
||||
|
||||
public getCharWidth(char: string, font: string): number {
|
||||
const cacheKey = char + font;
|
||||
if (this._cache[cacheKey]) {
|
||||
return this._cache[cacheKey];
|
||||
}
|
||||
|
||||
const context = this._canvas.getContext('2d')!;
|
||||
context.font = font;
|
||||
const metrics = context.measureText(char);
|
||||
const width = metrics.width;
|
||||
this._cache[cacheKey] = width;
|
||||
return width;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart';
|
||||
import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers';
|
||||
import { Margin } from 'vs/editor/browser/viewParts/margin/margin';
|
||||
import { RenderLineNumbersType, EditorOption, IComputedEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { RenderLineNumbersType, EditorOption, IComputedEditorOptions, EditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { WordCharacterClass, getMapForWordSeparators } from 'vs/editor/common/controller/wordCharacterClassifier';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
@@ -62,8 +62,8 @@ export class TextAreaHandler extends ViewPart {
|
||||
private _scrollLeft: number;
|
||||
private _scrollTop: number;
|
||||
|
||||
private _accessibilitySupport: AccessibilitySupport;
|
||||
private _accessibilityPageSize: number;
|
||||
private _accessibilitySupport!: AccessibilitySupport;
|
||||
private _accessibilityPageSize!: number;
|
||||
private _contentLeft: number;
|
||||
private _contentWidth: number;
|
||||
private _contentHeight: number;
|
||||
@@ -77,6 +77,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
*/
|
||||
private _visibleTextArea: VisibleTextAreaData | null;
|
||||
private _selections: Selection[];
|
||||
private _modelSelections: Selection[];
|
||||
|
||||
/**
|
||||
* The position at which the textarea was rendered.
|
||||
@@ -99,8 +100,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
const options = this._context.configuration.options;
|
||||
const layoutInfo = options.get(EditorOption.layoutInfo);
|
||||
|
||||
this._accessibilitySupport = options.get(EditorOption.accessibilitySupport);
|
||||
this._accessibilityPageSize = options.get(EditorOption.accessibilityPageSize);
|
||||
this._setAccessibilityOptions(options);
|
||||
this._contentLeft = layoutInfo.contentLeft;
|
||||
this._contentWidth = layoutInfo.contentWidth;
|
||||
this._contentHeight = layoutInfo.height;
|
||||
@@ -111,6 +111,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
this._visibleTextArea = null;
|
||||
this._selections = [new Selection(1, 1, 1, 1)];
|
||||
this._modelSelections = [new Selection(1, 1, 1, 1)];
|
||||
this._lastRenderPosition = null;
|
||||
|
||||
// Text Area (The focus will always be in the textarea when the cursor is blinking)
|
||||
@@ -149,24 +150,30 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
const textAreaInputHost: ITextAreaInputHost = {
|
||||
getDataToCopy: (generateHTML: boolean): ClipboardDataToCopy => {
|
||||
const rawTextToCopy = this._context.model.getPlainTextToCopy(this._selections, this._emptySelectionClipboard, platform.isWindows);
|
||||
const rawTextToCopy = this._context.model.getPlainTextToCopy(this._modelSelections, this._emptySelectionClipboard, platform.isWindows);
|
||||
const newLineCharacter = this._context.model.getEOL();
|
||||
|
||||
const isFromEmptySelection = (this._emptySelectionClipboard && this._selections.length === 1 && this._selections[0].isEmpty());
|
||||
const isFromEmptySelection = (this._emptySelectionClipboard && this._modelSelections.length === 1 && this._modelSelections[0].isEmpty());
|
||||
const multicursorText = (Array.isArray(rawTextToCopy) ? rawTextToCopy : null);
|
||||
const text = (Array.isArray(rawTextToCopy) ? rawTextToCopy.join(newLineCharacter) : rawTextToCopy);
|
||||
|
||||
let html: string | null | undefined = undefined;
|
||||
let mode: string | null = null;
|
||||
if (generateHTML) {
|
||||
if (CopyOptions.forceCopyWithSyntaxHighlighting || (this._copyWithSyntaxHighlighting && text.length < 65536)) {
|
||||
html = this._context.model.getHTMLToCopy(this._selections, this._emptySelectionClipboard);
|
||||
const richText = this._context.model.getRichTextToCopy(this._modelSelections, this._emptySelectionClipboard);
|
||||
if (richText) {
|
||||
html = richText.html;
|
||||
mode = richText.mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
isFromEmptySelection,
|
||||
multicursorText,
|
||||
text,
|
||||
html
|
||||
html,
|
||||
mode
|
||||
};
|
||||
},
|
||||
|
||||
@@ -220,11 +227,13 @@ export class TextAreaHandler extends ViewPart {
|
||||
this._register(this._textAreaInput.onPaste((e: IPasteData) => {
|
||||
let pasteOnNewLine = false;
|
||||
let multicursorText: string[] | null = null;
|
||||
let mode: string | null = null;
|
||||
if (e.metadata) {
|
||||
pasteOnNewLine = (this._emptySelectionClipboard && !!e.metadata.isFromEmptySelection);
|
||||
multicursorText = (typeof e.metadata.multicursorText !== 'undefined' ? e.metadata.multicursorText : null);
|
||||
mode = e.metadata.mode;
|
||||
}
|
||||
this._viewController.paste('keyboard', e.text, pasteOnNewLine, multicursorText);
|
||||
this._viewController.paste('keyboard', e.text, pasteOnNewLine, multicursorText, mode);
|
||||
}));
|
||||
|
||||
this._register(this._textAreaInput.onCut(() => {
|
||||
@@ -344,14 +353,24 @@ export class TextAreaHandler extends ViewPart {
|
||||
return options.get(EditorOption.ariaLabel);
|
||||
}
|
||||
|
||||
private _setAccessibilityOptions(options: IComputedEditorOptions): void {
|
||||
this._accessibilitySupport = options.get(EditorOption.accessibilitySupport);
|
||||
const accessibilityPageSize = options.get(EditorOption.accessibilityPageSize);
|
||||
if (this._accessibilitySupport === AccessibilitySupport.Enabled && accessibilityPageSize === EditorOptions.accessibilityPageSize.defaultValue) {
|
||||
// If a screen reader is attached and the default value is not set we shuold automatically increase the page size to 1000 for a better experience
|
||||
this._accessibilityPageSize = 1000;
|
||||
} else {
|
||||
this._accessibilityPageSize = accessibilityPageSize;
|
||||
}
|
||||
}
|
||||
|
||||
// --- begin event handlers
|
||||
|
||||
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
|
||||
const options = this._context.configuration.options;
|
||||
const layoutInfo = options.get(EditorOption.layoutInfo);
|
||||
|
||||
this._accessibilitySupport = options.get(EditorOption.accessibilitySupport);
|
||||
this._accessibilityPageSize = options.get(EditorOption.accessibilityPageSize);
|
||||
this._setAccessibilityOptions(options);
|
||||
this._contentLeft = layoutInfo.contentLeft;
|
||||
this._contentWidth = layoutInfo.contentWidth;
|
||||
this._contentHeight = layoutInfo.height;
|
||||
@@ -377,6 +396,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
}
|
||||
public onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean {
|
||||
this._selections = e.selections.slice(0);
|
||||
this._modelSelections = e.modelSelections.slice(0);
|
||||
this._textAreaInput.writeScreenReaderContent('selection changed');
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,12 +41,14 @@ export interface ClipboardDataToCopy {
|
||||
multicursorText: string[] | null | undefined;
|
||||
text: string;
|
||||
html: string | null | undefined;
|
||||
mode: string | null;
|
||||
}
|
||||
|
||||
export interface ClipboardStoredMetadata {
|
||||
version: 1;
|
||||
isFromEmptySelection: boolean | undefined;
|
||||
multicursorText: string[] | null | undefined;
|
||||
mode: string | null;
|
||||
}
|
||||
|
||||
export interface ITextAreaInputHost {
|
||||
@@ -550,7 +552,8 @@ export class TextAreaInput extends Disposable {
|
||||
const storedMetadata: ClipboardStoredMetadata = {
|
||||
version: 1,
|
||||
isFromEmptySelection: dataToCopy.isFromEmptySelection,
|
||||
multicursorText: dataToCopy.multicursorText
|
||||
multicursorText: dataToCopy.multicursorText,
|
||||
mode: dataToCopy.mode
|
||||
};
|
||||
InMemoryClipboardMetadataManager.INSTANCE.set(
|
||||
// When writing "LINE\r\n" to the clipboard and then pasting,
|
||||
|
||||
@@ -308,6 +308,14 @@ export interface IPartialEditorMouseEvent {
|
||||
readonly target: IMouseTarget | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A paste event originating from the editor.
|
||||
*/
|
||||
export interface IPasteEvent {
|
||||
readonly range: Range;
|
||||
readonly mode: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An overview ruler
|
||||
* @internal
|
||||
@@ -416,11 +424,11 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
/**
|
||||
* An event emitted after composition has started.
|
||||
*/
|
||||
onCompositionStart(listener: () => void): IDisposable;
|
||||
onDidCompositionStart(listener: () => void): IDisposable;
|
||||
/**
|
||||
* An event emitted after composition has ended.
|
||||
*/
|
||||
onCompositionEnd(listener: () => void): IDisposable;
|
||||
onDidCompositionEnd(listener: () => void): IDisposable;
|
||||
/**
|
||||
* An event emitted when editing failed because the editor is read-only.
|
||||
* @event
|
||||
@@ -431,7 +439,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* An event emitted when users paste text in the editor.
|
||||
* @event
|
||||
*/
|
||||
onDidPaste(listener: (range: Range) => void): IDisposable;
|
||||
onDidPaste(listener: (e: IPasteEvent) => void): IDisposable;
|
||||
/**
|
||||
* An event emitted on a "mouseup".
|
||||
* @event
|
||||
@@ -723,6 +731,11 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
*/
|
||||
getTelemetryData(): { [key: string]: any } | undefined;
|
||||
|
||||
/**
|
||||
* Returns the editor's container dom node
|
||||
*/
|
||||
getContainerDomNode(): HTMLElement;
|
||||
|
||||
/**
|
||||
* Returns the editor's dom node
|
||||
*/
|
||||
|
||||
@@ -182,7 +182,13 @@ export class GlobalEditorMouseMoveMonitor extends Disposable {
|
||||
this._keydownListener = null;
|
||||
}
|
||||
|
||||
public startMonitoring(initialButtons: number, merger: EditorMouseEventMerger, mouseMoveCallback: (e: EditorMouseEvent) => void, onStopCallback: () => void): void {
|
||||
public startMonitoring(
|
||||
initialElement: HTMLElement,
|
||||
initialButtons: number,
|
||||
merger: EditorMouseEventMerger,
|
||||
mouseMoveCallback: (e: EditorMouseEvent) => void,
|
||||
onStopCallback: () => void
|
||||
): void {
|
||||
|
||||
// Add a <<capture>> keydown event listener that will cancel the monitoring
|
||||
// if something other than a modifier key is pressed
|
||||
@@ -199,7 +205,7 @@ export class GlobalEditorMouseMoveMonitor extends Disposable {
|
||||
return merger(lastEvent, new EditorMouseEvent(currentEvent, this._editorViewDomNode));
|
||||
};
|
||||
|
||||
this._globalMouseMoveMonitor.startMonitoring(initialButtons, myMerger, mouseMoveCallback, () => {
|
||||
this._globalMouseMoveMonitor.startMonitoring(initialElement, initialButtons, myMerger, mouseMoveCallback, () => {
|
||||
this._keydownListener!.dispose();
|
||||
onStopCallback();
|
||||
});
|
||||
|
||||
@@ -89,7 +89,7 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC
|
||||
return editorWithWidgetFocus;
|
||||
}
|
||||
|
||||
abstract registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
|
||||
abstract registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string, editor?: ICodeEditor): void;
|
||||
abstract removeDecorationType(key: string): void;
|
||||
abstract resolveDecorationOptions(decorationTypeKey: string | undefined, writable: boolean): IModelDecorationOptions;
|
||||
|
||||
@@ -120,6 +120,16 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC
|
||||
return this._transientWatchers[uri].get(key);
|
||||
}
|
||||
|
||||
public getTransientModelProperties(model: ITextModel): [string, any][] | undefined {
|
||||
const uri = model.uri.toString();
|
||||
|
||||
if (!this._transientWatchers.hasOwnProperty(uri)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this._transientWatchers[uri].keys().map(key => [key, this._transientWatchers[uri].get(key)]);
|
||||
}
|
||||
|
||||
_removeWatcher(w: ModelTransientSettingWatcher): void {
|
||||
delete this._transientWatchers[w.uri];
|
||||
}
|
||||
@@ -145,4 +155,8 @@ export class ModelTransientSettingWatcher {
|
||||
public get(key: string): any {
|
||||
return this._values[key];
|
||||
}
|
||||
|
||||
public keys(): string[] {
|
||||
return Object.keys(this._values);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +37,13 @@ export interface ICodeEditorService {
|
||||
*/
|
||||
getFocusedCodeEditor(): ICodeEditor | null;
|
||||
|
||||
registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void;
|
||||
registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string, editor?: ICodeEditor): void;
|
||||
removeDecorationType(key: string): void;
|
||||
resolveDecorationOptions(typeKey: string, writable: boolean): IModelDecorationOptions;
|
||||
|
||||
setTransientModelProperty(model: ITextModel, key: string, value: any): void;
|
||||
getTransientModelProperty(model: ITextModel, key: string): any;
|
||||
getTransientModelProperties(model: ITextModel): [string, any][] | undefined;
|
||||
|
||||
getActiveCodeEditor(): ICodeEditor | null;
|
||||
openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Promise<ICodeEditor | null>;
|
||||
|
||||
@@ -14,31 +14,101 @@ import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, Overview
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { ITheme, IThemeService, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
class RefCountedStyleSheet {
|
||||
|
||||
private readonly _parent: CodeEditorServiceImpl;
|
||||
private readonly _editorId: string;
|
||||
public readonly styleSheet: HTMLStyleElement;
|
||||
private _refCount: number;
|
||||
|
||||
constructor(parent: CodeEditorServiceImpl, editorId: string, styleSheet: HTMLStyleElement) {
|
||||
this._parent = parent;
|
||||
this._editorId = editorId;
|
||||
this.styleSheet = styleSheet;
|
||||
this._refCount = 0;
|
||||
}
|
||||
|
||||
public ref(): void {
|
||||
this._refCount++;
|
||||
}
|
||||
|
||||
public unref(): void {
|
||||
this._refCount--;
|
||||
if (this._refCount === 0) {
|
||||
this.styleSheet.parentNode?.removeChild(this.styleSheet);
|
||||
this._parent._removeEditorStyleSheets(this._editorId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GlobalStyleSheet {
|
||||
public readonly styleSheet: HTMLStyleElement;
|
||||
|
||||
constructor(styleSheet: HTMLStyleElement) {
|
||||
this.styleSheet = styleSheet;
|
||||
}
|
||||
|
||||
public ref(): void {
|
||||
}
|
||||
|
||||
public unref(): void {
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
|
||||
private readonly _styleSheet: HTMLStyleElement;
|
||||
private _globalStyleSheet: GlobalStyleSheet | null;
|
||||
private readonly _decorationOptionProviders = new Map<string, IModelDecorationOptionsProvider>();
|
||||
private readonly _editorStyleSheets = new Map<string, RefCountedStyleSheet>();
|
||||
private readonly _themeService: IThemeService;
|
||||
|
||||
constructor(@IThemeService themeService: IThemeService, styleSheet = dom.createStyleSheet()) {
|
||||
constructor(@IThemeService themeService: IThemeService, styleSheet: HTMLStyleElement | null = null) {
|
||||
super();
|
||||
this._styleSheet = styleSheet;
|
||||
this._globalStyleSheet = styleSheet ? new GlobalStyleSheet(styleSheet) : null;
|
||||
this._themeService = themeService;
|
||||
}
|
||||
|
||||
public registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void {
|
||||
private _getOrCreateGlobalStyleSheet(): GlobalStyleSheet {
|
||||
if (!this._globalStyleSheet) {
|
||||
this._globalStyleSheet = new GlobalStyleSheet(dom.createStyleSheet());
|
||||
}
|
||||
return this._globalStyleSheet;
|
||||
}
|
||||
|
||||
private _getOrCreateStyleSheet(editor: ICodeEditor | undefined): GlobalStyleSheet | RefCountedStyleSheet {
|
||||
if (!editor) {
|
||||
return this._getOrCreateGlobalStyleSheet();
|
||||
}
|
||||
const domNode = editor.getContainerDomNode();
|
||||
if (!dom.isInShadowDOM(domNode)) {
|
||||
return this._getOrCreateGlobalStyleSheet();
|
||||
}
|
||||
const editorId = editor.getId();
|
||||
if (!this._editorStyleSheets.has(editorId)) {
|
||||
const refCountedStyleSheet = new RefCountedStyleSheet(this, editorId, dom.createStyleSheet(domNode));
|
||||
this._editorStyleSheets.set(editorId, refCountedStyleSheet);
|
||||
}
|
||||
return this._editorStyleSheets.get(editorId)!;
|
||||
}
|
||||
|
||||
_removeEditorStyleSheets(editorId: string): void {
|
||||
this._editorStyleSheets.delete(editorId);
|
||||
}
|
||||
|
||||
public registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string, editor?: ICodeEditor): void {
|
||||
let provider = this._decorationOptionProviders.get(key);
|
||||
if (!provider) {
|
||||
const styleSheet = this._getOrCreateStyleSheet(editor);
|
||||
const providerArgs: ProviderArguments = {
|
||||
styleSheet: this._styleSheet,
|
||||
styleSheet: styleSheet.styleSheet,
|
||||
key: key,
|
||||
parentTypeKey: parentTypeKey,
|
||||
options: options || Object.create(null)
|
||||
};
|
||||
if (!parentTypeKey) {
|
||||
provider = new DecorationTypeOptionsProvider(this._themeService, providerArgs);
|
||||
provider = new DecorationTypeOptionsProvider(this._themeService, styleSheet, providerArgs);
|
||||
} else {
|
||||
provider = new DecorationSubTypeOptionsProvider(this._themeService, providerArgs);
|
||||
provider = new DecorationSubTypeOptionsProvider(this._themeService, styleSheet, providerArgs);
|
||||
}
|
||||
this._decorationOptionProviders.set(key, provider);
|
||||
}
|
||||
@@ -76,13 +146,16 @@ interface IModelDecorationOptionsProvider extends IDisposable {
|
||||
|
||||
class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvider {
|
||||
|
||||
private readonly _styleSheet: GlobalStyleSheet | RefCountedStyleSheet;
|
||||
public refCount: number;
|
||||
|
||||
private readonly _parentTypeKey: string | undefined;
|
||||
private _beforeContentRules: DecorationCSSRules | null;
|
||||
private _afterContentRules: DecorationCSSRules | null;
|
||||
|
||||
constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
|
||||
constructor(themeService: IThemeService, styleSheet: GlobalStyleSheet | RefCountedStyleSheet, providerArgs: ProviderArguments) {
|
||||
this._styleSheet = styleSheet;
|
||||
this._styleSheet.ref();
|
||||
this._parentTypeKey = providerArgs.parentTypeKey;
|
||||
this.refCount = 0;
|
||||
|
||||
@@ -110,6 +183,7 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
|
||||
this._afterContentRules.dispose();
|
||||
this._afterContentRules = null;
|
||||
}
|
||||
this._styleSheet.unref();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +198,7 @@ interface ProviderArguments {
|
||||
class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
|
||||
|
||||
private readonly _disposables = new DisposableStore();
|
||||
private readonly _styleSheet: GlobalStyleSheet | RefCountedStyleSheet;
|
||||
public refCount: number;
|
||||
|
||||
public className: string | undefined;
|
||||
@@ -136,7 +211,9 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
|
||||
public overviewRuler: IModelDecorationOverviewRulerOptions | undefined;
|
||||
public stickiness: TrackedRangeStickiness | undefined;
|
||||
|
||||
constructor(themeService: IThemeService, providerArgs: ProviderArguments) {
|
||||
constructor(themeService: IThemeService, styleSheet: GlobalStyleSheet | RefCountedStyleSheet, providerArgs: ProviderArguments) {
|
||||
this._styleSheet = styleSheet;
|
||||
this._styleSheet.ref();
|
||||
this.refCount = 0;
|
||||
|
||||
const createCSSRules = (type: ModelDecorationCSSRuleType) => {
|
||||
@@ -202,6 +279,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
|
||||
|
||||
public dispose(): void {
|
||||
this._disposables.dispose();
|
||||
this._styleSheet.unref();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface IMouseDispatchData {
|
||||
export interface ICommandDelegate {
|
||||
executeEditorCommand(editorCommand: CoreEditorCommand, args: any): void;
|
||||
|
||||
paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null): void;
|
||||
paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null, mode: string | null): void;
|
||||
type(source: string, text: string): void;
|
||||
replacePreviousChar(source: string, text: string, replaceCharCnt: number): void;
|
||||
compositionStart(source: string): void;
|
||||
@@ -69,8 +69,8 @@ export class ViewController {
|
||||
this.commandDelegate.executeEditorCommand(editorCommand, args);
|
||||
}
|
||||
|
||||
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null): void {
|
||||
this.commandDelegate.paste(source, text, pasteOnNewLine, multicursorText);
|
||||
public paste(source: string, text: string, pasteOnNewLine: boolean, multicursorText: string[] | null, mode: string | null): void {
|
||||
this.commandDelegate.paste(source, text, pasteOnNewLine, multicursorText, mode);
|
||||
}
|
||||
|
||||
public type(source: string, text: string): void {
|
||||
|
||||
@@ -38,6 +38,7 @@ import { ViewCursors } from 'vs/editor/browser/viewParts/viewCursors/viewCursors
|
||||
import { ViewZones } from 'vs/editor/browser/viewParts/viewZones/viewZones';
|
||||
import { Cursor } from 'vs/editor/common/controller/cursor';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
@@ -525,10 +526,15 @@ export class View extends ViewEventHandler {
|
||||
}
|
||||
|
||||
public layoutContentWidget(widgetData: IContentWidgetData): void {
|
||||
const newPosition = widgetData.position ? widgetData.position.position : null;
|
||||
const newRange = widgetData.position ? widgetData.position.range || null : null;
|
||||
let newRange = widgetData.position ? widgetData.position.range || null : null;
|
||||
if (newRange === null) {
|
||||
const newPosition = widgetData.position ? widgetData.position.position : null;
|
||||
if (newPosition !== null) {
|
||||
newRange = new Range(newPosition.lineNumber, newPosition.column, newPosition.lineNumber, newPosition.column);
|
||||
}
|
||||
}
|
||||
const newPreference = widgetData.position ? widgetData.position.preference : null;
|
||||
this.contentWidgets.setWidgetPosition(widgetData.widget, newPosition, newRange, newPreference);
|
||||
this.contentWidgets.setWidgetPosition(widgetData.widget, newRange, newPreference);
|
||||
this._scheduleRender();
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user