mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-26 10:16:01 +01:00
@@ -31,6 +31,7 @@ addons:
|
||||
- libsecret-1-dev
|
||||
|
||||
before_install:
|
||||
- export GITHUB_TOKEN=$PUBLIC_GITHUB_TOKEN
|
||||
- git submodule update --init --recursive
|
||||
- git clone --depth 1 https://github.com/creationix/nvm.git ./.nvm
|
||||
- source ./.nvm/nvm.sh
|
||||
|
||||
@@ -45,8 +45,8 @@ const nodeModules = ['electron', 'original-fs']
|
||||
// Build
|
||||
|
||||
const builtInExtensions = [
|
||||
{ name: 'ms-vscode.node-debug', version: '1.19.7' },
|
||||
{ name: 'ms-vscode.node-debug2', version: '1.19.3' }
|
||||
{ name: 'ms-vscode.node-debug', version: '1.20.0' },
|
||||
{ name: 'ms-vscode.node-debug2', version: '1.19.4' }
|
||||
];
|
||||
|
||||
const excludedExtensions = [
|
||||
|
||||
@@ -318,7 +318,7 @@
|
||||
"@emmetio/css-parser": "ramya-rao-a/css-parser#vscode",
|
||||
"@emmetio/math-expression": "^0.1.1",
|
||||
"vscode-emmet-helper": "^1.1.19",
|
||||
"vscode-languageserver-types": "^3.0.3",
|
||||
"vscode-languageserver-types": "^3.5.0",
|
||||
"image-size": "^0.5.2",
|
||||
"vscode-nls": "2.0.2"
|
||||
}
|
||||
|
||||
@@ -23,6 +23,12 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
|
||||
const isSyntaxMapped = mappedLanguages[document.languageId] ? true : false;
|
||||
let syntax = getEmmetMode((isSyntaxMapped ? mappedLanguages[document.languageId] : document.languageId), excludedLanguages);
|
||||
|
||||
if (!syntax
|
||||
|| emmetConfig['showExpandedAbbreviation'] === 'never'
|
||||
|| ((isSyntaxMapped || syntax === 'jsx') && emmetConfig['showExpandedAbbreviation'] !== 'always')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const helper = getEmmetHelper();
|
||||
const extractAbbreviationResults = helper.extractAbbreviation(document, position);
|
||||
if (!extractAbbreviationResults) {
|
||||
@@ -46,12 +52,6 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
|
||||
}
|
||||
}
|
||||
|
||||
if (!syntax
|
||||
|| ((isSyntaxMapped || syntax === 'jsx')
|
||||
&& emmetConfig['showExpandedAbbreviation'] !== 'always')) {
|
||||
return;
|
||||
}
|
||||
|
||||
let noiseCheckPromise: Thenable<any> = Promise.resolve();
|
||||
|
||||
// Fix for https://github.com/Microsoft/vscode/issues/32647
|
||||
|
||||
@@ -2059,6 +2059,10 @@ vscode-languageserver-types@^3.0.3:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz#8964dc7c2247536fbefd2d6836bf3febac80dd00"
|
||||
|
||||
vscode-languageserver-types@^3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz#e48d79962f0b8e02de955e3f524908e2b19c0374"
|
||||
|
||||
vscode-nls@2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
|
||||
|
||||
@@ -519,6 +519,7 @@ export class Repository implements Disposable {
|
||||
this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)");
|
||||
this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] };
|
||||
this._sourceControl.quickDiffProvider = this;
|
||||
this._sourceControl.inputBox.lineWarningLength = 72;
|
||||
this.disposables.push(this._sourceControl);
|
||||
|
||||
this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes"));
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
],
|
||||
"main": "./out/javascriptMain",
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^0.3.1",
|
||||
"request-light": "^0.2.0",
|
||||
"jsonc-parser": "^1.0.0",
|
||||
"request-light": "^0.2.1",
|
||||
"vscode-nls": "^2.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -36,19 +36,17 @@ https-proxy-agent@^0.3.5:
|
||||
debug "2"
|
||||
extend "3"
|
||||
|
||||
jsonc-parser@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-0.3.1.tgz#6ebf5c75224368d4b07ef4c26f9434e657472e95"
|
||||
dependencies:
|
||||
vscode-nls "^2.0.2"
|
||||
jsonc-parser@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272"
|
||||
|
||||
ms@0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
|
||||
|
||||
request-light@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.0.tgz#922497791c2e68528124dfb82354cf37e4bb2cfc"
|
||||
request-light@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.1.tgz#986f5a82893e9d1ca6a896ebe6f46c51c6b4557f"
|
||||
dependencies:
|
||||
http-proxy-agent "^0.2.6"
|
||||
https-proxy-agent "^0.3.5"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// @ts-check
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
@@ -29,6 +29,13 @@
|
||||
};
|
||||
}
|
||||
|
||||
function postMessage(command, args) {
|
||||
window.parent.postMessage({
|
||||
command: 'did-click-link',
|
||||
data: `command:${command}?${encodeURIComponent(JSON.stringify(args))}`
|
||||
}, 'file://');
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the html elements that map to a specific target line in the editor.
|
||||
*
|
||||
@@ -196,14 +203,34 @@
|
||||
const offset = event.pageY;
|
||||
const line = getEditorLineNumberForPageOffset(offset);
|
||||
if (!isNaN(line)) {
|
||||
const args = [settings.source, line];
|
||||
window.parent.postMessage({
|
||||
command: "did-click-link",
|
||||
data: `command:_markdown.didClick?${encodeURIComponent(JSON.stringify(args))}`
|
||||
}, "file://");
|
||||
postMessage('_markdown.didClick', [settings.source, line]);
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('click', event => {
|
||||
if (!event) {
|
||||
return;
|
||||
}
|
||||
|
||||
const baseElement = document.getElementsByTagName('base')[0];
|
||||
|
||||
/** @type {any} */
|
||||
let node = event.target;
|
||||
while (node) {
|
||||
if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) {
|
||||
if (node.href.startsWith('file://')) {
|
||||
const [path, fragment] = node.href.replace(/^file:\/\//i, '').split('#');
|
||||
postMessage('_markdown.openDocumentLink', { path, fragment });
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
node = node.parentNode;
|
||||
}
|
||||
}, true);
|
||||
|
||||
if (settings.scrollEditorWithPreview) {
|
||||
window.addEventListener('scroll', throttle(() => {
|
||||
if (scrollDisabled) {
|
||||
@@ -211,11 +238,7 @@
|
||||
} else {
|
||||
const line = getEditorLineNumberForPageOffset(window.scrollY);
|
||||
if (!isNaN(line)) {
|
||||
const args = [settings.source, line];
|
||||
window.parent.postMessage({
|
||||
command: 'did-click-link',
|
||||
data: `command:_markdown.revealLine?${encodeURIComponent(JSON.stringify(args))}`
|
||||
}, 'file://');
|
||||
postMessage('_markdown.revealLine', [settings.source, line]);
|
||||
}
|
||||
}
|
||||
}, 50));
|
||||
|
||||
@@ -311,8 +311,8 @@
|
||||
"highlight.js": "9.5.0",
|
||||
"markdown-it": "^8.4.0",
|
||||
"markdown-it-named-headers": "0.0.4",
|
||||
"vscode-extension-telemetry": "0.0.8",
|
||||
"vscode-nls": "2.0.2"
|
||||
"vscode-extension-telemetry": "^0.0.8",
|
||||
"vscode-nls": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/highlight.js": "9.1.10",
|
||||
|
||||
@@ -264,6 +264,16 @@ export class OpenDocumentLinkCommand implements Command {
|
||||
new vscode.Range(line, 0, line, 0),
|
||||
vscode.TextEditorRevealType.AtTop);
|
||||
}
|
||||
|
||||
const lineNumberFragment = args.fragment.match(/^L(\d+)$/);
|
||||
if (lineNumberFragment) {
|
||||
const line = +lineNumberFragment[1] - 1;
|
||||
if (!isNaN(line)) {
|
||||
return editor.revealRange(
|
||||
new vscode.Range(line, 0, line, 0),
|
||||
vscode.TextEditorRevealType.AtTop);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -137,8 +137,9 @@ export class MarkdownEngine {
|
||||
md.normalizeLink = (link: string) => {
|
||||
try {
|
||||
let uri = vscode.Uri.parse(link);
|
||||
if (!uri.scheme && uri.path && !uri.fragment) {
|
||||
if (!uri.scheme && uri.path) {
|
||||
// Assume it must be a file
|
||||
const fragment = uri.fragment;
|
||||
if (uri.path[0] === '/') {
|
||||
const root = vscode.workspace.getWorkspaceFolder(this.currentDocument);
|
||||
if (root) {
|
||||
@@ -147,6 +148,10 @@ export class MarkdownEngine {
|
||||
} else {
|
||||
uri = vscode.Uri.file(path.join(path.dirname(this.currentDocument.path), uri.path));
|
||||
}
|
||||
|
||||
if (fragment) {
|
||||
uri = uri.with({ fragment });
|
||||
}
|
||||
return normalizeLink(uri.toString(true));
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -155,14 +155,14 @@ util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
||||
vscode-extension-telemetry@0.0.8:
|
||||
vscode-extension-telemetry@^0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz#2261bff986b6690a6f1f746a45ac5bd1f85d29e0"
|
||||
dependencies:
|
||||
applicationinsights "0.18.0"
|
||||
winreg "1.2.3"
|
||||
|
||||
vscode-nls@2.0.2:
|
||||
vscode-nls@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
|
||||
|
||||
|
||||
+53
-43
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-debug",
|
||||
"version": "1.19.2",
|
||||
"version": "1.19.7",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -42,21 +42,21 @@
|
||||
}
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "2.2.42",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.42.tgz",
|
||||
"integrity": "sha512-b6gVDoxEbAQGwbV7gSzeFw/hy3/eEAokztktdzl4bHvGgb9K5zW4mVQDlVYch2w31m8t/J7L2iqhQvz3r5edCQ==",
|
||||
"version": "2.2.44",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz",
|
||||
"integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "6.0.52",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.52.tgz",
|
||||
"integrity": "sha1-GsOpm0IyD55GNILyWvTCNZRzqqY=",
|
||||
"version": "7.0.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz",
|
||||
"integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/source-map": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/source-map/-/source-map-0.5.1.tgz",
|
||||
"integrity": "sha512-/GVAjL1Y8puvZab63n8tsuBiYwZt1bApMdx58/msQ9ID5T05ov+wm/ZV1DvYC/DKKEygpTJViqQvkh5Rhrl4CA==",
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/source-map/-/source-map-0.5.2.tgz",
|
||||
"integrity": "sha512-++w4WmMbk3dS3UeHGzAG+xJOSz5Xqtjys/TBkqG3qp3SeWE7Wwezqe5eB7B51cxUyh4PW7bwVotpsLdBK0D8cw==",
|
||||
"dev": true
|
||||
},
|
||||
"abbrev": {
|
||||
@@ -4755,9 +4755,9 @@
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
|
||||
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.5.0.tgz",
|
||||
"integrity": "sha512-v/jMDoK/qKptnTuC3YUNbIj8uUYvTCIHzVu9BHldKSWja48wusAtfjlcBlqnFrqClu3yf69ScDxBPrIyFnF51g==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-db": {
|
||||
@@ -5149,13 +5149,30 @@
|
||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
||||
"dev": true
|
||||
},
|
||||
"parse-semver": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
|
||||
"integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "5.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
|
||||
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"parse5": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
|
||||
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "6.0.52"
|
||||
"@types/node": "7.0.43"
|
||||
}
|
||||
},
|
||||
"path-dirname": {
|
||||
@@ -6671,9 +6688,9 @@
|
||||
}
|
||||
},
|
||||
"vsce": {
|
||||
"version": "1.32.0",
|
||||
"resolved": "https://registry.npmjs.org/vsce/-/vsce-1.32.0.tgz",
|
||||
"integrity": "sha1-EN+pIyGCwg6r5r8xJdMzpLIG/j0=",
|
||||
"version": "1.33.2",
|
||||
"resolved": "https://registry.npmjs.org/vsce/-/vsce-1.33.2.tgz",
|
||||
"integrity": "sha1-NkX2mq+YTiL3TqSdNfON0Y1m/18=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cheerio": "1.0.0-rc.2",
|
||||
@@ -6682,9 +6699,10 @@
|
||||
"glob": "7.1.2",
|
||||
"lodash": "4.17.4",
|
||||
"markdown-it": "8.4.0",
|
||||
"mime": "1.4.1",
|
||||
"mime": "1.5.0",
|
||||
"minimatch": "3.0.4",
|
||||
"osenv": "0.1.4",
|
||||
"parse-semver": "1.1.1",
|
||||
"read": "1.0.7",
|
||||
"semver": "5.4.1",
|
||||
"tmp": "0.0.29",
|
||||
@@ -6709,9 +6727,9 @@
|
||||
}
|
||||
},
|
||||
"vscode": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.6.tgz",
|
||||
"integrity": "sha1-Ru0a+iwbnWifY5TI8WvR1xkPdfs=",
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.8.tgz",
|
||||
"integrity": "sha512-kT6sIA1AEKR5M+us2fXk5dxwV9SR/IEdLHNmVW4/dl1wNBHoEvgIo1qMQwHNxPVTQmw70KTGZ9UVeVb8FbpNFA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "7.1.2",
|
||||
@@ -6739,34 +6757,26 @@
|
||||
}
|
||||
},
|
||||
"vscode-debugadapter": {
|
||||
"version": "1.25.0-pre.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.25.0-pre.0.tgz",
|
||||
"integrity": "sha1-0pDsVH5h5Pvss2P/9ojSAyMZQmQ=",
|
||||
"version": "1.25.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.25.0.tgz",
|
||||
"integrity": "sha512-tsOtNNKKTbnQanARdkFfUxI8qKVKba+QHOKWC1reDDeeyvzoNKkLMGkL/xsiKn5vQDeaP3zFBcLY8Ysak9GrvQ==",
|
||||
"requires": {
|
||||
"vscode-debugprotocol": "1.25.0-pre.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-debugprotocol": {
|
||||
"version": "1.25.0-pre.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.25.0-pre.0.tgz",
|
||||
"integrity": "sha1-rYPnvZWxmseV31D6Di/pA0YqcrY="
|
||||
}
|
||||
"vscode-debugprotocol": "1.25.0"
|
||||
}
|
||||
},
|
||||
"vscode-debugadapter-testsupport": {
|
||||
"version": "1.24.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugadapter-testsupport/-/vscode-debugadapter-testsupport-1.24.0.tgz",
|
||||
"integrity": "sha1-rDZ1scU/wW+1JMvSt+znEhtiXng=",
|
||||
"version": "1.25.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugadapter-testsupport/-/vscode-debugadapter-testsupport-1.25.0.tgz",
|
||||
"integrity": "sha512-6E2N7CoH7B0KEDvI9mFVFt4H+dRFDhtj3PmLVjNojfZ1VZZS2yfhE0XO0E5Axdhef3zTpUU6WZoeOOMVFGZGIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"vscode-debugprotocol": "1.24.0"
|
||||
"vscode-debugprotocol": "1.25.0"
|
||||
}
|
||||
},
|
||||
"vscode-debugprotocol": {
|
||||
"version": "1.24.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.24.0.tgz",
|
||||
"integrity": "sha1-28EOjX2VsQJyehmvPw/O9+JSsI4=",
|
||||
"dev": true
|
||||
"version": "1.25.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.25.0.tgz",
|
||||
"integrity": "sha512-e1EUy/5npqa0NlAwRCUu8A9LnVRf6tkwiPQcCLyUFCC9o2GxcAqH5Va4mqXDoxQ58ar3zODivKQeRb3z1KH7WA=="
|
||||
},
|
||||
"vscode-nls": {
|
||||
"version": "2.0.2",
|
||||
@@ -6774,9 +6784,9 @@
|
||||
"integrity": "sha1-gIUiOAhEuK0VNJmvXDsDkhrqAto="
|
||||
},
|
||||
"vscode-nls-dev": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls-dev/-/vscode-nls-dev-2.1.5.tgz",
|
||||
"integrity": "sha1-GfqjsYp/MCIBA5pMlnu9IvoShE0=",
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls-dev/-/vscode-nls-dev-2.1.6.tgz",
|
||||
"integrity": "sha512-1IylC/ekENYqz1vEItfrzrMXS8LW9aZQnNTU6BfdwT0Jddzed+l+nvU8amgVKFFmC1/GoiMFk5wtC20zWBbEbw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clone": "1.0.3",
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": "4.3.6",
|
||||
"vscode-extension-telemetry": "0.0.8",
|
||||
"vscode-nls": "2.0.1"
|
||||
"vscode-extension-telemetry": "^0.0.8",
|
||||
"vscode-nls": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "8.0.33",
|
||||
|
||||
@@ -399,8 +399,13 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
||||
}
|
||||
|
||||
private snippetForFunctionCall(detail: CompletionEntryDetails): SnippetString {
|
||||
const suggestionArgumentNames: string[] = [];
|
||||
let hasOptionalParemeters = false;
|
||||
let hasOptionalParameters = false;
|
||||
let hasAddedParameters = false;
|
||||
|
||||
const snippet = new SnippetString();
|
||||
snippet.appendText(detail.name);
|
||||
snippet.appendText('(');
|
||||
|
||||
let parenCount = 0;
|
||||
let i = 0;
|
||||
for (; i < detail.displayParts.length; ++i) {
|
||||
@@ -411,9 +416,13 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
||||
// Skip optional parameters
|
||||
const nameIsFollowedByOptionalIndicator = next && next.text === '?';
|
||||
if (!nameIsFollowedByOptionalIndicator) {
|
||||
suggestionArgumentNames.push(`\${${i + 1}:${part.text}}`);
|
||||
if (hasAddedParameters) {
|
||||
snippet.appendText(', ');
|
||||
}
|
||||
hasAddedParameters = true;
|
||||
snippet.appendPlaceholder(part.text);
|
||||
}
|
||||
hasOptionalParemeters = hasOptionalParemeters || nameIsFollowedByOptionalIndicator;
|
||||
hasOptionalParameters = hasOptionalParameters || nameIsFollowedByOptionalIndicator;
|
||||
} else if (part.kind === 'punctuation') {
|
||||
if (part.text === '(') {
|
||||
++parenCount;
|
||||
@@ -421,13 +430,17 @@ export default class TypeScriptCompletionItemProvider implements CompletionItemP
|
||||
--parenCount;
|
||||
} else if (part.text === '...' && parenCount === 1) {
|
||||
// Found rest parmeter. Do not fill in any further arguments
|
||||
hasOptionalParemeters = true;
|
||||
hasOptionalParameters = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const codeSnippet = `${detail.name}(${suggestionArgumentNames.join(', ')}${hasOptionalParemeters ? '${' + i + '}' : ''})$0`;
|
||||
return new SnippetString(codeSnippet);
|
||||
if (hasOptionalParameters) {
|
||||
snippet.appendTabstop();
|
||||
}
|
||||
snippet.appendText(')');
|
||||
snippet.appendTabstop(0);
|
||||
return snippet;
|
||||
}
|
||||
|
||||
private getConfiguration(resource: Uri): Configuration {
|
||||
|
||||
@@ -27,6 +27,7 @@ import { TypeScriptServiceConfiguration, TsServerLogLevel } from './utils/config
|
||||
import { TypeScriptVersionProvider, TypeScriptVersion } from './utils/versionProvider';
|
||||
import { TypeScriptVersionPicker } from './utils/versionPicker';
|
||||
import * as fileSchemes from './utils/fileSchemes';
|
||||
import { inferredProjectConfig } from './utils/tsconfig';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -330,11 +331,9 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
||||
this.error('Starting TSServer failed with error.', err);
|
||||
window.showErrorMessage(localize('serverCouldNotBeStarted', 'TypeScript language server couldn\'t be started. Error message is: {0}', err.message || err));
|
||||
/* __GDPR__
|
||||
"error" : {
|
||||
"message": { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" }
|
||||
}
|
||||
"error" : {}
|
||||
*/
|
||||
this.logTelemetry('error', { message: err.message });
|
||||
this.logTelemetry('error');
|
||||
this.resetClientVersion();
|
||||
return;
|
||||
}
|
||||
@@ -476,20 +475,12 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
||||
}
|
||||
|
||||
private getCompilerOptionsForInferredProjects(configuration: TypeScriptServiceConfiguration): Proto.ExternalProjectCompilerOptions {
|
||||
const compilerOptions: Proto.ExternalProjectCompilerOptions = {
|
||||
module: 'CommonJS' as Proto.ModuleKind,
|
||||
target: 'ES6' as Proto.ScriptTarget,
|
||||
return {
|
||||
...inferredProjectConfig(configuration),
|
||||
allowJs: true,
|
||||
allowSyntheticDefaultImports: true,
|
||||
allowNonTsExtensions: true,
|
||||
allowJs: true,
|
||||
jsx: 'Preserve' as Proto.JsxEmit
|
||||
};
|
||||
|
||||
if (this.apiVersion.has230Features()) {
|
||||
compilerOptions.checkJs = configuration.checkJs;
|
||||
compilerOptions.experimentalDecorators = configuration.experimentalDecorators;
|
||||
}
|
||||
return compilerOptions;
|
||||
}
|
||||
|
||||
private serviceExited(restart: boolean): void {
|
||||
|
||||
@@ -5,27 +5,39 @@
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import * as Proto from '../protocol';
|
||||
|
||||
import { TypeScriptServiceConfiguration } from './configuration';
|
||||
|
||||
export function isImplicitProjectConfigFile(configFileName: string) {
|
||||
return configFileName.indexOf('/dev/null/') === 0;
|
||||
}
|
||||
|
||||
function getEmptyConfig(
|
||||
isTypeScriptProject: boolean,
|
||||
export function inferredProjectConfig(
|
||||
config: TypeScriptServiceConfiguration
|
||||
): Proto.ExternalProjectCompilerOptions {
|
||||
const base: Proto.ExternalProjectCompilerOptions = {
|
||||
module: 'commonjs' as Proto.ModuleKind,
|
||||
target: 'es2016' as Proto.ScriptTarget,
|
||||
jsx: 'preserve' as Proto.JsxEmit
|
||||
};
|
||||
|
||||
if (config.checkJs) {
|
||||
base.checkJs = true;
|
||||
}
|
||||
|
||||
if (config.experimentalDecorators) {
|
||||
base.experimentalDecorators = true;
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
function inferredProjectConfigSnippet(
|
||||
config: TypeScriptServiceConfiguration
|
||||
) {
|
||||
const compilerOptions = [
|
||||
'"target": "ES6"',
|
||||
'"module": "commonjs"',
|
||||
'"jsx": "preserve"',
|
||||
];
|
||||
if (!isTypeScriptProject && config.checkJs) {
|
||||
compilerOptions.push('"checkJs": true');
|
||||
}
|
||||
if (!isTypeScriptProject && config.experimentalDecorators) {
|
||||
compilerOptions.push('"experimentalDecorators": true');
|
||||
}
|
||||
const baseConfig = inferredProjectConfig(config);
|
||||
const compilerOptions = Object.keys(baseConfig).map(key => `"${key}": ${JSON.stringify(baseConfig[key])}`);
|
||||
return new vscode.SnippetString(`{
|
||||
"compilerOptions": {
|
||||
${compilerOptions.join(',\n\t\t')}$0
|
||||
@@ -51,7 +63,7 @@ export async function openOrCreateConfigFile(
|
||||
const doc = await vscode.workspace.openTextDocument(configFile.with({ scheme: 'untitled' }));
|
||||
const editor = await vscode.window.showTextDocument(doc, col);
|
||||
if (editor.document.getText().length === 0) {
|
||||
await editor.insertSnippet(getEmptyConfig(isTypeScriptProject, config));
|
||||
await editor.insertSnippet(inferredProjectConfigSnippet(config));
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
@@ -18,16 +18,16 @@ semver@4.3.6:
|
||||
version "4.3.6"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
|
||||
|
||||
vscode-extension-telemetry@0.0.8:
|
||||
vscode-extension-telemetry@^0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz#2261bff986b6690a6f1f746a45ac5bd1f85d29e0"
|
||||
dependencies:
|
||||
applicationinsights "0.18.0"
|
||||
winreg "1.2.3"
|
||||
|
||||
vscode-nls@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.1.tgz#7853866e33f9c50ca415e51b9640d081800e36c6"
|
||||
vscode-nls@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
|
||||
|
||||
winreg@1.2.3:
|
||||
version "1.2.3"
|
||||
|
||||
@@ -10,14 +10,21 @@ set VSCODEUSERDATADIR=%TMP%\vscodeuserfolder-%RANDOM%-%TIME:~6,5%
|
||||
|
||||
:: Tests in the extension host
|
||||
call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testWorkspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out --disableExtensions --user-data-dir=%VSCODEUSERDATADIR%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
call .\scripts\code.bat %~dp0\..\extensions\vscode-colorize-tests\test --extensionDevelopmentPath=%~dp0\..\extensions\vscode-colorize-tests --extensionTestsPath=%~dp0\..\extensions\vscode-colorize-tests\out --disableExtensions --user-data-dir=%VSCODEUSERDATADIR%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
call .\scripts\code.bat $%~dp0\..\extensions\emmet\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test --disableExtensions --user-data-dir=%VSCODEUSERDATADIR%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
:: Integration & performance tests in AMD
|
||||
call .\scripts\test.bat --runGlob **\*.integrationTest.js %*
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
:: Tests in commonJS (language servers tests...)
|
||||
call .\scripts\node-electron.bat .\node_modules\mocha\bin\_mocha .\extensions\html\server\out\test\
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
rmdir /s /q %VSCODEUSERDATADIR%
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ function formatEnvironment(info: IMainProcessInfo): string {
|
||||
|
||||
const output: string[] = [];
|
||||
output.push(`Version: ${pkg.name} ${pkg.version} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})`);
|
||||
output.push(`OS Version: ${os.type()} ${os.arch()} ${os.release()})`);
|
||||
output.push(`OS Version: ${os.type()} ${os.arch()} ${os.release()}`);
|
||||
const cpus = os.cpus();
|
||||
if (cpus && cpus.length > 0) {
|
||||
output.push(`CPUs: ${cpus[0].model} (${cpus.length} x ${cpus[0].speed})`);
|
||||
|
||||
@@ -472,8 +472,8 @@ export class View extends ViewEventHandler {
|
||||
return this.outgoingEvents;
|
||||
}
|
||||
|
||||
public createOverviewRuler(cssClassName: string, minimumHeight: number, maximumHeight: number): OverviewRuler {
|
||||
return new OverviewRuler(this._context, cssClassName, minimumHeight, maximumHeight);
|
||||
public createOverviewRuler(cssClassName: string): OverviewRuler {
|
||||
return new OverviewRuler(this._context, cssClassName);
|
||||
}
|
||||
|
||||
public change(callback: (changeAccessor: editorBrowser.IViewZoneChangeAccessor) => any): boolean {
|
||||
|
||||
@@ -11,38 +11,23 @@ import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { OverviewRulerPosition } from 'vs/editor/common/config/editorOptions';
|
||||
import { OverviewRulerZone, OverviewZoneManager, ColorZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
import { OverviewRulerLane } from 'vs/editor/common/editorCommon';
|
||||
|
||||
export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
|
||||
private _context: ViewContext;
|
||||
private _canvasLeftOffset: number;
|
||||
private _domNode: FastDomNode<HTMLCanvasElement>;
|
||||
private _lanesCount: number;
|
||||
private _zoneManager: OverviewZoneManager;
|
||||
private _background: Color;
|
||||
|
||||
constructor(context: ViewContext, cssClassName: string, minimumHeight: number, maximumHeight: number) {
|
||||
constructor(context: ViewContext, cssClassName: string) {
|
||||
super();
|
||||
this._context = context;
|
||||
|
||||
this._canvasLeftOffset = 0;
|
||||
|
||||
this._domNode = createFastDomNode(document.createElement('canvas'));
|
||||
this._domNode.setClassName(cssClassName);
|
||||
this._domNode.setPosition('absolute');
|
||||
this._domNode.setLayerHinting(true);
|
||||
|
||||
this._lanesCount = 3;
|
||||
|
||||
this._background = null;
|
||||
|
||||
this._zoneManager = new OverviewZoneManager((lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber));
|
||||
this._zoneManager.setMinimumHeight(minimumHeight);
|
||||
this._zoneManager.setMaximumHeight(maximumHeight);
|
||||
this._zoneManager.setThemeType(LIGHT);
|
||||
this._zoneManager.setDOMWidth(0);
|
||||
this._zoneManager.setDOMHeight(0);
|
||||
this._zoneManager.setOuterHeight(this._context.viewLayout.getScrollHeight());
|
||||
@@ -64,7 +49,7 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
|
||||
if (e.lineHeight) {
|
||||
this._zoneManager.setLineHeight(this._context.configuration.editor.lineHeight);
|
||||
this.render(true);
|
||||
this._render();
|
||||
}
|
||||
|
||||
if (e.pixelRatio) {
|
||||
@@ -73,23 +58,24 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
this._domNode.setHeight(this._zoneManager.getDOMHeight());
|
||||
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
|
||||
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
|
||||
this.render(true);
|
||||
this._render();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
|
||||
this._render();
|
||||
return true;
|
||||
}
|
||||
|
||||
public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
|
||||
this._zoneManager.setOuterHeight(e.scrollHeight);
|
||||
this.render(true);
|
||||
return super.onScrollChanged(e) || e.scrollHeightChanged;
|
||||
if (e.scrollHeightChanged) {
|
||||
this._zoneManager.setOuterHeight(e.scrollHeight);
|
||||
this._render();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean {
|
||||
this._render();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -113,16 +99,16 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
this._domNode.domNode.width = this._zoneManager.getCanvasWidth();
|
||||
this._domNode.domNode.height = this._zoneManager.getCanvasHeight();
|
||||
|
||||
this.render(true);
|
||||
this._render();
|
||||
}
|
||||
}
|
||||
|
||||
public setZones(zones: OverviewRulerZone[]): void {
|
||||
this._zoneManager.setZones(zones);
|
||||
this.render(false);
|
||||
this._render();
|
||||
}
|
||||
|
||||
public render(forceRender: boolean): boolean {
|
||||
private _render(): boolean {
|
||||
if (this._zoneManager.getOuterHeight() === 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -134,79 +120,29 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
let id2Color = this._zoneManager.getId2Color();
|
||||
|
||||
let ctx = this._domNode.domNode.getContext('2d');
|
||||
if (this._background === null) {
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
} else {
|
||||
ctx.fillStyle = Color.Format.CSS.formatHex(this._background);
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
}
|
||||
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
if (colorZones.length > 0) {
|
||||
let remainingWidth = width - this._canvasLeftOffset;
|
||||
|
||||
if (this._lanesCount >= 3) {
|
||||
this._renderThreeLanes(ctx, colorZones, id2Color, remainingWidth);
|
||||
} else if (this._lanesCount === 2) {
|
||||
this._renderTwoLanes(ctx, colorZones, id2Color, remainingWidth);
|
||||
} else if (this._lanesCount === 1) {
|
||||
this._renderOneLane(ctx, colorZones, id2Color, remainingWidth);
|
||||
}
|
||||
this._renderOneLane(ctx, colorZones, id2Color, width);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private _renderOneLane(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
|
||||
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left | OverviewRulerLane.Center | OverviewRulerLane.Right, this._canvasLeftOffset, w);
|
||||
|
||||
}
|
||||
|
||||
private _renderTwoLanes(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
|
||||
|
||||
let leftWidth = Math.floor(w / 2);
|
||||
let rightWidth = w - leftWidth;
|
||||
let leftOffset = this._canvasLeftOffset;
|
||||
let rightOffset = this._canvasLeftOffset + leftWidth;
|
||||
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left | OverviewRulerLane.Center, leftOffset, leftWidth);
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Right, rightOffset, rightWidth);
|
||||
}
|
||||
|
||||
private _renderThreeLanes(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], w: number): void {
|
||||
|
||||
let leftWidth = Math.floor(w / 3);
|
||||
let rightWidth = Math.floor(w / 3);
|
||||
let centerWidth = w - leftWidth - rightWidth;
|
||||
let leftOffset = this._canvasLeftOffset;
|
||||
let centerOffset = this._canvasLeftOffset + leftWidth;
|
||||
let rightOffset = this._canvasLeftOffset + leftWidth + centerWidth;
|
||||
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Left, leftOffset, leftWidth);
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Center, centerOffset, centerWidth);
|
||||
this._renderVerticalPatch(ctx, colorZones, id2Color, OverviewRulerLane.Right, rightOffset, rightWidth);
|
||||
}
|
||||
|
||||
private _renderVerticalPatch(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], laneMask: number, xpos: number, width: number): void {
|
||||
private _renderOneLane(ctx: CanvasRenderingContext2D, colorZones: ColorZone[], id2Color: string[], width: number): void {
|
||||
|
||||
let currentColorId = 0;
|
||||
let currentFrom = 0;
|
||||
let currentTo = 0;
|
||||
|
||||
for (let i = 0, len = colorZones.length; i < len; i++) {
|
||||
let zone = colorZones[i];
|
||||
const zone = colorZones[i];
|
||||
|
||||
if (!(zone.position & laneMask)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let zoneColorId = zone.colorId;
|
||||
let zoneFrom = zone.from;
|
||||
let zoneTo = zone.to;
|
||||
const zoneColorId = zone.colorId;
|
||||
const zoneFrom = zone.from;
|
||||
const zoneTo = zone.to;
|
||||
|
||||
if (zoneColorId !== currentColorId) {
|
||||
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
|
||||
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
|
||||
|
||||
currentColorId = zoneColorId;
|
||||
ctx.fillStyle = id2Color[currentColorId];
|
||||
@@ -216,14 +152,14 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
|
||||
if (currentTo >= zoneFrom) {
|
||||
currentTo = Math.max(currentTo, zoneTo);
|
||||
} else {
|
||||
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
|
||||
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
|
||||
currentFrom = zoneFrom;
|
||||
currentTo = zoneTo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.fillRect(xpos, currentFrom, width, currentTo - currentFrom);
|
||||
ctx.fillRect(0, currentFrom, width, currentTo - currentFrom);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,8 +157,8 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public createOverviewRuler(cssClassName: string, minimumHeight: number, maximumHeight: number): editorBrowser.IOverviewRuler {
|
||||
return this._view.createOverviewRuler(cssClassName, minimumHeight, maximumHeight);
|
||||
public createOverviewRuler(cssClassName: string): editorBrowser.IOverviewRuler {
|
||||
return this._view.createOverviewRuler(cssClassName);
|
||||
}
|
||||
|
||||
public getDomNode(): HTMLElement {
|
||||
|
||||
@@ -361,14 +361,14 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode());
|
||||
this._originalOverviewRuler.dispose();
|
||||
}
|
||||
this._originalOverviewRuler = this.originalEditor.createOverviewRuler('original diffOverviewRuler', 4, Number.MAX_VALUE);
|
||||
this._originalOverviewRuler = this.originalEditor.createOverviewRuler('original diffOverviewRuler');
|
||||
this._overviewDomElement.appendChild(this._originalOverviewRuler.getDomNode());
|
||||
|
||||
if (this._modifiedOverviewRuler) {
|
||||
this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode());
|
||||
this._modifiedOverviewRuler.dispose();
|
||||
}
|
||||
this._modifiedOverviewRuler = this.modifiedEditor.createOverviewRuler('modified diffOverviewRuler', 4, Number.MAX_VALUE);
|
||||
this._modifiedOverviewRuler = this.modifiedEditor.createOverviewRuler('modified diffOverviewRuler');
|
||||
this._overviewDomElement.appendChild(this._modifiedOverviewRuler.getDomNode());
|
||||
|
||||
this._layoutOverviewRulers();
|
||||
@@ -1594,6 +1594,7 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
}
|
||||
|
||||
_getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._removeColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
decorations: [],
|
||||
@@ -1614,16 +1615,10 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
result.decorations.push(createDecoration(lineChange.originalStartLineNumber, 1, lineChange.originalEndLineNumber, Number.MAX_VALUE, DECORATIONS.charDeleteWholeLine));
|
||||
}
|
||||
|
||||
let color = this._removeColor.toString();
|
||||
|
||||
result.overviewZones.push(new OverviewRulerZone(
|
||||
lineChange.originalStartLineNumber,
|
||||
lineChange.originalEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
overviewZoneColor
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
@@ -1659,6 +1654,7 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
}
|
||||
|
||||
_getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._insertColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
decorations: [],
|
||||
@@ -1679,15 +1675,10 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
if (!isChangeOrDelete(lineChange) || !lineChange.charChanges) {
|
||||
result.decorations.push(createDecoration(lineChange.modifiedStartLineNumber, 1, lineChange.modifiedEndLineNumber, Number.MAX_VALUE, DECORATIONS.charInsertWholeLine));
|
||||
}
|
||||
let color = this._insertColor.toString();
|
||||
result.overviewZones.push(new OverviewRulerZone(
|
||||
lineChange.modifiedStartLineNumber,
|
||||
lineChange.modifiedEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
overviewZoneColor
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
@@ -1783,6 +1774,8 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
}
|
||||
|
||||
_getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._removeColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
decorations: [],
|
||||
overviewZones: []
|
||||
@@ -1798,15 +1791,10 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
options: DECORATIONS.lineDeleteMargin
|
||||
});
|
||||
|
||||
let color = this._removeColor.toString();
|
||||
result.overviewZones.push(new OverviewRulerZone(
|
||||
lineChange.originalStartLineNumber,
|
||||
lineChange.originalEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
overviewZoneColor
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -1815,6 +1803,7 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
}
|
||||
|
||||
_getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._insertColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
decorations: [],
|
||||
@@ -1833,15 +1822,10 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
options: (renderIndicators ? DECORATIONS.lineInsertWithSign : DECORATIONS.lineInsert)
|
||||
});
|
||||
|
||||
let color = this._insertColor.toString();
|
||||
result.overviewZones.push(new OverviewRulerZone(
|
||||
lineChange.modifiedStartLineNumber,
|
||||
lineChange.modifiedEndLineNumber,
|
||||
editorCommon.OverviewRulerLane.Full,
|
||||
0,
|
||||
color,
|
||||
color,
|
||||
color
|
||||
overviewZoneColor
|
||||
));
|
||||
|
||||
if (lineChange.charChanges) {
|
||||
|
||||
@@ -4,22 +4,31 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { OverviewRulerLane } from 'vs/editor/common/editorCommon';
|
||||
import { ThemeType, DARK, HIGH_CONTRAST, LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
const enum Constants {
|
||||
MINIMUM_HEIGHT = 4
|
||||
}
|
||||
|
||||
export class ColorZone {
|
||||
_colorZoneBrand: void;
|
||||
|
||||
from: number;
|
||||
to: number;
|
||||
colorId: number;
|
||||
position: OverviewRulerLane;
|
||||
public readonly from: number;
|
||||
public readonly to: number;
|
||||
public readonly colorId: number;
|
||||
|
||||
constructor(from: number, to: number, colorId: number, position: OverviewRulerLane) {
|
||||
constructor(from: number, to: number, colorId: number) {
|
||||
this.from = from | 0;
|
||||
this.to = to | 0;
|
||||
this.colorId = colorId | 0;
|
||||
this.position = position | 0;
|
||||
}
|
||||
|
||||
public static compare(a: ColorZone, b: ColorZone): number {
|
||||
if (a.colorId === b.colorId) {
|
||||
if (a.from === b.from) {
|
||||
return a.to - b.to;
|
||||
}
|
||||
return a.from - b.from;
|
||||
}
|
||||
return a.colorId - b.colorId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,74 +38,39 @@ export class ColorZone {
|
||||
export class OverviewRulerZone {
|
||||
_overviewRulerZoneBrand: void;
|
||||
|
||||
startLineNumber: number;
|
||||
endLineNumber: number;
|
||||
position: OverviewRulerLane;
|
||||
forceHeight: number;
|
||||
public readonly startLineNumber: number;
|
||||
public readonly endLineNumber: number;
|
||||
public readonly color: string;
|
||||
|
||||
private _color: string;
|
||||
private _darkColor: string;
|
||||
private _hcColor: string;
|
||||
|
||||
private _colorZones: ColorZone[];
|
||||
private _colorZone: ColorZone;
|
||||
|
||||
constructor(
|
||||
startLineNumber: number, endLineNumber: number,
|
||||
position: OverviewRulerLane,
|
||||
forceHeight: number,
|
||||
color: string, darkColor: string, hcColor: string
|
||||
startLineNumber: number,
|
||||
endLineNumber: number,
|
||||
color: string
|
||||
) {
|
||||
this.startLineNumber = startLineNumber;
|
||||
this.endLineNumber = endLineNumber;
|
||||
this.position = position;
|
||||
this.forceHeight = forceHeight;
|
||||
this._color = color;
|
||||
this._darkColor = darkColor;
|
||||
this._hcColor = hcColor;
|
||||
this._colorZones = null;
|
||||
this.color = color;
|
||||
this._colorZone = null;
|
||||
}
|
||||
|
||||
public getColor(themeType: ThemeType): string {
|
||||
switch (themeType) {
|
||||
case HIGH_CONTRAST:
|
||||
return this._hcColor;
|
||||
case DARK:
|
||||
return this._darkColor;
|
||||
}
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public compareTo(other: OverviewRulerZone): number {
|
||||
if (this.startLineNumber === other.startLineNumber) {
|
||||
if (this.endLineNumber === other.endLineNumber) {
|
||||
if (this.forceHeight === other.forceHeight) {
|
||||
if (this.position === other.position) {
|
||||
if (this._darkColor === other._darkColor) {
|
||||
if (this._color === other._color) {
|
||||
if (this._hcColor === other._hcColor) {
|
||||
return 0;
|
||||
}
|
||||
return this._hcColor < other._hcColor ? -1 : 1;
|
||||
}
|
||||
return this._color < other._color ? -1 : 1;
|
||||
}
|
||||
return this._darkColor < other._darkColor ? -1 : 1;
|
||||
}
|
||||
return this.position - other.position;
|
||||
}
|
||||
return this.forceHeight - other.forceHeight;
|
||||
public static compare(a: OverviewRulerZone, b: OverviewRulerZone): number {
|
||||
if (a.color === b.color) {
|
||||
if (a.startLineNumber === b.startLineNumber) {
|
||||
return a.endLineNumber - b.endLineNumber;
|
||||
}
|
||||
return this.endLineNumber - other.endLineNumber;
|
||||
return a.startLineNumber - b.startLineNumber;
|
||||
}
|
||||
return this.startLineNumber - other.startLineNumber;
|
||||
return a.color < b.color ? -1 : 1;
|
||||
}
|
||||
|
||||
public setColorZones(colorZones: ColorZone[]): void {
|
||||
this._colorZones = colorZones;
|
||||
public setColorZone(colorZone: ColorZone): void {
|
||||
this._colorZone = colorZone;
|
||||
}
|
||||
|
||||
public getColorZones(): ColorZone[] {
|
||||
return this._colorZones;
|
||||
public getColorZones(): ColorZone {
|
||||
return this._colorZone;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,9 +83,6 @@ export class OverviewZoneManager {
|
||||
private _domWidth: number;
|
||||
private _domHeight: number;
|
||||
private _outerHeight: number;
|
||||
private _maximumHeight: number;
|
||||
private _minimumHeight: number;
|
||||
private _themeType: ThemeType;
|
||||
private _pixelRatio: number;
|
||||
|
||||
private _lastAssignedId: number;
|
||||
@@ -126,9 +97,6 @@ export class OverviewZoneManager {
|
||||
this._domWidth = 0;
|
||||
this._domHeight = 0;
|
||||
this._outerHeight = 0;
|
||||
this._maximumHeight = 0;
|
||||
this._minimumHeight = 0;
|
||||
this._themeType = LIGHT;
|
||||
this._pixelRatio = 1;
|
||||
|
||||
this._lastAssignedId = 0;
|
||||
@@ -141,39 +109,8 @@ export class OverviewZoneManager {
|
||||
}
|
||||
|
||||
public setZones(newZones: OverviewRulerZone[]): void {
|
||||
newZones.sort((a, b) => a.compareTo(b));
|
||||
|
||||
let oldZones = this._zones;
|
||||
let oldIndex = 0;
|
||||
let oldLength = this._zones.length;
|
||||
let newIndex = 0;
|
||||
let newLength = newZones.length;
|
||||
|
||||
let result: OverviewRulerZone[] = [];
|
||||
while (newIndex < newLength) {
|
||||
let newZone = newZones[newIndex];
|
||||
|
||||
if (oldIndex >= oldLength) {
|
||||
result.push(newZone);
|
||||
newIndex++;
|
||||
} else {
|
||||
let oldZone = oldZones[oldIndex];
|
||||
let cmp = oldZone.compareTo(newZone);
|
||||
if (cmp < 0) {
|
||||
oldIndex++;
|
||||
} else if (cmp > 0) {
|
||||
result.push(newZone);
|
||||
newIndex++;
|
||||
} else {
|
||||
// cmp === 0
|
||||
result.push(oldZone);
|
||||
oldIndex++;
|
||||
newIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._zones = result;
|
||||
this._zones = newZones;
|
||||
this._zones.sort(OverviewRulerZone.compare);
|
||||
}
|
||||
|
||||
public setLineHeight(lineHeight: number): boolean {
|
||||
@@ -237,146 +174,58 @@ export class OverviewZoneManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
public setMaximumHeight(maximumHeight: number): boolean {
|
||||
if (this._maximumHeight === maximumHeight) {
|
||||
return false;
|
||||
}
|
||||
this._maximumHeight = maximumHeight;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public setMinimumHeight(minimumHeight: number): boolean {
|
||||
if (this._minimumHeight === minimumHeight) {
|
||||
return false;
|
||||
}
|
||||
this._minimumHeight = minimumHeight;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public setThemeType(themeType: ThemeType): boolean {
|
||||
if (this._themeType === themeType) {
|
||||
return false;
|
||||
}
|
||||
this._themeType = themeType;
|
||||
this._colorZonesInvalid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public resolveColorZones(): ColorZone[] {
|
||||
const colorZonesInvalid = this._colorZonesInvalid;
|
||||
const lineHeight = Math.floor(this._lineHeight); // @perf
|
||||
const totalHeight = Math.floor(this.getCanvasHeight()); // @perf
|
||||
const maximumHeight = Math.floor(this._maximumHeight * this._pixelRatio); // @perf
|
||||
const minimumHeight = Math.floor(this._minimumHeight * this._pixelRatio); // @perf
|
||||
const themeType = this._themeType; // @perf
|
||||
const outerHeight = Math.floor(this._outerHeight); // @perf
|
||||
const heightRatio = totalHeight / outerHeight;
|
||||
|
||||
let allColorZones: ColorZone[] = [];
|
||||
for (let i = 0, len = this._zones.length; i < len; i++) {
|
||||
let zone = this._zones[i];
|
||||
const zone = this._zones[i];
|
||||
|
||||
if (!colorZonesInvalid) {
|
||||
let colorZones = zone.getColorZones();
|
||||
if (colorZones) {
|
||||
for (let j = 0, lenJ = colorZones.length; j < lenJ; j++) {
|
||||
allColorZones.push(colorZones[j]);
|
||||
}
|
||||
const colorZone = zone.getColorZones();
|
||||
if (colorZone) {
|
||||
allColorZones.push(colorZone);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let colorZones: ColorZone[] = [];
|
||||
if (zone.forceHeight) {
|
||||
let forcedHeight = Math.floor(zone.forceHeight * this._pixelRatio);
|
||||
const y1 = Math.floor(heightRatio * (this._getVerticalOffsetForLine(zone.startLineNumber)));
|
||||
const y2 = Math.floor(heightRatio * (this._getVerticalOffsetForLine(zone.endLineNumber) + lineHeight));
|
||||
|
||||
let y1 = Math.floor(this._getVerticalOffsetForLine(zone.startLineNumber));
|
||||
y1 = Math.floor(y1 * heightRatio);
|
||||
let ycenter = Math.floor((y1 + y2) / 2);
|
||||
let halfHeight = (y2 - ycenter);
|
||||
|
||||
let y2 = y1 + forcedHeight;
|
||||
colorZones.push(this.createZone(totalHeight, y1, y2, forcedHeight, forcedHeight, zone.getColor(themeType), zone.position));
|
||||
} else {
|
||||
let y1 = Math.floor(this._getVerticalOffsetForLine(zone.startLineNumber));
|
||||
let y2 = Math.floor(this._getVerticalOffsetForLine(zone.endLineNumber)) + lineHeight;
|
||||
|
||||
y1 = Math.floor(y1 * heightRatio);
|
||||
y2 = Math.floor(y2 * heightRatio);
|
||||
|
||||
// Figure out if we can render this in one continuous zone
|
||||
let zoneLineNumbers = zone.endLineNumber - zone.startLineNumber + 1;
|
||||
let zoneMaximumHeight = zoneLineNumbers * maximumHeight;
|
||||
|
||||
if (y2 - y1 > zoneMaximumHeight) {
|
||||
// We need to draw one zone per line
|
||||
for (let lineNumber = zone.startLineNumber; lineNumber <= zone.endLineNumber; lineNumber++) {
|
||||
y1 = Math.floor(this._getVerticalOffsetForLine(lineNumber));
|
||||
y2 = y1 + lineHeight;
|
||||
|
||||
y1 = Math.floor(y1 * heightRatio);
|
||||
y2 = Math.floor(y2 * heightRatio);
|
||||
|
||||
colorZones.push(this.createZone(totalHeight, y1, y2, minimumHeight, maximumHeight, zone.getColor(themeType), zone.position));
|
||||
}
|
||||
} else {
|
||||
colorZones.push(this.createZone(totalHeight, y1, y2, minimumHeight, zoneMaximumHeight, zone.getColor(themeType), zone.position));
|
||||
}
|
||||
if (halfHeight < Constants.MINIMUM_HEIGHT / 2) {
|
||||
halfHeight = Constants.MINIMUM_HEIGHT / 2;
|
||||
}
|
||||
|
||||
zone.setColorZones(colorZones);
|
||||
for (let j = 0, lenJ = colorZones.length; j < lenJ; j++) {
|
||||
allColorZones.push(colorZones[j]);
|
||||
if (ycenter - halfHeight < 0) {
|
||||
ycenter = halfHeight;
|
||||
}
|
||||
if (ycenter + halfHeight > totalHeight) {
|
||||
ycenter = totalHeight - halfHeight;
|
||||
}
|
||||
|
||||
const color = zone.color;
|
||||
let colorId = this._color2Id[color];
|
||||
if (!colorId) {
|
||||
colorId = (++this._lastAssignedId);
|
||||
this._color2Id[color] = colorId;
|
||||
this._id2Color[colorId] = color;
|
||||
}
|
||||
const colorZone = new ColorZone(ycenter - halfHeight, ycenter + halfHeight, colorId);
|
||||
|
||||
zone.setColorZone(colorZone);
|
||||
allColorZones.push(colorZone);
|
||||
}
|
||||
|
||||
this._colorZonesInvalid = false;
|
||||
|
||||
let sortFunc = (a: ColorZone, b: ColorZone) => {
|
||||
if (a.colorId === b.colorId) {
|
||||
if (a.from === b.from) {
|
||||
return a.to - b.to;
|
||||
}
|
||||
return a.from - b.from;
|
||||
}
|
||||
return a.colorId - b.colorId;
|
||||
};
|
||||
|
||||
allColorZones.sort(sortFunc);
|
||||
allColorZones.sort(ColorZone.compare);
|
||||
return allColorZones;
|
||||
}
|
||||
|
||||
public createZone(totalHeight: number, y1: number, y2: number, minimumHeight: number, maximumHeight: number, color: string, position: OverviewRulerLane): ColorZone {
|
||||
totalHeight = Math.floor(totalHeight); // @perf
|
||||
y1 = Math.floor(y1); // @perf
|
||||
y2 = Math.floor(y2); // @perf
|
||||
minimumHeight = Math.floor(minimumHeight); // @perf
|
||||
maximumHeight = Math.floor(maximumHeight); // @perf
|
||||
|
||||
let ycenter = Math.floor((y1 + y2) / 2);
|
||||
let halfHeight = (y2 - ycenter);
|
||||
|
||||
|
||||
if (halfHeight > maximumHeight / 2) {
|
||||
halfHeight = maximumHeight / 2;
|
||||
}
|
||||
if (halfHeight < minimumHeight / 2) {
|
||||
halfHeight = minimumHeight / 2;
|
||||
}
|
||||
|
||||
if (ycenter - halfHeight < 0) {
|
||||
ycenter = halfHeight;
|
||||
}
|
||||
if (ycenter + halfHeight > totalHeight) {
|
||||
ycenter = totalHeight - halfHeight;
|
||||
}
|
||||
|
||||
let colorId = this._color2Id[color];
|
||||
if (!colorId) {
|
||||
colorId = (++this._lastAssignedId);
|
||||
this._color2Id[color] = colorId;
|
||||
this._id2Color[colorId] = color;
|
||||
}
|
||||
return new ColorZone(ycenter - halfHeight, ycenter + halfHeight, colorId, position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { OverviewRulerLane } from 'vs/editor/common/editorCommon';
|
||||
import { OverviewZoneManager, ColorZone, OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
suite('Editor View - OverviewZoneManager', () => {
|
||||
|
||||
@@ -15,9 +13,6 @@ suite('Editor View - OverviewZoneManager', () => {
|
||||
const LINE_COUNT = 50;
|
||||
const LINE_HEIGHT = 20;
|
||||
let manager = new OverviewZoneManager((lineNumber) => LINE_HEIGHT * lineNumber);
|
||||
manager.setMinimumHeight(6);
|
||||
manager.setMaximumHeight(6);
|
||||
manager.setThemeType(LIGHT);
|
||||
manager.setDOMWidth(30);
|
||||
manager.setDOMHeight(600);
|
||||
manager.setOuterHeight(LINE_COUNT * LINE_HEIGHT);
|
||||
@@ -25,19 +20,18 @@ suite('Editor View - OverviewZoneManager', () => {
|
||||
manager.setPixelRatio(1);
|
||||
|
||||
manager.setZones([
|
||||
new OverviewRulerZone(1, 1, OverviewRulerLane.Full, 10, '1', '1', '1'),
|
||||
new OverviewRulerZone(10, 10, OverviewRulerLane.Full, 0, '2', '2', '2'),
|
||||
new OverviewRulerZone(30, 31, OverviewRulerLane.Full, 0, '3', '3', '3'),
|
||||
new OverviewRulerZone(50, 50, OverviewRulerLane.Full, 0, '4', '4', '4'),
|
||||
new OverviewRulerZone(1, 1, '1'),
|
||||
new OverviewRulerZone(10, 10, '2'),
|
||||
new OverviewRulerZone(30, 31, '3'),
|
||||
new OverviewRulerZone(50, 50, '4'),
|
||||
]);
|
||||
|
||||
// one line = 12, but cap is at 6
|
||||
assert.deepEqual(manager.resolveColorZones(), [
|
||||
new ColorZone(12, 22, 1, OverviewRulerLane.Full), // forced height of 10
|
||||
new ColorZone(123, 129, 2, OverviewRulerLane.Full), // 120 -> 132
|
||||
new ColorZone(363, 369, 3, OverviewRulerLane.Full), // 360 -> 372 [360 -> 384]
|
||||
new ColorZone(375, 381, 3, OverviewRulerLane.Full), // 372 -> 384 [360 -> 384]
|
||||
new ColorZone(594, 600, 4, OverviewRulerLane.Full), // 588 -> 600
|
||||
new ColorZone(12, 24, 1), //
|
||||
new ColorZone(120, 132, 2), // 120 -> 132
|
||||
new ColorZone(360, 384, 3), // 360 -> 372 [360 -> 384]
|
||||
new ColorZone(588, 600, 4), // 588 -> 600
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -45,9 +39,6 @@ suite('Editor View - OverviewZoneManager', () => {
|
||||
const LINE_COUNT = 50;
|
||||
const LINE_HEIGHT = 20;
|
||||
let manager = new OverviewZoneManager((lineNumber) => LINE_HEIGHT * lineNumber);
|
||||
manager.setMinimumHeight(6);
|
||||
manager.setMaximumHeight(6);
|
||||
manager.setThemeType(LIGHT);
|
||||
manager.setDOMWidth(30);
|
||||
manager.setDOMHeight(300);
|
||||
manager.setOuterHeight(LINE_COUNT * LINE_HEIGHT);
|
||||
@@ -55,18 +46,18 @@ suite('Editor View - OverviewZoneManager', () => {
|
||||
manager.setPixelRatio(1);
|
||||
|
||||
manager.setZones([
|
||||
new OverviewRulerZone(1, 1, OverviewRulerLane.Full, 10, '1', '1', '1'),
|
||||
new OverviewRulerZone(10, 10, OverviewRulerLane.Full, 0, '2', '2', '2'),
|
||||
new OverviewRulerZone(30, 31, OverviewRulerLane.Full, 0, '3', '3', '3'),
|
||||
new OverviewRulerZone(50, 50, OverviewRulerLane.Full, 0, '4', '4', '4'),
|
||||
new OverviewRulerZone(1, 1, '1'),
|
||||
new OverviewRulerZone(10, 10, '2'),
|
||||
new OverviewRulerZone(30, 31, '3'),
|
||||
new OverviewRulerZone(50, 50, '4'),
|
||||
]);
|
||||
|
||||
// one line = 6, cap is at 6
|
||||
assert.deepEqual(manager.resolveColorZones(), [
|
||||
new ColorZone(6, 16, 1, OverviewRulerLane.Full), // forced height of 10
|
||||
new ColorZone(60, 66, 2, OverviewRulerLane.Full), // 60 -> 66
|
||||
new ColorZone(180, 192, 3, OverviewRulerLane.Full), // 180 -> 192
|
||||
new ColorZone(294, 300, 4, OverviewRulerLane.Full), // 294 -> 300
|
||||
new ColorZone(6, 12, 1), //
|
||||
new ColorZone(60, 66, 2), // 60 -> 66
|
||||
new ColorZone(180, 192, 3), // 180 -> 192
|
||||
new ColorZone(294, 300, 4), // 294 -> 300
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -74,9 +65,6 @@ suite('Editor View - OverviewZoneManager', () => {
|
||||
const LINE_COUNT = 50;
|
||||
const LINE_HEIGHT = 20;
|
||||
let manager = new OverviewZoneManager((lineNumber) => LINE_HEIGHT * lineNumber);
|
||||
manager.setMinimumHeight(6);
|
||||
manager.setMaximumHeight(6);
|
||||
manager.setThemeType(LIGHT);
|
||||
manager.setDOMWidth(30);
|
||||
manager.setDOMHeight(300);
|
||||
manager.setOuterHeight(LINE_COUNT * LINE_HEIGHT);
|
||||
@@ -84,18 +72,18 @@ suite('Editor View - OverviewZoneManager', () => {
|
||||
manager.setPixelRatio(2);
|
||||
|
||||
manager.setZones([
|
||||
new OverviewRulerZone(1, 1, OverviewRulerLane.Full, 10, '1', '1', '1'),
|
||||
new OverviewRulerZone(10, 10, OverviewRulerLane.Full, 0, '2', '2', '2'),
|
||||
new OverviewRulerZone(30, 31, OverviewRulerLane.Full, 0, '3', '3', '3'),
|
||||
new OverviewRulerZone(50, 50, OverviewRulerLane.Full, 0, '4', '4', '4'),
|
||||
new OverviewRulerZone(1, 1, '1'),
|
||||
new OverviewRulerZone(10, 10, '2'),
|
||||
new OverviewRulerZone(30, 31, '3'),
|
||||
new OverviewRulerZone(50, 50, '4'),
|
||||
]);
|
||||
|
||||
// one line = 6, cap is at 12
|
||||
assert.deepEqual(manager.resolveColorZones(), [
|
||||
new ColorZone(12, 32, 1, OverviewRulerLane.Full), // forced height of 10 => forced height of 20
|
||||
new ColorZone(120, 132, 2, OverviewRulerLane.Full), // 120 -> 132
|
||||
new ColorZone(360, 384, 3, OverviewRulerLane.Full), // 360 -> 384
|
||||
new ColorZone(588, 600, 4, OverviewRulerLane.Full), // 588 -> 600
|
||||
new ColorZone(12, 24, 1), //
|
||||
new ColorZone(120, 132, 2), // 120 -> 132
|
||||
new ColorZone(360, 384, 3), // 360 -> 384
|
||||
new ColorZone(588, 600, 4), // 588 -> 600
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Vendored
+5
@@ -5782,6 +5782,11 @@ declare module 'vscode' {
|
||||
* A string to show as place holder in the input box to guide the user.
|
||||
*/
|
||||
placeholder: string;
|
||||
|
||||
/**
|
||||
* The warning threshold for lines in the input box.
|
||||
*/
|
||||
lineWarningLength: number | undefined;
|
||||
}
|
||||
|
||||
interface QuickDiffProvider {
|
||||
|
||||
@@ -391,4 +391,14 @@ export class MainThreadSCM implements MainThreadSCMShape {
|
||||
|
||||
repository.input.placeholder = placeholder;
|
||||
}
|
||||
|
||||
$setLineWarningLength(sourceControlHandle: number, lineWarningLength: number): void {
|
||||
const repository = this._repositories[sourceControlHandle];
|
||||
|
||||
if (!repository) {
|
||||
return;
|
||||
}
|
||||
|
||||
repository.input.lineWarningLength = lineWarningLength;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,6 +410,7 @@ export interface MainThreadSCMShape extends IDisposable {
|
||||
|
||||
$setInputBoxValue(sourceControlHandle: number, value: string): void;
|
||||
$setInputBoxPlaceholder(sourceControlHandle: number, placeholder: string): void;
|
||||
$setLineWarningLength(sourceControlHandle: number, lineWarningLength: number): void;
|
||||
}
|
||||
|
||||
export type DebugSessionUUID = string;
|
||||
|
||||
@@ -110,7 +110,7 @@ function compareResourceStates(a: vscode.SourceControlResourceState, b: vscode.S
|
||||
return result;
|
||||
}
|
||||
|
||||
export class ExtHostSCMInputBox {
|
||||
export class ExtHostSCMInputBox implements vscode.SourceControlInputBox {
|
||||
|
||||
private _value: string = '';
|
||||
|
||||
@@ -140,6 +140,17 @@ export class ExtHostSCMInputBox {
|
||||
this._placeholder = placeholder;
|
||||
}
|
||||
|
||||
private _lineWarningLength: number | undefined;
|
||||
|
||||
get lineWarningLength(): number | undefined {
|
||||
return this._lineWarningLength;
|
||||
}
|
||||
|
||||
set lineWarningLength(lineWarningLength: number) {
|
||||
this._proxy.$setLineWarningLength(this._sourceControlHandle, lineWarningLength);
|
||||
this._lineWarningLength = lineWarningLength;
|
||||
}
|
||||
|
||||
constructor(private _proxy: MainThreadSCMShape, private _sourceControlHandle: number) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@@ -580,16 +580,22 @@ export class ViewsViewlet extends PanelViewlet {
|
||||
if (this.length > 1) {
|
||||
return false;
|
||||
}
|
||||
// Check in cache so that view do not jump. See #29609
|
||||
if (ViewLocation.getContributedViewLocation(this.location.id) && !this.areExtensionsReady) {
|
||||
|
||||
if (ViewLocation.getContributedViewLocation(this.location.id)) {
|
||||
let visibleViewsCount = 0;
|
||||
this.viewsStates.forEach((viewState, id) => {
|
||||
if (!viewState.isHidden) {
|
||||
visibleViewsCount++;
|
||||
}
|
||||
});
|
||||
if (this.areExtensionsReady) {
|
||||
visibleViewsCount = this.getViewDescriptorsFromRegistry().reduce((visibleViewsCount, v) => visibleViewsCount + (this.canBeVisible(v) ? 1 : 0), 0);
|
||||
} else {
|
||||
// Check in cache so that view do not jump. See #29609
|
||||
this.viewsStates.forEach((viewState, id) => {
|
||||
if (!viewState.isHidden) {
|
||||
visibleViewsCount++;
|
||||
}
|
||||
});
|
||||
}
|
||||
return visibleViewsCount === 1;
|
||||
}
|
||||
|
||||
return super.isSingleView();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,11 +46,12 @@
|
||||
if (!event || !event.view || !event.view.document) {
|
||||
return;
|
||||
}
|
||||
|
||||
var baseElement = event.view.document.getElementsByTagName('base')[0];
|
||||
/** @type {any} */
|
||||
var node = event.target;
|
||||
while (node) {
|
||||
if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) {
|
||||
var baseElement = event.view.document.getElementsByTagName('base')[0];
|
||||
if (node.getAttribute('href') === '#') {
|
||||
event.view.scrollTo(0, 0);
|
||||
} else if (node.hash && (node.getAttribute('href') === node.hash || (baseElement && node.href.indexOf(baseElement.href) >= 0))) {
|
||||
|
||||
@@ -196,6 +196,10 @@ export default class Webview {
|
||||
this._onDidClickLink.dispose();
|
||||
this._disposables = dispose(this._disposables);
|
||||
|
||||
if (this._contextKey) {
|
||||
this._contextKey.reset();
|
||||
}
|
||||
|
||||
if (this._webview.parentElement) {
|
||||
this._webview.parentElement.removeChild(this._webview);
|
||||
const findWidgetDomNode = this._webviewFindWidget.getDomNode();
|
||||
|
||||
@@ -74,5 +74,11 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
|
||||
default: 'all',
|
||||
description: localize('diffDecorations', "Controls diff decorations in the editor.")
|
||||
},
|
||||
'scm.inputCounter': {
|
||||
type: 'string',
|
||||
enum: ['always', 'warn', 'off'],
|
||||
default: 'warn',
|
||||
description: localize('inputCounter', "Controls when to display the input counter.")
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -8,7 +8,7 @@
|
||||
import 'vs/css!./media/scmViewlet';
|
||||
import { localize } from 'vs/nls';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import Event, { Emitter, chain, mapEvent } from 'vs/base/common/event';
|
||||
import Event, { Emitter, chain, mapEvent, anyEvent } from 'vs/base/common/event';
|
||||
import { domEvent, stop } from 'vs/base/browser/event';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
@@ -45,7 +45,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions';
|
||||
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { IMessage, InputBox, MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Command } from 'vs/editor/common/modes';
|
||||
@@ -56,6 +56,7 @@ import { format } from 'vs/base/common/strings';
|
||||
import { ISpliceable, ISequence, ISplice } from 'vs/base/common/sequence';
|
||||
import { firstIndex } from 'vs/base/common/arrays';
|
||||
import { WorkbenchList, IListService } from 'vs/platform/list/browser/listService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
// TODO@Joao
|
||||
// Need to subclass MenuItemActionItem in order to respect
|
||||
@@ -695,7 +696,8 @@ export class RepositoryPanel extends ViewletPanel {
|
||||
@IWorkbenchEditorService protected editorService: IWorkbenchEditorService,
|
||||
@IEditorGroupService protected editorGroupService: IEditorGroupService,
|
||||
@IContextKeyService protected contextKeyService: IContextKeyService,
|
||||
@IInstantiationService protected instantiationService: IInstantiationService
|
||||
@IInstantiationService protected instantiationService: IInstantiationService,
|
||||
@IConfigurationService protected configurationService: IConfigurationService
|
||||
) {
|
||||
super(repository.provider.label, {}, keybindingService, contextMenuService);
|
||||
this.menus = instantiationService.createInstance(SCMMenus, repository.provider);
|
||||
@@ -753,10 +755,63 @@ export class RepositoryPanel extends ViewletPanel {
|
||||
this.inputBox.setPlaceHolder(placeholder);
|
||||
};
|
||||
|
||||
this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, { flexibleHeight: true });
|
||||
const validation = (text: string): IMessage => {
|
||||
const setting = this.configurationService.getValue<'always' | 'warn' | 'off'>('scm.inputCounter');
|
||||
|
||||
if (setting === 'off') {
|
||||
return null;
|
||||
}
|
||||
|
||||
let position = this.inputBox.inputElement.selectionStart;
|
||||
let start = 0, end;
|
||||
let match: RegExpExecArray;
|
||||
const regex = /\r?\n/g;
|
||||
|
||||
while ((match = regex.exec(text)) && position > match.index) {
|
||||
start = match.index + match[0].length;
|
||||
}
|
||||
|
||||
end = match ? match.index : text.length;
|
||||
|
||||
const line = text.substring(start, end);
|
||||
|
||||
const lineWarningLength = this.repository.input.lineWarningLength;
|
||||
|
||||
if (lineWarningLength === undefined) {
|
||||
return {
|
||||
content: localize('commitMessageInfo', "{0} characters in current line", text.length),
|
||||
type: MessageType.INFO
|
||||
};
|
||||
}
|
||||
|
||||
if (line.length <= lineWarningLength) {
|
||||
if (setting !== 'always') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
content: localize('commitMessageCountdown', "{0} characters left in current line", lineWarningLength - line.length),
|
||||
type: MessageType.INFO
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
content: localize('commitMessageWarning', "{0} characters over {1} in current line", line.length - lineWarningLength, lineWarningLength),
|
||||
type: MessageType.WARNING
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, {
|
||||
flexibleHeight: true,
|
||||
validationOptions: { validation: validation }
|
||||
});
|
||||
this.disposables.push(attachInputBoxStyler(this.inputBox, this.themeService));
|
||||
this.disposables.push(this.inputBox);
|
||||
|
||||
const onKeyUp = domEvent(this.inputBox.inputElement, 'keyup');
|
||||
const onMouseUp = domEvent(this.inputBox.inputElement, 'mouseup');
|
||||
anyEvent<any>(onKeyUp, onMouseUp)(() => this.inputBox.validate(), null, this.disposables);
|
||||
|
||||
this.inputBox.value = this.repository.input.value;
|
||||
this.inputBox.onDidChange(value => this.repository.input.value = value, null, this.disposables);
|
||||
this.repository.input.onDidChange(value => this.inputBox.value = value, null, this.disposables);
|
||||
|
||||
@@ -35,14 +35,13 @@ import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import pkg from 'vs/platform/node/package';
|
||||
import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/parts/terminal/electron-browser/terminalColorRegistry';
|
||||
import { PANEL_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
/** The amount of time to consider terminal errors to be related to the launch */
|
||||
const LAUNCHING_DURATION = 500;
|
||||
|
||||
// Enable search functionality in xterm.js instance
|
||||
XTermTerminal.loadAddon('search');
|
||||
// Enable the winpty compatibility addon which will simulate wraparound mode
|
||||
XTermTerminal.loadAddon('winptyCompat');
|
||||
let Terminal: typeof XTermTerminal;
|
||||
|
||||
enum ProcessState {
|
||||
// The process has not been initialized yet.
|
||||
@@ -97,6 +96,7 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
private _initialCwd: string;
|
||||
private _windowsShellHelper: WindowsShellHelper;
|
||||
private _onLineDataListeners: ((lineData: string) => void)[];
|
||||
private _xtermReadyPromise: TPromise<void>;
|
||||
|
||||
private _widgetManager: TerminalWidgetManager;
|
||||
private _linkHandler: TerminalLinkHandler;
|
||||
@@ -123,7 +123,9 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IClipboardService private _clipboardService: IClipboardService,
|
||||
@IHistoryService private _historyService: IHistoryService,
|
||||
@IThemeService private _themeService: IThemeService
|
||||
@IThemeService private _themeService: IThemeService,
|
||||
@IConfigurationResolverService private _configurationResolverService: IConfigurationResolverService,
|
||||
@IWorkspaceContextService private _workspaceContextService: IWorkspaceContextService
|
||||
) {
|
||||
this._instanceDisposables = [];
|
||||
this._processDisposables = [];
|
||||
@@ -150,7 +152,6 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
|
||||
this._initDimensions();
|
||||
this._createProcess();
|
||||
this._createXterm();
|
||||
|
||||
if (platform.isWindows) {
|
||||
this._processReady.then(() => {
|
||||
@@ -160,10 +161,13 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
});
|
||||
}
|
||||
|
||||
// Only attach xterm.js to the DOM if the terminal panel has been opened before.
|
||||
if (_container) {
|
||||
this.attachToElement(_container);
|
||||
}
|
||||
this._xtermReadyPromise = this._createXterm();
|
||||
this._xtermReadyPromise.then(() => {
|
||||
// Only attach xterm.js to the DOM if the terminal panel has been opened before.
|
||||
if (_container) {
|
||||
this.attachToElement(_container);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public addDisposable(disposable: lifecycle.IDisposable): void {
|
||||
@@ -248,9 +252,16 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
/**
|
||||
* Create xterm.js instance and attach data listeners.
|
||||
*/
|
||||
protected _createXterm(): void {
|
||||
protected async _createXterm(): TPromise<void> {
|
||||
if (!Terminal) {
|
||||
Terminal = (await import('xterm')).Terminal;
|
||||
// Enable search functionality in xterm.js instance
|
||||
Terminal.loadAddon('search');
|
||||
// Enable the winpty compatibility addon which will simulate wraparound mode
|
||||
Terminal.loadAddon('winptyCompat');
|
||||
}
|
||||
const font = this._configHelper.getFont(true);
|
||||
this._xterm = new XTermTerminal({
|
||||
this._xterm = new Terminal({
|
||||
scrollback: this._configHelper.config.scrollback,
|
||||
theme: this._getXtermTheme(),
|
||||
fontFamily: font.fontFamily,
|
||||
@@ -284,100 +295,102 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
}
|
||||
|
||||
public attachToElement(container: HTMLElement): void {
|
||||
if (this._wrapperElement) {
|
||||
throw new Error('The terminal instance has already been attached to a container');
|
||||
}
|
||||
|
||||
this._container = container;
|
||||
this._wrapperElement = document.createElement('div');
|
||||
dom.addClass(this._wrapperElement, 'terminal-wrapper');
|
||||
this._xtermElement = document.createElement('div');
|
||||
|
||||
// Attach the xterm object to the DOM, exposing it to the smoke tests
|
||||
(<any>this._wrapperElement).xterm = this._xterm;
|
||||
|
||||
this._xterm.open(this._xtermElement);
|
||||
this._xterm.attachCustomKeyEventHandler((event: KeyboardEvent) => {
|
||||
// Disable all input if the terminal is exiting
|
||||
if (this._isExiting) {
|
||||
return false;
|
||||
this._xtermReadyPromise.then(() => {
|
||||
if (this._wrapperElement) {
|
||||
throw new Error('The terminal instance has already been attached to a container');
|
||||
}
|
||||
|
||||
// Skip processing by xterm.js of keyboard events that resolve to commands described
|
||||
// within commandsToSkipShell
|
||||
const standardKeyboardEvent = new StandardKeyboardEvent(event);
|
||||
const resolveResult = this._keybindingService.softDispatch(standardKeyboardEvent, standardKeyboardEvent.target);
|
||||
if (resolveResult && this._skipTerminalCommands.some(k => k === resolveResult.commandId)) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
this._container = container;
|
||||
this._wrapperElement = document.createElement('div');
|
||||
dom.addClass(this._wrapperElement, 'terminal-wrapper');
|
||||
this._xtermElement = document.createElement('div');
|
||||
|
||||
// If tab focus mode is on, tab is not passed to the terminal
|
||||
if (TabFocus.getTabFocusMode() && event.keyCode === 9) {
|
||||
return false;
|
||||
}
|
||||
// Attach the xterm object to the DOM, exposing it to the smoke tests
|
||||
(<any>this._wrapperElement).xterm = this._xterm;
|
||||
|
||||
return undefined;
|
||||
this._xterm.open(this._xtermElement);
|
||||
this._xterm.attachCustomKeyEventHandler((event: KeyboardEvent) => {
|
||||
// Disable all input if the terminal is exiting
|
||||
if (this._isExiting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip processing by xterm.js of keyboard events that resolve to commands described
|
||||
// within commandsToSkipShell
|
||||
const standardKeyboardEvent = new StandardKeyboardEvent(event);
|
||||
const resolveResult = this._keybindingService.softDispatch(standardKeyboardEvent, standardKeyboardEvent.target);
|
||||
if (resolveResult && this._skipTerminalCommands.some(k => k === resolveResult.commandId)) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
// If tab focus mode is on, tab is not passed to the terminal
|
||||
if (TabFocus.getTabFocusMode() && event.keyCode === 9) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.element, 'mouseup', (event: KeyboardEvent) => {
|
||||
// Wait until mouseup has propagated through the DOM before
|
||||
// evaluating the new selection state.
|
||||
setTimeout(() => this._refreshSelectionContextKey(), 0);
|
||||
}));
|
||||
|
||||
// xterm.js currently drops selection on keyup as we need to handle this case.
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.element, 'keyup', (event: KeyboardEvent) => {
|
||||
// Wait until keyup has propagated through the DOM before evaluating
|
||||
// the new selection state.
|
||||
setTimeout(() => this._refreshSelectionContextKey(), 0);
|
||||
}));
|
||||
|
||||
const xtermHelper: HTMLElement = <HTMLElement>this._xterm.element.querySelector('.xterm-helpers');
|
||||
const focusTrap: HTMLElement = document.createElement('div');
|
||||
focusTrap.setAttribute('tabindex', '0');
|
||||
dom.addClass(focusTrap, 'focus-trap');
|
||||
this._instanceDisposables.push(dom.addDisposableListener(focusTrap, 'focus', (event: FocusEvent) => {
|
||||
let currentElement = focusTrap;
|
||||
while (!dom.hasClass(currentElement, 'part')) {
|
||||
currentElement = currentElement.parentElement;
|
||||
}
|
||||
const hidePanelElement = <HTMLElement>currentElement.querySelector('.hide-panel-action');
|
||||
hidePanelElement.focus();
|
||||
}));
|
||||
xtermHelper.insertBefore(focusTrap, this._xterm.textarea);
|
||||
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.textarea, 'focus', (event: KeyboardEvent) => {
|
||||
this._terminalFocusContextKey.set(true);
|
||||
}));
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.textarea, 'blur', (event: KeyboardEvent) => {
|
||||
this._terminalFocusContextKey.reset();
|
||||
this._refreshSelectionContextKey();
|
||||
}));
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.element, 'focus', (event: KeyboardEvent) => {
|
||||
this._terminalFocusContextKey.set(true);
|
||||
}));
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.element, 'blur', (event: KeyboardEvent) => {
|
||||
this._terminalFocusContextKey.reset();
|
||||
this._refreshSelectionContextKey();
|
||||
}));
|
||||
|
||||
this._wrapperElement.appendChild(this._xtermElement);
|
||||
this._widgetManager = new TerminalWidgetManager(this._wrapperElement);
|
||||
this._linkHandler.setWidgetManager(this._widgetManager);
|
||||
this._container.appendChild(this._wrapperElement);
|
||||
|
||||
const computedStyle = window.getComputedStyle(this._container);
|
||||
const width = parseInt(computedStyle.getPropertyValue('width').replace('px', ''), 10);
|
||||
const height = parseInt(computedStyle.getPropertyValue('height').replace('px', ''), 10);
|
||||
this.layout(new Dimension(width, height));
|
||||
this.setVisible(this._isVisible);
|
||||
this.updateConfig();
|
||||
|
||||
// If IShellLaunchConfig.waitOnExit was true and the process finished before the terminal
|
||||
// panel was initialized.
|
||||
if (this._xterm.getOption('disableStdin')) {
|
||||
this._attachPressAnyKeyToCloseListener();
|
||||
}
|
||||
});
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.element, 'mouseup', (event: KeyboardEvent) => {
|
||||
// Wait until mouseup has propagated through the DOM before
|
||||
// evaluating the new selection state.
|
||||
setTimeout(() => this._refreshSelectionContextKey(), 0);
|
||||
}));
|
||||
|
||||
// xterm.js currently drops selection on keyup as we need to handle this case.
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.element, 'keyup', (event: KeyboardEvent) => {
|
||||
// Wait until keyup has propagated through the DOM before evaluating
|
||||
// the new selection state.
|
||||
setTimeout(() => this._refreshSelectionContextKey(), 0);
|
||||
}));
|
||||
|
||||
const xtermHelper: HTMLElement = <HTMLElement>this._xterm.element.querySelector('.xterm-helpers');
|
||||
const focusTrap: HTMLElement = document.createElement('div');
|
||||
focusTrap.setAttribute('tabindex', '0');
|
||||
dom.addClass(focusTrap, 'focus-trap');
|
||||
this._instanceDisposables.push(dom.addDisposableListener(focusTrap, 'focus', (event: FocusEvent) => {
|
||||
let currentElement = focusTrap;
|
||||
while (!dom.hasClass(currentElement, 'part')) {
|
||||
currentElement = currentElement.parentElement;
|
||||
}
|
||||
const hidePanelElement = <HTMLElement>currentElement.querySelector('.hide-panel-action');
|
||||
hidePanelElement.focus();
|
||||
}));
|
||||
xtermHelper.insertBefore(focusTrap, this._xterm.textarea);
|
||||
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.textarea, 'focus', (event: KeyboardEvent) => {
|
||||
this._terminalFocusContextKey.set(true);
|
||||
}));
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.textarea, 'blur', (event: KeyboardEvent) => {
|
||||
this._terminalFocusContextKey.reset();
|
||||
this._refreshSelectionContextKey();
|
||||
}));
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.element, 'focus', (event: KeyboardEvent) => {
|
||||
this._terminalFocusContextKey.set(true);
|
||||
}));
|
||||
this._instanceDisposables.push(dom.addDisposableListener(this._xterm.element, 'blur', (event: KeyboardEvent) => {
|
||||
this._terminalFocusContextKey.reset();
|
||||
this._refreshSelectionContextKey();
|
||||
}));
|
||||
|
||||
this._wrapperElement.appendChild(this._xtermElement);
|
||||
this._widgetManager = new TerminalWidgetManager(this._wrapperElement);
|
||||
this._linkHandler.setWidgetManager(this._widgetManager);
|
||||
this._container.appendChild(this._wrapperElement);
|
||||
|
||||
const computedStyle = window.getComputedStyle(this._container);
|
||||
const width = parseInt(computedStyle.getPropertyValue('width').replace('px', ''), 10);
|
||||
const height = parseInt(computedStyle.getPropertyValue('height').replace('px', ''), 10);
|
||||
this.layout(new Dimension(width, height));
|
||||
this.setVisible(this._isVisible);
|
||||
this.updateConfig();
|
||||
|
||||
// If IShellLaunchConfig.waitOnExit was true and the process finished before the terminal
|
||||
// panel was initialized.
|
||||
if (this._xterm.getOption('disableStdin')) {
|
||||
this._attachPressAnyKeyToCloseListener();
|
||||
}
|
||||
}
|
||||
|
||||
public registerLinkMatcher(regex: RegExp, handler: (url: string) => void, matchIndex?: number, validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void): number {
|
||||
@@ -585,16 +598,24 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
if (!this._shellLaunchConfig.executable) {
|
||||
this._configHelper.mergeDefaultShellPathAndArgs(this._shellLaunchConfig);
|
||||
}
|
||||
this._initialCwd = this._getCwd(this._shellLaunchConfig, this._historyService.getLastActiveWorkspaceRoot('file'));
|
||||
|
||||
const lastActiveWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot('file');
|
||||
this._initialCwd = this._getCwd(this._shellLaunchConfig, lastActiveWorkspaceRootUri);
|
||||
|
||||
// Resolve env vars from config and shell
|
||||
const lastActiveWorkspaceRoot = this._workspaceContextService.getWorkspaceFolder(lastActiveWorkspaceRootUri);
|
||||
const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
|
||||
const envFromConfig = TerminalInstance.resolveConfigurationVariables(this._configurationResolverService, { ...this._configHelper.config.env[platformKey] }, lastActiveWorkspaceRoot);
|
||||
const envFromShell = TerminalInstance.resolveConfigurationVariables(this._configurationResolverService, { ...this._shellLaunchConfig.env }, lastActiveWorkspaceRoot);
|
||||
this._shellLaunchConfig.env = envFromShell;
|
||||
|
||||
// Merge process env with the env from config
|
||||
const envFromConfig = { ...process.env };
|
||||
const envSettingKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux');
|
||||
TerminalInstance.mergeEnvironments(envFromConfig, this._configHelper.config.env[envSettingKey]);
|
||||
const parentEnv = { ...process.env };
|
||||
TerminalInstance.mergeEnvironments(parentEnv, envFromConfig);
|
||||
|
||||
// Continue env initialization, merging in the env from the launch
|
||||
// config and adding keys that are needed to create the process
|
||||
const env = TerminalInstance.createTerminalEnv(envFromConfig, this._shellLaunchConfig, this._initialCwd, locale, this._cols, this._rows);
|
||||
const env = TerminalInstance.createTerminalEnv(parentEnv, this._shellLaunchConfig, this._initialCwd, locale, this._cols, this._rows);
|
||||
this._process = cp.fork(Uri.parse(require.toUrl('bootstrap')).fsPath, ['--type=terminal'], {
|
||||
env,
|
||||
cwd: Uri.parse(path.dirname(require.toUrl('../node/terminalProcess'))).fsPath
|
||||
@@ -636,6 +657,16 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
}, LAUNCHING_DURATION);
|
||||
}
|
||||
|
||||
// TODO: Should be protected
|
||||
private static resolveConfigurationVariables(configurationResolverService: IConfigurationResolverService, env: IStringDictionary<string>, lastActiveWorkspaceRoot: IWorkspaceFolder): IStringDictionary<string> {
|
||||
Object.keys(env).forEach((key) => {
|
||||
if (typeof env[key] === 'string') {
|
||||
env[key] = configurationResolverService.resolve(lastActiveWorkspaceRoot, env[key]);
|
||||
}
|
||||
});
|
||||
return env;
|
||||
}
|
||||
|
||||
private _sendPtyDataToXterm(message: { type: string, content: string }): void {
|
||||
if (message.type === 'data') {
|
||||
if (this._widgetManager) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import { MockContextKeyService, MockKeybindingService } from 'vs/platform/keybin
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
class TestTerminalInstance extends TerminalInstance {
|
||||
public _getCwd(shell: IShellLaunchConfig, root: Uri): string {
|
||||
@@ -27,7 +28,7 @@ class TestTerminalInstance extends TerminalInstance {
|
||||
}
|
||||
|
||||
protected _createProcess(): void { }
|
||||
protected _createXterm(): void { }
|
||||
protected _createXterm(): TPromise<void> { return TPromise.as(void 0); }
|
||||
}
|
||||
|
||||
suite('Workbench - TerminalInstance', () => {
|
||||
|
||||
@@ -10,7 +10,6 @@ import fs = require('fs');
|
||||
import os = require('os');
|
||||
import crypto = require('crypto');
|
||||
import assert = require('assert');
|
||||
import sudoPrompt = require('sudo-prompt');
|
||||
|
||||
import { isParent, FileOperation, FileOperationEvent, IContent, IFileService, IResolveFileOptions, IResolveFileResult, IResolveContentOptions, IFileStat, IStreamContent, FileOperationError, FileOperationResult, IUpdateContentOptions, FileChangeType, IImportResult, FileChangesEvent, ICreateFileOptions, IContentData } from 'vs/platform/files/common/files';
|
||||
import { MAX_FILE_SIZE } from 'vs/platform/files/node/files';
|
||||
@@ -598,14 +597,16 @@ export class FileService implements IFileService {
|
||||
return this.updateContent(uri.file(tmpPath), value, writeOptions).then(() => {
|
||||
|
||||
// 3.) invoke our CLI as super user
|
||||
return new TPromise<void>((c, e) => {
|
||||
const promptOptions = { name: this.options.elevationSupport.promptTitle.replace('-', ''), icns: this.options.elevationSupport.promptIcnsPath };
|
||||
sudoPrompt.exec(`"${this.options.elevationSupport.cliPath}" --write-elevated-helper "${tmpPath}" "${absolutePath}"`, promptOptions, (error: string, stdout: string, stderr: string) => {
|
||||
if (error || stderr) {
|
||||
e(error || stderr);
|
||||
} else {
|
||||
c(void 0);
|
||||
}
|
||||
return (import('sudo-prompt')).then(sudoPrompt => {
|
||||
return new TPromise<void>((c, e) => {
|
||||
const promptOptions = { name: this.options.elevationSupport.promptTitle.replace('-', ''), icns: this.options.elevationSupport.promptIcnsPath };
|
||||
sudoPrompt.exec(`"${this.options.elevationSupport.cliPath}" --write-elevated-helper "${tmpPath}" "${absolutePath}"`, promptOptions, (error: string, stdout: string, stderr: string) => {
|
||||
if (error || stderr) {
|
||||
e(error || stderr);
|
||||
} else {
|
||||
c(void 0);
|
||||
}
|
||||
});
|
||||
});
|
||||
}).then(() => {
|
||||
|
||||
|
||||
@@ -74,6 +74,8 @@ export interface ISCMInput {
|
||||
|
||||
placeholder: string;
|
||||
readonly onDidChangePlaceholder: Event<string>;
|
||||
|
||||
lineWarningLength: number | undefined;
|
||||
}
|
||||
|
||||
export interface ISCMRepository extends IDisposable {
|
||||
|
||||
@@ -39,6 +39,8 @@ class SCMInput implements ISCMInput {
|
||||
|
||||
private _onDidChangePlaceholder = new Emitter<string>();
|
||||
get onDidChangePlaceholder(): Event<string> { return this._onDidChangePlaceholder.event; }
|
||||
|
||||
public lineWarningLength: number | undefined = undefined;
|
||||
}
|
||||
|
||||
class SCMRepository implements ISCMRepository {
|
||||
@@ -106,4 +108,4 @@ export class SCMService implements ISCMService {
|
||||
|
||||
return repository;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,5 +306,10 @@ suite('Search-integration', function () {
|
||||
});
|
||||
|
||||
function makeExpression(...patterns: string[]): glob.IExpression {
|
||||
return patterns.reduce((glob, cur) => { glob[cur] = true; return glob; }, Object.create(null));
|
||||
}
|
||||
return patterns.reduce((glob, pattern) => {
|
||||
// glob.ts needs forward slashes
|
||||
pattern = pattern.replace(/\\/g, '/');
|
||||
glob[pattern] = true;
|
||||
return glob;
|
||||
}, Object.create(null));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user