From b02c4facaf2c3b983af7f8e6617bf54ce2261259 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 28 Apr 2016 17:14:58 +0200 Subject: [PATCH] Fixes #5362: MainThreadTextEditor: disassociate code editor as soon as code editor's model changes --- build/gulpfile.hygiene.js | 3 +- .../vscode-api-tests/src/window.test.ts | 68 ++++++++++++++++++- .../testWorkspace/10linefile.ts | 10 +++ .../testWorkspace/30linefile.ts | 30 ++++++++ .../workbench/api/node/mainThreadEditors.ts | 5 ++ 5 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 extensions/vscode-api-tests/testWorkspace/10linefile.ts create mode 100644 extensions/vscode-api-tests/testWorkspace/30linefile.ts diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index a6bf42dde93..eb6a10ae45f 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -55,7 +55,8 @@ var indentationFilter = [ '!extensions/**/snippets/**', '!extensions/**/syntaxes/**', '!extensions/**/themes/**', - '!extensions/**/colorize-fixtures/**' + '!extensions/**/colorize-fixtures/**', + '!extensions/vscode-api-tests/testWorkspace/**' ]; var copyrightFilter = [ diff --git a/extensions/vscode-api-tests/src/window.test.ts b/extensions/vscode-api-tests/src/window.test.ts index c52ed3333eb..e6445b43a60 100644 --- a/extensions/vscode-api-tests/src/window.test.ts +++ b/extensions/vscode-api-tests/src/window.test.ts @@ -6,7 +6,7 @@ 'use strict'; import * as assert from 'assert'; -import {workspace, window, ViewColumn, TextEditorViewColumnChangeEvent, Uri} from 'vscode'; +import {workspace, window, ViewColumn, TextEditorViewColumnChangeEvent, Uri, Selection, Position} from 'vscode'; import {join} from 'path'; import {cleanUp, pathEquals} from './utils'; @@ -82,4 +82,68 @@ suite('window namespace tests', () => { }); }); }); -}); \ No newline at end of file + + test('issue #5362 - Incorrect TextEditor passed by onDidChangeTextEditorSelection', (done) => { + const file10Path = join(workspace.rootPath, './10linefile.ts'); + const file30Path = join(workspace.rootPath, './30linefile.ts'); + + let finished = false; + let failOncePlease = (err:Error) => { + if (finished) { + return; + } + finished = true; + done(err); + }; + + let passOncePlease = () => { + if (finished) { + return; + } + finished = true; + done(null); + }; + + let subscription = window.onDidChangeTextEditorSelection((e) => { + let lineCount = e.textEditor.document.lineCount; + let pos1 = e.textEditor.selections[0].active.line; + let pos2 = e.selections[0].active.line; + + if (pos1 !== pos2) { + failOncePlease(new Error('received invalid selection changed event!')); + return; + } + + if (pos1 >= lineCount) { + failOncePlease(new Error(`Cursor position (${pos1}) is not valid in the document ${e.textEditor.document.fileName} that has ${lineCount} lines.`)); + return; + } + }); + + // Open 10 line file, show it in slot 1, set cursor to line 10 + // Open 30 line file, show it in slot 1, set cursor to line 30 + // Open 10 line file, show it in slot 1 + // Open 30 line file, show it in slot 1 + workspace.openTextDocument(file10Path).then((doc) => { + return window.showTextDocument(doc, ViewColumn.One); + }).then((editor10line) => { + editor10line.selection = new Selection(new Position(9,0), new Position(9, 0)); + }).then(() => { + return workspace.openTextDocument(file30Path); + }).then((doc) => { + return window.showTextDocument(doc, ViewColumn.One); + }).then((editor30line) => { + editor30line.selection = new Selection(new Position(29,0), new Position(29, 0)); + }).then(() => { + return workspace.openTextDocument(file10Path); + }).then((doc) => { + return window.showTextDocument(doc, ViewColumn.One); + }).then(() => { + return workspace.openTextDocument(file30Path); + }).then((doc) => { + return window.showTextDocument(doc, ViewColumn.One); + }).then(() => { + subscription.dispose(); + }).then(passOncePlease, failOncePlease); + }); +}); diff --git a/extensions/vscode-api-tests/testWorkspace/10linefile.ts b/extensions/vscode-api-tests/testWorkspace/10linefile.ts new file mode 100644 index 00000000000..fadcc7fee40 --- /dev/null +++ b/extensions/vscode-api-tests/testWorkspace/10linefile.ts @@ -0,0 +1,10 @@ +function foo(): void { + var a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; +} \ No newline at end of file diff --git a/extensions/vscode-api-tests/testWorkspace/30linefile.ts b/extensions/vscode-api-tests/testWorkspace/30linefile.ts new file mode 100644 index 00000000000..2307a1dd4ca --- /dev/null +++ b/extensions/vscode-api-tests/testWorkspace/30linefile.ts @@ -0,0 +1,30 @@ +function bar(): void { + var a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; + a = 1; +} \ No newline at end of file diff --git a/src/vs/workbench/api/node/mainThreadEditors.ts b/src/vs/workbench/api/node/mainThreadEditors.ts index 34425e2e463..4b309ff1dee 100644 --- a/src/vs/workbench/api/node/mainThreadEditors.ts +++ b/src/vs/workbench/api/node/mainThreadEditors.ts @@ -126,6 +126,11 @@ export class MainThreadTextEditor { this._codeEditor = codeEditor; if (this._codeEditor) { + // Catch early the case that this code editor gets a different model set and disassociate from this model + this._codeEditorListeners.push(this._codeEditor.addListener2(EditorCommon.EventType.ModelChanged, () => { + this.setCodeEditor(null); + })); + let forwardSelection = () => { this._lastSelection = this._codeEditor.getSelections(); this._onSelectionChanged.fire(this._lastSelection); -- GitLab