diff --git a/src/vs/editor/contrib/inPlaceReplace/inPlaceReplace.ts b/src/vs/editor/contrib/inPlaceReplace/inPlaceReplace.ts index 4d7b492685d3b3852be423e7304be47a2c880b31..3127c005bfe4e52cb9f7c7762891b3c7b09a9808 100644 --- a/src/vs/editor/contrib/inPlaceReplace/inPlaceReplace.ts +++ b/src/vs/editor/contrib/inPlaceReplace/inPlaceReplace.ts @@ -20,6 +20,8 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic import { editorBracketMatchBorder } from 'vs/editor/common/view/editorColorRegistry'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { CancelablePromise, createCancelablePromise, timeout } from 'vs/base/common/async'; +import { onUnexpectedError } from 'vs/base/common/errors'; class InPlaceReplaceController implements IEditorContribution { @@ -33,11 +35,11 @@ class InPlaceReplaceController implements IEditorContribution { className: 'valueSetReplacement' }); - private editor: ICodeEditor; - private currentRequest: TPromise; - private decorationRemover: TPromise; - private decorationIds: string[]; - private editorWorkerService: IEditorWorkerService; + private readonly editor: ICodeEditor; + private readonly editorWorkerService: IEditorWorkerService; + private decorationIds: string[] = []; + private currentRequest: CancelablePromise; + private decorationRemover: CancelablePromise; constructor( editor: ICodeEditor, @@ -45,9 +47,6 @@ class InPlaceReplaceController implements IEditorContribution { ) { this.editor = editor; this.editorWorkerService = editorWorkerService; - this.currentRequest = TPromise.as(null); - this.decorationRemover = TPromise.as(null); - this.decorationIds = []; } public dispose(): void { @@ -57,10 +56,12 @@ class InPlaceReplaceController implements IEditorContribution { return InPlaceReplaceController.ID; } - public run(source: string, up: boolean): TPromise { + public run(source: string, up: boolean): Thenable { // cancel any pending request - this.currentRequest.cancel(); + if (this.currentRequest) { + this.currentRequest.cancel(); + } let selection = this.editor.getSelection(); const model = this.editor.getModel(); @@ -74,18 +75,12 @@ class InPlaceReplaceController implements IEditorContribution { const state = new EditorState(this.editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position); if (!this.editorWorkerService.canNavigateValueSet(modelURI)) { - this.currentRequest = TPromise.as(null); - } else { - this.currentRequest = this.editorWorkerService.navigateValueSet(modelURI, selection, up); - this.currentRequest = this.currentRequest.then((basicResult) => { - if (basicResult && basicResult.range && basicResult.value) { - return basicResult; - } - return null; - }); + return undefined; } - return this.currentRequest.then((result: IInplaceReplaceSupportResult) => { + this.currentRequest = createCancelablePromise(token => this.editorWorkerService.navigateValueSet(modelURI, selection, up)); + + return this.currentRequest.then(result => { if (!result || !result.range || !result.value) { // No proper result @@ -127,12 +122,13 @@ class InPlaceReplaceController implements IEditorContribution { }]); // remove decoration after delay - this.decorationRemover.cancel(); - this.decorationRemover = TPromise.timeout(350); - this.decorationRemover.then(() => { - this.decorationIds = this.editor.deltaDecorations(this.decorationIds, []); - }); - }); + if (this.decorationRemover) { + this.decorationRemover.cancel(); + } + this.decorationRemover = timeout(350); + this.decorationRemover.then(() => this.decorationIds = this.editor.deltaDecorations(this.decorationIds, [])).catch(onUnexpectedError); + + }).catch(onUnexpectedError); } } @@ -156,7 +152,7 @@ class InPlaceReplaceUp extends EditorAction { if (!controller) { return undefined; } - return controller.run(this.id, true); + return TPromise.wrap(controller.run(this.id, true)); } } @@ -180,7 +176,7 @@ class InPlaceReplaceDown extends EditorAction { if (!controller) { return undefined; } - return controller.run(this.id, false); + return TPromise.wrap(controller.run(this.id, false)); } }