diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index a6bf42dde93d191e81ad1af69560c414b2943c38..eb6a10ae45fc82bf8ae0528c891b6bfecb638423 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 c52ed3333eb77de530a9fff9414ef232e0175e03..e6445b43a60bbc4b73ed99f915bda2079ef4b89c 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 0000000000000000000000000000000000000000..fadcc7fee40f2e34d8a297f5101aa364d1ebf16c --- /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 0000000000000000000000000000000000000000..2307a1dd4ca40c7a0f7d0321c86375bda78752d4 --- /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 34425e2e46316a6b8d93ae84ed7da4fb931a2b85..4b309ff1dee13db6c1dd1aa1f23527897b463629 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);