mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-14 12:11:43 +01:00
Merge branch 'master' into ben/sqlite
This commit is contained in:
@@ -20,7 +20,10 @@
|
||||
},
|
||||
diff-editor: [],
|
||||
dropdown: [],
|
||||
editor: [],
|
||||
editor: {
|
||||
assignees: [],
|
||||
assignLabel: false
|
||||
},
|
||||
editor-1000-limit: [],
|
||||
editor-autoclosing: [],
|
||||
editor-autoindent: [],
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
disturl "https://atom.io/download/electron"
|
||||
target "2.0.9"
|
||||
target "2.0.11"
|
||||
runtime "electron"
|
||||
|
||||
+2
-1
@@ -48,12 +48,13 @@ Do not add your issue as a comment to an existing issue unless it's for the iden
|
||||
|
||||
The more information you can provide, the more likely someone will be successful at reproducing the issue and finding a fix.
|
||||
|
||||
The built-in tool for reporting an issue, which you can access by using `Report Issue` in VS Code's Help menu, can help streamline this process by automatically providing the version of VS Code, all your installed extensions, and your system info. Additionally, the tool will search among existing issues to see if a similar issue already exists.
|
||||
|
||||
Please include the following with each issue:
|
||||
|
||||
* Version of VS Code
|
||||
|
||||
* List of extensions that you have installed.
|
||||
* **Tip:** You can easily add the list of extensions by creating the issue using `Report Issues` from VS Code's Help menu
|
||||
|
||||
* Reproducible steps (1... 2... 3...) that cause the issue
|
||||
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@
|
||||
},
|
||||
{
|
||||
"name": "electron",
|
||||
"version": "2.0.9",
|
||||
"version": "2.0.11",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/electron/electron",
|
||||
"isProd": true
|
||||
|
||||
@@ -315,7 +315,6 @@ function generateDeclarationFile(out, inputFiles, recipe) {
|
||||
var resultTxt = result.join(endl);
|
||||
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
|
||||
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
|
||||
resultTxt = resultTxt.replace(/\bTPromise</g, 'Promise<');
|
||||
resultTxt = format(resultTxt);
|
||||
return [
|
||||
resultTxt,
|
||||
|
||||
@@ -366,7 +366,6 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
|
||||
let resultTxt = result.join(endl);
|
||||
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
|
||||
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
|
||||
resultTxt = resultTxt.replace(/\bTPromise</g, 'Promise<');
|
||||
|
||||
resultTxt = format(resultTxt);
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ async function publish(commit: string, quality: string, platform: string, type:
|
||||
|
||||
const queuedBy = process.env['BUILD_QUEUEDBY']!;
|
||||
const sourceBranch = process.env['BUILD_SOURCEBRANCH']!;
|
||||
const isReleased = (quality === 'insider' || quality === 'exploration')
|
||||
const isReleased = quality === 'insider'
|
||||
&& /^master$|^refs\/heads\/master$/.test(sourceBranch)
|
||||
&& /Project Collection Service Accounts|Microsoft.VisualStudio.Services.TFS/.test(queuedBy);
|
||||
|
||||
|
||||
@@ -308,7 +308,6 @@
|
||||
"dependencies": {
|
||||
"highlight.js": "9.12.0",
|
||||
"markdown-it": "^8.4.1",
|
||||
"markdown-it-named-headers": "0.0.4",
|
||||
"vscode-extension-telemetry": "0.0.22",
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
|
||||
@@ -17,8 +17,8 @@ export class MarkdownEngine {
|
||||
private md?: MarkdownIt;
|
||||
|
||||
private firstLine?: number;
|
||||
|
||||
private currentDocument?: vscode.Uri;
|
||||
private _slugCount = new Map<string, number>();
|
||||
|
||||
public constructor(
|
||||
private readonly extensionPreviewResourceProvider: MarkdownContributions,
|
||||
@@ -36,7 +36,6 @@ export class MarkdownEngine {
|
||||
private async getEngine(resource: vscode.Uri): Promise<MarkdownIt> {
|
||||
if (!this.md) {
|
||||
const hljs = await import('highlight.js');
|
||||
const mdnh = await import('markdown-it-named-headers');
|
||||
this.md = (await import('markdown-it'))({
|
||||
html: true,
|
||||
highlight: (str: string, lang?: string) => {
|
||||
@@ -54,8 +53,6 @@ export class MarkdownEngine {
|
||||
}
|
||||
return `<code><div>${this.md!.utils.escapeHtml(str)}</div></code>`;
|
||||
}
|
||||
}).use(mdnh, {
|
||||
slugify: (header: string) => this.slugifier.fromHeading(header).value
|
||||
});
|
||||
|
||||
for (const plugin of this.extensionPreviewResourceProvider.markdownItPlugins) {
|
||||
@@ -71,6 +68,7 @@ export class MarkdownEngine {
|
||||
|
||||
this.addLinkNormalizer(this.md);
|
||||
this.addLinkValidator(this.md);
|
||||
this.addNamedHeaders(this.md);
|
||||
}
|
||||
|
||||
const config = vscode.workspace.getConfiguration('markdown', resource);
|
||||
@@ -101,6 +99,8 @@ export class MarkdownEngine {
|
||||
}
|
||||
this.currentDocument = document;
|
||||
this.firstLine = offset;
|
||||
this._slugCount = new Map<string, number>();
|
||||
|
||||
const engine = await this.getEngine(document);
|
||||
return engine.render(text);
|
||||
}
|
||||
@@ -108,6 +108,8 @@ export class MarkdownEngine {
|
||||
public async parse(document: vscode.Uri, source: string): Promise<Token[]> {
|
||||
const { text, offset } = this.stripFrontmatter(source);
|
||||
this.currentDocument = document;
|
||||
this._slugCount = new Map<string, number>();
|
||||
|
||||
const engine = await this.getEngine(document);
|
||||
|
||||
return engine.parse(text, {}).map(token => {
|
||||
@@ -219,4 +221,29 @@ export class MarkdownEngine {
|
||||
return validateLink(link) || link.indexOf('file:') === 0;
|
||||
};
|
||||
}
|
||||
|
||||
private addNamedHeaders(md: any): void {
|
||||
const original = md.renderer.rules.heading_open;
|
||||
md.renderer.rules.heading_open = (tokens: any, idx: number, options: any, env: any, self: any) => {
|
||||
const title = tokens[idx + 1].children.reduce((acc: string, t: any) => acc + t.content, '');
|
||||
let slug = this.slugifier.fromHeading(title);
|
||||
|
||||
if (this._slugCount.has(slug.value)) {
|
||||
const count = this._slugCount.get(slug.value)!;
|
||||
this._slugCount.set(slug.value, count + 1);
|
||||
slug = this.slugifier.fromHeading(slug.value + '-' + (count + 1));
|
||||
} else {
|
||||
this._slugCount.set(slug.value, 0);
|
||||
}
|
||||
|
||||
tokens[idx].attrs = tokens[idx].attrs || [];
|
||||
tokens[idx].attrs.push(['id', slug.value]);
|
||||
|
||||
if (original) {
|
||||
return original(tokens, idx, options, env, self);
|
||||
} else {
|
||||
return self.renderToken(tokens, idx, options, env, self);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -51,11 +51,23 @@ export class TableOfContentsProvider {
|
||||
const toc: TocEntry[] = [];
|
||||
const tokens = await this.engine.parse(document.uri, document.getText());
|
||||
|
||||
const slugCount = new Map<string, number>();
|
||||
|
||||
for (const heading of tokens.filter(token => token.type === 'heading_open')) {
|
||||
const lineNumber = heading.map[0];
|
||||
const line = document.lineAt(lineNumber);
|
||||
|
||||
let slug = githubSlugifier.fromHeading(line.text);
|
||||
if (slugCount.has(slug.value)) {
|
||||
const count = slugCount.get(slug.value)!;
|
||||
slugCount.set(slug.value, count + 1);
|
||||
slug = githubSlugifier.fromHeading(slug.value + '-' + (count + 1));
|
||||
} else {
|
||||
slugCount.set(slug.value, 0);
|
||||
}
|
||||
|
||||
toc.push({
|
||||
slug: githubSlugifier.fromHeading(line.text),
|
||||
slug,
|
||||
text: TableOfContentsProvider.getHeaderText(line.text),
|
||||
level: TableOfContentsProvider.getHeaderLevel(heading.markup),
|
||||
line: lineNumber,
|
||||
|
||||
@@ -106,4 +106,25 @@ suite('markdown.TableOfContentsProvider', () => {
|
||||
assert.strictEqual((await provider.lookup('Заголовок-header-3'))!.line, 4);
|
||||
assert.strictEqual((await provider.lookup('Заголовок'))!.line, 5);
|
||||
});
|
||||
|
||||
test('Lookup should support suffixes for repeated headers', async () => {
|
||||
const doc = new InMemoryDocument(testFileName, `# a\n# a\n## a`);
|
||||
const provider = new TableOfContentsProvider(createNewMarkdownEngine(), doc);
|
||||
|
||||
{
|
||||
const entry = await provider.lookup('a');
|
||||
assert.ok(entry);
|
||||
assert.strictEqual(entry!.line, 0);
|
||||
}
|
||||
{
|
||||
const entry = await provider.lookup('a-1');
|
||||
assert.ok(entry);
|
||||
assert.strictEqual(entry!.line, 1);
|
||||
}
|
||||
{
|
||||
const entry = await provider.lookup('a-2');
|
||||
assert.ok(entry);
|
||||
assert.strictEqual(entry!.line, 2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3895,13 +3895,6 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
markdown-it-named-headers@0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz#82efc28324240a6b1e77b9aae501771d5f351c1f"
|
||||
integrity sha1-gu/CgyQkCmsed7mq5QF3HV81HB8=
|
||||
dependencies:
|
||||
string "^3.0.1"
|
||||
|
||||
markdown-it@^8.4.1:
|
||||
version "8.4.1"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.1.tgz#206fe59b0e4e1b78a7c73250af9b34a4ad0aaf44"
|
||||
@@ -5711,11 +5704,6 @@ string-width@^2.0.0, string-width@^2.1.0:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string@^3.0.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/string/-/string-3.3.1.tgz#8d2757ec1c0e6c526796fbb6b14036a4098398b7"
|
||||
integrity sha1-jSdX7BwObFJnlvu2sUA2pAmDmLc=
|
||||
|
||||
string_decoder@^1.0.0, string_decoder@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"description": "Dependencies shared by all extensions",
|
||||
"dependencies": {
|
||||
"typescript": "3.1.1"
|
||||
"typescript": "3.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./postinstall"
|
||||
|
||||
@@ -254,8 +254,8 @@
|
||||
"body": [
|
||||
"try {",
|
||||
"\t${1://code...}",
|
||||
"} catch (\\Exception \\$$e) {",
|
||||
"\t${2://throw $$e;}",
|
||||
"} catch (${2:\\Throwable} ${3:$$th}) {",
|
||||
"\t${4://throw $$th;}",
|
||||
"}"
|
||||
],
|
||||
"description": "Try catch block"
|
||||
|
||||
@@ -11,6 +11,13 @@ import { ITypeScriptServiceClient, ServerResponse } from '../typescriptService';
|
||||
import API from '../utils/api';
|
||||
import * as typeConverters from '../utils/typeConverters';
|
||||
|
||||
// TODO: Remove when we pick up TS 3.2
|
||||
declare module '../protocol' {
|
||||
interface RenameTextSpan extends Proto.TextSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
}
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -102,8 +109,9 @@ class TypeScriptRenameProvider implements vscode.RenameProvider {
|
||||
for (const spanGroup of locations) {
|
||||
const resource = this.client.toResource(spanGroup.file);
|
||||
if (resource) {
|
||||
for (const textSpan of spanGroup.locs) {
|
||||
edit.replace(resource, typeConverters.Range.fromTextSpan(textSpan), newName);
|
||||
for (const textSpan of spanGroup.locs as Proto.RenameTextSpan[]) {
|
||||
edit.replace(resource, typeConverters.Range.fromTextSpan(textSpan),
|
||||
(textSpan.prefixText || '') + newName + (textSpan.suffixText || ''));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ suite('Webview tests', () => {
|
||||
});
|
||||
|
||||
test('webviews should not have scripts enabled by default', async () => {
|
||||
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { }));
|
||||
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {}));
|
||||
const response = Promise.race<any>([
|
||||
getMesssage(webview),
|
||||
new Promise<{}>(resolve => setTimeout(() => resolve({ value: '🎉' }), 1000))
|
||||
@@ -71,14 +71,14 @@ suite('Webview tests', () => {
|
||||
assert.strictEqual((await response).value, 'first');
|
||||
}
|
||||
{
|
||||
const firstResponse = getMesssage(webview);
|
||||
const response = getMesssage(webview);
|
||||
webview.webview.html = createHtmlDocumentWithBody(/*html*/`
|
||||
<script>
|
||||
const vscode = acquireVsCodeApi();
|
||||
vscode.postMessage({ value: 'second' });
|
||||
</script>`);
|
||||
|
||||
assert.strictEqual((await firstResponse).value, 'second');
|
||||
assert.strictEqual((await response).value, 'second');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -243,6 +243,70 @@ suite('Webview tests', () => {
|
||||
const secondResponse = await sendRecieveMessage(webview, { type: 'get' });
|
||||
assert.strictEqual(secondResponse.value, 100);
|
||||
});
|
||||
|
||||
test('webviews should only be able to load resources from workspace by default', async () => {
|
||||
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, { enableScripts: true }));
|
||||
|
||||
webview.webview.html = createHtmlDocumentWithBody(/*html*/`
|
||||
<script>
|
||||
const vscode = acquireVsCodeApi();
|
||||
window.addEventListener('message', (message) => {
|
||||
const img = document.createElement('img');
|
||||
img.addEventListener('load', () => { vscode.postMessage({ value: true }); });
|
||||
img.addEventListener('error', () => { vscode.postMessage({ value: false }); });
|
||||
img.src = message.data.src;
|
||||
document.body.appendChild(img);
|
||||
});
|
||||
</script>`);
|
||||
|
||||
const workspaceRootUri = vscode.Uri.file(vscode.workspace.rootPath!).with({ scheme: 'vscode-resource' });
|
||||
|
||||
{
|
||||
const imagePath = workspaceRootUri.toString() + '/image.png';
|
||||
const response = sendRecieveMessage(webview, { src: imagePath });
|
||||
assert.strictEqual((await response).value, true);
|
||||
}
|
||||
{
|
||||
const imagePath = workspaceRootUri.toString() + '/no-such-image.png';
|
||||
const response = sendRecieveMessage(webview, { src: imagePath });
|
||||
assert.strictEqual((await response).value, false);
|
||||
}
|
||||
{
|
||||
const imagePath = vscode.Uri.file(join(vscode.workspace.rootPath!, '..', '..', '..', 'resources', 'linux', 'code.png')).with({ scheme: 'vscode-resource' });
|
||||
const response = sendRecieveMessage(webview, { src: imagePath.toString() });
|
||||
assert.strictEqual((await response).value, false);
|
||||
}
|
||||
});
|
||||
|
||||
test('webviews should allow overriding allowed resource paths using localResourceRoots', async () => {
|
||||
const webview = _register(vscode.window.createWebviewPanel(webviewId, 'title', { viewColumn: vscode.ViewColumn.One }, {
|
||||
enableScripts: true,
|
||||
localResourceRoots: [vscode.Uri.file(join(vscode.workspace.rootPath!, 'sub'))]
|
||||
}));
|
||||
|
||||
webview.webview.html = createHtmlDocumentWithBody(/*html*/`
|
||||
<script>
|
||||
const vscode = acquireVsCodeApi();
|
||||
window.addEventListener('message', (message) => {
|
||||
const img = document.createElement('img');
|
||||
img.addEventListener('load', () => { vscode.postMessage({ value: true }); });
|
||||
img.addEventListener('error', () => { vscode.postMessage({ value: false }); });
|
||||
img.src = message.data.src;
|
||||
document.body.appendChild(img);
|
||||
});
|
||||
</script>`);
|
||||
|
||||
const workspaceRootUri = vscode.Uri.file(vscode.workspace.rootPath!).with({ scheme: 'vscode-resource' });
|
||||
|
||||
{
|
||||
const response = sendRecieveMessage(webview, { src: workspaceRootUri.toString() + '/sub/image.png' });
|
||||
assert.strictEqual((await response).value, true);
|
||||
}
|
||||
{
|
||||
const response = sendRecieveMessage(webview, { src: workspaceRootUri.toString() + '/image.png' });
|
||||
assert.strictEqual((await response).value, false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function createHtmlDocumentWithBody(body: string): string {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
typescript@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.1.tgz#3362ba9dd1e482ebb2355b02dfe8bcd19a2c7c96"
|
||||
integrity sha512-Veu0w4dTc/9wlWNf2jeRInNodKlcdLgemvPsrNpfu5Pq39sgfFjvIIgTsvUHCoLBnMhPoUA+tFxsXjU6VexVRQ==
|
||||
typescript@3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.2.tgz#c03a5d16f30bb60ad8bb6fe8e7cb212eedeec950"
|
||||
integrity sha512-gOoGJWbNnFAfP9FlrSV63LYD5DJqYJHG5ky1kOXSl3pCImn4rqWy/flyq1BRd4iChQsoCqjbQaqtmXO4yCVPCA==
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@
|
||||
"vscode-nsfw": "1.0.17",
|
||||
"vscode-ripgrep": "^1.2.2",
|
||||
"vscode-textmate": "^4.0.1",
|
||||
"vscode-xterm": "3.9.0-beta1",
|
||||
"vscode-xterm": "3.9.0-beta5",
|
||||
"winreg": "^1.2.4",
|
||||
"yauzl": "^2.9.1",
|
||||
"yazl": "^2.4.3"
|
||||
|
||||
Vendored
+10
@@ -89,6 +89,16 @@ declare module 'vscode-xterm' {
|
||||
*/
|
||||
experimentalCharAtlas?: 'none' | 'static' | 'dynamic';
|
||||
|
||||
/**
|
||||
* (EXPERIMENTAL) Defines which implementation to use for buffer lines.
|
||||
*
|
||||
* - 'JsArray': The default/stable implementation.
|
||||
* - 'TypedArray': The new experimental implementation based on TypedArrays that is expected to
|
||||
* significantly boost performance and memory consumption. Use at your own risk.
|
||||
*
|
||||
* This option will be removed in the future.
|
||||
*/
|
||||
experimentalBufferLineImpl?: 'JsArray' | 'TypedArray';
|
||||
/**
|
||||
* The font size used to render text.
|
||||
*/
|
||||
|
||||
@@ -28,10 +28,6 @@
|
||||
.monaco-action-bar .action-item {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
-ms-transition: -ms-transform 50ms ease;
|
||||
-webkit-transition: -webkit-transform 50ms ease;
|
||||
-moz-transition: -moz-transform 50ms ease;
|
||||
-o-transition: -o-transform 50ms ease;
|
||||
transition: transform 50ms ease;
|
||||
position: relative; /* DO NOT REMOVE - this is the key to preventing the ghosting icon bug in Chrome 42 */
|
||||
}
|
||||
@@ -41,11 +37,7 @@
|
||||
}
|
||||
|
||||
.monaco-action-bar.animated .action-item.active {
|
||||
-ms-transform: scale(1.272019649, 1.272019649); /* 1.272019649 = √φ */
|
||||
-webkit-transform: scale(1.272019649, 1.272019649);
|
||||
-moz-transform: scale(1.272019649, 1.272019649);
|
||||
-o-transform: scale(1.272019649, 1.272019649);
|
||||
transform: scale(1.272019649, 1.272019649);
|
||||
transform: scale(1.272019649, 1.272019649); /* 1.272019649 = √φ */
|
||||
}
|
||||
|
||||
.monaco-action-bar .action-item .icon {
|
||||
@@ -87,10 +79,6 @@
|
||||
}
|
||||
|
||||
.monaco-action-bar.animated.vertical .action-item.active {
|
||||
-ms-transform: translate(5px, 0);
|
||||
-webkit-transform: translate(5px, 0);
|
||||
-moz-transform: translate(5px, 0);
|
||||
-o-transform: translate(5px, 0);
|
||||
transform: translate(5px, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -419,6 +419,10 @@ export class ActionBar extends Disposable implements IActionRunner {
|
||||
this._context = options.context;
|
||||
this._actionRunner = this.options.actionRunner;
|
||||
|
||||
if (!this.options.triggerKeys) {
|
||||
this.options.triggerKeys = defaultOptions.triggerKeys;
|
||||
}
|
||||
|
||||
if (!this._actionRunner) {
|
||||
this._actionRunner = new ActionRunner();
|
||||
this._register(this._actionRunner);
|
||||
|
||||
@@ -14,20 +14,12 @@
|
||||
|
||||
.monaco-menu .monaco-action-bar.vertical .action-item {
|
||||
padding: 0;
|
||||
-ms-transform: none;
|
||||
-webkit-transform: none;
|
||||
-moz-transform: none;
|
||||
-o-transform: none;
|
||||
transform: none;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-menu .monaco-action-bar.vertical .action-item.active {
|
||||
-ms-transform: none;
|
||||
-webkit-transform: none;
|
||||
-moz-transform: none;
|
||||
-o-transform: none;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
.monaco-progress-container.discrete .progress-bit {
|
||||
left: 0;
|
||||
transition: width 100ms linear;
|
||||
-webkit-transition: width 100ms linear;
|
||||
-o-transition: width 100ms linear;
|
||||
-moz-transition: width 100ms linear;
|
||||
-ms-transition: width 100ms linear;
|
||||
}
|
||||
|
||||
.monaco-progress-container.discrete.done .progress-bit {
|
||||
|
||||
@@ -44,10 +44,6 @@
|
||||
/* Background rule added for IE9 - to allow clicks on dom node */
|
||||
background:rgba(0,0,0,0);
|
||||
|
||||
-webkit-transition: opacity 100ms linear;
|
||||
-o-transition: opacity 100ms linear;
|
||||
-moz-transition: opacity 100ms linear;
|
||||
-ms-transition: opacity 100ms linear;
|
||||
transition: opacity 100ms linear;
|
||||
}
|
||||
.monaco-scrollable-element > .invisible {
|
||||
@@ -55,10 +51,6 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
.monaco-scrollable-element > .invisible.fade {
|
||||
-webkit-transition: opacity 800ms linear;
|
||||
-o-transition: opacity 800ms linear;
|
||||
-moz-transition: opacity 800ms linear;
|
||||
-ms-transition: opacity 800ms linear;
|
||||
transition: opacity 800ms linear;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,21 +90,13 @@
|
||||
|
||||
.monaco-panel-view.animated .split-view-view {
|
||||
transition-duration: 0.15s;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-moz-transition-duration: 0.15s;
|
||||
transition-timing-function: ease-out;
|
||||
-webkit-transition-timing-function: ease-out;
|
||||
-moz-transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.monaco-panel-view.animated.vertical .split-view-view {
|
||||
transition-property: height;
|
||||
-webkit-transition-property: height;
|
||||
-moz-transition-property: height;
|
||||
}
|
||||
|
||||
.monaco-panel-view.animated.horizontal .split-view-view {
|
||||
transition-property: width;
|
||||
-webkit-transition-property: width;
|
||||
-moz-transition-property: width;
|
||||
}
|
||||
|
||||
@@ -188,9 +188,9 @@ export abstract class Panel implements IView {
|
||||
|
||||
layout(size: number): void {
|
||||
const headerSize = this.headerVisible ? Panel.HEADER_SIZE : 0;
|
||||
this.layoutBody(size - headerSize);
|
||||
|
||||
if (this.isExpanded()) {
|
||||
this.layoutBody(size - headerSize);
|
||||
this.expandedSize = size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,7 +657,7 @@ export class RunOnceWorker<T> extends RunOnceScheduler {
|
||||
export function nfcall(fn: Function, ...args: any[]): Promise<any>;
|
||||
export function nfcall<T>(fn: Function, ...args: any[]): Promise<T>;
|
||||
export function nfcall(fn: Function, ...args: any[]): any {
|
||||
return new Promise((c, e) => fn(...args, (err: any, result: any) => err ? e(err) : c(result)));
|
||||
return new TPromise((c, e) => fn(...args, (err: any, result: any) => err ? e(err) : c(result)));
|
||||
}
|
||||
|
||||
export function ninvoke(thisArg: any, fn: Function, ...args: any[]): TPromise;
|
||||
|
||||
@@ -686,4 +686,20 @@ export function containsUppercaseCharacter(target: string, ignoreEscapedChars =
|
||||
|
||||
export function uppercaseFirstLetter(str: string): string {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
export function getNLines(str: string, n = 1): string {
|
||||
if (n === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let idx = -1;
|
||||
do {
|
||||
idx = str.indexOf('\n', idx + 1);
|
||||
n--;
|
||||
} while (n > 0 && idx >= 0);
|
||||
|
||||
return idx >= 0 ?
|
||||
str.substr(0, idx) :
|
||||
str;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import { transformErrorForSerialization } from 'vs/base/common/errors';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ErrorCallback, TPromise, ValueCallback } from 'vs/base/common/winjs.base';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
|
||||
const INITIALIZE = '$initialize';
|
||||
@@ -56,13 +55,13 @@ interface IReplyMessage extends IMessage {
|
||||
}
|
||||
|
||||
interface IMessageReply {
|
||||
c: ValueCallback;
|
||||
e: ErrorCallback;
|
||||
resolve: (value?: any) => void;
|
||||
reject: (error?: any) => void;
|
||||
}
|
||||
|
||||
interface IMessageHandler {
|
||||
sendMessage(msg: string): void;
|
||||
handleMessage(method: string, args: any[]): TPromise<any>;
|
||||
handleMessage(method: string, args: any[]): Promise<any>;
|
||||
}
|
||||
|
||||
class SimpleWorkerProtocol {
|
||||
@@ -83,15 +82,15 @@ class SimpleWorkerProtocol {
|
||||
this._workerId = workerId;
|
||||
}
|
||||
|
||||
public sendMessage(method: string, args: any[]): TPromise<any> {
|
||||
public sendMessage(method: string, args: any[]): Promise<any> {
|
||||
let req = String(++this._lastSentReq);
|
||||
let reply: IMessageReply = {
|
||||
c: null,
|
||||
e: null
|
||||
resolve: null,
|
||||
reject: null
|
||||
};
|
||||
let result = new TPromise<any>((c, e) => {
|
||||
reply.c = c;
|
||||
reply.e = e;
|
||||
let result = new Promise<any>((resolve, reject) => {
|
||||
reply.resolve = resolve;
|
||||
reply.reject = reject;
|
||||
});
|
||||
this._pendingReplies[req] = reply;
|
||||
|
||||
@@ -140,11 +139,11 @@ class SimpleWorkerProtocol {
|
||||
err.message = replyMessage.err.message;
|
||||
err.stack = replyMessage.err.stack;
|
||||
}
|
||||
reply.e(err);
|
||||
reply.reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
reply.c(replyMessage.res);
|
||||
reply.resolve(replyMessage.res);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -185,14 +184,14 @@ class SimpleWorkerProtocol {
|
||||
export class SimpleWorkerClient<T> extends Disposable {
|
||||
|
||||
private _worker: IWorker;
|
||||
private _onModuleLoaded: TPromise<string[]>;
|
||||
private _onModuleLoaded: Promise<string[]>;
|
||||
private _protocol: SimpleWorkerProtocol;
|
||||
private _lazyProxy: TPromise<T>;
|
||||
private _lazyProxy: Promise<T>;
|
||||
|
||||
constructor(workerFactory: IWorkerFactory, moduleId: string) {
|
||||
super();
|
||||
|
||||
let lazyProxyFulfill: (v: T) => void = null;
|
||||
let lazyProxyResolve: (v: T) => void = null;
|
||||
let lazyProxyReject: (err: any) => void = null;
|
||||
|
||||
this._worker = this._register(workerFactory.create(
|
||||
@@ -211,9 +210,9 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
sendMessage: (msg: string): void => {
|
||||
this._worker.postMessage(msg);
|
||||
},
|
||||
handleMessage: (method: string, args: any[]): TPromise<any> => {
|
||||
handleMessage: (method: string, args: any[]): Promise<any> => {
|
||||
// Intentionally not supporting worker -> main requests
|
||||
return TPromise.as(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
});
|
||||
this._protocol.setWorkerId(this._worker.getId());
|
||||
@@ -228,9 +227,9 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
loaderConfiguration = (<any>self).requirejs.s.contexts._.config;
|
||||
}
|
||||
|
||||
this._lazyProxy = new TPromise<T>((c, e) => {
|
||||
lazyProxyFulfill = c;
|
||||
lazyProxyReject = e;
|
||||
this._lazyProxy = new Promise<T>((resolve, reject) => {
|
||||
lazyProxyResolve = resolve;
|
||||
lazyProxyReject = reject;
|
||||
});
|
||||
|
||||
// Send initialize message
|
||||
@@ -244,18 +243,18 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
for (let i = 0; i < availableMethods.length; i++) {
|
||||
(proxy as any)[availableMethods[i]] = createProxyMethod(availableMethods[i], proxyMethodRequest);
|
||||
}
|
||||
lazyProxyFulfill(proxy);
|
||||
lazyProxyResolve(proxy);
|
||||
}, (e) => {
|
||||
lazyProxyReject(e);
|
||||
this._onError('Worker failed to load ' + moduleId, e);
|
||||
});
|
||||
|
||||
// Create proxy to loaded code
|
||||
let proxyMethodRequest = (method: string, args: any[]): TPromise<any> => {
|
||||
let proxyMethodRequest = (method: string, args: any[]): Promise<any> => {
|
||||
return this._request(method, args);
|
||||
};
|
||||
|
||||
let createProxyMethod = (method: string, proxyMethodRequest: (method: string, args: any[]) => TPromise<any>): Function => {
|
||||
let createProxyMethod = (method: string, proxyMethodRequest: (method: string, args: any[]) => Promise<any>): Function => {
|
||||
return function () {
|
||||
let args = Array.prototype.slice.call(arguments, 0);
|
||||
return proxyMethodRequest(method, args);
|
||||
@@ -263,15 +262,15 @@ export class SimpleWorkerClient<T> extends Disposable {
|
||||
};
|
||||
}
|
||||
|
||||
public getProxyObject(): TPromise<T> {
|
||||
public getProxyObject(): Promise<T> {
|
||||
return this._lazyProxy;
|
||||
}
|
||||
|
||||
private _request(method: string, args: any[]): TPromise<any> {
|
||||
return new TPromise<any>((c, e) => {
|
||||
private _request(method: string, args: any[]): Promise<any> {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
this._onModuleLoaded.then(() => {
|
||||
this._protocol.sendMessage(method, args).then(c, e);
|
||||
}, e);
|
||||
this._protocol.sendMessage(method, args).then(resolve, reject);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -300,7 +299,7 @@ export class SimpleWorkerServer {
|
||||
sendMessage: (msg: string): void => {
|
||||
postSerializedMessage(msg);
|
||||
},
|
||||
handleMessage: (method: string, args: any[]): TPromise<any> => this._handleMessage(method, args)
|
||||
handleMessage: (method: string, args: any[]): Promise<any> => this._handleMessage(method, args)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -308,23 +307,23 @@ export class SimpleWorkerServer {
|
||||
this._protocol.handleMessage(msg);
|
||||
}
|
||||
|
||||
private _handleMessage(method: string, args: any[]): TPromise<any> {
|
||||
private _handleMessage(method: string, args: any[]): Promise<any> {
|
||||
if (method === INITIALIZE) {
|
||||
return this.initialize(<number>args[0], <string>args[1], <any>args[2]);
|
||||
}
|
||||
|
||||
if (!this._requestHandler || typeof this._requestHandler[method] !== 'function') {
|
||||
return TPromise.wrapError(new Error('Missing requestHandler or method: ' + method));
|
||||
return Promise.reject(new Error('Missing requestHandler or method: ' + method));
|
||||
}
|
||||
|
||||
try {
|
||||
return TPromise.as(this._requestHandler[method].apply(this._requestHandler, args));
|
||||
return Promise.resolve(this._requestHandler[method].apply(this._requestHandler, args));
|
||||
} catch (e) {
|
||||
return TPromise.wrapError(e);
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
private initialize(workerId: number, moduleId: string, loaderConfig: any): TPromise<any> {
|
||||
private initialize(workerId: number, moduleId: string, loaderConfig: any): Promise<string[]> {
|
||||
this._protocol.setWorkerId(workerId);
|
||||
|
||||
if (this._requestHandler) {
|
||||
@@ -335,7 +334,7 @@ export class SimpleWorkerServer {
|
||||
methods.push(prop);
|
||||
}
|
||||
}
|
||||
return TPromise.as(methods);
|
||||
return Promise.resolve(methods);
|
||||
}
|
||||
|
||||
if (loaderConfig) {
|
||||
@@ -354,11 +353,11 @@ export class SimpleWorkerServer {
|
||||
(<any>self).require.config(loaderConfig);
|
||||
}
|
||||
|
||||
let cc: ValueCallback;
|
||||
let ee: ErrorCallback;
|
||||
let r = new TPromise<any>((c, e) => {
|
||||
cc = c;
|
||||
ee = e;
|
||||
let resolve: (value?: string[]) => void;
|
||||
let reject: (error?: any) => void;
|
||||
let r = new Promise<string[]>((_resolve, _reject) => {
|
||||
resolve = _resolve;
|
||||
reject = _reject;
|
||||
});
|
||||
|
||||
// Use the global require to be sure to get the global config
|
||||
@@ -373,8 +372,8 @@ export class SimpleWorkerServer {
|
||||
}
|
||||
}
|
||||
|
||||
cc(methods);
|
||||
}, ee);
|
||||
resolve(methods);
|
||||
}, reject);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -391,4 +391,16 @@ suite('Strings', () => {
|
||||
assert.equal(strings.uppercaseFirstLetter(inStr), result, `Wrong result for ${inStr}`);
|
||||
});
|
||||
});
|
||||
|
||||
test('getNLines', () => {
|
||||
assert.equal(strings.getNLines('', 5), '');
|
||||
assert.equal(strings.getNLines('foo', 5), 'foo');
|
||||
assert.equal(strings.getNLines('foo\nbar', 5), 'foo\nbar');
|
||||
assert.equal(strings.getNLines('foo\nbar', 2), 'foo\nbar');
|
||||
|
||||
assert.equal(strings.getNLines('foo\nbar', 1), 'foo');
|
||||
assert.equal(strings.getNLines('foo\nbar'), 'foo');
|
||||
assert.equal(strings.getNLines('foo\nbar\nsomething', 2), 'foo\nbar');
|
||||
assert.equal(strings.getNLines('foo', 0), '');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,14 +5,7 @@
|
||||
|
||||
import * as nativeKeymap from 'native-keymap';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IStateService } from 'vs/platform/state/common/state';
|
||||
import { Event, Emitter, once } from 'vs/base/common/event';
|
||||
import { ConfigWatcher } from 'vs/base/node/config';
|
||||
import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ipcMain as ipc } from 'electron';
|
||||
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
|
||||
export class KeyboardLayoutMonitor {
|
||||
|
||||
@@ -36,109 +29,4 @@ export class KeyboardLayoutMonitor {
|
||||
}
|
||||
return this._emitter.event(callback);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IKeybinding {
|
||||
id: string;
|
||||
label: string;
|
||||
isNative: boolean;
|
||||
}
|
||||
|
||||
export class KeybindingsResolver {
|
||||
|
||||
private static readonly lastKnownKeybindingsMapStorageKey = 'lastKnownKeybindings';
|
||||
|
||||
private commandIds: Set<string>;
|
||||
private keybindings: { [commandId: string]: IKeybinding };
|
||||
private keybindingsWatcher: ConfigWatcher<IUserFriendlyKeybinding[]>;
|
||||
|
||||
private _onKeybindingsChanged = new Emitter<void>();
|
||||
onKeybindingsChanged: Event<void> = this._onKeybindingsChanged.event;
|
||||
|
||||
constructor(
|
||||
@IStateService private stateService: IStateService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@IWindowsMainService private windowsMainService: IWindowsMainService,
|
||||
@ILogService private logService: ILogService
|
||||
) {
|
||||
this.commandIds = new Set<string>();
|
||||
this.keybindings = this.stateService.getItem<{ [id: string]: string; }>(KeybindingsResolver.lastKnownKeybindingsMapStorageKey) || Object.create(null);
|
||||
this.keybindingsWatcher = new ConfigWatcher<IUserFriendlyKeybinding[]>(environmentService.appKeybindingsPath, { changeBufferDelay: 100, onError: error => this.logService.error(error) });
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
|
||||
// Listen to resolved keybindings from window
|
||||
ipc.on('vscode:keybindingsResolved', (event, rawKeybindings: string) => {
|
||||
let keybindings: IKeybinding[] = [];
|
||||
try {
|
||||
keybindings = JSON.parse(rawKeybindings);
|
||||
} catch (error) {
|
||||
// Should not happen
|
||||
}
|
||||
|
||||
// Fill hash map of resolved keybindings and check for changes
|
||||
let keybindingsChanged = false;
|
||||
let keybindingsCount = 0;
|
||||
const resolvedKeybindings: { [commandId: string]: IKeybinding } = Object.create(null);
|
||||
keybindings.forEach(keybinding => {
|
||||
keybindingsCount++;
|
||||
|
||||
resolvedKeybindings[keybinding.id] = keybinding;
|
||||
|
||||
if (!this.keybindings[keybinding.id] || keybinding.label !== this.keybindings[keybinding.id].label) {
|
||||
keybindingsChanged = true;
|
||||
}
|
||||
});
|
||||
|
||||
// A keybinding might have been unassigned, so we have to account for that too
|
||||
if (Object.keys(this.keybindings).length !== keybindingsCount) {
|
||||
keybindingsChanged = true;
|
||||
}
|
||||
|
||||
if (keybindingsChanged) {
|
||||
this.keybindings = resolvedKeybindings;
|
||||
this.stateService.setItem(KeybindingsResolver.lastKnownKeybindingsMapStorageKey, this.keybindings); // keep to restore instantly after restart
|
||||
|
||||
this._onKeybindingsChanged.fire();
|
||||
}
|
||||
});
|
||||
|
||||
// Resolve keybindings when any first window is loaded
|
||||
const onceOnWindowReady = once(this.windowsMainService.onWindowReady);
|
||||
onceOnWindowReady(win => this.resolveKeybindings(win));
|
||||
|
||||
// Resolve keybindings again when keybindings.json changes
|
||||
this.keybindingsWatcher.onDidUpdateConfiguration(() => this.resolveKeybindings());
|
||||
|
||||
// Resolve keybindings when window reloads because an installed extension could have an impact
|
||||
this.windowsMainService.onWindowReload(() => this.resolveKeybindings());
|
||||
}
|
||||
|
||||
private resolveKeybindings(win = this.windowsMainService.getLastActiveWindow()): void {
|
||||
if (this.commandIds.size && win) {
|
||||
const commandIds: string[] = [];
|
||||
this.commandIds.forEach(id => commandIds.push(id));
|
||||
win.sendWhenReady('vscode:resolveKeybindings', JSON.stringify(commandIds));
|
||||
}
|
||||
}
|
||||
|
||||
public getKeybinding(commandId: string): IKeybinding {
|
||||
if (!commandId) {
|
||||
return void 0;
|
||||
}
|
||||
|
||||
if (!this.commandIds.has(commandId)) {
|
||||
this.commandIds.add(commandId);
|
||||
}
|
||||
|
||||
return this.keybindings[commandId];
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._onKeybindingsChanged.dispose();
|
||||
this.keybindingsWatcher.dispose();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -138,7 +138,7 @@ export class ViewCursor {
|
||||
width = dom.computeScreenAwareSize(1);
|
||||
}
|
||||
let left = visibleRange.left;
|
||||
if (width >= 2) {
|
||||
if (width >= 2 && left >= 1) {
|
||||
// try to center cursor
|
||||
left -= 1;
|
||||
}
|
||||
|
||||
@@ -287,9 +287,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
||||
action.label,
|
||||
action.alias,
|
||||
action.precondition,
|
||||
(): void | TPromise<void> => {
|
||||
(): Promise<void> => {
|
||||
return this._instantiationService.invokeFunction((accessor) => {
|
||||
return action.runEditorCommand(accessor, this, null);
|
||||
return Promise.resolve(action.runEditorCommand(accessor, this, null));
|
||||
});
|
||||
},
|
||||
this._contextKeyService
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IEditorAction } from 'vs/editor/common/editorCommon';
|
||||
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
@@ -14,7 +13,7 @@ export class InternalEditorAction implements IEditorAction {
|
||||
public readonly alias: string;
|
||||
|
||||
private readonly _precondition: ContextKeyExpr;
|
||||
private readonly _run: () => void | TPromise<void>;
|
||||
private readonly _run: () => Promise<void>;
|
||||
private readonly _contextKeyService: IContextKeyService;
|
||||
|
||||
constructor(
|
||||
@@ -22,7 +21,7 @@ export class InternalEditorAction implements IEditorAction {
|
||||
label: string,
|
||||
alias: string,
|
||||
precondition: ContextKeyExpr,
|
||||
run: () => void,
|
||||
run: () => Promise<void>,
|
||||
contextKeyService: IContextKeyService
|
||||
) {
|
||||
this.id = id;
|
||||
@@ -37,12 +36,12 @@ export class InternalEditorAction implements IEditorAction {
|
||||
return this._contextKeyService.contextMatchesRules(this._precondition);
|
||||
}
|
||||
|
||||
public run(): TPromise<void> {
|
||||
public run(): Promise<void> {
|
||||
if (!this.isSupported()) {
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve(void 0);
|
||||
}
|
||||
|
||||
const r = this._run();
|
||||
return r ? r : TPromise.as(void 0);
|
||||
return r ? r : Promise.resolve(void 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
@@ -185,7 +184,7 @@ export interface IEditorAction {
|
||||
readonly label: string;
|
||||
readonly alias: string;
|
||||
isSupported(): boolean;
|
||||
run(): TPromise<void>;
|
||||
run(): Promise<void>;
|
||||
}
|
||||
|
||||
export type IEditorModel = ITextModel | IDiffEditorModel;
|
||||
|
||||
@@ -111,8 +111,8 @@ export function guessIndentation(source: ITextBuffer, defaultTabSize: number, de
|
||||
let previousLineText = ''; // content of latest line that contained non-whitespace chars
|
||||
let previousLineIndentation = 0; // index at which latest line contained the first non-whitespace char
|
||||
|
||||
const ALLOWED_TAB_SIZE_GUESSES = [2, 4, 6, 8]; // limit guesses for `tabSize` to 2, 4, 6 or 8.
|
||||
const MAX_ALLOWED_TAB_SIZE_GUESS = 8; // max(2,4,6,8) = 8
|
||||
const ALLOWED_TAB_SIZE_GUESSES = [2, 4, 6, 8, 3, 5, 7]; // prefer even guesses for `tabSize`, limit to [2, 8].
|
||||
const MAX_ALLOWED_TAB_SIZE_GUESS = 8; // max(ALLOWED_TAB_SIZE_GUESSES) = 8
|
||||
|
||||
let spacesDiffCount = [0, 0, 0, 0, 0, 0, 0, 0, 0]; // `tabSize` scores
|
||||
let tmp = new SpacesDiffResult();
|
||||
|
||||
@@ -26,34 +26,6 @@ export class SearchParams {
|
||||
this.wordSeparators = wordSeparators;
|
||||
}
|
||||
|
||||
private static _isMultilineRegexSource(searchString: string): boolean {
|
||||
if (!searchString || searchString.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0, len = searchString.length; i < len; i++) {
|
||||
const chCode = searchString.charCodeAt(i);
|
||||
|
||||
if (chCode === CharCode.Backslash) {
|
||||
|
||||
// move to next char
|
||||
i++;
|
||||
|
||||
if (i >= len) {
|
||||
// string ends with a \
|
||||
break;
|
||||
}
|
||||
|
||||
const nextChCode = searchString.charCodeAt(i);
|
||||
if (nextChCode === CharCode.n || nextChCode === CharCode.r || nextChCode === CharCode.W) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public parseSearchRequest(): SearchData {
|
||||
if (this.searchString === '') {
|
||||
return null;
|
||||
@@ -62,7 +34,7 @@ export class SearchParams {
|
||||
// Try to create a RegExp out of the params
|
||||
let multiline: boolean;
|
||||
if (this.isRegex) {
|
||||
multiline = SearchParams._isMultilineRegexSource(this.searchString);
|
||||
multiline = isMultilineRegexSource(this.searchString);
|
||||
} else {
|
||||
multiline = (this.searchString.indexOf('\n') >= 0);
|
||||
}
|
||||
@@ -93,6 +65,34 @@ export class SearchParams {
|
||||
}
|
||||
}
|
||||
|
||||
export function isMultilineRegexSource(searchString: string): boolean {
|
||||
if (!searchString || searchString.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0, len = searchString.length; i < len; i++) {
|
||||
const chCode = searchString.charCodeAt(i);
|
||||
|
||||
if (chCode === CharCode.Backslash) {
|
||||
|
||||
// move to next char
|
||||
i++;
|
||||
|
||||
if (i >= len) {
|
||||
// string ends with a \
|
||||
break;
|
||||
}
|
||||
|
||||
const nextChCode = searchString.charCodeAt(i);
|
||||
if (nextChCode === CharCode.n || nextChCode === CharCode.r || nextChCode === CharCode.W) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export class SearchData {
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IRequestHandler } from 'vs/base/common/worker/simpleWorker';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
@@ -336,7 +335,7 @@ export abstract class BaseEditorSimpleWorker {
|
||||
|
||||
// ---- BEGIN diff --------------------------------------------------------------------------
|
||||
|
||||
public computeDiff(originalUrl: string, modifiedUrl: string, ignoreTrimWhitespace: boolean): TPromise<editorCommon.ILineChange[]> {
|
||||
public computeDiff(originalUrl: string, modifiedUrl: string, ignoreTrimWhitespace: boolean): Promise<editorCommon.ILineChange[]> {
|
||||
let original = this._getModel(originalUrl);
|
||||
let modified = this._getModel(modifiedUrl);
|
||||
if (!original || !modified) {
|
||||
@@ -351,10 +350,10 @@ export abstract class BaseEditorSimpleWorker {
|
||||
shouldIgnoreTrimWhitespace: ignoreTrimWhitespace,
|
||||
shouldMakePrettyDiff: true
|
||||
});
|
||||
return TPromise.as(diffComputer.computeDiff());
|
||||
return Promise.resolve(diffComputer.computeDiff());
|
||||
}
|
||||
|
||||
public computeDirtyDiff(originalUrl: string, modifiedUrl: string, ignoreTrimWhitespace: boolean): TPromise<editorCommon.IChange[]> {
|
||||
public computeDirtyDiff(originalUrl: string, modifiedUrl: string, ignoreTrimWhitespace: boolean): Promise<editorCommon.IChange[]> {
|
||||
let original = this._getModel(originalUrl);
|
||||
let modified = this._getModel(modifiedUrl);
|
||||
if (!original || !modified) {
|
||||
@@ -369,7 +368,7 @@ export abstract class BaseEditorSimpleWorker {
|
||||
shouldIgnoreTrimWhitespace: ignoreTrimWhitespace,
|
||||
shouldMakePrettyDiff: true
|
||||
});
|
||||
return TPromise.as(diffComputer.computeDiff());
|
||||
return Promise.resolve(diffComputer.computeDiff());
|
||||
}
|
||||
|
||||
// ---- END diff --------------------------------------------------------------------------
|
||||
@@ -379,10 +378,10 @@ export abstract class BaseEditorSimpleWorker {
|
||||
|
||||
private static readonly _diffLimit = 10000;
|
||||
|
||||
public computeMoreMinimalEdits(modelUrl: string, edits: TextEdit[]): TPromise<TextEdit[]> {
|
||||
public computeMoreMinimalEdits(modelUrl: string, edits: TextEdit[]): Promise<TextEdit[]> {
|
||||
const model = this._getModel(modelUrl);
|
||||
if (!model) {
|
||||
return TPromise.as(edits);
|
||||
return Promise.resolve(edits);
|
||||
}
|
||||
|
||||
const result: TextEdit[] = [];
|
||||
@@ -437,25 +436,25 @@ export abstract class BaseEditorSimpleWorker {
|
||||
result.push({ eol: lastEol, text: undefined, range: undefined });
|
||||
}
|
||||
|
||||
return TPromise.as(result);
|
||||
return Promise.resolve(result);
|
||||
}
|
||||
|
||||
// ---- END minimal edits ---------------------------------------------------------------
|
||||
|
||||
public computeLinks(modelUrl: string): TPromise<ILink[]> {
|
||||
public computeLinks(modelUrl: string): Promise<ILink[]> {
|
||||
let model = this._getModel(modelUrl);
|
||||
if (!model) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return TPromise.as(computeLinks(model));
|
||||
return Promise.resolve(computeLinks(model));
|
||||
}
|
||||
|
||||
// ---- BEGIN suggest --------------------------------------------------------------------------
|
||||
|
||||
private static readonly _suggestionsLimit = 10000;
|
||||
|
||||
public textualSuggest(modelUrl: string, position: IPosition, wordDef: string, wordDefFlags: string): TPromise<CompletionList> {
|
||||
public textualSuggest(modelUrl: string, position: IPosition, wordDef: string, wordDefFlags: string): Promise<CompletionList> {
|
||||
const model = this._getModel(modelUrl);
|
||||
if (model) {
|
||||
const suggestions: CompletionItem[] = [];
|
||||
@@ -488,7 +487,7 @@ export abstract class BaseEditorSimpleWorker {
|
||||
});
|
||||
}
|
||||
|
||||
return TPromise.as({ suggestions });
|
||||
return Promise.resolve({ suggestions });
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -529,7 +528,7 @@ export abstract class BaseEditorSimpleWorker {
|
||||
|
||||
//#endregion
|
||||
|
||||
public navigateValueSet(modelUrl: string, range: IRange, up: boolean, wordDef: string, wordDefFlags: string): TPromise<IInplaceReplaceSupportResult> {
|
||||
public navigateValueSet(modelUrl: string, range: IRange, up: boolean, wordDef: string, wordDefFlags: string): Promise<IInplaceReplaceSupportResult> {
|
||||
let model = this._getModel(modelUrl);
|
||||
if (!model) {
|
||||
return null;
|
||||
@@ -555,12 +554,12 @@ export abstract class BaseEditorSimpleWorker {
|
||||
}
|
||||
|
||||
let result = BasicInplaceReplace.INSTANCE.navigateValueSet(range, selectionText, wordRange, word, up);
|
||||
return TPromise.as(result);
|
||||
return Promise.resolve(result);
|
||||
}
|
||||
|
||||
// ---- BEGIN foreign module support --------------------------------------------------------------------------
|
||||
|
||||
public loadForeignModule(moduleId: string, createData: any): TPromise<string[]> {
|
||||
public loadForeignModule(moduleId: string, createData: any): Promise<string[]> {
|
||||
let ctx: IWorkerContext = {
|
||||
getMirrorModels: (): IMirrorModel[] => {
|
||||
return this._getModels();
|
||||
@@ -576,10 +575,10 @@ export abstract class BaseEditorSimpleWorker {
|
||||
methods.push(prop);
|
||||
}
|
||||
}
|
||||
return TPromise.as(methods);
|
||||
return Promise.resolve(methods);
|
||||
}
|
||||
// ESM-comment-begin
|
||||
return new TPromise<any>((c, e) => {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
require([moduleId], (foreignModule: { create: IForeignModuleFactory }) => {
|
||||
this._foreignModule = foreignModule.create(ctx, createData);
|
||||
|
||||
@@ -590,27 +589,27 @@ export abstract class BaseEditorSimpleWorker {
|
||||
}
|
||||
}
|
||||
|
||||
c(methods);
|
||||
resolve(methods);
|
||||
|
||||
}, e);
|
||||
}, reject);
|
||||
});
|
||||
// ESM-comment-end
|
||||
|
||||
// ESM-uncomment-begin
|
||||
// return TPromise.wrapError(new Error(`Unexpected usage`));
|
||||
// return Promise.reject(new Error(`Unexpected usage`));
|
||||
// ESM-uncomment-end
|
||||
}
|
||||
|
||||
// foreign method request
|
||||
public fmr(method: string, args: any[]): TPromise<any> {
|
||||
public fmr(method: string, args: any[]): Promise<any> {
|
||||
if (!this._foreignModule || typeof this._foreignModule[method] !== 'function') {
|
||||
return TPromise.wrapError(new Error('Missing requestHandler or method: ' + method));
|
||||
return Promise.reject(new Error('Missing requestHandler or method: ' + method));
|
||||
}
|
||||
|
||||
try {
|
||||
return TPromise.as(this._foreignModule[method].apply(this._foreignModule, args));
|
||||
return Promise.resolve(this._foreignModule[method].apply(this._foreignModule, args));
|
||||
} catch (e) {
|
||||
return TPromise.wrapError(e);
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IChange, ILineChange } from 'vs/editor/common/editorCommon';
|
||||
import { IInplaceReplaceSupportResult, TextEdit } from 'vs/editor/common/modes';
|
||||
@@ -17,16 +16,16 @@ export interface IEditorWorkerService {
|
||||
_serviceBrand: any;
|
||||
|
||||
canComputeDiff(original: URI, modified: URI): boolean;
|
||||
computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): TPromise<ILineChange[]>;
|
||||
computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<ILineChange[]>;
|
||||
|
||||
canComputeDirtyDiff(original: URI, modified: URI): boolean;
|
||||
computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): TPromise<IChange[]>;
|
||||
computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<IChange[]>;
|
||||
|
||||
computeMoreMinimalEdits(resource: URI, edits: TextEdit[]): TPromise<TextEdit[]>;
|
||||
computeMoreMinimalEdits(resource: URI, edits: TextEdit[]): Promise<TextEdit[]>;
|
||||
|
||||
canComputeWordRanges(resource: URI): boolean;
|
||||
computeWordRanges(resource: URI, range: IRange): TPromise<{ [word: string]: IRange[] }>;
|
||||
computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] }>;
|
||||
|
||||
canNavigateValueSet(resource: URI): boolean;
|
||||
navigateValueSet(resource: URI, range: IRange, up: boolean): TPromise<IInplaceReplaceSupportResult>;
|
||||
navigateValueSet(resource: URI, range: IRange, up: boolean): Promise<IInplaceReplaceSupportResult>;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import { IntervalTimer } from 'vs/base/common/async';
|
||||
import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { SimpleWorkerClient, logOnceWebWorkerWarning } from 'vs/base/common/worker/simpleWorker';
|
||||
import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
@@ -60,7 +59,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
||||
this._register(modes.LinkProviderRegistry.register('*', <modes.LinkProvider>{
|
||||
provideLinks: (model, token) => {
|
||||
if (!canSyncModel(this._modelService, model.uri)) {
|
||||
return TPromise.as([]); // File too large
|
||||
return Promise.resolve([]); // File too large
|
||||
}
|
||||
return this._workerManager.withWorker().then(client => client.computeLinks(model.uri));
|
||||
}
|
||||
@@ -76,7 +75,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
||||
return (canSyncModel(this._modelService, original) && canSyncModel(this._modelService, modified));
|
||||
}
|
||||
|
||||
public computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): TPromise<editorCommon.ILineChange[]> {
|
||||
public computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<editorCommon.ILineChange[]> {
|
||||
return this._workerManager.withWorker().then(client => client.computeDiff(original, modified, ignoreTrimWhitespace));
|
||||
}
|
||||
|
||||
@@ -84,16 +83,16 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
||||
return (canSyncModel(this._modelService, original) && canSyncModel(this._modelService, modified));
|
||||
}
|
||||
|
||||
public computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): TPromise<editorCommon.IChange[]> {
|
||||
public computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<editorCommon.IChange[]> {
|
||||
return this._workerManager.withWorker().then(client => client.computeDirtyDiff(original, modified, ignoreTrimWhitespace));
|
||||
}
|
||||
|
||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[]): TPromise<modes.TextEdit[]> {
|
||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[]): Promise<modes.TextEdit[]> {
|
||||
if (!Array.isArray(edits) || edits.length === 0) {
|
||||
return TPromise.as(edits);
|
||||
return Promise.resolve(edits);
|
||||
} else {
|
||||
if (!canSyncModel(this._modelService, resource)) {
|
||||
return TPromise.as(edits); // File too large
|
||||
return Promise.resolve(edits); // File too large
|
||||
}
|
||||
return this._workerManager.withWorker().then(client => client.computeMoreMinimalEdits(resource, edits));
|
||||
}
|
||||
@@ -103,7 +102,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
||||
return (canSyncModel(this._modelService, resource));
|
||||
}
|
||||
|
||||
public navigateValueSet(resource: URI, range: IRange, up: boolean): TPromise<modes.IInplaceReplaceSupportResult> {
|
||||
public navigateValueSet(resource: URI, range: IRange, up: boolean): Promise<modes.IInplaceReplaceSupportResult> {
|
||||
return this._workerManager.withWorker().then(client => client.navigateValueSet(resource, range, up));
|
||||
}
|
||||
|
||||
@@ -111,7 +110,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
||||
return canSyncModel(this._modelService, resource);
|
||||
}
|
||||
|
||||
computeWordRanges(resource: URI, range: IRange): TPromise<{ [word: string]: IRange[] }> {
|
||||
computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] }> {
|
||||
return this._workerManager.withWorker().then(client => client.computeWordRanges(resource, range));
|
||||
}
|
||||
}
|
||||
@@ -132,7 +131,7 @@ class WordBasedCompletionItemProvider implements modes.CompletionItemProvider {
|
||||
this._modelService = modelService;
|
||||
}
|
||||
|
||||
provideCompletionItems(model: ITextModel, position: Position): TPromise<modes.CompletionList> {
|
||||
provideCompletionItems(model: ITextModel, position: Position): Promise<modes.CompletionList> {
|
||||
const { wordBasedSuggestions } = this._configurationService.getValue<IEditorOptions>(model.uri, position, 'editor');
|
||||
if (!wordBasedSuggestions) {
|
||||
return undefined;
|
||||
@@ -200,12 +199,12 @@ class WorkerManager extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public withWorker(): TPromise<EditorWorkerClient> {
|
||||
public withWorker(): Promise<EditorWorkerClient> {
|
||||
this._lastWorkerUsedTime = (new Date()).getTime();
|
||||
if (!this._editorWorkerClient) {
|
||||
this._editorWorkerClient = new EditorWorkerClient(this._modelService, 'editorWorkerService');
|
||||
}
|
||||
return TPromise.as(this._editorWorkerClient);
|
||||
return Promise.resolve(this._editorWorkerClient);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,17 +307,17 @@ class EditorModelManager extends Disposable {
|
||||
}
|
||||
|
||||
interface IWorkerClient<T> {
|
||||
getProxyObject(): TPromise<T>;
|
||||
getProxyObject(): Promise<T>;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
class SynchronousWorkerClient<T extends IDisposable> implements IWorkerClient<T> {
|
||||
private _instance: T;
|
||||
private _proxyObj: TPromise<T>;
|
||||
private _proxyObj: Promise<T>;
|
||||
|
||||
constructor(instance: T) {
|
||||
this._instance = instance;
|
||||
this._proxyObj = TPromise.as(this._instance);
|
||||
this._proxyObj = Promise.resolve(this._instance);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -327,7 +326,7 @@ class SynchronousWorkerClient<T extends IDisposable> implements IWorkerClient<T>
|
||||
this._proxyObj = null;
|
||||
}
|
||||
|
||||
public getProxyObject(): TPromise<T> {
|
||||
public getProxyObject(): Promise<T> {
|
||||
return this._proxyObj;
|
||||
}
|
||||
}
|
||||
@@ -362,7 +361,7 @@ export class EditorWorkerClient extends Disposable {
|
||||
return this._worker;
|
||||
}
|
||||
|
||||
protected _getProxy(): TPromise<EditorSimpleWorkerImpl> {
|
||||
protected _getProxy(): Promise<EditorSimpleWorkerImpl> {
|
||||
return this._getOrCreateWorker().getProxyObject().then(null, (err) => {
|
||||
logOnceWebWorkerWarning(err);
|
||||
this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl(null));
|
||||
@@ -377,38 +376,38 @@ export class EditorWorkerClient extends Disposable {
|
||||
return this._modelManager;
|
||||
}
|
||||
|
||||
protected _withSyncedResources(resources: URI[]): TPromise<EditorSimpleWorkerImpl> {
|
||||
protected _withSyncedResources(resources: URI[]): Promise<EditorSimpleWorkerImpl> {
|
||||
return this._getProxy().then((proxy) => {
|
||||
this._getOrCreateModelManager(proxy).esureSyncedResources(resources);
|
||||
return proxy;
|
||||
});
|
||||
}
|
||||
|
||||
public computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): TPromise<editorCommon.ILineChange[]> {
|
||||
public computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<editorCommon.ILineChange[]> {
|
||||
return this._withSyncedResources([original, modified]).then(proxy => {
|
||||
return proxy.computeDiff(original.toString(), modified.toString(), ignoreTrimWhitespace);
|
||||
});
|
||||
}
|
||||
|
||||
public computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): TPromise<editorCommon.IChange[]> {
|
||||
public computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<editorCommon.IChange[]> {
|
||||
return this._withSyncedResources([original, modified]).then(proxy => {
|
||||
return proxy.computeDirtyDiff(original.toString(), modified.toString(), ignoreTrimWhitespace);
|
||||
});
|
||||
}
|
||||
|
||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[]): TPromise<modes.TextEdit[]> {
|
||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[]): Promise<modes.TextEdit[]> {
|
||||
return this._withSyncedResources([resource]).then(proxy => {
|
||||
return proxy.computeMoreMinimalEdits(resource.toString(), edits);
|
||||
});
|
||||
}
|
||||
|
||||
public computeLinks(resource: URI): TPromise<modes.ILink[]> {
|
||||
public computeLinks(resource: URI): Promise<modes.ILink[]> {
|
||||
return this._withSyncedResources([resource]).then(proxy => {
|
||||
return proxy.computeLinks(resource.toString());
|
||||
});
|
||||
}
|
||||
|
||||
public textualSuggest(resource: URI, position: IPosition): TPromise<modes.CompletionList> {
|
||||
public textualSuggest(resource: URI, position: IPosition): Promise<modes.CompletionList> {
|
||||
return this._withSyncedResources([resource]).then(proxy => {
|
||||
let model = this._modelService.getModel(resource);
|
||||
if (!model) {
|
||||
@@ -421,7 +420,7 @@ export class EditorWorkerClient extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
computeWordRanges(resource: URI, range: IRange): TPromise<{ [word: string]: IRange[] }> {
|
||||
computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] }> {
|
||||
return this._withSyncedResources([resource]).then(proxy => {
|
||||
let model = this._modelService.getModel(resource);
|
||||
if (!model) {
|
||||
@@ -434,7 +433,7 @@ export class EditorWorkerClient extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
public navigateValueSet(resource: URI, range: IRange, up: boolean): TPromise<modes.IInplaceReplaceSupportResult> {
|
||||
public navigateValueSet(resource: URI, range: IRange, up: boolean): Promise<modes.IInplaceReplaceSupportResult> {
|
||||
return this._withSyncedResources([resource]).then(proxy => {
|
||||
let model = this._modelService.getModel(resource);
|
||||
if (!model) {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { EditorWorkerClient } from 'vs/editor/common/services/editorWorkerServiceImpl';
|
||||
|
||||
@@ -27,12 +26,12 @@ export interface MonacoWebWorker<T> {
|
||||
/**
|
||||
* Get a proxy to the arbitrary loaded code.
|
||||
*/
|
||||
getProxy(): TPromise<T>;
|
||||
getProxy(): Promise<T>;
|
||||
/**
|
||||
* Synchronize (send) the models at `resources` to the web worker,
|
||||
* making them available in the monaco.worker.getMirrorModels().
|
||||
*/
|
||||
withSyncedResources(resources: URI[]): TPromise<T>;
|
||||
withSyncedResources(resources: URI[]): Promise<T>;
|
||||
}
|
||||
|
||||
export interface IWebWorkerOptions {
|
||||
@@ -55,7 +54,7 @@ class MonacoWebWorkerImpl<T> extends EditorWorkerClient implements MonacoWebWork
|
||||
|
||||
private _foreignModuleId: string;
|
||||
private _foreignModuleCreateData: any;
|
||||
private _foreignProxy: TPromise<T>;
|
||||
private _foreignProxy: Promise<T>;
|
||||
|
||||
constructor(modelService: IModelService, opts: IWebWorkerOptions) {
|
||||
super(modelService, opts.label);
|
||||
@@ -64,18 +63,18 @@ class MonacoWebWorkerImpl<T> extends EditorWorkerClient implements MonacoWebWork
|
||||
this._foreignProxy = null;
|
||||
}
|
||||
|
||||
private _getForeignProxy(): TPromise<T> {
|
||||
private _getForeignProxy(): Promise<T> {
|
||||
if (!this._foreignProxy) {
|
||||
this._foreignProxy = this._getProxy().then((proxy) => {
|
||||
return proxy.loadForeignModule(this._foreignModuleId, this._foreignModuleCreateData).then((foreignMethods) => {
|
||||
this._foreignModuleId = null;
|
||||
this._foreignModuleCreateData = null;
|
||||
|
||||
let proxyMethodRequest = (method: string, args: any[]): TPromise<any> => {
|
||||
let proxyMethodRequest = (method: string, args: any[]): Promise<any> => {
|
||||
return proxy.fmr(method, args);
|
||||
};
|
||||
|
||||
let createProxyMethod = (method: string, proxyMethodRequest: (method: string, args: any[]) => TPromise<any>): Function => {
|
||||
let createProxyMethod = (method: string, proxyMethodRequest: (method: string, args: any[]) => Promise<any>): Function => {
|
||||
return function () {
|
||||
let args = Array.prototype.slice.call(arguments, 0);
|
||||
return proxyMethodRequest(method, args);
|
||||
@@ -94,11 +93,11 @@ class MonacoWebWorkerImpl<T> extends EditorWorkerClient implements MonacoWebWork
|
||||
return this._foreignProxy;
|
||||
}
|
||||
|
||||
public getProxy(): TPromise<T> {
|
||||
public getProxy(): Promise<T> {
|
||||
return this._getForeignProxy();
|
||||
}
|
||||
|
||||
public withSyncedResources(resources: URI[]): TPromise<T> {
|
||||
public withSyncedResources(resources: URI[]): Promise<T> {
|
||||
return this._withSyncedResources(resources).then(_ => this.getProxy());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,13 +36,7 @@
|
||||
height: 34px; /* find input height */
|
||||
overflow: hidden;
|
||||
line-height: 19px;
|
||||
|
||||
-webkit-transition: top 200ms linear;
|
||||
-o-transition: top 200ms linear;
|
||||
-moz-transition: top 200ms linear;
|
||||
-ms-transition: top 200ms linear;
|
||||
transition: top 200ms linear;
|
||||
|
||||
padding: 0 4px;
|
||||
}
|
||||
/* Find widget when replace is toggled on */
|
||||
@@ -253,7 +247,7 @@
|
||||
|
||||
/* COLLAPSED (SMALLER THAN NARROW) */
|
||||
.monaco-editor .find-widget.collapsed-find-widget {
|
||||
max-width: 111px !important;
|
||||
max-width: 170px !important;
|
||||
}
|
||||
|
||||
.monaco-editor .find-widget.collapsed-find-widget .button.previous,
|
||||
|
||||
@@ -22,11 +22,6 @@
|
||||
padding: 4px;
|
||||
align-items: center;
|
||||
pointer-events: all;
|
||||
|
||||
-webkit-transition: top 200ms linear;
|
||||
-o-transition: top 200ms linear;
|
||||
-moz-transition: top 200ms linear;
|
||||
-ms-transition: top 200ms linear;
|
||||
transition: top 200ms linear;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
}
|
||||
|
||||
.monaco-editor .parameter-hints-widget.visible {
|
||||
-webkit-transition: left .05s ease-in-out;
|
||||
-moz-transition: left .05s ease-in-out;
|
||||
-o-transition: left .05s ease-in-out;
|
||||
transition: left .05s ease-in-out;
|
||||
}
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ export class SuggestController implements IEditorContribution {
|
||||
/* __GDPR__
|
||||
"acceptSuggestion" : {
|
||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"multiline" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
"multiline" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
service.publicLog('acceptSuggestion', {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { ColorId, MetadataConsts, FontStyle, TokenizationRegistry, ITokenizationSupport } from 'vs/editor/common/modes';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
@@ -26,7 +25,7 @@ export interface IColorizerElementOptions extends IColorizerOptions {
|
||||
|
||||
export class Colorizer {
|
||||
|
||||
public static colorizeElement(themeService: IStandaloneThemeService, modeService: IModeService, domNode: HTMLElement, options: IColorizerElementOptions): TPromise<void> {
|
||||
public static colorizeElement(themeService: IStandaloneThemeService, modeService: IModeService, domNode: HTMLElement, options: IColorizerElementOptions): Promise<void> {
|
||||
options = options || {};
|
||||
let theme = options.theme || 'vs';
|
||||
let mimeType = options.mimeType || domNode.getAttribute('lang') || domNode.getAttribute('data-lang');
|
||||
@@ -45,7 +44,7 @@ export class Colorizer {
|
||||
return this.colorize(modeService, text, mimeType, options).then(render, (err) => console.error(err));
|
||||
}
|
||||
|
||||
public static colorize(modeService: IModeService, text: string, mimeType: string, options: IColorizerOptions): TPromise<string> {
|
||||
public static colorize(modeService: IModeService, text: string, mimeType: string, options: IColorizerOptions): Promise<string> {
|
||||
if (strings.startsWithUTF8BOM(text)) {
|
||||
text = text.substr(1);
|
||||
}
|
||||
@@ -62,10 +61,10 @@ export class Colorizer {
|
||||
|
||||
let tokenizationSupport = TokenizationRegistry.get(language);
|
||||
if (tokenizationSupport) {
|
||||
return TPromise.as(_colorize(lines, options.tabSize, tokenizationSupport));
|
||||
return Promise.resolve(_colorize(lines, options.tabSize, tokenizationSupport));
|
||||
}
|
||||
|
||||
return new TPromise<string>((resolve, reject) => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
let listener: IDisposable = null;
|
||||
let timeout: TimeoutTimer = null;
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import * as nls from 'vs/nls';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { matchesFuzzy } from 'vs/base/common/filters';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IContext, IHighlight, QuickOpenEntryGroup, QuickOpenModel } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { IAutoFocus, Mode } from 'vs/base/parts/quickopen/common/quickOpen';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
@@ -55,7 +54,7 @@ export class EditorActionCommandEntry extends QuickOpenEntryGroup {
|
||||
this.editor.focus();
|
||||
|
||||
try {
|
||||
let promise = this.action.run() || TPromise.as(null);
|
||||
let promise = this.action.run() || Promise.resolve();
|
||||
promise.then(null, onUnexpectedError);
|
||||
} catch (error) {
|
||||
onUnexpectedError(error);
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'vs/css!./quickOutline';
|
||||
import * as nls from 'vs/nls';
|
||||
import { matchesFuzzy } from 'vs/base/common/filters';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IContext, IHighlight, QuickOpenEntryGroup, QuickOpenModel } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { IAutoFocus, Mode } from 'vs/base/parts/quickopen/common/quickOpen';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
@@ -129,7 +128,7 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
|
||||
});
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): TPromise<void> {
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): Thenable<void> {
|
||||
|
||||
let model = editor.getModel();
|
||||
|
||||
@@ -138,13 +137,13 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
|
||||
}
|
||||
|
||||
// Resolve outline
|
||||
return TPromise.wrap(getDocumentSymbols(model, true, CancellationToken.None).then((result: DocumentSymbol[]) => {
|
||||
return getDocumentSymbols(model, true, CancellationToken.None).then((result: DocumentSymbol[]) => {
|
||||
if (result.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._run(editor, result);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private _run(editor: ICodeEditor, result: DocumentSymbol[]): void {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable, IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CommandsRegistry, ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands';
|
||||
@@ -72,7 +71,7 @@ export interface IActionDescriptor {
|
||||
* Method that will be executed when the action is triggered.
|
||||
* @param editor The editor instance is passed in as a convinience
|
||||
*/
|
||||
run(editor: ICodeEditor): void | TPromise<void>;
|
||||
run(editor: ICodeEditor): void | Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,9 +220,8 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon
|
||||
);
|
||||
const contextMenuGroupId = _descriptor.contextMenuGroupId || null;
|
||||
const contextMenuOrder = _descriptor.contextMenuOrder || 0;
|
||||
const run = (): TPromise<void> => {
|
||||
const r = _descriptor.run(this);
|
||||
return r ? r : TPromise.as(void 0);
|
||||
const run = (): Promise<void> => {
|
||||
return Promise.resolve(_descriptor.run(this));
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -240,14 +240,14 @@ export function createWebWorker<T>(opts: IWebWorkerOptions): MonacoWebWorker<T>
|
||||
/**
|
||||
* Colorize the contents of `domNode` using attribute `data-lang`.
|
||||
*/
|
||||
export function colorizeElement(domNode: HTMLElement, options: IColorizerElementOptions): TPromise<void> {
|
||||
export function colorizeElement(domNode: HTMLElement, options: IColorizerElementOptions): Promise<void> {
|
||||
return Colorizer.colorizeElement(StaticServices.standaloneThemeService.get(), StaticServices.modeService.get(), domNode, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorize `text` using language `languageId`.
|
||||
*/
|
||||
export function colorize(text: string, languageId: string, options: IColorizerOptions): TPromise<string> {
|
||||
export function colorize(text: string, languageId: string, options: IColorizerOptions): Promise<string> {
|
||||
return Colorizer.colorize(StaticServices.modeService.get(), text, languageId, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ suite('Editor Model - TextModel', () => {
|
||||
' ',
|
||||
' ',
|
||||
], 'whitespace lines don\'t count');
|
||||
assertGuess(true, 4, [
|
||||
assertGuess(true, 3, [
|
||||
'x',
|
||||
' x',
|
||||
' x',
|
||||
@@ -326,8 +326,8 @@ suite('Editor Model - TextModel', () => {
|
||||
' x',
|
||||
' x',
|
||||
' x',
|
||||
], 'odd number is not allowed: 6x3, 3x4');
|
||||
assertGuess(true, 4, [
|
||||
], '6x3, 3x4');
|
||||
assertGuess(true, 5, [
|
||||
'x',
|
||||
' x',
|
||||
' x',
|
||||
@@ -340,8 +340,12 @@ suite('Editor Model - TextModel', () => {
|
||||
' x',
|
||||
' x',
|
||||
' x',
|
||||
], 'odd number is not allowed: 6x5, 3x4');
|
||||
assertGuess(true, 4, [
|
||||
], '6x5, 3x4');
|
||||
assertGuess(true, 7, [
|
||||
'x',
|
||||
' x',
|
||||
' x',
|
||||
' x',
|
||||
'x',
|
||||
' x',
|
||||
' x',
|
||||
@@ -350,11 +354,7 @@ suite('Editor Model - TextModel', () => {
|
||||
' x',
|
||||
' x',
|
||||
' x',
|
||||
'x',
|
||||
' x',
|
||||
' x',
|
||||
' x',
|
||||
], 'odd number is not allowed: 6x7, 3x4');
|
||||
], '6x7, 1x5, 2x4');
|
||||
assertGuess(true, 2, [
|
||||
'x',
|
||||
' x',
|
||||
@@ -506,7 +506,7 @@ suite('Editor Model - TextModel', () => {
|
||||
' x',
|
||||
' x',
|
||||
], '6x4, 2x5, 4x8');
|
||||
assertGuess(true, undefined, [
|
||||
assertGuess(true, 3, [
|
||||
'x',
|
||||
' x',
|
||||
' x',
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Position } from 'vs/editor/common/core/position';
|
||||
import { FindMatch, EndOfLineSequence } from 'vs/editor/common/model';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { TextModelSearch, SearchParams, SearchData } from 'vs/editor/common/model/textModelSearch';
|
||||
import { TextModelSearch, SearchParams, SearchData, isMultilineRegexSource } from 'vs/editor/common/model/textModelSearch';
|
||||
import { getMapForWordSeparators } from 'vs/editor/common/controller/wordCharacterClassifier';
|
||||
import { USUAL_WORD_SEPARATORS } from 'vs/editor/common/model/wordHelper';
|
||||
|
||||
@@ -720,4 +720,17 @@ suite('TextModelSearch', () => {
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
test('isMultilineRegexSource', () => {
|
||||
assert(!isMultilineRegexSource('foo'));
|
||||
assert(!isMultilineRegexSource(''));
|
||||
assert(!isMultilineRegexSource('foo\\sbar'));
|
||||
assert(!isMultilineRegexSource('\\\\notnewline'));
|
||||
|
||||
assert(isMultilineRegexSource('foo\\nbar'));
|
||||
assert(isMultilineRegexSource('foo\\nbar\\s'));
|
||||
assert(isMultilineRegexSource('foo\\r\\n'));
|
||||
assert(isMultilineRegexSource('\\n'));
|
||||
assert(isMultilineRegexSource('foo\\W'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -94,4 +94,14 @@ suite('LanguageSelector', function () {
|
||||
assert.equal(score({ language: 'javascript', scheme: 'file', hasAccessToAllModels: true }, doc.uri, doc.langId, false), 10);
|
||||
assert.equal(score(['fooLang', '*', { language: '*', hasAccessToAllModels: true }], doc.uri, doc.langId, false), 5);
|
||||
});
|
||||
|
||||
test('Document selector match - unexpected result value #60232', function () {
|
||||
let selector = {
|
||||
language: 'json',
|
||||
scheme: 'file',
|
||||
pattern: '**/*.interface.json'
|
||||
};
|
||||
let value = score(selector, URI.parse('file:///C:/Users/zlhe/Desktop/test.interface.json'), 'json', true);
|
||||
assert.equal(value, 10);
|
||||
});
|
||||
});
|
||||
|
||||
+50
-45
@@ -19,10 +19,11 @@
|
||||
*---------------------------------------------------------------------------------------------
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var _amdLoaderGlobal = this;
|
||||
var _commonjsGlobal = typeof global === 'object' ? global : {};
|
||||
var AMDLoader;
|
||||
(function (AMDLoader) {
|
||||
AMDLoader.global = _amdLoaderGlobal;
|
||||
var Environment = /** @class */ (function () {
|
||||
var Environment = (function () {
|
||||
function Environment() {
|
||||
this._detected = false;
|
||||
this._isWindows = false;
|
||||
@@ -93,7 +94,7 @@ var AMDLoader;
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var AMDLoader;
|
||||
(function (AMDLoader) {
|
||||
var LoaderEvent = /** @class */ (function () {
|
||||
var LoaderEvent = (function () {
|
||||
function LoaderEvent(type, detail, timestamp) {
|
||||
this.type = type;
|
||||
this.detail = detail;
|
||||
@@ -102,7 +103,7 @@ var AMDLoader;
|
||||
return LoaderEvent;
|
||||
}());
|
||||
AMDLoader.LoaderEvent = LoaderEvent;
|
||||
var LoaderEventRecorder = /** @class */ (function () {
|
||||
var LoaderEventRecorder = (function () {
|
||||
function LoaderEventRecorder(loaderAvailableTimestamp) {
|
||||
this._events = [new LoaderEvent(1 /* LoaderAvailable */, '', loaderAvailableTimestamp)];
|
||||
}
|
||||
@@ -115,7 +116,7 @@ var AMDLoader;
|
||||
return LoaderEventRecorder;
|
||||
}());
|
||||
AMDLoader.LoaderEventRecorder = LoaderEventRecorder;
|
||||
var NullLoaderEventRecorder = /** @class */ (function () {
|
||||
var NullLoaderEventRecorder = (function () {
|
||||
function NullLoaderEventRecorder() {
|
||||
}
|
||||
NullLoaderEventRecorder.prototype.record = function (type, detail) {
|
||||
@@ -124,9 +125,9 @@ var AMDLoader;
|
||||
NullLoaderEventRecorder.prototype.getEvents = function () {
|
||||
return [];
|
||||
};
|
||||
NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder();
|
||||
return NullLoaderEventRecorder;
|
||||
}());
|
||||
NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder();
|
||||
AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder;
|
||||
})(AMDLoader || (AMDLoader = {}));
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
@@ -135,7 +136,7 @@ var AMDLoader;
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var AMDLoader;
|
||||
(function (AMDLoader) {
|
||||
var Utilities = /** @class */ (function () {
|
||||
var Utilities = (function () {
|
||||
function Utilities() {
|
||||
}
|
||||
/**
|
||||
@@ -221,11 +222,11 @@ var AMDLoader;
|
||||
}
|
||||
return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now());
|
||||
};
|
||||
Utilities.NEXT_ANONYMOUS_ID = 1;
|
||||
Utilities.PERFORMANCE_NOW_PROBED = false;
|
||||
Utilities.HAS_PERFORMANCE_NOW = false;
|
||||
return Utilities;
|
||||
}());
|
||||
Utilities.NEXT_ANONYMOUS_ID = 1;
|
||||
Utilities.PERFORMANCE_NOW_PROBED = false;
|
||||
Utilities.HAS_PERFORMANCE_NOW = false;
|
||||
AMDLoader.Utilities = Utilities;
|
||||
})(AMDLoader || (AMDLoader = {}));
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
@@ -234,7 +235,7 @@ var AMDLoader;
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
var AMDLoader;
|
||||
(function (AMDLoader) {
|
||||
var ConfigurationOptionsUtil = /** @class */ (function () {
|
||||
var ConfigurationOptionsUtil = (function () {
|
||||
function ConfigurationOptionsUtil() {
|
||||
}
|
||||
/**
|
||||
@@ -343,7 +344,7 @@ var AMDLoader;
|
||||
return ConfigurationOptionsUtil;
|
||||
}());
|
||||
AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil;
|
||||
var Configuration = /** @class */ (function () {
|
||||
var Configuration = (function () {
|
||||
function Configuration(env, options) {
|
||||
this._env = env;
|
||||
this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options);
|
||||
@@ -554,7 +555,7 @@ var AMDLoader;
|
||||
/**
|
||||
* Load `scriptSrc` only once (avoid multiple <script> tags)
|
||||
*/
|
||||
var OnlyOnceScriptLoader = /** @class */ (function () {
|
||||
var OnlyOnceScriptLoader = (function () {
|
||||
function OnlyOnceScriptLoader(env) {
|
||||
this._env = env;
|
||||
this._scriptLoader = null;
|
||||
@@ -596,7 +597,7 @@ var AMDLoader;
|
||||
};
|
||||
return OnlyOnceScriptLoader;
|
||||
}());
|
||||
var BrowserScriptLoader = /** @class */ (function () {
|
||||
var BrowserScriptLoader = (function () {
|
||||
function BrowserScriptLoader() {
|
||||
}
|
||||
/**
|
||||
@@ -634,7 +635,7 @@ var AMDLoader;
|
||||
};
|
||||
return BrowserScriptLoader;
|
||||
}());
|
||||
var WorkerScriptLoader = /** @class */ (function () {
|
||||
var WorkerScriptLoader = (function () {
|
||||
function WorkerScriptLoader() {
|
||||
}
|
||||
WorkerScriptLoader.prototype.load = function (moduleManager, scriptSrc, callback, errorback) {
|
||||
@@ -648,7 +649,7 @@ var AMDLoader;
|
||||
};
|
||||
return WorkerScriptLoader;
|
||||
}());
|
||||
var NodeScriptLoader = /** @class */ (function () {
|
||||
var NodeScriptLoader = (function () {
|
||||
function NodeScriptLoader(env) {
|
||||
this._env = env;
|
||||
this._didInitialize = false;
|
||||
@@ -719,7 +720,7 @@ var AMDLoader;
|
||||
var compileWrapper = script.runInThisContext(options);
|
||||
var dirname = that._path.dirname(filename);
|
||||
var require = makeRequireFunction(this);
|
||||
var args = [this.exports, require, this, filename, dirname, process, AMDLoader.global, Buffer];
|
||||
var args = [this.exports, require, this, filename, dirname, process, _commonjsGlobal, Buffer];
|
||||
var result = compileWrapper.apply(this.exports, args);
|
||||
that._processCachedData(moduleManager, script, cachedDataPath);
|
||||
return result;
|
||||
@@ -830,15 +831,17 @@ var AMDLoader;
|
||||
errorCode: 'cachedDataRejected',
|
||||
path: cachedDataPath
|
||||
});
|
||||
NodeScriptLoader._runSoon(function () { return _this._fs.unlink(cachedDataPath, function (err) {
|
||||
if (err) {
|
||||
moduleManager.getConfig().getOptionsLiteral().onNodeCachedData({
|
||||
errorCode: 'unlink',
|
||||
path: cachedDataPath,
|
||||
detail: err
|
||||
});
|
||||
}
|
||||
}); }, moduleManager.getConfig().getOptionsLiteral().nodeCachedDataWriteDelay);
|
||||
NodeScriptLoader._runSoon(function () {
|
||||
return _this._fs.unlink(cachedDataPath, function (err) {
|
||||
if (err) {
|
||||
moduleManager.getConfig().getOptionsLiteral().onNodeCachedData({
|
||||
errorCode: 'unlink',
|
||||
path: cachedDataPath,
|
||||
detail: err
|
||||
});
|
||||
}
|
||||
});
|
||||
}, moduleManager.getConfig().getOptionsLiteral().nodeCachedDataWriteDelay);
|
||||
}
|
||||
else if (script.cachedDataProduced) {
|
||||
// data produced => tell outside world
|
||||
@@ -847,24 +850,26 @@ var AMDLoader;
|
||||
length: script.cachedData.length
|
||||
});
|
||||
// data produced => write cache file
|
||||
NodeScriptLoader._runSoon(function () { return _this._fs.writeFile(cachedDataPath, script.cachedData, function (err) {
|
||||
if (err) {
|
||||
moduleManager.getConfig().getOptionsLiteral().onNodeCachedData({
|
||||
errorCode: 'writeFile',
|
||||
path: cachedDataPath,
|
||||
detail: err
|
||||
});
|
||||
}
|
||||
}); }, moduleManager.getConfig().getOptionsLiteral().nodeCachedDataWriteDelay);
|
||||
NodeScriptLoader._runSoon(function () {
|
||||
return _this._fs.writeFile(cachedDataPath, script.cachedData, function (err) {
|
||||
if (err) {
|
||||
moduleManager.getConfig().getOptionsLiteral().onNodeCachedData({
|
||||
errorCode: 'writeFile',
|
||||
path: cachedDataPath,
|
||||
detail: err
|
||||
});
|
||||
}
|
||||
});
|
||||
}, moduleManager.getConfig().getOptionsLiteral().nodeCachedDataWriteDelay);
|
||||
}
|
||||
};
|
||||
NodeScriptLoader._runSoon = function (callback, minTimeout) {
|
||||
var timeout = minTimeout + Math.ceil(Math.random() * minTimeout);
|
||||
setTimeout(callback, timeout);
|
||||
};
|
||||
NodeScriptLoader._BOM = 0xFEFF;
|
||||
return NodeScriptLoader;
|
||||
}());
|
||||
NodeScriptLoader._BOM = 0xFEFF;
|
||||
function createScriptLoader(env) {
|
||||
return new OnlyOnceScriptLoader(env);
|
||||
}
|
||||
@@ -878,7 +883,7 @@ var AMDLoader;
|
||||
(function (AMDLoader) {
|
||||
// ------------------------------------------------------------------------
|
||||
// ModuleIdResolver
|
||||
var ModuleIdResolver = /** @class */ (function () {
|
||||
var ModuleIdResolver = (function () {
|
||||
function ModuleIdResolver(fromModuleId) {
|
||||
var lastSlash = fromModuleId.lastIndexOf('/');
|
||||
if (lastSlash !== -1) {
|
||||
@@ -921,13 +926,13 @@ var AMDLoader;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
ModuleIdResolver.ROOT = new ModuleIdResolver('');
|
||||
return ModuleIdResolver;
|
||||
}());
|
||||
ModuleIdResolver.ROOT = new ModuleIdResolver('');
|
||||
AMDLoader.ModuleIdResolver = ModuleIdResolver;
|
||||
// ------------------------------------------------------------------------
|
||||
// Module
|
||||
var Module = /** @class */ (function () {
|
||||
var Module = (function () {
|
||||
function Module(id, strId, dependencies, callback, errorback, moduleIdResolver) {
|
||||
this.id = id;
|
||||
this.strId = strId;
|
||||
@@ -1017,7 +1022,7 @@ var AMDLoader;
|
||||
return Module;
|
||||
}());
|
||||
AMDLoader.Module = Module;
|
||||
var ModuleIdProvider = /** @class */ (function () {
|
||||
var ModuleIdProvider = (function () {
|
||||
function ModuleIdProvider() {
|
||||
this._nextId = 0;
|
||||
this._strModuleIdToIntModuleId = new Map();
|
||||
@@ -1044,17 +1049,17 @@ var AMDLoader;
|
||||
};
|
||||
return ModuleIdProvider;
|
||||
}());
|
||||
var RegularDependency = /** @class */ (function () {
|
||||
var RegularDependency = (function () {
|
||||
function RegularDependency(id) {
|
||||
this.id = id;
|
||||
}
|
||||
RegularDependency.EXPORTS = new RegularDependency(0 /* EXPORTS */);
|
||||
RegularDependency.MODULE = new RegularDependency(1 /* MODULE */);
|
||||
RegularDependency.REQUIRE = new RegularDependency(2 /* REQUIRE */);
|
||||
return RegularDependency;
|
||||
}());
|
||||
RegularDependency.EXPORTS = new RegularDependency(0 /* EXPORTS */);
|
||||
RegularDependency.MODULE = new RegularDependency(1 /* MODULE */);
|
||||
RegularDependency.REQUIRE = new RegularDependency(2 /* REQUIRE */);
|
||||
AMDLoader.RegularDependency = RegularDependency;
|
||||
var PluginDependency = /** @class */ (function () {
|
||||
var PluginDependency = (function () {
|
||||
function PluginDependency(id, pluginId, pluginParam) {
|
||||
this.id = id;
|
||||
this.pluginId = pluginId;
|
||||
@@ -1063,7 +1068,7 @@ var AMDLoader;
|
||||
return PluginDependency;
|
||||
}());
|
||||
AMDLoader.PluginDependency = PluginDependency;
|
||||
var ModuleManager = /** @class */ (function () {
|
||||
var ModuleManager = (function () {
|
||||
function ModuleManager(env, scriptLoader, defineFunc, requireFunc, loaderAvailableTimestamp) {
|
||||
if (loaderAvailableTimestamp === void 0) { loaderAvailableTimestamp = 0; }
|
||||
this._env = env;
|
||||
|
||||
@@ -27,6 +27,7 @@ export interface IBaseCommandAction {
|
||||
export interface ICommandAction extends IBaseCommandAction {
|
||||
iconLocation?: { dark: URI; light?: URI; };
|
||||
precondition?: ContextKeyExpr;
|
||||
toggled?: ContextKeyExpr;
|
||||
}
|
||||
|
||||
export interface ISerializableCommandAction extends IBaseCommandAction {
|
||||
@@ -220,7 +221,6 @@ export class ExecuteCommandAction extends Action {
|
||||
}
|
||||
|
||||
export class SubmenuItemAction extends Action {
|
||||
// private _options: IMenuActionOptions;
|
||||
|
||||
readonly item: ISubmenuItem;
|
||||
constructor(item: ISubmenuItem) {
|
||||
@@ -246,6 +246,8 @@ export class MenuItemAction extends ExecuteCommandAction {
|
||||
typeof item.title === 'string' ? super(item.id, item.title, commandService) : super(item.id, item.title.value, commandService);
|
||||
this._cssClass = undefined;
|
||||
this._enabled = !item.precondition || contextKeyService.contextMatchesRules(item.precondition);
|
||||
this._checked = item.toggled && contextKeyService.contextMatchesRules(item.toggled);
|
||||
|
||||
this._options = options || {};
|
||||
|
||||
this.item = item;
|
||||
|
||||
@@ -47,6 +47,11 @@ export class Menu implements IMenu {
|
||||
if (isIMenuItem(item) && item.command.precondition) {
|
||||
Menu._fillInKbExprKeys(item.command.precondition, keysFilter);
|
||||
}
|
||||
|
||||
// keep toggled keys for event if applicable
|
||||
if (isIMenuItem(item) && item.command.toggled) {
|
||||
Menu._fillInKbExprKeys(item.command.toggled, keysFilter);
|
||||
}
|
||||
}
|
||||
|
||||
// subscribe to context changes
|
||||
|
||||
@@ -186,7 +186,7 @@ export class InstantiationService implements IInstantiationService {
|
||||
|
||||
for (let { data } of roots) {
|
||||
// create instance and overwrite the service collections
|
||||
const instance = this._createServiceInstance(data.desc.ctor, data.desc.staticArguments, data._trace);
|
||||
const instance = this._createServiceInstanceWithOwner(data.id, data.desc.ctor, data.desc.staticArguments, data._trace);
|
||||
this._setServiceInstance(data.id, instance);
|
||||
graph.removeNode(data);
|
||||
}
|
||||
@@ -195,6 +195,14 @@ export class InstantiationService implements IInstantiationService {
|
||||
return <T>this._getServiceInstanceOrDescriptor(id);
|
||||
}
|
||||
|
||||
private _createServiceInstanceWithOwner<T>(id: ServiceIdentifier<T>, ctor: any, args: any[] = [], _trace: Trace): T {
|
||||
if (this._services.get(id) instanceof SyncDescriptor) {
|
||||
return this._createServiceInstance(ctor, args, _trace);
|
||||
} else {
|
||||
return this._parent._createServiceInstanceWithOwner(id, ctor, args, _trace);
|
||||
}
|
||||
}
|
||||
|
||||
protected _createServiceInstance<T>(ctor: any, args: any[] = [], _trace: Trace): T {
|
||||
return this._createInstance(ctor, args, _trace);
|
||||
}
|
||||
|
||||
@@ -11,13 +11,12 @@ export const IMenubarService = createDecorator<IMenubarService>('menubarService'
|
||||
export interface IMenubarService {
|
||||
_serviceBrand: any;
|
||||
|
||||
updateMenubar(windowId: number, menus: IMenubarData, additionalKeybindings?: Array<IMenubarKeybinding>): TPromise<void>;
|
||||
updateMenubar(windowId: number, menuData: IMenubarData): TPromise<void>;
|
||||
}
|
||||
|
||||
export interface IMenubarData {
|
||||
'Files'?: IMenubarMenu;
|
||||
'Edit'?: IMenubarMenu;
|
||||
[id: string]: IMenubarMenu;
|
||||
menus: { [id: string]: IMenubarMenu };
|
||||
keybindings: { [id: string]: IMenubarKeybinding };
|
||||
}
|
||||
|
||||
export interface IMenubarMenu {
|
||||
@@ -25,17 +24,15 @@ export interface IMenubarMenu {
|
||||
}
|
||||
|
||||
export interface IMenubarKeybinding {
|
||||
id: string;
|
||||
label: string;
|
||||
isNative: boolean;
|
||||
isNative?: boolean; // Assumed true if missing
|
||||
}
|
||||
|
||||
export interface IMenubarMenuItemAction {
|
||||
id: string;
|
||||
label: string;
|
||||
checked: boolean;
|
||||
enabled: boolean;
|
||||
keybinding?: IMenubarKeybinding;
|
||||
checked?: boolean; // Assumed false if missing
|
||||
enabled?: boolean; // Assumed true if missing
|
||||
}
|
||||
|
||||
export interface IMenubarMenuItemSubmenu {
|
||||
@@ -54,10 +51,10 @@ export function isMenubarMenuItemSubmenu(menuItem: MenubarMenuItem): menuItem is
|
||||
return (<IMenubarMenuItemSubmenu>menuItem).submenu !== undefined;
|
||||
}
|
||||
|
||||
export function isMenubarMenuItemAction(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemAction {
|
||||
return (<IMenubarMenuItemAction>menuItem).checked !== undefined || (<IMenubarMenuItemAction>menuItem).enabled !== undefined;
|
||||
}
|
||||
|
||||
export function isMenubarMenuItemSeparator(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemSeparator {
|
||||
return (<IMenubarMenuItemSeparator>menuItem).id === 'vscode.menubar.separator';
|
||||
}
|
||||
|
||||
export function isMenubarMenuItemAction(menuItem: MenubarMenuItem): menuItem is IMenubarMenuItemAction {
|
||||
return !isMenubarMenuItemSubmenu(menuItem) && !isMenubarMenuItemSeparator(menuItem);
|
||||
}
|
||||
@@ -18,18 +18,22 @@ import { mnemonicMenuLabel as baseMnemonicLabel, unmnemonicLabel } from 'vs/base
|
||||
import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IHistoryMainService } from 'vs/platform/history/common/history';
|
||||
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction } from 'vs/platform/menubar/common/menubar';
|
||||
import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction, IMenubarMenu } from 'vs/platform/menubar/common/menubar';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IStateService } from 'vs/platform/state/common/state';
|
||||
|
||||
const telemetryFrom = 'menu';
|
||||
|
||||
interface IMenuItemClickHandler {
|
||||
inDevTools: (contents: Electron.WebContents) => void;
|
||||
inNoWindow: () => void;
|
||||
}
|
||||
|
||||
export class Menubar {
|
||||
|
||||
private static readonly MAX_MENU_RECENT_ENTRIES = 10;
|
||||
private static readonly lastKnownMenubarStorageKey = 'lastKnownMenubar';
|
||||
private static readonly lastKnownAdditionalKeybindings = 'lastKnownAdditionalKeybindings';
|
||||
private static readonly lastKnownMenubarStorageKey = 'lastKnownMenubarData';
|
||||
|
||||
private isQuitting: boolean;
|
||||
private appMenuInstalled: boolean;
|
||||
@@ -42,7 +46,7 @@ export class Menubar {
|
||||
// TODO@sbatten Remove this when fixed upstream by Electron
|
||||
private oldMenus: Menu[];
|
||||
|
||||
private menubarMenus: IMenubarData;
|
||||
private menubarMenus: { [id: string]: IMenubarMenu };
|
||||
|
||||
private keybindings: { [commandId: string]: IMenubarKeybinding };
|
||||
|
||||
@@ -63,9 +67,10 @@ export class Menubar {
|
||||
|
||||
this.menuGC = new RunOnceScheduler(() => { this.oldMenus = []; }, 10000);
|
||||
|
||||
this.menubarMenus = this.stateService.getItem<IMenubarData>(Menubar.lastKnownMenubarStorageKey) || Object.create(null);
|
||||
this.menubarMenus = Object.create(null);
|
||||
this.keybindings = Object.create(null);
|
||||
|
||||
this.keybindings = this.stateService.getItem<IMenubarData>(Menubar.lastKnownAdditionalKeybindings) || Object.create(null);
|
||||
this.restoreCachedMenubarData();
|
||||
|
||||
this.addFallbackHandlers();
|
||||
|
||||
@@ -78,6 +83,23 @@ export class Menubar {
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
private restoreCachedMenubarData() {
|
||||
// TODO@sbatten remove this at some point down the road
|
||||
const outdatedKeys = ['lastKnownAdditionalKeybindings', 'lastKnownKeybindings', 'lastKnownMenubar'];
|
||||
outdatedKeys.forEach(key => this.stateService.removeItem(key));
|
||||
|
||||
const menubarData = this.stateService.getItem<IMenubarData>(Menubar.lastKnownMenubarStorageKey);
|
||||
if (menubarData) {
|
||||
if (menubarData.menus) {
|
||||
this.menubarMenus = menubarData.menus;
|
||||
}
|
||||
|
||||
if (menubarData.keybindings) {
|
||||
this.keybindings = menubarData.keybindings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private addFallbackHandlers(): void {
|
||||
// File Menu Items
|
||||
this.fallbackMenuHandlers['workbench.action.files.newUntitledFile'] = () => this.windowsMainService.openNewWindow(OpenContext.MENU);
|
||||
@@ -162,17 +184,12 @@ export class Menubar {
|
||||
return enableNativeTabs;
|
||||
}
|
||||
|
||||
updateMenu(menus: IMenubarData, windowId: number, additionalKeybindings?: Array<IMenubarKeybinding>) {
|
||||
this.menubarMenus = menus;
|
||||
if (additionalKeybindings) {
|
||||
additionalKeybindings.forEach(keybinding => {
|
||||
this.keybindings[keybinding.id] = keybinding;
|
||||
});
|
||||
}
|
||||
updateMenu(menubarData: IMenubarData, windowId: number) {
|
||||
this.menubarMenus = menubarData.menus;
|
||||
this.keybindings = menubarData.keybindings;
|
||||
|
||||
// Save off new menu and keybindings
|
||||
this.stateService.setItem(Menubar.lastKnownMenubarStorageKey, this.menubarMenus);
|
||||
this.stateService.setItem(Menubar.lastKnownAdditionalKeybindings, this.keybindings);
|
||||
this.stateService.setItem(Menubar.lastKnownMenubarStorageKey, menubarData);
|
||||
|
||||
this.scheduleUpdateMenu();
|
||||
}
|
||||
@@ -413,13 +430,6 @@ export class Menubar {
|
||||
this.insertCheckForUpdatesItems(menu);
|
||||
}
|
||||
|
||||
// Store the keybinding
|
||||
if (item.keybinding) {
|
||||
this.keybindings[item.id] = item.keybinding;
|
||||
} else if (this.keybindings[item.id]) {
|
||||
this.keybindings[item.id] = undefined;
|
||||
}
|
||||
|
||||
if (isMacintosh) {
|
||||
if (this.windowsMainService.getWindowCount() === 0 && this.closedLastWindow) {
|
||||
// In the fallback scenario, we are either disabled or using a fallback handler
|
||||
@@ -429,10 +439,10 @@ export class Menubar {
|
||||
menu.append(this.createMenuItem(item.label, item.id, false, item.checked));
|
||||
}
|
||||
} else {
|
||||
menu.append(this.createMenuItem(item.label, item.id, item.enabled, item.checked));
|
||||
menu.append(this.createMenuItem(item.label, item.id, item.enabled === false ? false : true, !!item.checked));
|
||||
}
|
||||
} else {
|
||||
menu.append(this.createMenuItem(item.label, item.id, item.enabled, item.checked));
|
||||
menu.append(this.createMenuItem(item.label, item.id, item.enabled === false ? false : true, !!item.checked));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -634,20 +644,58 @@ export class Menubar {
|
||||
commandId = arg2[0];
|
||||
}
|
||||
|
||||
// Add role for special case menu items
|
||||
if (isMacintosh) {
|
||||
// Add role for special case menu items
|
||||
if (commandId === 'editor.action.clipboardCutAction') {
|
||||
options['role'] = 'cut';
|
||||
} else if (commandId === 'editor.action.clipboardCopyAction') {
|
||||
options['role'] = 'copy';
|
||||
} else if (commandId === 'editor.action.clipboardPasteAction') {
|
||||
options['role'] = 'paste';
|
||||
} else if (commandId === 'editor.action.selectAll') {
|
||||
options['role'] = 'selectAll';
|
||||
}
|
||||
|
||||
// Add context aware click handlers for special case menu items
|
||||
if (commandId === 'undo') {
|
||||
options.click = this.makeContextAwareClickHandler(click, {
|
||||
inDevTools: devTools => devTools.undo(),
|
||||
inNoWindow: () => Menu.sendActionToFirstResponder('undo:')
|
||||
});
|
||||
} else if (commandId === 'redo') {
|
||||
options.click = this.makeContextAwareClickHandler(click, {
|
||||
inDevTools: devTools => devTools.redo(),
|
||||
inNoWindow: () => Menu.sendActionToFirstResponder('redo:')
|
||||
});
|
||||
} else if (commandId === 'editor.action.selectAll') {
|
||||
options.click = this.makeContextAwareClickHandler(click, {
|
||||
inDevTools: devTools => devTools.selectAll(),
|
||||
inNoWindow: () => Menu.sendActionToFirstResponder('selectAll:')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return new MenuItem(this.withKeybinding(commandId, options));
|
||||
}
|
||||
|
||||
private makeContextAwareClickHandler(click: () => void, contextSpecificHandlers: IMenuItemClickHandler): () => void {
|
||||
return () => {
|
||||
// No Active Window
|
||||
const activeWindow = this.windowsMainService.getFocusedWindow();
|
||||
if (!activeWindow) {
|
||||
return contextSpecificHandlers.inNoWindow();
|
||||
}
|
||||
|
||||
// DevTools focused
|
||||
if (activeWindow.win.webContents.isDevToolsFocused()) {
|
||||
return contextSpecificHandlers.inDevTools(activeWindow.win.webContents.devToolsWebContents);
|
||||
}
|
||||
|
||||
// Finally execute command in Window
|
||||
click();
|
||||
};
|
||||
}
|
||||
|
||||
private runActionInRenderer(id: string): void {
|
||||
// We make sure to not run actions when the window has no focus, this helps
|
||||
// for https://github.com/Microsoft/vscode/issues/25907 and specifically for
|
||||
@@ -665,7 +713,7 @@ export class Menubar {
|
||||
if (binding && binding.label) {
|
||||
|
||||
// if the binding is native, we can just apply it
|
||||
if (binding.isNative) {
|
||||
if (binding.isNative !== false) {
|
||||
options.accelerator = binding.label;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IMenubarService, IMenubarData, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar';
|
||||
import { IMenubarService, IMenubarData } from 'vs/platform/menubar/common/menubar';
|
||||
import { Menubar } from 'vs/platform/menubar/electron-main/menubar';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
@@ -22,11 +22,11 @@ export class MenubarService implements IMenubarService {
|
||||
this._menubar = this.instantiationService.createInstance(Menubar);
|
||||
}
|
||||
|
||||
updateMenubar(windowId: number, menus: IMenubarData, additionalKeybindings?: Array<IMenubarKeybinding>): TPromise<void> {
|
||||
updateMenubar(windowId: number, menus: IMenubarData): TPromise<void> {
|
||||
this.logService.trace('menubarService#updateMenubar', windowId);
|
||||
|
||||
if (this._menubar) {
|
||||
this._menubar.updateMenu(menus, windowId, additionalKeybindings);
|
||||
this._menubar.updateMenu(menus, windowId);
|
||||
}
|
||||
|
||||
return TPromise.as(null);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { IChannel } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IMenubarService, IMenubarData, IMenubarKeybinding } from 'vs/platform/menubar/common/menubar';
|
||||
import { IMenubarService, IMenubarData } from 'vs/platform/menubar/common/menubar';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
export interface IMenubarChannel extends IChannel {
|
||||
@@ -22,7 +22,7 @@ export class MenubarChannel implements IMenubarChannel {
|
||||
|
||||
call(command: string, arg?: any): TPromise<any> {
|
||||
switch (command) {
|
||||
case 'updateMenubar': return this.service.updateMenubar(arg[0], arg[1], arg[2]);
|
||||
case 'updateMenubar': return this.service.updateMenubar(arg[0], arg[1]);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -34,7 +34,7 @@ export class MenubarChannelClient implements IMenubarService {
|
||||
|
||||
constructor(private channel: IMenubarChannel) { }
|
||||
|
||||
updateMenubar(windowId: number, menus: IMenubarData, additionalKeybindings?: Array<IMenubarKeybinding>): TPromise<void> {
|
||||
return this.channel.call('updateMenubar', [windowId, menus, additionalKeybindings]);
|
||||
updateMenubar(windowId: number, menuData: IMenubarData): TPromise<void> {
|
||||
return this.channel.call('updateMenubar', [windowId, menuData]);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IFilesConfiguration } from 'vs/platform/files/common/files';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { getNLines } from 'vs/base/common/strings';
|
||||
|
||||
export const VIEW_ID = 'workbench.view.search';
|
||||
|
||||
@@ -235,41 +236,53 @@ export class TextSearchResult implements ITextSearchResult {
|
||||
range: ISearchRange;
|
||||
preview: ITextSearchResultPreview;
|
||||
|
||||
constructor(fullLine: string, range: ISearchRange, previewOptions?: ITextSearchPreviewOptions) {
|
||||
constructor(text: string, range: ISearchRange, previewOptions?: ITextSearchPreviewOptions) {
|
||||
this.range = range;
|
||||
if (previewOptions) {
|
||||
text = getNLines(text, previewOptions.matchLines);
|
||||
const leadingChars = Math.floor(previewOptions.charsPerLine / 5);
|
||||
const endColumnByTrimmedLines = (range.startLineNumber + previewOptions.matchLines - 1) === range.endLineNumber ? // if single line...
|
||||
range.endColumn :
|
||||
previewOptions.charsPerLine;
|
||||
|
||||
// This doesn't handle all previewOptions correctly
|
||||
const previewStart = Math.max(range.startColumn - leadingChars, 0);
|
||||
const previewEnd = previewOptions.charsPerLine + previewStart;
|
||||
const endOfMatchRangeInPreview = Math.min(previewEnd, range.endColumn - previewStart);
|
||||
const endByCharsPerLine = previewOptions.charsPerLine + previewStart;
|
||||
const trimmedEndOfMatchRangeInPreview = Math.min(endByCharsPerLine, endColumnByTrimmedLines - previewStart);
|
||||
|
||||
this.preview = {
|
||||
text: fullLine.substring(previewStart, previewEnd),
|
||||
match: new OneLineRange(0, range.startColumn - previewStart, endOfMatchRangeInPreview)
|
||||
text: text.substring(previewStart, endByCharsPerLine),
|
||||
match: new OneLineRange(0, range.startColumn - previewStart, trimmedEndOfMatchRangeInPreview)
|
||||
};
|
||||
} else {
|
||||
this.preview = {
|
||||
text: fullLine,
|
||||
text: text,
|
||||
match: new OneLineRange(0, range.startColumn, range.endColumn)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class OneLineRange implements ISearchRange {
|
||||
export class SearchRange implements ISearchRange {
|
||||
startLineNumber: number;
|
||||
startColumn: number;
|
||||
endLineNumber: number;
|
||||
endColumn: number;
|
||||
|
||||
constructor(lineNumber: number, startColumn: number, endColumn: number) {
|
||||
this.startLineNumber = lineNumber;
|
||||
constructor(startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number) {
|
||||
this.startLineNumber = startLineNumber;
|
||||
this.startColumn = startColumn;
|
||||
this.endLineNumber = lineNumber;
|
||||
this.endLineNumber = endLineNumber;
|
||||
this.endColumn = endColumn;
|
||||
}
|
||||
}
|
||||
|
||||
export class OneLineRange extends SearchRange {
|
||||
constructor(lineNumber: number, startColumn: number, endColumn: number) {
|
||||
super(lineNumber, startColumn, lineNumber, endColumn);
|
||||
}
|
||||
}
|
||||
|
||||
export interface ISearchConfigurationProperties {
|
||||
exclude: glob.IExpression;
|
||||
useRipgrep: boolean;
|
||||
@@ -282,6 +295,8 @@ export interface ISearchConfigurationProperties {
|
||||
smartCase: boolean;
|
||||
globalFindClipboard: boolean;
|
||||
location: 'sidebar' | 'panel';
|
||||
useReplacePreview: boolean;
|
||||
showLineNumbers: boolean;
|
||||
}
|
||||
|
||||
export interface ISearchConfiguration extends IFilesConfiguration {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import { ITextSearchPreviewOptions, OneLineRange, TextSearchResult } from 'vs/platform/search/common/search';
|
||||
import { ITextSearchPreviewOptions, OneLineRange, TextSearchResult, SearchRange } from 'vs/platform/search/common/search';
|
||||
|
||||
suite('TextSearchResult', () => {
|
||||
|
||||
@@ -78,4 +78,28 @@ suite('TextSearchResult', () => {
|
||||
assert.deepEqual(result.range, range);
|
||||
assertPreviewRangeText('b', result);
|
||||
});
|
||||
|
||||
test('one line of multiline match', () => {
|
||||
const previewOptions: ITextSearchPreviewOptions = {
|
||||
matchLines: 1,
|
||||
charsPerLine: 10000
|
||||
};
|
||||
|
||||
const range = new SearchRange(5, 4, 6, 3);
|
||||
const result = new TextSearchResult('foo bar\nfoo bar', range, previewOptions);
|
||||
assert.deepEqual(result.range, range);
|
||||
assertPreviewRangeText('bar', result);
|
||||
});
|
||||
|
||||
// test('all lines of multiline match', () => {
|
||||
// const previewOptions: ITextSearchPreviewOptions = {
|
||||
// matchLines: 5,
|
||||
// charsPerLine: 10000
|
||||
// };
|
||||
|
||||
// const range = new SearchRange(5, 4, 6, 3);
|
||||
// const result = new TextSearchResult('foo bar\nfoo bar', range, previewOptions);
|
||||
// assert.deepEqual(result.range, range);
|
||||
// assertPreviewRangeText('bar\nfoo', result);
|
||||
// });
|
||||
});
|
||||
Vendored
+19
-3
@@ -3023,10 +3023,13 @@ declare module 'vscode' {
|
||||
export class ParameterInformation {
|
||||
|
||||
/**
|
||||
* The label of this signature. *Note*: Must be a substring of its
|
||||
* containing signature information's [label](#SignatureInformation.label).
|
||||
* The label of this signature.
|
||||
*
|
||||
* Either a string or inclusive start and exclusive end offsets within its containing
|
||||
* [signature label](#SignatureInformation.label). *Note*: A label of type string must be
|
||||
* a substring of its containing signature information's [label](#SignatureInformation.label).
|
||||
*/
|
||||
label: string;
|
||||
label: string | [number, number];
|
||||
|
||||
/**
|
||||
* The human-readable doc-comment of this signature. Will be shown
|
||||
@@ -5917,6 +5920,19 @@ declare module 'vscode' {
|
||||
*/
|
||||
export const terminals: ReadonlyArray<Terminal>;
|
||||
|
||||
/**
|
||||
* The currently active terminal or `undefined`. The active terminal is the one that
|
||||
* currently has focus or most recently had focus.
|
||||
*/
|
||||
export const activeTerminal: Terminal | undefined;
|
||||
|
||||
/**
|
||||
* An [event](#Event) which fires when the [active terminal](#window.activeTerminal)
|
||||
* has changed. *Note* that the event also fires when the active terminal changes
|
||||
* to `undefined`.
|
||||
*/
|
||||
export const onDidChangeActiveTerminal: Event<Terminal | undefined>;
|
||||
|
||||
/**
|
||||
* An [event](#Event) which fires when a terminal has been created, either through the
|
||||
* [createTerminal](#window.createTerminal) API or commands.
|
||||
|
||||
Vendored
+13
-13
@@ -11,6 +11,19 @@ declare module 'vscode' {
|
||||
export function sampleFunction(): Thenable<any>;
|
||||
}
|
||||
|
||||
//#region Joh - clipboard https://github.com/Microsoft/vscode/issues/217
|
||||
|
||||
export interface Clipboard {
|
||||
readText(): Promise<string>;
|
||||
writeText(value: string): Promise<void>;
|
||||
}
|
||||
|
||||
export namespace env {
|
||||
export const clipboard: Clipboard;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Joh - read/write in chunks
|
||||
|
||||
export interface FileSystemProvider {
|
||||
@@ -982,19 +995,6 @@ declare module 'vscode' {
|
||||
}
|
||||
|
||||
export namespace window {
|
||||
/**
|
||||
* The currently active terminal or `undefined`. The active terminal is the one that
|
||||
* currently has focus or most recently had focus.
|
||||
*/
|
||||
export const activeTerminal: Terminal | undefined;
|
||||
|
||||
/**
|
||||
* An [event](#Event) which fires when the [active terminal](#window.activeTerminal)
|
||||
* has changed. *Note* that the event also fires when the active terminal changes
|
||||
* to `undefined`.
|
||||
*/
|
||||
export const onDidChangeActiveTerminal: Event<Terminal | undefined>;
|
||||
|
||||
/**
|
||||
* Create a [TerminalRenderer](#TerminalRenderer).
|
||||
*
|
||||
|
||||
@@ -15,6 +15,7 @@ import { LanguageConfigurationFileHandler } from 'vs/workbench/parts/codeEditor/
|
||||
|
||||
// --- mainThread participants
|
||||
import 'vs/workbench/api/node/apiCommands';
|
||||
import './mainThreadClipboard';
|
||||
import './mainThreadCommands';
|
||||
import './mainThreadConfiguration';
|
||||
import './mainThreadDebugService';
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { clipboard } from 'electron';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { MainContext, MainThreadClipboardShape } from '../node/extHost.protocol';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadClipboard)
|
||||
export class MainThreadCommands implements MainThreadClipboardShape {
|
||||
|
||||
dispose(): void {
|
||||
// nothing
|
||||
}
|
||||
|
||||
$readText(): Promise<string> {
|
||||
return Promise.resolve(clipboard.readText());
|
||||
}
|
||||
|
||||
$writeText(value: string): Promise<void> {
|
||||
clipboard.writeText(value);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import { ICommandService, CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ExtHostContext, MainThreadCommandsShape, ExtHostCommandsShape, MainContext, IExtHostContext } from '../node/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
@@ -79,7 +78,7 @@ export class MainThreadCommands implements MainThreadCommandsShape {
|
||||
}
|
||||
|
||||
$getCommands(): Thenable<string[]> {
|
||||
return TPromise.as(Object.keys(CommandsRegistry.getCommands()));
|
||||
return Promise.resolve(Object.keys(CommandsRegistry.getCommands()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
}
|
||||
|
||||
public $customDebugAdapterRequest(sessionId: DebugSessionUUID, request: string, args: any): Thenable<any> {
|
||||
const session = this.debugService.getSession(sessionId);
|
||||
const session = this.debugService.getModel().getSessions(true).filter(s => s.getId() === sessionId).pop();
|
||||
if (session) {
|
||||
return session.customRequest(request, args).then(response => {
|
||||
if (response && response.success) {
|
||||
|
||||
@@ -61,6 +61,7 @@ import { ExtHostComments } from './extHostComments';
|
||||
import { ExtHostSearch } from './extHostSearch';
|
||||
import { ExtHostUrls } from './extHostUrls';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ExtHostClipboard } from 'vs/workbench/api/node/extHostClipboard';
|
||||
|
||||
export interface IExtensionApiFactory {
|
||||
(extension: IExtensionDescription): typeof vscode;
|
||||
@@ -134,6 +135,7 @@ export function createApiFactory(
|
||||
rpcProtocol.assertRegistered(expected);
|
||||
|
||||
// Other instances
|
||||
const extHostClipboard = new ExtHostClipboard(rpcProtocol);
|
||||
const extHostMessageService = new ExtHostMessageService(rpcProtocol);
|
||||
const extHostDialogs = new ExtHostDialogs(rpcProtocol);
|
||||
const extHostStatusBar = new ExtHostStatusBar(rpcProtocol);
|
||||
@@ -237,6 +239,10 @@ export function createApiFactory(
|
||||
get onDidChangeLogLevel() {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostLogService.onDidChangeLogLevel;
|
||||
},
|
||||
get clipboard(): vscode.Clipboard {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostClipboard;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -348,7 +354,7 @@ export function createApiFactory(
|
||||
return extHostEditors.getVisibleTextEditors();
|
||||
},
|
||||
get activeTerminal() {
|
||||
return proposedApiFunction(extension, extHostTerminalService.activeTerminal);
|
||||
return extHostTerminalService.activeTerminal;
|
||||
},
|
||||
get terminals() {
|
||||
return extHostTerminalService.terminals;
|
||||
@@ -391,9 +397,9 @@ export function createApiFactory(
|
||||
onDidOpenTerminal(listener, thisArg?, disposables?) {
|
||||
return extHostTerminalService.onDidOpenTerminal(listener, thisArg, disposables);
|
||||
},
|
||||
onDidChangeActiveTerminal: proposedApiFunction(extension, (listener, thisArg?, disposables?) => {
|
||||
onDidChangeActiveTerminal(listener, thisArg?, disposables?) {
|
||||
return extHostTerminalService.onDidChangeActiveTerminal(listener, thisArg, disposables);
|
||||
}),
|
||||
},
|
||||
get state() {
|
||||
return extHostWindow.state;
|
||||
},
|
||||
|
||||
@@ -86,6 +86,11 @@ export interface IMainContext extends IRPCProtocol {
|
||||
|
||||
// --- main thread
|
||||
|
||||
export interface MainThreadClipboardShape extends IDisposable {
|
||||
$readText(): Promise<string>;
|
||||
$writeText(value: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface MainThreadCommandsShape extends IDisposable {
|
||||
$registerCommand(id: string): void;
|
||||
$unregisterCommand(id: string): void;
|
||||
@@ -1014,6 +1019,7 @@ export interface ExtHostCommentsShape {
|
||||
// --- proxy identifiers
|
||||
|
||||
export const MainContext = {
|
||||
MainThreadClipboard: <ProxyIdentifier<MainThreadClipboardShape>>createMainId<MainThreadClipboardShape>('MainThreadClipboard'),
|
||||
MainThreadCommands: <ProxyIdentifier<MainThreadCommandsShape>>createMainId<MainThreadCommandsShape>('MainThreadCommands'),
|
||||
MainThreadComments: createMainId<MainThreadCommentsShape>('MainThreadComments'),
|
||||
MainThreadConfiguration: createMainId<MainThreadConfigurationShape>('MainThreadConfiguration'),
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { IMainContext, MainContext, MainThreadClipboardShape } from 'vs/workbench/api/node/extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export class ExtHostClipboard implements vscode.Clipboard {
|
||||
|
||||
private readonly _proxy: MainThreadClipboardShape;
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadClipboard);
|
||||
}
|
||||
|
||||
readText(): Promise<string> {
|
||||
return this._proxy.$readText();
|
||||
}
|
||||
|
||||
writeText(value: string): Promise<void> {
|
||||
return this._proxy.$writeText(value);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import { isLinux } from 'vs/base/common/platform';
|
||||
import { basenameOrAuthority, dirname, isEqual } from 'vs/base/common/resources';
|
||||
import { compare } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Severity } from 'vs/platform/notification/common/notification';
|
||||
@@ -373,7 +372,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
}
|
||||
|
||||
if (token && token.isCancellationRequested) {
|
||||
return TPromise.wrap([]);
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
return this._proxy.$startFileSearch(includePattern, includeFolder, excludePatternOrDisregardExcludes, maxResults, token)
|
||||
@@ -433,18 +432,16 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
|
||||
};
|
||||
|
||||
if (token.isCancellationRequested) {
|
||||
return TPromise.wrap(undefined);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
return this._proxy.$startTextSearch(query, queryOptions, requestId, token).then(
|
||||
result => {
|
||||
delete this._activeSearchCallbacks[requestId];
|
||||
return result;
|
||||
},
|
||||
err => {
|
||||
delete this._activeSearchCallbacks[requestId];
|
||||
return TPromise.wrapError(err);
|
||||
});
|
||||
return this._proxy.$startTextSearch(query, queryOptions, requestId, token).then(result => {
|
||||
delete this._activeSearchCallbacks[requestId];
|
||||
return result;
|
||||
}, err => {
|
||||
delete this._activeSearchCallbacks[requestId];
|
||||
return Promise.reject(err);
|
||||
});
|
||||
}
|
||||
|
||||
$handleTextSearchResult(result: IRawFileMatch2, requestId: number): void {
|
||||
|
||||
@@ -544,15 +544,6 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr
|
||||
position(this.workbenchContainer, 0, 0, 0, 0, 'relative');
|
||||
size(this.workbenchContainer, this.workbenchSize.width, this.workbenchSize.height);
|
||||
|
||||
// Bug on Chrome: Sometimes Chrome wants to scroll the workbench container on layout changes. The fix is to reset scrolling in this case.
|
||||
const workbenchContainer = this.workbenchContainer;
|
||||
if (workbenchContainer.scrollTop > 0) {
|
||||
workbenchContainer.scrollTop = 0;
|
||||
}
|
||||
if (workbenchContainer.scrollLeft > 0) {
|
||||
workbenchContainer.scrollLeft = 0;
|
||||
}
|
||||
|
||||
// Title Part
|
||||
const titleContainer = this.parts.titlebar.getContainer();
|
||||
if (isTitlebarHidden) {
|
||||
|
||||
@@ -4,24 +4,30 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/activityaction';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { IActivity, IGlobalActivity } from 'vs/workbench/common/activity';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { IViewletService, } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
||||
import { IThemeService, ITheme, registerThemingParticipant, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { ActivityAction, ActivityActionItem, ICompositeBarColors, ToggleCompositePinnedAction, ICompositeBar } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { ActivityAction, ActivityActionItem, ICompositeBar, ICompositeBarColors, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
|
||||
import { IActivity, IGlobalActivity } from 'vs/workbench/common/activity';
|
||||
import { ACTIVITY_BAR_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { IActivityService } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
|
||||
export class ViewletActivityAction extends ActivityAction {
|
||||
|
||||
@@ -188,6 +194,77 @@ export class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinne
|
||||
}
|
||||
}
|
||||
|
||||
class SwitchSidebarViewAction extends Action {
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService private viewletService: IViewletService,
|
||||
@IActivityService private activityService: IActivityService
|
||||
) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
run(offset: number): TPromise<any> {
|
||||
const pinnedViewletIds = this.activityService.getPinnedViewletIds();
|
||||
|
||||
const activeViewlet = this.viewletService.getActiveViewlet();
|
||||
if (!activeViewlet) {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
let targetViewletId: string;
|
||||
for (let i = 0; i < pinnedViewletIds.length; i++) {
|
||||
if (pinnedViewletIds[i] === activeViewlet.getId()) {
|
||||
targetViewletId = pinnedViewletIds[(i + pinnedViewletIds.length + offset) % pinnedViewletIds.length];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this.viewletService.openViewlet(targetViewletId, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class PreviousSidebarViewAction extends SwitchSidebarViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.previousSidebarView';
|
||||
static LABEL = nls.localize('previousSidebarView', 'Previous Sidebar View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IActivityService activityService: IActivityService
|
||||
) {
|
||||
super(id, name, viewletService, activityService);
|
||||
}
|
||||
|
||||
run(): TPromise<any> {
|
||||
return super.run(-1);
|
||||
}
|
||||
}
|
||||
|
||||
export class NextSidebarViewAction extends SwitchSidebarViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.nextSidebarView';
|
||||
static LABEL = nls.localize('nextSidebarView', 'Next Sidebar View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IActivityService activityService: IActivityService
|
||||
) {
|
||||
super(id, name, viewletService, activityService);
|
||||
}
|
||||
|
||||
run(): TPromise<any> {
|
||||
return super.run(1);
|
||||
}
|
||||
}
|
||||
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(PreviousSidebarViewAction, PreviousSidebarViewAction.ID, PreviousSidebarViewAction.LABEL), 'View: Open Previous Sidebar View', nls.localize('view', "View"));
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(NextSidebarViewAction, NextSidebarViewAction.ID, NextSidebarViewAction.LABEL), 'View: Open Next Sidebar View', nls.localize('view', "View"));
|
||||
|
||||
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
|
||||
const activeForegroundColor = theme.getColor(ACTIVITY_BAR_FOREGROUND);
|
||||
|
||||
@@ -304,8 +304,12 @@ export class ActivitybarPart extends Part {
|
||||
}
|
||||
}
|
||||
|
||||
getPinned(): string[] {
|
||||
return this.viewletService.getViewlets().map(v => v.id).filter(id => this.compositeBar.isPinned(id));
|
||||
getPinnedViewletIds(): string[] {
|
||||
const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(v => v.id);
|
||||
return this.viewletService.getViewlets()
|
||||
.filter(v => this.compositeBar.isPinned(v.id))
|
||||
.sort((v1, v2) => pinnedCompositeIds.indexOf(v1.id) - pinnedCompositeIds.indexOf(v2.id))
|
||||
.map(v => v.id);
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[] {
|
||||
|
||||
@@ -70,6 +70,10 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
return this.model.items;
|
||||
}
|
||||
|
||||
getPinnedComposites(): ICompositeBarItem[] {
|
||||
return this.model.pinnedItems;
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): HTMLElement {
|
||||
const actionBarDiv = parent.appendChild($('.composite-bar'));
|
||||
this.compositeSwitcherBar = this._register(new ActionBar(actionBarDiv, {
|
||||
@@ -458,6 +462,10 @@ class CompositeBarModel {
|
||||
return this.items.filter(item => item.visible);
|
||||
}
|
||||
|
||||
get pinnedItems(): ICompositeBarItem[] {
|
||||
return this.items.filter(item => item.visible && item.pinned);
|
||||
}
|
||||
|
||||
private createCompositeBarItem(id: string, name: string, order: number, pinned: boolean, visible: boolean): ICompositeBarItem {
|
||||
const options = this.options;
|
||||
return {
|
||||
|
||||
@@ -323,7 +323,7 @@ export class BreadcrumbsControl {
|
||||
editorViewState = undefined;
|
||||
}
|
||||
this._contextViewService.hideContextView(this);
|
||||
this._revealInEditor(event, data.target, this._getEditorGroup(data.payload && data.payload.originalEvent), (data.payload && data.payload.originalEvent.middleButton));
|
||||
this._revealInEditor(event, data.target, this._getEditorGroup(data.payload && data.payload.originalEvent), (data.payload && data.payload.originalEvent && data.payload.originalEvent.middleButton));
|
||||
/* __GDPR__
|
||||
"breadcrumbs/open" : {
|
||||
"type": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
@@ -458,7 +458,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, {
|
||||
order: 99,
|
||||
command: {
|
||||
id: 'breadcrumbs.toggle',
|
||||
title: localize('miToggleBreadcrumbs', "Toggle &&Breadcrumbs")
|
||||
title: localize('miToggleBreadcrumbs', "Toggle &&Breadcrumbs"),
|
||||
toggled: ContextKeyExpr.equals('config.breadcrumbs.enabled', true)
|
||||
}
|
||||
});
|
||||
CommandsRegistry.registerCommand('breadcrumbs.toggle', accessor => {
|
||||
|
||||
@@ -179,6 +179,69 @@ export class PanelActivityAction extends ActivityAction {
|
||||
}
|
||||
}
|
||||
|
||||
export class SwitchPanelViewAction extends Action {
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPanelService private panelService: IPanelService
|
||||
) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
run(offset: number): Thenable<any> {
|
||||
const pinnedPanels = this.panelService.getPinnedPanels();
|
||||
const activePanel = this.panelService.getActivePanel();
|
||||
if (!activePanel) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
let targetPanelId: string;
|
||||
for (let i = 0; i < pinnedPanels.length; i++) {
|
||||
if (pinnedPanels[i].id === activePanel.getId()) {
|
||||
targetPanelId = pinnedPanels[(i + pinnedPanels.length + offset) % pinnedPanels.length].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this.panelService.openPanel(targetPanelId, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class PreviousPanelViewAction extends SwitchPanelViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.previousPanelView';
|
||||
static LABEL = nls.localize('previousPanelView', 'Previous Panel View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPanelService panelService: IPanelService
|
||||
) {
|
||||
super(id, name, panelService);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
return super.run(-1);
|
||||
}
|
||||
}
|
||||
|
||||
export class NextPanelViewAction extends SwitchPanelViewAction {
|
||||
|
||||
static readonly ID = 'workbench.action.nextPanelView';
|
||||
static LABEL = nls.localize('nextPanelView', 'Next Panel View');
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPanelService panelService: IPanelService
|
||||
) {
|
||||
super(id, name, panelService);
|
||||
}
|
||||
|
||||
public run(): Thenable<any> {
|
||||
return super.run(1);
|
||||
}
|
||||
}
|
||||
|
||||
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchExtensions.WorkbenchActions);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelAction, TogglePanelAction.ID, TogglePanelAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_J }), 'View: Toggle Panel', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPanelAction, FocusPanelAction.ID, FocusPanelAction.LABEL), 'View: Focus into Panel', nls.localize('view', "View"));
|
||||
@@ -186,6 +249,8 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMaximizedP
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClosePanelAction, ClosePanelAction.ID, ClosePanelAction.LABEL), 'View: Close Panel', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelPositionAction, TogglePanelPositionAction.ID, TogglePanelPositionAction.LABEL), 'View: Toggle Panel Position', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, undefined), 'View: Toggle Panel Position', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(PreviousPanelViewAction, PreviousPanelViewAction.ID, PreviousPanelViewAction.LABEL), 'View: Open Previous Panel View', nls.localize('view', "View"));
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(NextPanelViewAction, NextPanelViewAction.ID, NextPanelViewAction.LABEL), 'View: Open Next Panel View', nls.localize('view', "View"));
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, {
|
||||
group: '2_workbench_layout',
|
||||
|
||||
@@ -198,6 +198,13 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
.sort((v1, v2) => v1.order - v2.order);
|
||||
}
|
||||
|
||||
getPinnedPanels(): PanelDescriptor[] {
|
||||
const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(c => c.id);
|
||||
return this.getPanels()
|
||||
.filter(p => pinnedCompositeIds.indexOf(p.id) !== -1)
|
||||
.sort((p1, p2) => pinnedCompositeIds.indexOf(p1.id) - pinnedCompositeIds.indexOf(p2.id));
|
||||
}
|
||||
|
||||
setPanelEnablement(id: string, enabled: boolean): void {
|
||||
const descriptor = Registry.as<PanelRegistry>(PanelExtensions.Panels).getPanels().filter(p => p.id === id).pop();
|
||||
if (descriptor && descriptor.enabled !== enabled) {
|
||||
|
||||
@@ -179,10 +179,6 @@ export class MenubarControl extends Disposable {
|
||||
return enableMenuBarMnemonics;
|
||||
}
|
||||
|
||||
private get currentAutoSaveSetting(): string {
|
||||
return this.configurationService.getValue<string>('files.autoSave');
|
||||
}
|
||||
|
||||
private get currentSidebarPosition(): string {
|
||||
return this.configurationService.getValue<string>('workbench.sideBar.location');
|
||||
}
|
||||
@@ -443,9 +439,6 @@ export class MenubarControl extends Disposable {
|
||||
// Listen to update service
|
||||
this.updateService.onStateChange(() => this.setupMenubar());
|
||||
|
||||
// Listen for context changes
|
||||
this._register(this.contextKeyService.onDidChangeContext(() => this.setupMenubar()));
|
||||
|
||||
// Listen for changes in recently opened menu
|
||||
this._register(this.windowsService.onRecentlyOpenedChange(() => { this.onRecentlyOpenedChange(); }));
|
||||
|
||||
@@ -470,9 +463,9 @@ export class MenubarControl extends Disposable {
|
||||
this.setupCustomMenubar();
|
||||
} else {
|
||||
// Send menus to main process to be rendered by Electron
|
||||
const menubarData = {};
|
||||
const menubarData = { menus: {}, keybindings: {} };
|
||||
if (this.getMenubarMenus(menubarData)) {
|
||||
this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), menubarData, this.getAdditionalKeybindings());
|
||||
this.menubarService.updateMenubar(this.windowService.getCurrentWindowId(), menubarData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -485,17 +478,6 @@ export class MenubarControl extends Disposable {
|
||||
this.mnemonics.set(KeyCodeUtils.fromString(mnemonic), menuIndex);
|
||||
}
|
||||
|
||||
private setCheckedStatus(action: IAction | IMenubarMenuItemAction) {
|
||||
switch (action.id) {
|
||||
case 'workbench.action.toggleAutoSave':
|
||||
action.checked = this.currentAutoSaveSetting !== 'off';
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private calculateActionLabel(action: IAction | IMenubarMenuItemAction): string {
|
||||
let label = action.label;
|
||||
switch (action.id) {
|
||||
@@ -717,7 +699,6 @@ export class MenubarControl extends Disposable {
|
||||
target.push(new SubmenuAction(action.label, submenuActions));
|
||||
} else {
|
||||
action.label = this.calculateActionLabel(action);
|
||||
this.setCheckedStatus(action);
|
||||
target.push(action);
|
||||
}
|
||||
}
|
||||
@@ -942,25 +923,25 @@ export class MenubarControl extends Disposable {
|
||||
private getMenubarKeybinding(id: string): IMenubarKeybinding {
|
||||
const binding = this.keybindingService.lookupKeybinding(id);
|
||||
if (!binding) {
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// first try to resolve a native accelerator
|
||||
const electronAccelerator = binding.getElectronAccelerator();
|
||||
if (electronAccelerator) {
|
||||
return { id, label: electronAccelerator, isNative: true };
|
||||
return { label: electronAccelerator };
|
||||
}
|
||||
|
||||
// we need this fallback to support keybindings that cannot show in electron menus (e.g. chords)
|
||||
const acceleratorLabel = binding.getLabel();
|
||||
if (acceleratorLabel) {
|
||||
return { id, label: acceleratorLabel, isNative: false };
|
||||
return { label: acceleratorLabel, isNative: false };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private populateMenuItems(menu: IMenu, menuToPopulate: IMenubarMenu) {
|
||||
private populateMenuItems(menu: IMenu, menuToPopulate: IMenubarMenu, keybindings: { [id: string]: IMenubarKeybinding }) {
|
||||
let groups = menu.getActions();
|
||||
for (let group of groups) {
|
||||
const [, actions] = group;
|
||||
@@ -969,7 +950,7 @@ export class MenubarControl extends Disposable {
|
||||
|
||||
if (menuItem instanceof SubmenuItemAction) {
|
||||
const submenu = { items: [] };
|
||||
this.populateMenuItems(this.menuService.createMenu(menuItem.item.submenu, this.contextKeyService), submenu);
|
||||
this.populateMenuItems(this.menuService.createMenu(menuItem.item.submenu, this.contextKeyService), submenu, keybindings);
|
||||
|
||||
let menubarSubmenuItem: IMenubarMenuItemSubmenu = {
|
||||
id: menuItem.id,
|
||||
@@ -981,15 +962,19 @@ export class MenubarControl extends Disposable {
|
||||
} else {
|
||||
let menubarMenuItem: IMenubarMenuItemAction = {
|
||||
id: menuItem.id,
|
||||
label: menuItem.label,
|
||||
checked: menuItem.checked,
|
||||
enabled: menuItem.enabled,
|
||||
keybinding: this.getMenubarKeybinding(menuItem.id)
|
||||
label: menuItem.label
|
||||
};
|
||||
|
||||
this.setCheckedStatus(menubarMenuItem);
|
||||
menubarMenuItem.label = this.calculateActionLabel(menubarMenuItem);
|
||||
if (menuItem.checked) {
|
||||
menubarMenuItem.checked = true;
|
||||
}
|
||||
|
||||
if (!menuItem.enabled) {
|
||||
menubarMenuItem.enabled = false;
|
||||
}
|
||||
|
||||
menubarMenuItem.label = this.calculateActionLabel(menubarMenuItem);
|
||||
keybindings[menuItem.id] = this.getMenubarKeybinding(menuItem.id);
|
||||
menuToPopulate.items.push(menubarMenuItem);
|
||||
}
|
||||
});
|
||||
@@ -1002,10 +987,10 @@ export class MenubarControl extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private getAdditionalKeybindings(): Array<IMenubarKeybinding> {
|
||||
const keybindings = [];
|
||||
private getAdditionalKeybindings(): { [id: string]: IMenubarKeybinding } {
|
||||
const keybindings = {};
|
||||
if (isMacintosh) {
|
||||
keybindings.push(this.getMenubarKeybinding('workbench.action.quit'));
|
||||
keybindings['workbench.action.quit'] = (this.getMenubarKeybinding('workbench.action.quit'));
|
||||
}
|
||||
|
||||
return keybindings;
|
||||
@@ -1016,15 +1001,16 @@ export class MenubarControl extends Disposable {
|
||||
return false;
|
||||
}
|
||||
|
||||
menubarData.keybindings = this.getAdditionalKeybindings();
|
||||
for (let topLevelMenuName of Object.keys(this.topLevelMenus)) {
|
||||
const menu = this.topLevelMenus[topLevelMenuName];
|
||||
let menubarMenu: IMenubarMenu = { items: [] };
|
||||
this.populateMenuItems(menu, menubarMenu);
|
||||
this.populateMenuItems(menu, menubarMenu, menubarData.keybindings);
|
||||
if (menubarMenu.items.length === 0) {
|
||||
// Menus are incomplete
|
||||
return false;
|
||||
}
|
||||
menubarData[topLevelMenuName] = menubarMenu;
|
||||
menubarData.menus[topLevelMenuName] = menubarMenu;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -767,7 +767,7 @@ export class Workbench extends Disposable implements IPartService {
|
||||
|
||||
return {
|
||||
customKeybindingsCount: this.keybindingService.customKeybindingsCount(),
|
||||
pinnedViewlets: this.activitybarPart.getPinned(),
|
||||
pinnedViewlets: this.activitybarPart.getPinnedViewletIds(),
|
||||
restoredViewlet: viewletIdToRestore,
|
||||
restoredEditorsCount: this.editorService.visibleEditors.length
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
export class ToggleMinimapAction extends Action {
|
||||
public static readonly ID = 'editor.action.toggleMinimap';
|
||||
@@ -35,7 +36,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, {
|
||||
group: '5_editor',
|
||||
command: {
|
||||
id: ToggleMinimapAction.ID,
|
||||
title: nls.localize({ key: 'miToggleMinimap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Minimap")
|
||||
title: nls.localize({ key: 'miToggleMinimap', comment: ['&& denotes a mnemonic'] }, "Toggle &&Minimap"),
|
||||
toggled: ContextKeyExpr.equals('config.editor.minimap.enabled', true)
|
||||
},
|
||||
order: 2
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
export class ToggleRenderControlCharacterAction extends Action {
|
||||
|
||||
@@ -36,7 +37,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, {
|
||||
group: '5_editor',
|
||||
command: {
|
||||
id: ToggleRenderControlCharacterAction.ID,
|
||||
title: nls.localize({ key: 'miToggleRenderControlCharacters', comment: ['&& denotes a mnemonic'] }, "Toggle &&Control Characters")
|
||||
title: nls.localize({ key: 'miToggleRenderControlCharacters', comment: ['&& denotes a mnemonic'] }, "Toggle &&Control Characters"),
|
||||
toggled: ContextKeyExpr.equals('config.editor.renderControlCharacters', true)
|
||||
},
|
||||
order: 4
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
export class ToggleRenderWhitespaceAction extends Action {
|
||||
|
||||
@@ -44,7 +45,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, {
|
||||
group: '5_editor',
|
||||
command: {
|
||||
id: ToggleRenderWhitespaceAction.ID,
|
||||
title: nls.localize({ key: 'miToggleRenderWhitespace', comment: ['&& denotes a mnemonic'] }, "Toggle &&Render Whitespace")
|
||||
title: nls.localize({ key: 'miToggleRenderWhitespace', comment: ['&& denotes a mnemonic'] }, "Toggle &&Render Whitespace"),
|
||||
toggled: ContextKeyExpr.notEquals('config.editor.renderWhitespace', 'none')
|
||||
},
|
||||
order: 3
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
|
||||
import { SelectActionItem, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IDebugService } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IDebugService, IDebugSession } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { attachSelectBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
@@ -190,7 +190,7 @@ export class StartDebugActionItem implements IActionItem {
|
||||
export class FocusSessionActionItem extends SelectActionItem {
|
||||
constructor(
|
||||
action: IAction,
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IDebugService protected debugService: IDebugService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextViewService contextViewService: IContextViewService,
|
||||
) {
|
||||
@@ -201,7 +201,7 @@ export class FocusSessionActionItem extends SelectActionItem {
|
||||
this.toDispose.push(this.debugService.getViewModel().onDidFocusSession(() => {
|
||||
const session = this.debugService.getViewModel().focusedSession;
|
||||
if (session) {
|
||||
const index = this.debugService.getModel().getSessions().indexOf(session);
|
||||
const index = this.getSessions().indexOf(session);
|
||||
this.select(index);
|
||||
}
|
||||
}));
|
||||
@@ -214,8 +214,12 @@ export class FocusSessionActionItem extends SelectActionItem {
|
||||
|
||||
private update() {
|
||||
const session = this.debugService.getViewModel().focusedSession;
|
||||
const sessions = this.debugService.getModel().getSessions();
|
||||
const sessions = this.getSessions();
|
||||
const names = sessions.map(s => s.getLabel());
|
||||
this.setOptions(names, session ? sessions.indexOf(session) : undefined);
|
||||
}
|
||||
|
||||
protected getSessions(): ReadonlyArray<IDebugSession> {
|
||||
return this.debugService.getModel().getSessions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import * as lifecycle from 'vs/base/common/lifecycle';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IDebugService, State, IDebugSession, IThread, IEnablement, IBreakpoint, IStackFrame, REPL_ID }
|
||||
@@ -197,7 +196,6 @@ export class SelectAndStartAction extends AbstractDebugAction {
|
||||
@IQuickOpenService private quickOpenService: IQuickOpenService
|
||||
) {
|
||||
super(id, label, undefined, debugService, keybindingService);
|
||||
this.quickOpenService = quickOpenService;
|
||||
}
|
||||
|
||||
public run(): TPromise<any> {
|
||||
@@ -677,30 +675,6 @@ export class RemoveAllWatchExpressionsAction extends AbstractDebugAction {
|
||||
}
|
||||
}
|
||||
|
||||
export class ClearReplAction extends AbstractDebugAction {
|
||||
static readonly ID = 'workbench.debug.panel.action.clearReplAction';
|
||||
static LABEL = nls.localize('clearRepl', "Clear Console");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@IDebugService debugService: IDebugService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IPanelService private panelService: IPanelService
|
||||
) {
|
||||
super(id, label, 'debug-action clear-repl', debugService, keybindingService);
|
||||
}
|
||||
|
||||
public run(): TPromise<any> {
|
||||
const session = this.debugService.getViewModel().focusedSession;
|
||||
if (session) {
|
||||
session.removeReplExpressions();
|
||||
aria.status(nls.localize('debugConsoleCleared', "Debug console was cleared"));
|
||||
}
|
||||
|
||||
// focus back to repl
|
||||
return this.panelService.openPanel(REPL_ID, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class ToggleReplAction extends TogglePanelAction {
|
||||
static readonly ID = 'workbench.debug.action.toggleRepl';
|
||||
static LABEL = nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugConsoleAction' }, 'Debug Console');
|
||||
|
||||
@@ -72,7 +72,6 @@
|
||||
background-position: center center;
|
||||
flex-shrink: 0;
|
||||
transition: transform 50ms ease;
|
||||
-webkit-transition: -webkit-transform 50ms ease;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part > .title > .title-actions .start-debug-action-item .icon,
|
||||
@@ -93,7 +92,6 @@
|
||||
}
|
||||
|
||||
.monaco-workbench > .part > .title > .title-actions .start-debug-action-item .icon.active {
|
||||
-webkit-transform: scale(1.272019649, 1.272019649);
|
||||
transform: scale(1.272019649, 1.272019649);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ export const CONTEXT_DEBUG_TYPE = new RawContextKey<string>('debugType', undefin
|
||||
export const CONTEXT_DEBUG_CONFIGURATION_TYPE = new RawContextKey<string>('debugConfigurationType', undefined);
|
||||
export const CONTEXT_DEBUG_STATE = new RawContextKey<string>('debugState', 'inactive');
|
||||
export const CONTEXT_IN_DEBUG_MODE = new RawContextKey<boolean>('inDebugMode', false);
|
||||
export const CONTEXT_NOT_IN_DEBUG_MODE = CONTEXT_IN_DEBUG_MODE.toNegated();
|
||||
export const CONTEXT_IN_DEBUG_REPL = new RawContextKey<boolean>('inDebugRepl', false);
|
||||
export const CONTEXT_BREAKPOINT_WIDGET_VISIBLE = new RawContextKey<boolean>('breakpointWidgetVisible', false);
|
||||
export const CONTEXT_IN_BREAKPOINT_WIDGET = new RawContextKey<boolean>('inBreakpointWidget', false);
|
||||
@@ -117,8 +116,6 @@ export interface IDebugger {
|
||||
getCustomTelemetryService(): TPromise<TelemetryService>;
|
||||
}
|
||||
|
||||
export type ActualBreakpoints = { [id: string]: DebugProtocol.Breakpoint };
|
||||
|
||||
export enum State {
|
||||
Inactive,
|
||||
Initializing,
|
||||
@@ -183,13 +180,13 @@ export interface IDebugSession extends ITreeElement {
|
||||
|
||||
initialize(dbgr: IDebugger): TPromise<void>;
|
||||
launchOrAttach(config: IConfig): TPromise<void>;
|
||||
restart(): TPromise<DebugProtocol.RestartResponse>;
|
||||
restart(): TPromise<void>;
|
||||
terminate(restart?: boolean /* false */): TPromise<void>;
|
||||
disconnect(restart?: boolean /* false */): TPromise<void>;
|
||||
|
||||
sendBreakpoints(modelUri: uri, bpts: IBreakpoint[], sourceModified: boolean): TPromise<ActualBreakpoints | undefined>;
|
||||
sendFunctionBreakpoints(fbps: IFunctionBreakpoint[]): TPromise<ActualBreakpoints | undefined>;
|
||||
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): TPromise<any>;
|
||||
sendBreakpoints(modelUri: uri, bpts: IBreakpoint[], sourceModified: boolean): TPromise<void>;
|
||||
sendFunctionBreakpoints(fbps: IFunctionBreakpoint[]): TPromise<void>;
|
||||
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): TPromise<void>;
|
||||
|
||||
stackTrace(threadId: number, startFrame: number, levels: number): TPromise<DebugProtocol.StackTraceResponse>;
|
||||
exceptionInfo(threadId: number): TPromise<IExceptionInfo>;
|
||||
@@ -198,15 +195,15 @@ export interface IDebugSession extends ITreeElement {
|
||||
evaluate(expression: string, frameId?: number, context?: string): TPromise<DebugProtocol.EvaluateResponse>;
|
||||
customRequest(request: string, args: any): TPromise<DebugProtocol.Response>;
|
||||
|
||||
restartFrame(frameId: number, threadId: number): TPromise<DebugProtocol.RestartFrameResponse>;
|
||||
next(threadId: number): TPromise<DebugProtocol.NextResponse>;
|
||||
stepIn(threadId: number): TPromise<DebugProtocol.StepInResponse>;
|
||||
stepOut(threadId: number): TPromise<DebugProtocol.StepOutResponse>;
|
||||
stepBack(threadId: number): TPromise<DebugProtocol.StepBackResponse>;
|
||||
continue(threadId: number): TPromise<DebugProtocol.ContinueResponse>;
|
||||
reverseContinue(threadId: number): TPromise<DebugProtocol.ReverseContinueResponse>;
|
||||
pause(threadId: number): TPromise<DebugProtocol.PauseResponse>;
|
||||
terminateThreads(threadIds: number[]): TPromise<DebugProtocol.TerminateThreadsResponse>;
|
||||
restartFrame(frameId: number, threadId: number): TPromise<void>;
|
||||
next(threadId: number): TPromise<void>;
|
||||
stepIn(threadId: number): TPromise<void>;
|
||||
stepOut(threadId: number): TPromise<void>;
|
||||
stepBack(threadId: number): TPromise<void>;
|
||||
continue(threadId: number): TPromise<void>;
|
||||
reverseContinue(threadId: number): TPromise<void>;
|
||||
pause(threadId: number): TPromise<void>;
|
||||
terminateThreads(threadIds: number[]): TPromise<void>;
|
||||
|
||||
completions(frameId: number, text: string, position: Position, overwriteBefore: number): TPromise<CompletionItem[]>;
|
||||
setVariable(variablesReference: number, name: string, value: string): TPromise<DebugProtocol.SetVariableResponse>;
|
||||
@@ -376,7 +373,7 @@ export interface IViewModel extends ITreeElement {
|
||||
}
|
||||
|
||||
export interface IDebugModel extends ITreeElement {
|
||||
getSessions(): ReadonlyArray<IDebugSession>;
|
||||
getSessions(includeInactive?: boolean): ReadonlyArray<IDebugSession>;
|
||||
getBreakpoints(filter?: { uri?: uri, lineNumber?: number, column?: number, enabledOnly?: boolean }): ReadonlyArray<IBreakpoint>;
|
||||
areBreakpointsActivated(): boolean;
|
||||
getFunctionBreakpoints(): ReadonlyArray<IFunctionBreakpoint>;
|
||||
@@ -772,11 +769,6 @@ export interface IDebugService {
|
||||
*/
|
||||
sourceIsNotAvailable(uri: uri): void;
|
||||
|
||||
/**
|
||||
* returns Session with the given ID (or undefined if ID is not found)
|
||||
*/
|
||||
getSession(sessionId: string): IDebugSession;
|
||||
|
||||
/**
|
||||
* Gets the current debug model.
|
||||
*/
|
||||
|
||||
@@ -17,7 +17,7 @@ import { distinct } from 'vs/base/common/arrays';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import {
|
||||
ITreeElement, IExpression, IExpressionContainer, IDebugSession, IStackFrame, IExceptionBreakpoint, IBreakpoint, IFunctionBreakpoint, IDebugModel, IReplElementSource,
|
||||
IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint
|
||||
IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint, State
|
||||
} from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Source } from 'vs/workbench/parts/debug/common/debugSource';
|
||||
import { commonSuffixLength } from 'vs/base/common/strings';
|
||||
@@ -376,7 +376,7 @@ export class StackFrame implements IStackFrame {
|
||||
});
|
||||
}
|
||||
|
||||
public restart(): TPromise<any> {
|
||||
public restart(): TPromise<void> {
|
||||
return this.thread.session.restartFrame(this.frameId, this.thread.threadId);
|
||||
}
|
||||
|
||||
@@ -751,16 +751,16 @@ export class DebugModel implements IDebugModel {
|
||||
return 'root';
|
||||
}
|
||||
|
||||
public getSessions(): IDebugSession[] {
|
||||
return this.sessions;
|
||||
public getSessions(includeInactive = false): IDebugSession[] {
|
||||
// By default do not return inactive sesions.
|
||||
// However we are still holding onto inactive sessions due to repl and debug service session revival (eh scenario)
|
||||
return this.sessions.filter(s => includeInactive || s.state !== State.Inactive);
|
||||
}
|
||||
|
||||
public addSession(session: IDebugSession): void {
|
||||
// Make sure to remove all inactive sessions once a new session is started
|
||||
this.sessions = this.sessions.filter(s => s.state !== State.Inactive);
|
||||
this.sessions.push(session);
|
||||
}
|
||||
|
||||
public removeSession(id: string): void {
|
||||
this.sessions = this.sessions.filter(p => p.getId() !== id);
|
||||
this._onDidChangeCallStack.fire();
|
||||
}
|
||||
|
||||
@@ -1049,6 +1049,8 @@ export class DebugModel implements IDebugModel {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
// Make sure to shutdown each session, such that no debugged process is left laying around
|
||||
this.sessions.forEach(s => s.shutdown());
|
||||
this.toDispose = lifecycle.dispose(this.toDispose);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ import { WatchExpressionsView } from 'vs/workbench/parts/debug/electron-browser/
|
||||
import { CallStackView } from 'vs/workbench/parts/debug/electron-browser/callStackView';
|
||||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import {
|
||||
IDebugService, VIEWLET_ID, REPL_ID, CONTEXT_NOT_IN_DEBUG_MODE, CONTEXT_IN_DEBUG_MODE, INTERNAL_CONSOLE_OPTIONS_SCHEMA,
|
||||
IDebugService, VIEWLET_ID, REPL_ID, CONTEXT_IN_DEBUG_MODE, INTERNAL_CONSOLE_OPTIONS_SCHEMA,
|
||||
CONTEXT_DEBUG_STATE, VARIABLES_VIEW_ID, CALLSTACK_VIEW_ID, WATCH_VIEW_ID, BREAKPOINTS_VIEW_ID, VIEW_CONTAINER, LOADED_SCRIPTS_VIEW_ID, CONTEXT_LOADED_SCRIPTS_SUPPORTED
|
||||
} from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { DebugEditorModelManager } from 'vs/workbench/parts/debug/browser/debugEditorModelManager';
|
||||
import {
|
||||
StepOverAction, ClearReplAction, FocusReplAction, StepIntoAction, StepOutAction, StartAction, RestartAction, ContinueAction, StopAction, DisconnectAction, PauseAction, AddFunctionBreakpointAction,
|
||||
StepOverAction, FocusReplAction, StepIntoAction, StepOutAction, StartAction, RestartAction, ContinueAction, StopAction, DisconnectAction, PauseAction, AddFunctionBreakpointAction,
|
||||
ConfigureAction, DisableAllBreakpointsAction, EnableAllBreakpointsAction, RemoveAllBreakpointsAction, RunAction, ReapplyBreakpointsAction, SelectAndStartAction, TerminateThreadAction
|
||||
} from 'vs/workbench/parts/debug/browser/debugActions';
|
||||
import { DebugToolbar } from 'vs/workbench/parts/debug/browser/debugToolbar';
|
||||
@@ -130,7 +130,7 @@ Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).regi
|
||||
|
||||
const debugCategory = nls.localize('debugCategory', "Debug");
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(
|
||||
StartAction, StartAction.ID, StartAction.LABEL, { primary: KeyCode.F5 }, CONTEXT_NOT_IN_DEBUG_MODE), 'Debug: Start Debugging', debugCategory);
|
||||
StartAction, StartAction.ID, StartAction.LABEL, { primary: KeyCode.F5 }, CONTEXT_IN_DEBUG_MODE.toNegated()), 'Debug: Start Debugging', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(StepOverAction, StepOverAction.ID, StepOverAction.LABEL, { primary: KeyCode.F10 }, CONTEXT_IN_DEBUG_MODE), 'Debug: Step Over', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(StepIntoAction, StepIntoAction.ID, StepIntoAction.LABEL, { primary: KeyCode.F11 }, CONTEXT_IN_DEBUG_MODE, KeybindingWeight.WorkbenchContrib + 1), 'Debug: Step Into', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(StepOutAction, StepOutAction.ID, StepOutAction.LABEL, { primary: KeyMod.Shift | KeyCode.F11 }, CONTEXT_IN_DEBUG_MODE), 'Debug: Step Out', debugCategory);
|
||||
@@ -143,11 +143,10 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(TerminateThreadAction,
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ConfigureAction, ConfigureAction.ID, ConfigureAction.LABEL), 'Debug: Open launch.json', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(AddFunctionBreakpointAction, AddFunctionBreakpointAction.ID, AddFunctionBreakpointAction.LABEL), 'Debug: Add Function Breakpoint', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ReapplyBreakpointsAction, ReapplyBreakpointsAction.ID, ReapplyBreakpointsAction.LABEL), 'Debug: Reapply All Breakpoints', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(RunAction, RunAction.ID, RunAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.F5, mac: { primary: KeyMod.WinCtrl | KeyCode.F5 } }, CONTEXT_NOT_IN_DEBUG_MODE), 'Debug: Start Without Debugging', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(RunAction, RunAction.ID, RunAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.F5, mac: { primary: KeyMod.WinCtrl | KeyCode.F5 } }, CONTEXT_IN_DEBUG_MODE.toNegated()), 'Debug: Start Without Debugging', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(RemoveAllBreakpointsAction, RemoveAllBreakpointsAction.ID, RemoveAllBreakpointsAction.LABEL), 'Debug: Remove All Breakpoints', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(EnableAllBreakpointsAction, EnableAllBreakpointsAction.ID, EnableAllBreakpointsAction.LABEL), 'Debug: Enable All Breakpoints', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(DisableAllBreakpointsAction, DisableAllBreakpointsAction.ID, DisableAllBreakpointsAction.LABEL), 'Debug: Disable All Breakpoints', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ClearReplAction, ClearReplAction.ID, ClearReplAction.LABEL), 'Debug: Clear Console', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(FocusReplAction, FocusReplAction.ID, FocusReplAction.LABEL), 'Debug: Focus on Debug Console View', debugCategory);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(SelectAndStartAction, SelectAndStartAction.ID, SelectAndStartAction.LABEL), 'Debug: Select and Start Debugging', debugCategory);
|
||||
|
||||
@@ -450,7 +449,7 @@ if (isMacintosh) {
|
||||
});
|
||||
};
|
||||
|
||||
registerTouchBarEntry(StartAction.ID, StartAction.LABEL, 0, CONTEXT_NOT_IN_DEBUG_MODE, 'continue-tb.png');
|
||||
registerTouchBarEntry(StartAction.ID, StartAction.LABEL, 0, CONTEXT_IN_DEBUG_MODE.toNegated(), 'continue-tb.png');
|
||||
registerTouchBarEntry(ContinueAction.ID, ContinueAction.LABEL, 0, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), 'continue-tb.png');
|
||||
registerTouchBarEntry(PauseAction.ID, PauseAction.LABEL, 1, ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, ContextKeyExpr.notEquals('debugState', 'stopped')), 'pause-tb.png');
|
||||
registerTouchBarEntry(StepOverAction.ID, StepOverAction.LABEL, 2, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), 'stepover-tb.png');
|
||||
|
||||
@@ -81,7 +81,6 @@ export class DebugService implements IDebugService {
|
||||
private model: DebugModel;
|
||||
private viewModel: ViewModel;
|
||||
private configurationManager: ConfigurationManager;
|
||||
private allSessions = new Map<string, IDebugSession>();
|
||||
private toDispose: IDisposable[];
|
||||
private debugType: IContextKey<string>;
|
||||
private debugState: IContextKey<string>;
|
||||
@@ -138,7 +137,7 @@ export class DebugService implements IDebugService {
|
||||
this.lifecycleService.onShutdown(this.dispose, this);
|
||||
|
||||
this.toDispose.push(this.broadcastService.onBroadcast(broadcast => {
|
||||
const session = this.getSession(broadcast.payload.debugId);
|
||||
const session = this.model.getSessions(true).filter(s => s.getId() === broadcast.payload.debugId).pop();
|
||||
if (session) {
|
||||
switch (broadcast.channel) {
|
||||
|
||||
@@ -179,10 +178,6 @@ export class DebugService implements IDebugService {
|
||||
}));
|
||||
}
|
||||
|
||||
getSession(sessionId: string): IDebugSession {
|
||||
return this.allSessions.get(sessionId);
|
||||
}
|
||||
|
||||
getModel(): IDebugModel {
|
||||
return this.model;
|
||||
}
|
||||
@@ -271,10 +266,6 @@ export class DebugService implements IDebugService {
|
||||
this.textFileService.saveAll().then(() => this.configurationService.reloadConfiguration(launch ? launch.workspace : undefined).then(() =>
|
||||
this.extensionService.whenInstalledExtensionsRegistered().then(() => {
|
||||
|
||||
if (this.model.getSessions().length === 0) {
|
||||
this.allSessions.clear();
|
||||
}
|
||||
|
||||
let config: IConfig, compound: ICompound;
|
||||
if (!configOrName) {
|
||||
configOrName = this.configurationManager.selectedConfiguration.name;
|
||||
@@ -431,7 +422,6 @@ export class DebugService implements IDebugService {
|
||||
private doCreateSession(root: IWorkspaceFolder, configuration: { resolved: IConfig, unresolved: IConfig }): TPromise<boolean> {
|
||||
|
||||
const session = this.instantiationService.createInstance(DebugSession, configuration, root, this.model);
|
||||
this.allSessions.set(session.getId(), session);
|
||||
|
||||
// register listeners as the very first thing!
|
||||
this.registerSessionListeners(session);
|
||||
@@ -881,13 +871,9 @@ export class DebugService implements IDebugService {
|
||||
|
||||
const breakpointsToSend = this.model.getBreakpoints({ uri: modelUri, enabledOnly: true });
|
||||
|
||||
return this.sendToOneOrAllSessions(session, s => {
|
||||
return s.sendBreakpoints(modelUri, breakpointsToSend, sourceModified).then(data => {
|
||||
if (data) {
|
||||
this.model.setBreakpointSessionData(s.getId(), data);
|
||||
}
|
||||
});
|
||||
});
|
||||
return this.sendToOneOrAllSessions(session, s =>
|
||||
s.sendBreakpoints(modelUri, breakpointsToSend, sourceModified)
|
||||
);
|
||||
}
|
||||
|
||||
private sendFunctionBreakpoints(session?: IDebugSession): TPromise<void> {
|
||||
@@ -895,11 +881,7 @@ export class DebugService implements IDebugService {
|
||||
const breakpointsToSend = this.model.getFunctionBreakpoints().filter(fbp => fbp.enabled && this.model.areBreakpointsActivated());
|
||||
|
||||
return this.sendToOneOrAllSessions(session, s => {
|
||||
return s.capabilities.supportsFunctionBreakpoints ? s.sendFunctionBreakpoints(breakpointsToSend).then(data => {
|
||||
if (data) {
|
||||
this.model.setBreakpointSessionData(s.getId(), data);
|
||||
}
|
||||
}) : Promise.resolve(undefined);
|
||||
return s.capabilities.supportsFunctionBreakpoints ? s.sendFunctionBreakpoints(breakpointsToSend) : Promise.resolve(undefined);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { CompletionItem, completionKindFromLegacyString } from 'vs/editor/common/modes';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, ActualBreakpoints, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Source } from 'vs/workbench/parts/debug/common/debugSource';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { Thread, ExpressionContainer, DebugModel } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
@@ -90,6 +90,10 @@ export class DebugSession implements IDebugSession {
|
||||
}
|
||||
|
||||
get state(): State {
|
||||
if (!this.raw) {
|
||||
return State.Inactive;
|
||||
}
|
||||
|
||||
const focusedThread = this.debugService.getViewModel().focusedThread;
|
||||
if (focusedThread && focusedThread.session === this) {
|
||||
return focusedThread.stopped ? State.Stopped : State.Running;
|
||||
@@ -98,7 +102,7 @@ export class DebugSession implements IDebugSession {
|
||||
return State.Stopped;
|
||||
}
|
||||
|
||||
return !!this.raw ? State.Running : State.Inactive;
|
||||
return State.Running;
|
||||
}
|
||||
|
||||
get capabilities(): DebugProtocol.Capabilities {
|
||||
@@ -161,7 +165,7 @@ export class DebugSession implements IDebugSession {
|
||||
supportsVariablePaging: true, // #9537
|
||||
supportsRunInTerminalRequest: true, // #10574
|
||||
locale: platform.locale
|
||||
}).then(response => {
|
||||
}).then(() => {
|
||||
this.model.addSession(this);
|
||||
this._onDidChangeState.fire();
|
||||
this.model.setExceptionBreakpoints(this.raw.capabilities.exceptionBreakpointFilters);
|
||||
@@ -219,14 +223,14 @@ export class DebugSession implements IDebugSession {
|
||||
/**
|
||||
* restart debug adapter session
|
||||
*/
|
||||
restart(): TPromise<DebugProtocol.RestartResponse> {
|
||||
restart(): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.restart();
|
||||
return this.raw.restart().then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
sendBreakpoints(modelUri: URI, breakpointsToSend: IBreakpoint[], sourceModified: boolean): TPromise<ActualBreakpoints | undefined> {
|
||||
sendBreakpoints(modelUri: URI, breakpointsToSend: IBreakpoint[], sourceModified: boolean): TPromise<void> {
|
||||
|
||||
if (!this.raw) {
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
@@ -257,42 +261,41 @@ export class DebugSession implements IDebugSession {
|
||||
breakpoints: breakpointsToSend.map(bp => ({ line: bp.lineNumber, column: bp.column, condition: bp.condition, hitCondition: bp.hitCondition, logMessage: bp.logMessage })),
|
||||
sourceModified
|
||||
}).then(response => {
|
||||
|
||||
if (response && response.body) {
|
||||
const data: ActualBreakpoints = Object.create(null);
|
||||
const data: { [id: string]: DebugProtocol.Breakpoint } = Object.create(null);
|
||||
for (let i = 0; i < breakpointsToSend.length; i++) {
|
||||
data[breakpointsToSend[i].getId()] = response.body.breakpoints[i];
|
||||
}
|
||||
|
||||
this.model.setBreakpointSessionData(this.getId(), data);
|
||||
return data;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
sendFunctionBreakpoints(fbpts: IFunctionBreakpoint[]): TPromise<ActualBreakpoints | undefined> {
|
||||
sendFunctionBreakpoints(fbpts: IFunctionBreakpoint[]): TPromise<void> {
|
||||
if (this.raw) {
|
||||
if (this.raw.readyForBreakpoints) {
|
||||
return this.raw.setFunctionBreakpoints({ breakpoints: fbpts }).then(response => {
|
||||
if (response && response.body) {
|
||||
const data: ActualBreakpoints = Object.create(null);
|
||||
const data: { [id: string]: DebugProtocol.Breakpoint } = Object.create(null);
|
||||
for (let i = 0; i < fbpts.length; i++) {
|
||||
data[fbpts[i].getId()] = response.body.breakpoints[i];
|
||||
}
|
||||
return data;
|
||||
this.model.setBreakpointSessionData(this.getId(), data);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
return Promise.resolve(undefined);
|
||||
|
||||
return TPromise.as(undefined);
|
||||
}
|
||||
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): TPromise<any> {
|
||||
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): TPromise<void> {
|
||||
if (this.raw) {
|
||||
if (this.raw.readyForBreakpoints) {
|
||||
return this.raw.setExceptionBreakpoints({ filters: exbpts.map(exb => exb.filter) });
|
||||
return this.raw.setExceptionBreakpoints({ filters: exbpts.map(exb => exb.filter) }).then(() => undefined);
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
@@ -351,65 +354,65 @@ export class DebugSession implements IDebugSession {
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
restartFrame(frameId: number, threadId: number): TPromise<DebugProtocol.RestartFrameResponse> {
|
||||
restartFrame(frameId: number, threadId: number): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.restartFrame({ frameId }, threadId);
|
||||
return this.raw.restartFrame({ frameId }, threadId).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
next(threadId: number): TPromise<DebugProtocol.NextResponse> {
|
||||
next(threadId: number): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.next({ threadId });
|
||||
return this.raw.next({ threadId }).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
stepIn(threadId: number): TPromise<DebugProtocol.StepInResponse> {
|
||||
stepIn(threadId: number): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.stepIn({ threadId });
|
||||
return this.raw.stepIn({ threadId }).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
stepOut(threadId: number): TPromise<DebugProtocol.StepOutResponse> {
|
||||
stepOut(threadId: number): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.stepOut({ threadId });
|
||||
return this.raw.stepOut({ threadId }).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
stepBack(threadId: number): TPromise<DebugProtocol.StepBackResponse> {
|
||||
stepBack(threadId: number): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.stepBack({ threadId });
|
||||
return this.raw.stepBack({ threadId }).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
continue(threadId: number): TPromise<DebugProtocol.ContinueResponse> {
|
||||
continue(threadId: number): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.continue({ threadId });
|
||||
return this.raw.continue({ threadId }).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
reverseContinue(threadId: number): TPromise<DebugProtocol.ReverseContinueResponse> {
|
||||
reverseContinue(threadId: number): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.reverseContinue({ threadId });
|
||||
return this.raw.reverseContinue({ threadId }).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
pause(threadId: number): TPromise<DebugProtocol.PauseResponse> {
|
||||
pause(threadId: number): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.pause({ threadId });
|
||||
return this.raw.pause({ threadId }).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
terminateThreads(threadIds?: number[]): TPromise<DebugProtocol.TerminateThreadsResponse> {
|
||||
terminateThreads(threadIds?: number[]): TPromise<void> {
|
||||
if (this.raw) {
|
||||
return this.raw.terminateThreads({ threadIds });
|
||||
return this.raw.terminateThreads({ threadIds }).then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
@@ -747,14 +750,13 @@ export class DebugSession implements IDebugSession {
|
||||
|
||||
shutdown(): void {
|
||||
dispose(this.rawListeners);
|
||||
this.model.clearThreads(this.getId(), true);
|
||||
this.model.removeSession(this.getId());
|
||||
this._onDidChangeState.fire();
|
||||
this.fetchThreadsScheduler = undefined;
|
||||
if (this.raw) {
|
||||
this.raw.disconnect();
|
||||
}
|
||||
this.raw = undefined;
|
||||
this.model.clearThreads(this.getId(), true);
|
||||
this._onDidChangeState.fire();
|
||||
}
|
||||
|
||||
//---- sources
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as nls from 'vs/nls';
|
||||
import { URI as uri } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { IAction, IActionItem } from 'vs/base/common/actions';
|
||||
import { IAction, IActionItem, Action } from 'vs/base/common/actions';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
@@ -19,7 +19,6 @@ import { Context as SuggestContext } from 'vs/editor/contrib/suggest/suggest';
|
||||
import { SuggestController } from 'vs/editor/contrib/suggest/suggestController';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { registerEditorAction, ServicesAccessor, EditorAction, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
@@ -29,9 +28,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ReplExpressionsRenderer, ReplExpressionsController, ReplExpressionsDataSource, ReplExpressionsActionProvider, ReplExpressionsAccessibilityProvider } from 'vs/workbench/parts/debug/electron-browser/replViewer';
|
||||
import { ClearReplAction, FocusSessionAction } from 'vs/workbench/parts/debug/browser/debugActions';
|
||||
import { Panel } from 'vs/workbench/browser/panel';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { clipboard } from 'electron';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
@@ -41,7 +38,7 @@ import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { OpenMode, ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { IDebugService, REPL_ID, DEBUG_SCHEME, CONTEXT_IN_DEBUG_REPL } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { IDebugService, REPL_ID, DEBUG_SCHEME, CONTEXT_IN_DEBUG_REPL, IDebugSession, State } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { HistoryNavigator } from 'vs/base/common/history';
|
||||
import { IHistoryNavigationWidget } from 'vs/base/browser/history';
|
||||
import { createAndBindHistoryNavigationWidgetScopedContextKeyService } from 'vs/platform/widget/browser/contextScopedHistoryWidget';
|
||||
@@ -52,6 +49,7 @@ import { IDecorationOptions } from 'vs/editor/common/editorCommon';
|
||||
import { transparent, editorForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { FocusSessionActionItem } from 'vs/workbench/parts/debug/browser/debugActionItems';
|
||||
import { CompletionContext, CompletionList, CompletionProviderRegistry } from 'vs/editor/common/modes';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -68,18 +66,19 @@ export interface IPrivateReplService {
|
||||
_serviceBrand: any;
|
||||
acceptReplInput(): void;
|
||||
getVisibleContent(): string;
|
||||
selectSession(session: IDebugSession): void;
|
||||
clearRepl(): void;
|
||||
}
|
||||
|
||||
export class Repl extends Panel implements IPrivateReplService, IHistoryNavigationWidget {
|
||||
public _serviceBrand: any;
|
||||
_serviceBrand: any;
|
||||
|
||||
private static readonly HALF_WIDTH_TYPICAL = 'n';
|
||||
|
||||
private history: HistoryNavigator<string>;
|
||||
private static readonly REFRESH_DELAY = 500; // delay in ms to refresh the repl for new elements to show
|
||||
private static readonly REPL_INPUT_INITIAL_HEIGHT = 19;
|
||||
private static readonly REPL_INPUT_MAX_HEIGHT = 170;
|
||||
|
||||
private history: HistoryNavigator<string>;
|
||||
private tree: ITree;
|
||||
private renderer: ReplExpressionsRenderer;
|
||||
private container: HTMLElement;
|
||||
@@ -91,13 +90,14 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
private replInputHeight: number;
|
||||
private model: ITextModel;
|
||||
private historyNavigationEnablement: IContextKey<boolean>;
|
||||
private scopedInstantiationService: IInstantiationService;
|
||||
private replElementsChangeListener: IDisposable;
|
||||
|
||||
constructor(
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IStorageService private storageService: IStorageService,
|
||||
@IPanelService private panelService: IPanelService,
|
||||
@IThemeService protected themeService: IThemeService,
|
||||
@IModelService private modelService: IModelService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@@ -112,56 +112,193 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
let replElementsChangeListener: IDisposable;
|
||||
this._register(this.debugService.getViewModel().onDidFocusSession(session => {
|
||||
if (replElementsChangeListener) {
|
||||
replElementsChangeListener.dispose();
|
||||
if (this.isVisible()) {
|
||||
this.selectSession(session);
|
||||
}
|
||||
if (session) {
|
||||
replElementsChangeListener = session.onDidChangeReplElements(() => {
|
||||
this.refreshReplElements(session.getReplElements().length === 0);
|
||||
});
|
||||
|
||||
if (this.tree && this.isVisible()) {
|
||||
this.tree.setInput(session);
|
||||
}
|
||||
}
|
||||
this.replInput.updateOptions({ readOnly: !session });
|
||||
this.updateInputDecoration();
|
||||
}));
|
||||
this._register(this.panelService.onDidPanelOpen(panel => this.refreshReplElements(true)));
|
||||
this._register(this.debugService.onDidNewSession(() => this.updateTitleArea()));
|
||||
this._register(this.themeService.onThemeChange(() => this.updateInputDecoration()));
|
||||
this._register(this.themeService.onThemeChange(() => {
|
||||
if (this.isVisible()) {
|
||||
this.updateInputDecoration();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private refreshReplElements(noDelay: boolean): void {
|
||||
if (this.tree && this.isVisible()) {
|
||||
if (this.refreshTimeoutHandle) {
|
||||
return; // refresh already triggered
|
||||
setVisible(visible: boolean): Promise<void> {
|
||||
if (!visible) {
|
||||
dispose(this.model);
|
||||
} else {
|
||||
this.model = this.modelService.createModel('', null, uri.parse(`${DEBUG_SCHEME}:replinput`), true);
|
||||
this.replInput.setModel(this.model);
|
||||
this.updateInputDecoration();
|
||||
const focusedSession = this.debugService.getViewModel().focusedSession;
|
||||
if (focusedSession && this.tree.getInput() !== focusedSession) {
|
||||
this.selectSession(focusedSession);
|
||||
}
|
||||
}
|
||||
|
||||
const delay = noDelay ? 0 : Repl.REFRESH_DELAY;
|
||||
this.refreshTimeoutHandle = setTimeout(() => {
|
||||
this.refreshTimeoutHandle = null;
|
||||
const previousScrollPosition = this.tree.getScrollPosition();
|
||||
this.tree.refresh().then(() => {
|
||||
if (previousScrollPosition === 1) {
|
||||
// Only scroll if we were scrolled all the way down before tree refreshed #10486
|
||||
this.tree.setScrollPosition(1);
|
||||
}
|
||||
}, errors.onUnexpectedError);
|
||||
}, delay);
|
||||
return super.setVisible(visible);
|
||||
}
|
||||
|
||||
get isReadonly(): boolean {
|
||||
// Do not allow to edit inactive sessions
|
||||
const session: IDebugSession = this.tree.getInput();
|
||||
if (session && session.state !== State.Inactive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
showPreviousValue(): void {
|
||||
this.navigateHistory(true);
|
||||
}
|
||||
|
||||
showNextValue(): void {
|
||||
this.navigateHistory(false);
|
||||
}
|
||||
|
||||
private navigateHistory(previous: boolean): void {
|
||||
const historyInput = previous ? this.history.previous() : this.history.next();
|
||||
if (historyInput) {
|
||||
this.replInput.setValue(historyInput);
|
||||
aria.status(historyInput);
|
||||
// always leave cursor at the end.
|
||||
this.replInput.setPosition({ lineNumber: 1, column: historyInput.length + 1 });
|
||||
this.historyNavigationEnablement.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
public async create(parent: HTMLElement): Promise<void> {
|
||||
selectSession(session: IDebugSession): void {
|
||||
if (this.replElementsChangeListener) {
|
||||
this.replElementsChangeListener.dispose();
|
||||
}
|
||||
if (session) {
|
||||
this.replElementsChangeListener = session.onDidChangeReplElements(() => {
|
||||
this.refreshReplElements(session.getReplElements().length === 0);
|
||||
});
|
||||
|
||||
if (this.tree && this.tree.getInput() !== session) {
|
||||
this.tree.setInput(session);
|
||||
}
|
||||
}
|
||||
|
||||
this.replInput.updateOptions({ readOnly: this.isReadonly });
|
||||
this.updateInputDecoration();
|
||||
}
|
||||
|
||||
clearRepl(): void {
|
||||
const session: IDebugSession = this.tree.getInput();
|
||||
session.removeReplExpressions();
|
||||
this.replInput.focus();
|
||||
}
|
||||
|
||||
acceptReplInput(): void {
|
||||
const session: IDebugSession = this.tree.getInput();
|
||||
if (session) {
|
||||
session.addReplExpression(this.debugService.getViewModel().focusedStackFrame, this.replInput.getValue());
|
||||
this.history.add(this.replInput.getValue());
|
||||
this.replInput.setValue('');
|
||||
// Trigger a layout to shrink a potential multi line input
|
||||
this.replInputHeight = Repl.REPL_INPUT_INITIAL_HEIGHT;
|
||||
this.layout(this.dimension);
|
||||
}
|
||||
}
|
||||
|
||||
getVisibleContent(): string {
|
||||
let text = '';
|
||||
const navigator = this.tree.getNavigator();
|
||||
// skip first navigator element - the root node
|
||||
while (navigator.next()) {
|
||||
if (text) {
|
||||
text += `\n`;
|
||||
}
|
||||
text += navigator.current().toString();
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
layout(dimension: dom.Dimension): void {
|
||||
this.dimension = dimension;
|
||||
if (this.tree) {
|
||||
this.renderer.setWidth(dimension.width - 25, this.characterWidth);
|
||||
const treeHeight = dimension.height - this.replInputHeight;
|
||||
this.treeContainer.style.height = `${treeHeight}px`;
|
||||
this.tree.layout(treeHeight);
|
||||
}
|
||||
this.replInputContainer.style.height = `${this.replInputHeight}px`;
|
||||
|
||||
this.replInput.layout({ width: dimension.width - 20, height: this.replInputHeight });
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
this.replInput.focus();
|
||||
}
|
||||
|
||||
getActionItem(action: IAction): IActionItem {
|
||||
if (action.id === SelectReplAction.ID) {
|
||||
return this.instantiationService.createInstance(SelectReplActionItem, this.selectReplAction);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getActions(): IAction[] {
|
||||
const result: IAction[] = [];
|
||||
if (this.debugService.getModel().getSessions(true).length > 1) {
|
||||
result.push(this.selectReplAction);
|
||||
}
|
||||
result.push(this.clearReplAction);
|
||||
|
||||
result.forEach(a => this._register(a));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
shutdown(): void {
|
||||
const replHistory = this.history.getHistory();
|
||||
if (replHistory.length) {
|
||||
this.storageService.store(HISTORY_STORAGE_KEY, JSON.stringify(replHistory), StorageScope.WORKSPACE);
|
||||
} else {
|
||||
this.storageService.remove(HISTORY_STORAGE_KEY, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Cached locals
|
||||
@memoize
|
||||
private get characterWidth(): number {
|
||||
const characterWidthSurveyor = dom.append(this.container, $('.surveyor'));
|
||||
characterWidthSurveyor.textContent = Repl.HALF_WIDTH_TYPICAL;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
characterWidthSurveyor.textContent += characterWidthSurveyor.textContent;
|
||||
}
|
||||
characterWidthSurveyor.style.fontSize = isMacintosh ? '12px' : '14px';
|
||||
|
||||
return characterWidthSurveyor.clientWidth / characterWidthSurveyor.textContent.length;
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get selectReplAction(): SelectReplAction {
|
||||
return this.scopedInstantiationService.createInstance(SelectReplAction, SelectReplAction.ID, SelectReplAction.LABEL);
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get clearReplAction(): ClearReplAction {
|
||||
return this.scopedInstantiationService.createInstance(ClearReplAction, ClearReplAction.ID, ClearReplAction.LABEL);
|
||||
}
|
||||
|
||||
// --- Creation
|
||||
|
||||
async create(parent: HTMLElement): Promise<void> {
|
||||
await super.create(parent);
|
||||
this.container = dom.append(parent, $('.repl'));
|
||||
this.treeContainer = dom.append(this.container, $('.repl-tree'));
|
||||
this.createReplInput(this.container);
|
||||
|
||||
this.renderer = this.instantiationService.createInstance(ReplExpressionsRenderer);
|
||||
const controller = this.instantiationService.createInstance(ReplExpressionsController, new ReplExpressionsActionProvider(this.instantiationService, this.replInput), MenuId.DebugConsoleContext, { openMode: OpenMode.SINGLE_CLICK, clickBehavior: ClickBehavior.ON_MOUSE_UP /* do not change, to preserve focus behaviour in input field */ });
|
||||
const controller = this.instantiationService.createInstance(ReplExpressionsController, new ReplExpressionsActionProvider(this.clearReplAction, this.replInput), MenuId.DebugConsoleContext, { openMode: OpenMode.SINGLE_CLICK, clickBehavior: ClickBehavior.ON_MOUSE_UP /* do not change, to preserve focus behaviour in input field */ });
|
||||
controller.toFocusOnClick = this.replInput;
|
||||
|
||||
this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, {
|
||||
@@ -172,22 +309,6 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
}, replTreeOptions);
|
||||
}
|
||||
|
||||
public setVisible(visible: boolean): Promise<void> {
|
||||
if (!visible) {
|
||||
dispose(this.model);
|
||||
} else {
|
||||
this.model = this.modelService.createModel('', null, uri.parse(`${DEBUG_SCHEME}:replinput`), true);
|
||||
this.replInput.setModel(this.model);
|
||||
this.updateInputDecoration();
|
||||
const focusedSession = this.debugService.getViewModel().focusedSession;
|
||||
if (focusedSession && this.tree.getInput() !== focusedSession) {
|
||||
this.tree.setInput(focusedSession);
|
||||
}
|
||||
}
|
||||
|
||||
return super.setVisible(visible);
|
||||
}
|
||||
|
||||
private createReplInput(container: HTMLElement): void {
|
||||
this.replInputContainer = dom.append(container, $('.repl-input-wrapper'));
|
||||
|
||||
@@ -196,15 +317,15 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
this._register(scopedContextKeyService);
|
||||
CONTEXT_IN_DEBUG_REPL.bindTo(scopedContextKeyService).set(true);
|
||||
|
||||
const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection(
|
||||
this.scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection(
|
||||
[IContextKeyService, scopedContextKeyService], [IPrivateReplService, this]));
|
||||
const options = getSimpleEditorOptions();
|
||||
options.readOnly = true;
|
||||
this.replInput = scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, options, getSimpleCodeEditorWidgetOptions());
|
||||
this.replInput = this.scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, options, getSimpleCodeEditorWidgetOptions());
|
||||
|
||||
modes.CompletionProviderRegistry.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, {
|
||||
CompletionProviderRegistry.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, {
|
||||
triggerCharacters: ['.'],
|
||||
provideCompletionItems: (model: ITextModel, position: Position, _context: modes.CompletionContext, token: CancellationToken): Thenable<modes.CompletionList> => {
|
||||
provideCompletionItems: (model: ITextModel, position: Position, _context: CompletionContext, token: CancellationToken): Thenable<CompletionList> => {
|
||||
// Disable history navigation because up and down are used to navigate through the suggest widget
|
||||
this.historyNavigationEnablement.set(false);
|
||||
|
||||
@@ -242,123 +363,26 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
this._register(dom.addStandardDisposableListener(this.replInputContainer, dom.EventType.BLUR, () => dom.removeClass(this.replInputContainer, 'synthetic-focus')));
|
||||
}
|
||||
|
||||
private navigateHistory(previous: boolean): void {
|
||||
const historyInput = previous ? this.history.previous() : this.history.next();
|
||||
if (historyInput) {
|
||||
this.replInput.setValue(historyInput);
|
||||
aria.status(historyInput);
|
||||
// always leave cursor at the end.
|
||||
this.replInput.setPosition({ lineNumber: 1, column: historyInput.length + 1 });
|
||||
this.historyNavigationEnablement.set(true);
|
||||
}
|
||||
}
|
||||
// --- Update
|
||||
|
||||
public showPreviousValue(): void {
|
||||
this.navigateHistory(true);
|
||||
}
|
||||
|
||||
public showNextValue(): void {
|
||||
this.navigateHistory(false);
|
||||
}
|
||||
|
||||
public acceptReplInput(): void {
|
||||
const viewModel = this.debugService.getViewModel();
|
||||
const session = viewModel.focusedSession;
|
||||
if (session) {
|
||||
session.addReplExpression(viewModel.focusedStackFrame, this.replInput.getValue());
|
||||
this.history.add(this.replInput.getValue());
|
||||
this.replInput.setValue('');
|
||||
// Trigger a layout to shrink a potential multi line input
|
||||
this.replInputHeight = Repl.REPL_INPUT_INITIAL_HEIGHT;
|
||||
this.layout(this.dimension);
|
||||
}
|
||||
}
|
||||
|
||||
public getVisibleContent(): string {
|
||||
let text = '';
|
||||
const navigator = this.tree.getNavigator();
|
||||
// skip first navigator element - the root node
|
||||
while (navigator.next()) {
|
||||
if (text) {
|
||||
text += `\n`;
|
||||
private refreshReplElements(noDelay: boolean): void {
|
||||
if (this.tree && this.isVisible()) {
|
||||
if (this.refreshTimeoutHandle) {
|
||||
return; // refresh already triggered
|
||||
}
|
||||
text += navigator.current().toString();
|
||||
|
||||
const delay = noDelay ? 0 : Repl.REFRESH_DELAY;
|
||||
this.refreshTimeoutHandle = setTimeout(() => {
|
||||
this.refreshTimeoutHandle = null;
|
||||
const previousScrollPosition = this.tree.getScrollPosition();
|
||||
this.tree.refresh().then(() => {
|
||||
if (previousScrollPosition === 1) {
|
||||
// Only scroll if we were scrolled all the way down before tree refreshed #10486
|
||||
this.tree.setScrollPosition(1);
|
||||
}
|
||||
}, errors.onUnexpectedError);
|
||||
}, delay);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public layout(dimension: dom.Dimension): void {
|
||||
this.dimension = dimension;
|
||||
if (this.tree) {
|
||||
this.renderer.setWidth(dimension.width - 25, this.characterWidth);
|
||||
const treeHeight = dimension.height - this.replInputHeight;
|
||||
this.treeContainer.style.height = `${treeHeight}px`;
|
||||
this.tree.layout(treeHeight);
|
||||
}
|
||||
this.replInputContainer.style.height = `${this.replInputHeight}px`;
|
||||
|
||||
this.replInput.layout({ width: dimension.width - 20, height: this.replInputHeight });
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get characterWidth(): number {
|
||||
const characterWidthSurveyor = dom.append(this.container, $('.surveyor'));
|
||||
characterWidthSurveyor.textContent = Repl.HALF_WIDTH_TYPICAL;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
characterWidthSurveyor.textContent += characterWidthSurveyor.textContent;
|
||||
}
|
||||
characterWidthSurveyor.style.fontSize = isMacintosh ? '12px' : '14px';
|
||||
|
||||
return characterWidthSurveyor.clientWidth / characterWidthSurveyor.textContent.length;
|
||||
}
|
||||
|
||||
public focus(): void {
|
||||
this.replInput.focus();
|
||||
}
|
||||
|
||||
getActionItem(action: IAction): IActionItem {
|
||||
if (action.id === FocusSessionAction.ID) {
|
||||
return this.focusSessionActionItem;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getActions(): IAction[] {
|
||||
const result: IAction[] = [];
|
||||
if (this.debugService.getModel().getSessions().length > 1) {
|
||||
result.push(this.focusSessionAction);
|
||||
}
|
||||
result.push(this.clearReplAction);
|
||||
|
||||
result.forEach(a => this._register(a));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public shutdown(): void {
|
||||
const replHistory = this.history.getHistory();
|
||||
if (replHistory.length) {
|
||||
this.storageService.store(HISTORY_STORAGE_KEY, JSON.stringify(replHistory), StorageScope.WORKSPACE);
|
||||
} else {
|
||||
this.storageService.remove(HISTORY_STORAGE_KEY, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get focusSessionAction(): FocusSessionAction {
|
||||
return this.instantiationService.createInstance(FocusSessionAction, FocusSessionAction.ID, FocusSessionAction.LABEL);
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get clearReplAction(): ClearReplAction {
|
||||
return this.instantiationService.createInstance(ClearReplAction, ClearReplAction.ID, ClearReplAction.LABEL);
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get focusSessionActionItem(): FocusSessionActionItem {
|
||||
return this.instantiationService.createInstance(FocusSessionActionItem, this.focusSessionAction);
|
||||
}
|
||||
|
||||
private updateInputDecoration(): void {
|
||||
@@ -367,7 +391,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
}
|
||||
|
||||
const decorations: IDecorationOptions[] = [];
|
||||
if (!this.debugService.getViewModel().focusedSession) {
|
||||
if (this.isReadonly) {
|
||||
decorations.push({
|
||||
range: {
|
||||
startLineNumber: 0,
|
||||
@@ -387,8 +411,11 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
||||
this.replInput.setDecorations(DECORATION_KEY, decorations);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
dispose(): void {
|
||||
this.replInput.dispose();
|
||||
if (this.replElementsChangeListener) {
|
||||
this.replElementsChangeListener.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -409,7 +436,7 @@ class AcceptReplInputAction extends EditorAction {
|
||||
});
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void | TPromise<void> {
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor): void | TPromise<void> {
|
||||
SuggestController.get(editor).acceptSelectedSuggestion();
|
||||
accessor.get(IPrivateReplService).acceptReplInput();
|
||||
}
|
||||
@@ -426,7 +453,7 @@ export class ReplCopyAllAction extends EditorAction {
|
||||
});
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void | TPromise<void> {
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor): void | TPromise<void> {
|
||||
clipboard.writeText(accessor.get(IPrivateReplService).getVisibleContent());
|
||||
}
|
||||
}
|
||||
@@ -445,3 +472,54 @@ registerEditorCommand(new SuggestCommand({
|
||||
primary: KeyCode.RightArrow
|
||||
}
|
||||
}));
|
||||
|
||||
class SelectReplActionItem extends FocusSessionActionItem {
|
||||
protected getSessions(): ReadonlyArray<IDebugSession> {
|
||||
return this.debugService.getModel().getSessions(true);
|
||||
}
|
||||
}
|
||||
|
||||
class SelectReplAction extends Action {
|
||||
|
||||
static readonly ID = 'workbench.action.debug.selectRepl';
|
||||
static LABEL = nls.localize('selectRepl', "Select Debug Console");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@IDebugService private debugService: IDebugService,
|
||||
@IPrivateReplService private replService: IPrivateReplService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(sessionName: string): TPromise<any> {
|
||||
const session = this.debugService.getModel().getSessions(true).filter(p => p.getLabel() === sessionName).pop();
|
||||
// If session is already the focused session we need to manualy update the tree since view model will not send a focused change event
|
||||
if (session && session.state !== State.Inactive && session !== this.debugService.getViewModel().focusedSession) {
|
||||
this.debugService.focusStackFrame(undefined, undefined, session, true);
|
||||
} else {
|
||||
this.replService.selectSession(session);
|
||||
}
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
class ClearReplAction extends Action {
|
||||
static readonly ID = 'workbench.debug.panel.action.clearReplAction';
|
||||
static LABEL = nls.localize('clearRepl', "Clear Console");
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@IDebugService debugService: IDebugService,
|
||||
@IPrivateReplService private replService: IPrivateReplService
|
||||
) {
|
||||
super(id, label, 'debug-action clear-repl');
|
||||
}
|
||||
|
||||
public run(): TPromise<any> {
|
||||
this.replService.clearRepl();
|
||||
aria.status(nls.localize('debugConsoleCleared', "Debug console was cleared"));
|
||||
|
||||
// focus back to repl
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { IAction, Action } from 'vs/base/common/actions';
|
||||
import * as lifecycle from 'vs/base/common/lifecycle';
|
||||
import { isFullWidthCharacter, removeAnsiEscapeCodes, endsWith } from 'vs/base/common/strings';
|
||||
import { IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
@@ -17,7 +17,7 @@ import { ICancelableEvent } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
import { IExpressionContainer, IExpression, IReplElementSource } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { RawObjectReplElement, Expression, SimpleReplElement, Variable } from 'vs/workbench/parts/debug/common/debugModel';
|
||||
import { renderVariable, renderExpressionValue, IVariableTemplateData, BaseDebugController } from 'vs/workbench/parts/debug/browser/baseDebugView';
|
||||
import { ClearReplAction, ReplCollapseAllAction } from 'vs/workbench/parts/debug/browser/debugActions';
|
||||
import { ReplCollapseAllAction } from 'vs/workbench/parts/debug/browser/debugActions';
|
||||
import { CopyAction, CopyAllAction } from 'vs/workbench/parts/debug/electron-browser/electronDebugActions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
@@ -317,7 +317,7 @@ export class ReplExpressionsAccessibilityProvider implements IAccessibilityProvi
|
||||
|
||||
export class ReplExpressionsActionProvider implements IActionProvider {
|
||||
|
||||
constructor(private instantiationService: IInstantiationService, private toFocus: { focus(): void }) {
|
||||
constructor(private clearReplAction: Action, private toFocus: { focus(): void }) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ export class ReplExpressionsActionProvider implements IActionProvider {
|
||||
actions.push(new CopyAllAction(CopyAllAction.ID, CopyAllAction.LABEL, tree));
|
||||
actions.push(new ReplCollapseAllAction(tree, this.toFocus));
|
||||
actions.push(new Separator());
|
||||
actions.push(this.instantiationService.createInstance(ClearReplAction, ClearReplAction.ID, ClearReplAction.LABEL));
|
||||
actions.push(this.clearReplAction);
|
||||
|
||||
return Promise.resolve(actions);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Event } from 'vs/base/common/event';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { ILaunch, IDebugService, State, IDebugSession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IDebugModel, IViewModel, IBreakpoint, LoadedSourceEvent, IThread, IRawModelUpdate, ActualBreakpoints, IFunctionBreakpoint, IExceptionBreakpoint, IDebugger, IExceptionInfo, AdapterEndEvent, IReplElement, IExpression, IReplElementSource } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { ILaunch, IDebugService, State, IDebugSession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IDebugModel, IViewModel, IBreakpoint, LoadedSourceEvent, IThread, IRawModelUpdate, IFunctionBreakpoint, IExceptionBreakpoint, IDebugger, IExceptionInfo, AdapterEndEvent, IReplElement, IExpression, IReplElementSource } from 'vs/workbench/parts/debug/common/debug';
|
||||
import { Source } from 'vs/workbench/parts/debug/common/debugSource';
|
||||
import { CompletionItem } from 'vs/editor/common/modes';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
@@ -17,10 +17,6 @@ export class MockDebugService implements IDebugService {
|
||||
|
||||
public _serviceBrand: any;
|
||||
|
||||
getSession(sessionId: string): IDebugSession {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public get state(): State {
|
||||
return null;
|
||||
}
|
||||
@@ -210,16 +206,16 @@ export class MockSession implements IDebugSession {
|
||||
launchOrAttach(config: IConfig): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
restart(): TPromise<DebugProtocol.RestartResponse> {
|
||||
restart(): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
sendBreakpoints(modelUri: uri, bpts: IBreakpoint[], sourceModified: boolean): TPromise<ActualBreakpoints> {
|
||||
sendBreakpoints(modelUri: uri, bpts: IBreakpoint[], sourceModified: boolean): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
sendFunctionBreakpoints(fbps: IFunctionBreakpoint[]): TPromise<ActualBreakpoints> {
|
||||
sendFunctionBreakpoints(fbps: IFunctionBreakpoint[]): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): TPromise<any> {
|
||||
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
customRequest(request: string, args: any): TPromise<DebugProtocol.Response> {
|
||||
@@ -240,31 +236,31 @@ export class MockSession implements IDebugSession {
|
||||
evaluate(expression: string, frameId: number, context?: string): TPromise<DebugProtocol.EvaluateResponse> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
restartFrame(frameId: number, threadId: number): TPromise<DebugProtocol.RestartFrameResponse> {
|
||||
restartFrame(frameId: number, threadId: number): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
next(threadId: number): TPromise<DebugProtocol.NextResponse> {
|
||||
next(threadId: number): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
stepIn(threadId: number): TPromise<DebugProtocol.StepInResponse> {
|
||||
stepIn(threadId: number): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
stepOut(threadId: number): TPromise<DebugProtocol.StepOutResponse> {
|
||||
stepOut(threadId: number): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
stepBack(threadId: number): TPromise<DebugProtocol.StepBackResponse> {
|
||||
stepBack(threadId: number): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
continue(threadId: number): TPromise<DebugProtocol.ContinueResponse> {
|
||||
continue(threadId: number): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
reverseContinue(threadId: number): TPromise<DebugProtocol.ReverseContinueResponse> {
|
||||
reverseContinue(threadId: number): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
pause(threadId: number): TPromise<DebugProtocol.PauseResponse> {
|
||||
pause(threadId: number): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
terminateThreads(threadIds: number[]): TPromise<DebugProtocol.TerminateThreadsResponse> {
|
||||
terminateThreads(threadIds: number[]): TPromise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
setVariable(variablesReference: number, name: string, value: string): TPromise<DebugProtocol.SetVariableResponse> {
|
||||
|
||||
@@ -113,7 +113,7 @@ suite('Debug - Model', () => {
|
||||
const session = new DebugSession({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined, model, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined);
|
||||
model.addSession(session);
|
||||
|
||||
assert.equal(model.getSessions().length, 1);
|
||||
assert.equal(model.getSessions(true).length, 1);
|
||||
model.rawUpdate({
|
||||
sessionId: session.getId(),
|
||||
threadId: threadId,
|
||||
@@ -127,9 +127,7 @@ suite('Debug - Model', () => {
|
||||
|
||||
model.clearThreads(session.getId(), true);
|
||||
assert.equal(session.getThread(threadId), null);
|
||||
assert.equal(model.getSessions().length, 1);
|
||||
model.removeSession(session.getId());
|
||||
assert.equal(model.getSessions().length, 0);
|
||||
assert.equal(model.getSessions(true).length, 1);
|
||||
});
|
||||
|
||||
test('threads multiple wtih allThreadsStopped', () => {
|
||||
|
||||
@@ -555,7 +555,8 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
|
||||
group: '5_autosave',
|
||||
command: {
|
||||
id: ToggleAutoSaveAction.ID,
|
||||
title: nls.localize({ key: 'miAutoSave', comment: ['&& denotes a mnemonic'] }, "A&&uto Save")
|
||||
title: nls.localize({ key: 'miAutoSave', comment: ['&& denotes a mnemonic'] }, "A&&uto Save"),
|
||||
toggled: ContextKeyExpr.notEquals('config.files.autoSave', 'off')
|
||||
},
|
||||
order: 1
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user