diff --git a/src/vs/base/test/common/utils.ts b/src/vs/base/test/common/utils.ts index a00e86f3ea68bfae1995d87933547650f613f4f5..1ec1cb65c112da1533fa9518260bd3c11defcaf9 100644 --- a/src/vs/base/test/common/utils.ts +++ b/src/vs/base/test/common/utils.ts @@ -35,6 +35,39 @@ export class DeferredTPromise extends TPromise { } } +export class DeferredPromise { + + private completeCallback: TValueCallback; + private errorCallback: (err: any) => void; + + public p: Promise; + + constructor() { + this.p = new Promise((c, e) => { + this.completeCallback = c; + this.errorCallback = e; + }); + } + + public complete(value: T) { + process.nextTick(() => { + this.completeCallback(value); + }); + } + + public error(err: any) { + process.nextTick(() => { + this.errorCallback(err); + }); + } + + public cancel() { + process.nextTick(() => { + this.errorCallback(canceled()); + }); + } +} + export function toResource(this: any, path: string) { return URI.file(paths.join('C:\\', Buffer.from(this.test.fullTitle()).toString('base64'), path)); } diff --git a/src/vs/workbench/parts/search/browser/replaceService.ts b/src/vs/workbench/parts/search/browser/replaceService.ts index ea4de3b3dee0a85b5361e0011b2239483faafabe..0287f28a507ef278d49a80b0a77fda7d956874a3 100644 --- a/src/vs/workbench/parts/search/browser/replaceService.ts +++ b/src/vs/workbench/parts/search/browser/replaceService.ts @@ -5,7 +5,6 @@ import * as nls from 'vs/nls'; import * as errors from 'vs/base/common/errors'; -import { TPromise } from 'vs/base/common/winjs.base'; import { URI } from 'vs/base/common/uri'; import * as network from 'vs/base/common/network'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -47,7 +46,7 @@ export class ReplacePreviewContentProvider implements ITextModelContentProvider, this.textModelResolverService.registerTextModelContentProvider(network.Schemas.internal, this); } - public provideTextContent(uri: URI): TPromise { + public provideTextContent(uri: URI): Thenable { if (uri.fragment === REPLACE_PREVIEW) { return this.instantiationService.createInstance(ReplacePreviewModel).resolve(uri); } @@ -66,7 +65,7 @@ class ReplacePreviewModel extends Disposable { super(); } - resolve(replacePreviewUri: URI): TPromise { + resolve(replacePreviewUri: URI): Thenable { const fileResource = toFileResource(replacePreviewUri); const fileMatch = this.searchWorkbenchService.searchModel.searchResult.matches().filter(match => match.resource().toString() === fileResource.toString())[0]; return this.textModelResolverService.createModelReference(fileResource).then(ref => { @@ -101,17 +100,17 @@ export class ReplaceService implements IReplaceService { @IBulkEditService private bulkEditorService: IBulkEditService ) { } - public replace(match: Match): TPromise; - public replace(files: FileMatch[], progress?: IProgressRunner): TPromise; - public replace(match: FileMatchOrMatch, progress?: IProgressRunner, resource?: URI): TPromise; - public replace(arg: any, progress: IProgressRunner | null = null, resource: URI | null = null): TPromise { + public replace(match: Match): Promise; + public replace(files: FileMatch[], progress?: IProgressRunner): Promise; + public replace(match: FileMatchOrMatch, progress?: IProgressRunner, resource?: URI): Promise; + public replace(arg: any, progress: IProgressRunner | null = null, resource: URI | null = null): Promise { const edits: ResourceTextEdit[] = this.createEdits(arg, resource); return this.bulkEditorService.apply({ edits }, { progress }).then(() => this.textFileService.saveAll(edits.map(e => e.resource))); } - public openReplacePreview(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise { + public openReplacePreview(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Thenable { const fileMatch = element instanceof Match ? element.parent() : element; return this.editorService.openEditor({ @@ -139,13 +138,13 @@ export class ReplaceService implements IReplaceService { }, errors.onUnexpectedError); } - public updateReplacePreview(fileMatch: FileMatch, override: boolean = false): TPromise { + public updateReplacePreview(fileMatch: FileMatch, override: boolean = false): Promise { const replacePreviewUri = toReplaceResource(fileMatch.resource()); - return TPromise.join([this.textModelResolverService.createModelReference(fileMatch.resource()), this.textModelResolverService.createModelReference(replacePreviewUri)]) + return Promise.all([this.textModelResolverService.createModelReference(fileMatch.resource()), this.textModelResolverService.createModelReference(replacePreviewUri)]) .then(([sourceModelRef, replaceModelRef]) => { const sourceModel = sourceModelRef.object.textEditorModel; const replaceModel = replaceModelRef.object.textEditorModel; - let returnValue = TPromise.wrap(null); + let returnValue = Promise.resolve(null); // If model is disposed do not update if (sourceModel && replaceModel) { if (override) { diff --git a/src/vs/workbench/parts/search/browser/searchActions.ts b/src/vs/workbench/parts/search/browser/searchActions.ts index 8b05de34bf5804be75d4578352e177f19584bd29..dc23bd390ffb42cfa3a60622dbfea6ab6024f39f 100644 --- a/src/vs/workbench/parts/search/browser/searchActions.ts +++ b/src/vs/workbench/parts/search/browser/searchActions.ts @@ -11,7 +11,6 @@ import { normalizeDriveLetter } from 'vs/base/common/labels'; import { Schemas } from 'vs/base/common/network'; import { isWindows, OS } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; -import { TPromise } from 'vs/base/common/winjs.base'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import * as nls from 'vs/nls'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -45,7 +44,7 @@ export function appendKeyBindingLabel(label: string, keyBinding: number | Resolv } } -export function openSearchView(viewletService: IViewletService, panelService: IPanelService, focus?: boolean): TPromise { +export function openSearchView(viewletService: IViewletService, panelService: IPanelService, focus?: boolean): Thenable { if (viewletService.getViewlets().filter(v => v.id === VIEW_ID).length) { return viewletService.openViewlet(VIEW_ID, focus).then(viewlet => viewlet); } @@ -97,10 +96,10 @@ export class FocusNextInputAction extends Action { super(id, label); } - public run(): TPromise { + public run(): Thenable { const searchView = getSearchView(this.viewletService, this.panelService); searchView.focusNextInputBox(); - return TPromise.as(null); + return Promise.resolve(null); } } @@ -115,10 +114,10 @@ export class FocusPreviousInputAction extends Action { super(id, label); } - public run(): TPromise { + public run(): Thenable { const searchView = getSearchView(this.viewletService, this.panelService); searchView.focusPreviousInputBox(); - return TPromise.as(null); + return Promise.resolve(null); } } @@ -130,7 +129,7 @@ export abstract class FindOrReplaceInFilesAction extends Action { super(id, label); } - public run(): TPromise { + public run(): Thenable { return openSearchView(this.viewletService, this.panelService, false).then(openedView => { const searchAndReplaceWidget = openedView.searchAndReplaceWidget; searchAndReplaceWidget.toggleReplace(this.expandSearchReplaceWidget); @@ -165,7 +164,7 @@ export class OpenSearchViewletAction extends FindOrReplaceInFilesAction { super(id, label, viewletService, panelService, /*expandSearchReplaceWidget=*/false); } - public run(): TPromise { + public run(): Thenable { // Pass focus to viewlet if not open or focused if (this.otherViewletShowing() || !isSearchViewFocused(this.viewletService, this.panelService)) { @@ -175,7 +174,7 @@ export class OpenSearchViewletAction extends FindOrReplaceInFilesAction { // Otherwise pass focus to editor group this.editorGroupService.activeGroup.focus(); - return TPromise.as(true); + return Promise.resolve(true); } private otherViewletShowing(): boolean { @@ -205,11 +204,11 @@ export class CloseReplaceAction extends Action { super(id, label); } - public run(): TPromise { + public run(): Thenable { const searchView = getSearchView(this.viewletService, this.panelService); searchView.searchAndReplaceWidget.toggleReplace(false); searchView.searchAndReplaceWidget.focus(); - return TPromise.as(null); + return Promise.resolve(null); } } @@ -231,12 +230,12 @@ export class RefreshAction extends Action { this.enabled = searchView && searchView.isSearchSubmitted(); } - public run(): TPromise { + public run(): Thenable { const searchView = getSearchView(this.viewletService, this.panelService); if (searchView) { searchView.onQueryChanged(); } - return TPromise.as(null); + return Promise.resolve(null); } } @@ -258,12 +257,12 @@ export class CollapseDeepestExpandedLevelAction extends Action { this.enabled = searchView && searchView.hasSearchResults(); } - public run(): TPromise { + public run(): Thenable { const searchView = getSearchView(this.viewletService, this.panelService); if (searchView) { const viewer = searchView.getControl(); if (viewer.getHighlight()) { - return TPromise.as(null); // Global action disabled if user is in edit mode from another action + return Promise.resolve(null); // Global action disabled if user is in edit mode from another action } /** @@ -299,7 +298,7 @@ export class CollapseDeepestExpandedLevelAction extends Action { viewer.domFocus(); viewer.focusFirst(); } - return TPromise.as(null); + return Promise.resolve(null); } } @@ -321,12 +320,12 @@ export class ClearSearchResultsAction extends Action { this.enabled = searchView && searchView.isSearchSubmitted(); } - public run(): TPromise { + public run(): Thenable { const searchView = getSearchView(this.viewletService, this.panelService); if (searchView) { searchView.clearSearchResults(); } - return TPromise.as(null); + return Promise.resolve(null); } } @@ -348,13 +347,13 @@ export class CancelSearchAction extends Action { this.enabled = searchView && searchView.isSearching(); } - public run(): TPromise { + public run(): Thenable { const searchView = getSearchView(this.viewletService, this.panelService); if (searchView) { searchView.cancelSearch(); } - return TPromise.as(null); + return Promise.resolve(null); } } @@ -369,7 +368,7 @@ export class FocusNextSearchResultAction extends Action { super(id, label); } - public run(): TPromise { + public run(): Thenable { return openSearchView(this.viewletService, this.panelService).then(searchView => { searchView.selectNextMatch(); }); @@ -387,7 +386,7 @@ export class FocusPreviousSearchResultAction extends Action { super(id, label); } - public run(): TPromise { + public run(): Thenable { return openSearchView(this.viewletService, this.panelService).then(searchView => { searchView.selectPreviousMatch(); }); @@ -470,7 +469,7 @@ export class RemoveAction extends AbstractSearchAndReplaceAction { super('remove', RemoveAction.LABEL, 'action-remove'); } - public run(): TPromise { + public run(): Thenable { const currentFocusElement = this.viewer.getFocus(); const nextFocusElement = !currentFocusElement || currentFocusElement instanceof SearchResult || elementIsEqualOrParent(currentFocusElement, this.element) ? this.getElementToFocusAfterRemoved(this.viewer, this.element) : @@ -521,7 +520,7 @@ export class ReplaceAllAction extends AbstractSearchAndReplaceAction { super(Constants.ReplaceAllInFileActionId, appendKeyBindingLabel(ReplaceAllAction.LABEL, keyBindingService.lookupKeybinding(Constants.ReplaceAllInFileActionId), keyBindingService), 'action-replace-all'); } - public run(): TPromise { + public run(): Thenable { let nextFocusElement = this.getElementToFocusAfterRemoved(this.viewer, this.fileMatch); return this.fileMatch.parent().replace(this.fileMatch).then(() => { if (nextFocusElement) { @@ -543,7 +542,7 @@ export class ReplaceAllInFolderAction extends AbstractSearchAndReplaceAction { super(Constants.ReplaceAllInFolderActionId, appendKeyBindingLabel(ReplaceAllInFolderAction.LABEL, keyBindingService.lookupKeybinding(Constants.ReplaceAllInFolderActionId), keyBindingService), 'action-replace-all'); } - public run(): TPromise { + public run(): Thenable { let nextFocusElement = this.getElementToFocusAfterRemoved(this.viewer, this.folderMatch); return this.folderMatch.replaceAll() .then(() => { @@ -567,7 +566,7 @@ export class ReplaceAction extends AbstractSearchAndReplaceAction { super(Constants.ReplaceActionId, appendKeyBindingLabel(ReplaceAction.LABEL, keyBindingService.lookupKeybinding(Constants.ReplaceActionId), keyBindingService), 'action-replace'); } - public run(): TPromise { + public run(): Thenable { this.enabled = false; return this.element.parent().replace(this.element).then(() => { diff --git a/src/vs/workbench/parts/search/browser/searchResultsView.ts b/src/vs/workbench/parts/search/browser/searchResultsView.ts index a9d5deebf2cda64f08fa50ded3a5ec72b7d3ba2e..2a30a01449e5476ce6fa07646a01b09074d129a3 100644 --- a/src/vs/workbench/parts/search/browser/searchResultsView.ts +++ b/src/vs/workbench/parts/search/browser/searchResultsView.ts @@ -10,7 +10,6 @@ import { IAction } from 'vs/base/common/actions'; import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; import * as paths from 'vs/base/common/paths'; import * as resources from 'vs/base/common/resources'; -import { TPromise } from 'vs/base/common/winjs.base'; import { ContextMenuEvent, IAccessibilityProvider, IDataSource, IFilter, IRenderer, ISorter, ITree } from 'vs/base/parts/tree/browser/tree'; import * as nls from 'vs/nls'; import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem'; @@ -80,15 +79,15 @@ export class SearchDataSource implements IDataSource { return []; } - public getChildren(tree: ITree, element: any): TPromise { - return TPromise.as(this._getChildren(element)); + public getChildren(tree: ITree, element: any): Thenable { + return Promise.resolve(this._getChildren(element)); } public hasChildren(tree: ITree, element: any): boolean { return element instanceof FileMatch || element instanceof FolderMatch || element instanceof SearchResult; } - public getParent(tree: ITree, element: any): TPromise { + public getParent(tree: ITree, element: any): Thenable { let value: any = null; if (element instanceof Match) { @@ -99,7 +98,7 @@ export class SearchDataSource implements IDataSource { value = element.parent(); } - return TPromise.as(value); + return Promise.resolve(value); } public shouldAutoexpand(tree: ITree, element: any): boolean { @@ -425,7 +424,7 @@ export class SearchTreeController extends WorkbenchTreeController { getActions: () => { const actions: IAction[] = []; fillInContextMenuActions(this.contextMenu, { shouldForwardArgs: true }, actions, this.contextMenuService); - return actions; + return Promise.resolve(actions); }, getActionsContext: () => element diff --git a/src/vs/workbench/parts/search/browser/searchView.ts b/src/vs/workbench/parts/search/browser/searchView.ts index 8aea3f5a394548f186d8cedfe3cda84883085d64..4c1e61a907c279d3b867144c67cfe126d93990e6 100644 --- a/src/vs/workbench/parts/search/browser/searchView.ts +++ b/src/vs/workbench/parts/search/browser/searchView.ts @@ -18,7 +18,6 @@ import * as paths from 'vs/base/common/paths'; import * as env from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; -import { TPromise } from 'vs/base/common/winjs.base'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import 'vs/css!./media/searchview'; import { ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser'; @@ -368,23 +367,23 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { this.layout(this.size); } - private onSearchResultsChanged(event?: IChangeEvent): TPromise { + private onSearchResultsChanged(event?: IChangeEvent): Thenable { if (this.isVisible()) { return this.refreshAndUpdateCount(event); } else { this.changedWhileHidden = true; - return TPromise.wrap(null); + return Promise.resolve(null); } } - private refreshAndUpdateCount(event?: IChangeEvent): TPromise { + private refreshAndUpdateCount(event?: IChangeEvent): Thenable { return this.refreshTree(event).then(() => { this.searchWidget.setReplaceAllActionState(!this.viewModel.searchResult.isEmpty()); this.updateSearchResultCount(); }); } - private refreshTree(event?: IChangeEvent): TPromise { + private refreshTree(event?: IChangeEvent): Thenable { if (!event || event.added || event.removed) { return this.tree.refresh(this.viewModel.searchResult); } else { @@ -1087,14 +1086,14 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { }, onQueryValidationError); } - private validateQuery(query: ITextQuery): TPromise { + private validateQuery(query: ITextQuery): Thenable { // Validate folderQueries const folderQueriesExistP = query.folderQueries.map(fq => { return this.fileService.existsFile(fq.folder); }); - return TPromise.join(folderQueriesExistP).then(existResults => { + return Promise.resolve(folderQueriesExistP).then(existResults => { // If no folders exist, show an error message about the first one const existingFolderQueries = query.folderQueries.filter((folderQuery, i) => existResults[i]); if (!query.folderQueries.length || existingFolderQueries.length) { @@ -1102,7 +1101,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { } else { const nonExistantPath = query.folderQueries[0].folder.fsPath; const searchPathNotFoundError = nls.localize('searchPathNotFoundError', "Search path not found: {0}", nonExistantPath); - return TPromise.wrapError(new Error(searchPathNotFoundError)); + return Promise.reject(new Error(searchPathNotFoundError)); } return undefined; @@ -1349,7 +1348,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { this.openSettings('.exclude'); } - private openSettings(query: string): TPromise { + private openSettings(query: string): Thenable { const options: ISettingsEditorOptions = { query }; return this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? this.preferencesService.openWorkspaceSettings(undefined, options) : @@ -1427,10 +1426,10 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { this.currentSelectedFileMatch = null; } - private onFocus(lineMatch: any, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise { + private onFocus(lineMatch: any, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Thenable { if (!(lineMatch instanceof Match)) { this.viewModel.searchResult.rangeHighlightDecorations.removeHighlightRange(); - return TPromise.as(true); + return Promise.resolve(true); } const useReplacePreview = this.configurationService.getValue().search.useReplacePreview; @@ -1439,7 +1438,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { this.open(lineMatch, preserveFocus, sideBySide, pinned); } - public open(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise { + public open(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Thenable { const selection = this.getSelectionFrom(element); const resource = element instanceof Match ? element.parent().resource() : (element).resource(); return this.editorService.openEditor({ @@ -1463,7 +1462,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { if (editor) { return this.editorGroupsService.activateGroup(editor.group); } else { - return TPromise.wrap(null); + return Promise.resolve(null); } }, errors.onUnexpectedError); } diff --git a/src/vs/workbench/parts/search/browser/searchWidget.ts b/src/vs/workbench/parts/search/browser/searchWidget.ts index e038970faf3dff83c27b0ce00676e4bf7d45d383..806ce9f553e4688bd929c4abae26940b2101b953 100644 --- a/src/vs/workbench/parts/search/browser/searchWidget.ts +++ b/src/vs/workbench/parts/search/browser/searchWidget.ts @@ -17,7 +17,6 @@ import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import * as env from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; -import { TPromise } from 'vs/base/common/winjs.base'; import { CONTEXT_FIND_WIDGET_NOT_VISIBLE } from 'vs/editor/contrib/find/findModel'; import * as nls from 'vs/nls'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -67,11 +66,11 @@ class ReplaceAllAction extends Action { this._searchWidget = searchWidget; } - run(): TPromise { + run(): Promise { if (this._searchWidget) { return this._searchWidget.triggerReplaceAll(); } - return TPromise.as(null); + return Promise.resolve(null); } } @@ -349,9 +348,9 @@ export class SearchWidget extends Widget { this._register(this.replaceInputFocusTracker.onDidBlur(() => this.replaceInputBoxFocused.set(false))); } - triggerReplaceAll(): TPromise { + triggerReplaceAll(): Promise { this._onReplaceAll.fire(); - return TPromise.as(null); + return Promise.resolve(null); } private onToggleReplaceButton(): void { diff --git a/src/vs/workbench/parts/search/common/replace.ts b/src/vs/workbench/parts/search/common/replace.ts index 953a4704eda92378fafce8c7887084783caee98f..8f2d2e9026dedf70283c2641fb73ecf5bdecfcc0 100644 --- a/src/vs/workbench/parts/search/common/replace.ts +++ b/src/vs/workbench/parts/search/common/replace.ts @@ -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 { Match, FileMatch, FileMatchOrMatch } from 'vs/workbench/parts/search/common/searchModel'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProgressRunner } from 'vs/platform/progress/common/progress'; @@ -17,22 +16,22 @@ export interface IReplaceService { /** * Replaces the given match in the file that match belongs to */ - replace(match: Match): TPromise; + replace(match: Match): Thenable; /** * Replace all the matches from the given file matches in the files * You can also pass the progress runner to update the progress of replacing. */ - replace(files: FileMatch[], progress?: IProgressRunner): TPromise; + replace(files: FileMatch[], progress?: IProgressRunner): Thenable; /** * Opens the replace preview for given file match or match */ - openReplacePreview(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): TPromise; + openReplacePreview(element: FileMatchOrMatch, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Thenable; /** * Update the replace preview for the given file. * If `override` is `true`, then replace preview is constructed from source model */ - updateReplacePreview(file: FileMatch, override?: boolean): TPromise; + updateReplacePreview(file: FileMatch, override?: boolean): Thenable; } diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index 97bc18c295923c6205c6682e8392885d695d5566..c70002daa0bb9012e8d248987ee6c34cbbf62e82 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -13,7 +13,6 @@ import { ResourceMap, TernarySearchTree, values } from 'vs/base/common/map'; import * as objects from 'vs/base/common/objects'; import { lcut } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; -import { TPromise } from 'vs/base/common/winjs.base'; import { Range } from 'vs/editor/common/core/range'; import { FindMatch, IModelDeltaDecoration, ITextModel, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; @@ -293,7 +292,7 @@ export class FileMatch extends Disposable { this._onChange.fire(false); } - public replace(toReplace: Match): TPromise { + public replace(toReplace: Match): Thenable { return this.replaceService.replace(toReplace) .then(() => this.updatesMatchesForLineAfterReplace(toReplace.range().startLineNumber, false)); } @@ -455,13 +454,13 @@ export class FolderMatch extends Disposable { this.doRemove(match); } - public replace(match: FileMatch): TPromise { + public replace(match: FileMatch): Thenable { return this.replaceService.replace([match]).then(() => { this.doRemove(match, false, true); }); } - public replaceAll(): TPromise { + public replaceAll(): Thenable { const matches = this.matches(); return this.replaceService.replace(matches).then(() => { matches.forEach(match => this.doRemove(match, false, true)); @@ -641,11 +640,11 @@ export class SearchResult extends Disposable { } } - public replace(match: FileMatch): TPromise { + public replace(match: FileMatch): Thenable { return this.getFolderMatch(match.resource()).replace(match); } - public replaceAll(progressRunner: IProgressRunner): TPromise { + public replaceAll(progressRunner: IProgressRunner): Thenable { this.replacingAll = true; const promise = this.replaceService.replace(this.matches(), progressRunner); @@ -797,7 +796,7 @@ export class SearchModel extends Disposable { return this._searchResult; } - public search(query: ITextQuery, onProgress?: (result: ISearchProgressItem) => void): TPromise { + public search(query: ITextQuery, onProgress?: (result: ISearchProgressItem) => void): Thenable { this.cancelSearch(); this._searchQuery = query; diff --git a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts index 2b40ba617bc1e92287f0e2a77c5d3d9a5dacee20..b38067dd9f36597b4a44db13a41e4a680cffc7c1 100644 --- a/src/vs/workbench/parts/search/electron-browser/search.contribution.ts +++ b/src/vs/workbench/parts/search/electron-browser/search.contribution.ts @@ -9,7 +9,6 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import * as nls from 'vs/nls'; -import { TPromise } from 'vs/base/common/winjs.base'; import { Action } from 'vs/base/common/actions'; import * as objects from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; @@ -430,7 +429,7 @@ class ShowAllSymbolsAction extends Action { this.enabled = !!this.quickOpenService; } - public run(context?: any): TPromise { + public run(context?: any): Promise { let prefix = ShowAllSymbolsAction.ALL_SYMBOLS_PREFIX; let inputSelection: { start: number; end: number; } = void 0; @@ -443,7 +442,7 @@ class ShowAllSymbolsAction extends Action { this.quickOpenService.show(prefix, { inputSelection }); - return TPromise.as(null); + return Promise.resolve(null); } } diff --git a/src/vs/workbench/parts/search/test/common/searchModel.test.ts b/src/vs/workbench/parts/search/test/common/searchModel.test.ts index 15b6e8c401c1c4def784ccf89cbe640934437bb1..ff45b9468f0a653f08c24955d5beec42cee44a26 100644 --- a/src/vs/workbench/parts/search/test/common/searchModel.test.ts +++ b/src/vs/workbench/parts/search/test/common/searchModel.test.ts @@ -5,20 +5,19 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import { timeout } from 'vs/base/common/async'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { URI } from 'vs/base/common/uri'; -import { TPromise } from 'vs/base/common/winjs.base'; -import { DeferredTPromise } from 'vs/base/test/common/utils'; +import { DeferredPromise } from 'vs/base/test/common/utils'; import { Range } from 'vs/editor/common/core/range'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { IFileMatch, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, ITextSearchMatch, TextSearchMatch, OneLineRange } from 'vs/platform/search/common/search'; +import { IFileMatch, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchProgressItem, ISearchQuery, ISearchService, ITextSearchMatch, OneLineRange, TextSearchMatch } from 'vs/platform/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { SearchModel } from 'vs/workbench/parts/search/common/searchModel'; -import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; const nullEvent = new class { @@ -71,7 +70,7 @@ suite('SearchModel', () => { instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(IModelService, stubModelService(instantiationService)); instantiationService.stub(ISearchService, {}); - instantiationService.stub(ISearchService, 'textSearch', TPromise.as({ results: [] })); + instantiationService.stub(ISearchService, 'textSearch', Promise.resolve({ results: [] })); }); teardown(() => { @@ -82,8 +81,8 @@ suite('SearchModel', () => { function searchServiceWithResults(results: IFileMatch[], complete: ISearchComplete | null = null): ISearchService { return { - textSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): TPromise { - return new TPromise(resolve => { + textSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Thenable { + return new Promise(resolve => { process.nextTick(() => { results.forEach(onProgress); resolve(complete); @@ -95,8 +94,8 @@ suite('SearchModel', () => { function searchServiceWithError(error: Error): ISearchService { return { - textSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): TPromise { - return new TPromise((resolve, reject) => { + textSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Thenable { + return new Promise((resolve, reject) => { reject(error); }); } @@ -105,12 +104,12 @@ suite('SearchModel', () => { function canceleableSearchService(tokenSource: CancellationTokenSource): ISearchService { return { - textSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): TPromise { + textSearch(query: ISearchQuery, token?: CancellationToken, onProgress?: (result: ISearchProgressItem) => void): Thenable { if (token) { token.onCancellationRequested(() => tokenSource.cancel()); } - return new TPromise(resolve => { + return new Promise(resolve => { process.nextTick(() => { resolve({}); }); @@ -236,13 +235,13 @@ suite('SearchModel', () => { let target1 = sinon.stub().returns(nullEvent); instantiationService.stub(ITelemetryService, 'publicLog', target1); - let promise = new DeferredTPromise(); - instantiationService.stub(ISearchService, 'textSearch', promise); + let deferredPromise = new DeferredPromise(); + instantiationService.stub(ISearchService, 'textSearch', deferredPromise.p); let testObject = instantiationService.createInstance(SearchModel); let result = testObject.search({ contentPattern: { pattern: 'somestring' }, type: 1, folderQueries }); - promise.cancel(); + deferredPromise.cancel(); return timeout(1).then(() => { return result.then(() => { }, () => { diff --git a/src/vs/workbench/services/search/node/fileSearchManager.ts b/src/vs/workbench/services/search/node/fileSearchManager.ts index 77fe462871c26edf02a770c5ed0933f8773f3645..1342bbc34f171f1bf77d0901287494d081b98a69 100644 --- a/src/vs/workbench/services/search/node/fileSearchManager.ts +++ b/src/vs/workbench/services/search/node/fileSearchManager.ts @@ -10,7 +10,6 @@ import * as glob from 'vs/base/common/glob'; import * as resources from 'vs/base/common/resources'; import { StopWatch } from 'vs/base/common/stopwatch'; import { URI } from 'vs/base/common/uri'; -import { TPromise } from 'vs/base/common/winjs.base'; import { IFileMatch, IFileSearchProviderStats, IFolderQuery, ISearchCompleteStats, IFileQuery } from 'vs/platform/search/common/search'; import { QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/node/search'; import * as vscode from 'vscode'; @@ -64,10 +63,10 @@ class FileSearchEngine { this.activeCancellationTokens = new Set(); } - public search(_onResult: (match: IInternalFileMatch) => void): TPromise { + public search(_onResult: (match: IInternalFileMatch) => void): Promise { const folderQueries = this.config.folderQueries || []; - return new TPromise((resolve, reject) => { + return new Promise((resolve, reject) => { const onResult = (match: IInternalFileMatch) => { this.resultCount++; _onResult(match); @@ -94,7 +93,7 @@ class FileSearchEngine { } // For each root folder - TPromise.join(folderQueries.map(fq => { + Promise.all(folderQueries.map(fq => { return this.searchInFolder(fq, onResult); })).then(stats => { resolve({ @@ -111,9 +110,9 @@ class FileSearchEngine { }); } - private searchInFolder(fq: IFolderQuery, onResult: (match: IInternalFileMatch) => void): TPromise { + private searchInFolder(fq: IFolderQuery, onResult: (match: IInternalFileMatch) => void): Promise { let cancellation = new CancellationTokenSource(); - return new TPromise((resolve, reject) => { + return new Promise((resolve, reject) => { const options = this.getSearchOptionsForFolder(fq); const tree = this.initDirectoryTree(); @@ -121,7 +120,7 @@ class FileSearchEngine { const noSiblingsClauses = !queryTester.hasSiblingExcludeClauses(); let providerSW: StopWatch; - new TPromise(_resolve => process.nextTick(_resolve)) + new Promise(_resolve => process.nextTick(_resolve)) .then(() => { this.activeCancellationTokens.add(cancellation); @@ -287,7 +286,7 @@ export class FileSearchManager { private static readonly BATCH_SIZE = 512; - fileSearch(config: IFileQuery, provider: vscode.FileSearchProvider, onBatch: (matches: IFileMatch[]) => void, token: CancellationToken): TPromise { + fileSearch(config: IFileQuery, provider: vscode.FileSearchProvider, onBatch: (matches: IFileMatch[]) => void, token: CancellationToken): Promise { const engine = new FileSearchEngine(config, provider); let resultCount = 0; @@ -323,7 +322,7 @@ export class FileSearchManager { } } - private doSearch(engine: FileSearchEngine, batchSize: number, onResultBatch: (matches: IInternalFileMatch[]) => void, token: CancellationToken): TPromise { + private doSearch(engine: FileSearchEngine, batchSize: number, onResultBatch: (matches: IInternalFileMatch[]) => void, token: CancellationToken): Promise { token.onCancellationRequested(() => { engine.cancel(); }); @@ -350,7 +349,7 @@ export class FileSearchManager { onResultBatch(batch); } - return TPromise.wrapError(error); + return Promise.reject(error); }); } } diff --git a/src/vs/workbench/services/search/node/legacy/worker/searchWorker.ts b/src/vs/workbench/services/search/node/legacy/worker/searchWorker.ts index 569014888f35d3466117bb2274a1598ef4b0d5b2..4ae556fff5b71822fd49312e83acbf70734a4f13 100644 --- a/src/vs/workbench/services/search/node/legacy/worker/searchWorker.ts +++ b/src/vs/workbench/services/search/node/legacy/worker/searchWorker.ts @@ -7,7 +7,6 @@ import * as fs from 'fs'; import * as gracefulFs from 'graceful-fs'; import { onUnexpectedError } from 'vs/base/common/errors'; import * as strings from 'vs/base/common/strings'; -import { TPromise } from 'vs/base/common/winjs.base'; import { bomLength, decode, detectEncodingFromBuffer, encodingExists, UTF16be, UTF16le, UTF8, UTF8_with_bom } from 'vs/base/node/encoding'; import { Range } from 'vs/editor/common/core/range'; import { ITextSearchPreviewOptions, TextSearchMatch } from 'vs/platform/search/common/search'; @@ -32,21 +31,21 @@ function onError(error: any): void { export class SearchWorker implements ISearchWorker { private currentSearchEngine: SearchWorkerEngine; - initialize(): TPromise { + initialize(): Promise { this.currentSearchEngine = new SearchWorkerEngine(); - return TPromise.wrap(undefined); + return Promise.resolve(undefined); } - cancel(): TPromise { + cancel(): Promise { // Cancel the current search. It will stop searching and close its open files. if (this.currentSearchEngine) { this.currentSearchEngine.cancel(); } - return TPromise.wrap(null); + return Promise.resolve(null); } - search(args: ISearchWorkerSearchArgs): TPromise { + search(args: ISearchWorkerSearchArgs): Promise { if (!this.currentSearchEngine) { // Worker timed out during search this.initialize(); @@ -66,13 +65,13 @@ const LF = 0x0a; const CR = 0x0d; export class SearchWorkerEngine { - private nextSearch = TPromise.wrap(null); + private nextSearch = Promise.resolve(null); private isCanceled = false; /** * Searches some number of the given paths concurrently, and starts searches in other paths when those complete. */ - searchBatch(args: ISearchWorkerSearchArgs): TPromise { + searchBatch(args: ISearchWorkerSearchArgs): Promise { const contentPattern = strings.createRegExp(args.pattern.pattern, args.pattern.isRegExp, { matchCase: args.pattern.isCaseSensitive, wholeWord: args.pattern.isWordMatch, multiline: false, global: true }); const fileEncoding = encodingExists(args.fileEncoding) ? args.fileEncoding : UTF8; return this.nextSearch = @@ -80,12 +79,12 @@ export class SearchWorkerEngine { } - private _searchBatch(args: ISearchWorkerSearchArgs, contentPattern: RegExp, fileEncoding: string): TPromise { + private _searchBatch(args: ISearchWorkerSearchArgs, contentPattern: RegExp, fileEncoding: string): Promise { if (this.isCanceled) { - return TPromise.wrap(null); + return Promise.resolve(null); } - return new TPromise(batchDone => { + return new Promise(batchDone => { const result: ISearchWorkerSearchResult = { matches: [], numMatches: 0, @@ -93,7 +92,7 @@ export class SearchWorkerEngine { }; // Search in the given path, and when it's finished, search in the next path in absolutePaths - const startSearchInFile = (absolutePath: string): TPromise => { + const startSearchInFile = (absolutePath: string): Promise => { return this.searchInFile(absolutePath, contentPattern, fileEncoding, args.maxResults && (args.maxResults - result.numMatches), args.previewOptions).then(fileResult => { // Finish early if search is canceled if (this.isCanceled) { @@ -113,7 +112,7 @@ export class SearchWorkerEngine { }, onError); }; - TPromise.join(args.absolutePaths.map(startSearchInFile)).then(() => { + Promise.all(args.absolutePaths.map(startSearchInFile)).then(() => { batchDone(result); }); }); @@ -123,7 +122,7 @@ export class SearchWorkerEngine { this.isCanceled = true; } - private searchInFile(absolutePath: string, contentPattern: RegExp, fileEncoding: string, maxResults?: number, previewOptions?: ITextSearchPreviewOptions): TPromise { + private searchInFile(absolutePath: string, contentPattern: RegExp, fileEncoding: string, maxResults?: number, previewOptions?: ITextSearchPreviewOptions): Promise { let fileMatch: FileMatch | null = null; let limitReached = false; let numMatches = 0; @@ -154,8 +153,8 @@ export class SearchWorkerEngine { () => fileMatch ? { match: fileMatch, limitReached, numMatches } : null); } - private readlinesAsync(filename: string, perLineCallback: (line: string, lineNumber: number) => void, options: ReadLinesOptions): TPromise { - return new TPromise((resolve, reject) => { + private readlinesAsync(filename: string, perLineCallback: (line: string, lineNumber: number) => void, options: ReadLinesOptions): Promise { + return new Promise((resolve, reject) => { fs.open(filename, 'r', null, (error: Error, fd: number) => { if (error) { return resolve(null); diff --git a/src/vs/workbench/services/search/node/legacy/worker/searchWorkerIpc.ts b/src/vs/workbench/services/search/node/legacy/worker/searchWorkerIpc.ts index e81ae112398383f4137307b32f9c653728921f9d..d082554ea2fe7be07983b3948b3583a2e327cd2a 100644 --- a/src/vs/workbench/services/search/node/legacy/worker/searchWorkerIpc.ts +++ b/src/vs/workbench/services/search/node/legacy/worker/searchWorkerIpc.ts @@ -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 { IChannel } from 'vs/base/parts/ipc/node/ipc'; import { IPatternInfo, ITextSearchPreviewOptions } from 'vs/platform/search/common/search'; import { SearchWorker } from './searchWorker'; @@ -25,16 +24,16 @@ export interface ISearchWorkerSearchResult { } export interface ISearchWorker { - initialize(): TPromise; - search(args: ISearchWorkerSearchArgs): TPromise; - cancel(): TPromise; + initialize(): Promise; + search(args: ISearchWorkerSearchArgs): Promise; + cancel(): Promise; } export interface ISearchWorkerChannel extends IChannel { - call(command: 'initialize'): TPromise; - call(command: 'search', args: ISearchWorkerSearchArgs): TPromise; - call(command: 'cancel'): TPromise; - call(command: string, arg?: any): TPromise; + call(command: 'initialize'): Promise; + call(command: 'search', args: ISearchWorkerSearchArgs): Promise; + call(command: 'cancel'): Promise; + call(command: string, arg?: any): Promise; } export class SearchWorkerChannel implements ISearchWorkerChannel { @@ -45,7 +44,7 @@ export class SearchWorkerChannel implements ISearchWorkerChannel { throw new Error('No events'); } - call(command: string, arg?: any): TPromise { + call(command: string, arg?: any): Promise { switch (command) { case 'initialize': return this.worker.initialize(); case 'search': return this.worker.search(arg); @@ -58,15 +57,15 @@ export class SearchWorkerChannel implements ISearchWorkerChannel { export class SearchWorkerChannelClient implements ISearchWorker { constructor(private channel: ISearchWorkerChannel) { } - initialize(): TPromise { + initialize(): Promise { return this.channel.call('initialize'); } - search(args: ISearchWorkerSearchArgs): TPromise { + search(args: ISearchWorkerSearchArgs): Promise { return this.channel.call('search', args); } - cancel(): TPromise { + cancel(): Promise { return this.channel.call('cancel'); } } diff --git a/src/vs/workbench/services/search/node/textSearchManager.ts b/src/vs/workbench/services/search/node/textSearchManager.ts index bef7553ed8744d5d82c2d94155080320995e7a27..0f15a7709beb40d928ee0b16fb2d6d3fbabb2ad5 100644 --- a/src/vs/workbench/services/search/node/textSearchManager.ts +++ b/src/vs/workbench/services/search/node/textSearchManager.ts @@ -66,12 +66,9 @@ export class TextSearchManager { type: 'textSearchProvider' } }); - }, (errs: Error[]) => { + }, (err: Error) => { tokenSource.dispose(); - const errMsg = errs - .map(err => toErrorMessage(err)) - .filter(msg => !!msg)[0]; - + const errMsg = toErrorMessage(err); reject(new Error(errMsg)); }); }); diff --git a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts index f5809437d02fbede52621b770332a565c3aedf22..646b9af42aab499eb2053e97a18a70851a37ad57 100644 --- a/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts +++ b/src/vs/workbench/services/search/test/node/textSearch.integrationTest.ts @@ -9,7 +9,6 @@ import { getPathFromAmdModule } from 'vs/base/common/amd'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import * as glob from 'vs/base/common/glob'; import { URI } from 'vs/base/common/uri'; -import { TPromise } from 'vs/base/common/winjs.base'; import { IFolderQuery, ISearchRange, ITextQuery, ITextSearchMatch, QueryType, ITextSearchContext, deserializeSearchError, SearchErrorCode } from 'vs/platform/search/common/search'; import { LegacyTextSearchService } from 'vs/workbench/services/search/node/legacy/rawLegacyTextSearchService'; import { ISerializedFileMatch } from 'vs/workbench/services/search/node/search'; @@ -32,7 +31,7 @@ const MULTIROOT_QUERIES: IFolderQuery[] = [ { folder: URI.file(MORE_FIXTURES) } ]; -function doLegacySearchTest(config: ITextQuery, expectedResultCount: number | Function): TPromise { +function doLegacySearchTest(config: ITextQuery, expectedResultCount: number | Function): Promise { const engine = new LegacyTextSearchService(); let c = 0; @@ -49,7 +48,7 @@ function doLegacySearchTest(config: ITextQuery, expectedResultCount: number | Fu }); } -function doRipgrepSearchTest(query: ITextQuery, expectedResultCount: number | Function): TPromise { +function doRipgrepSearchTest(query: ITextQuery, expectedResultCount: number | Function): Promise { let engine = new TextSearchEngineAdapter(query); let c = 0; diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index ea8956af17478a67e0bdb32beaf6d3810299cb80..18c5c7078ae166ad59c327c86df9115d55060060 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -690,8 +690,8 @@ suite('ExtHostSearch', () => { const makeComparable = (results: vscode.TextSearchResult[]) => results .sort((a, b) => { - const compareKeyA = extensionResultIsMatch(a) ? a.preview.text : a.text; - const compareKeyB = extensionResultIsMatch(b) ? b.preview.text : b.text; + const compareKeyA = a.uri.toString() + ': ' + (extensionResultIsMatch(a) ? a.preview.text : a.text); + const compareKeyB = b.uri.toString() + ': ' + (extensionResultIsMatch(b) ? b.preview.text : b.text); return compareKeyB.localeCompare(compareKeyA); }) .map(r => extensionResultIsMatch(r) ? {