Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -12,7 +12,7 @@ import { ITreeContextMenuEvent, ITreeElement } from 'vs/base/browser/ui/tree/tre
import { IAction } from 'vs/base/common/actions';
import { Delayer } from 'vs/base/common/async';
import * as errors from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { Iterator } from 'vs/base/common/iterator';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
@@ -23,7 +23,7 @@ import 'vs/css!./media/searchview';
import { ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import * as nls from 'vs/nls';
import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenu, IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
@@ -33,8 +33,8 @@ import { FileChangesEvent, FileChangeType, IFileService } from 'vs/platform/file
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TreeResourceNavigator2, WorkbenchObjectTree, getSelectionKeyboardEvent } from 'vs/platform/list/browser/listService';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { IPatternInfo, ISearchComplete, ISearchConfiguration, ISearchConfigurationProperties, ITextQuery, SearchErrorCode, VIEW_ID } from 'vs/workbench/services/search/common/search';
import { IProgressService, IProgressStep, IProgress } from 'vs/platform/progress/common/progress';
import { IPatternInfo, ISearchComplete, ISearchConfiguration, ISearchConfigurationProperties, ITextQuery, SearchErrorCode, VIEW_ID, VIEWLET_ID } from 'vs/workbench/services/search/common/search';
import { ISearchHistoryService, ISearchHistoryValues } from 'vs/workbench/contrib/search/common/searchHistoryService';
import { diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, editorFindMatchHighlight, editorFindMatchHighlightBorder, listActiveSelectionForeground } from 'vs/platform/theme/common/colorRegistry';
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
@@ -59,11 +59,17 @@ import { relativePath } from 'vs/base/common/resources';
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { Memento } from 'vs/workbench/common/memento';
import { Memento, MementoObject } from 'vs/workbench/common/memento';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
const $ = dom.$;
enum SearchUIState {
Idle,
Searching,
SlowSearch
}
export class SearchView extends ViewletPanel {
private static readonly MAX_TEXT_RESULTS = 10000;
@@ -92,8 +98,7 @@ export class SearchView extends ViewletPanel {
private matchFocused: IContextKey<boolean>;
private hasSearchResultsKey: IContextKey<boolean>;
private searchSubmitted: boolean;
private searching: boolean;
private state: SearchUIState;
private actions: Array<CollapseDeepestExpandedLevelAction | ClearSearchResultsAction> = [];
private cancelAction: CancelSearchAction;
@@ -102,8 +107,8 @@ export class SearchView extends ViewletPanel {
private tree: WorkbenchObjectTree<RenderableMatch>;
private treeLabels: ResourceLabels;
private viewletState: object;
private globalMemento: object;
private viewletState: MementoObject;
private globalMemento: MementoObject;
private messagesElement: HTMLElement;
private messageDisposables: IDisposable[] = [];
private searchWidgetsContainerElement: HTMLElement;
@@ -117,7 +122,6 @@ export class SearchView extends ViewletPanel {
private currentSelectedFileMatch: FileMatch | undefined;
private readonly selectCurrentMatchEmitter: Emitter<string | undefined>;
private delayedRefresh: Delayer<void>;
private changedWhileHidden: boolean;
@@ -165,6 +169,7 @@ export class SearchView extends ViewletPanel {
this.matchFocused = Constants.MatchFocusKey.bindTo(this.contextKeyService);
this.hasSearchResultsKey = Constants.HasSearchResults.bindTo(this.contextKeyService);
this.viewModel = this._register(this.searchWorkbenchService.searchModel);
this.queryBuilder = this.instantiationService.createInstance(QueryBuilder);
this.memento = new Memento(this.id, storageService);
this.viewletState = this.memento.getMemento(StorageScope.WORKSPACE);
@@ -175,10 +180,6 @@ export class SearchView extends ViewletPanel {
this._register(this.contextService.onDidChangeWorkbenchState(() => this.onDidChangeWorkbenchState()));
this._register(this.searchHistoryService.onDidClearHistory(() => this.clearHistory()));
this.selectCurrentMatchEmitter = this._register(new Emitter<string>());
this._register(Event.debounce(this.selectCurrentMatchEmitter.event, (l, e) => e, 100, /*leading=*/true)
(() => this.selectCurrentMatch()));
this.delayedRefresh = this._register(new Delayer<void>(250));
this.actions = [
@@ -204,7 +205,6 @@ export class SearchView extends ViewletPanel {
}
renderBody(parent: HTMLElement): void {
this.viewModel = this._register(this.searchWorkbenchService.searchModel);
this.container = dom.append(parent, dom.$('.search-view'));
this.searchWidgetsContainerElement = dom.append(this.container, $('.search-widgets-container'));
@@ -320,14 +320,6 @@ export class SearchView extends ViewletPanel {
if (this.viewModel) {
this.viewModel.searchResult.toggleHighlights(visible);
}
// Open focused element from results in case the editor area is otherwise empty
if (visible && !this.editorService.activeEditor) {
const focus = this.tree.getFocus();
if (focus) {
this.onFocus(focus, true);
}
}
}
get searchAndReplaceWidget(): SearchWidget {
@@ -348,9 +340,11 @@ export class SearchView extends ViewletPanel {
protected updateActions(): void {
for (const action of this.actions) {
action.update();
this.refreshAction.update();
this.cancelAction.update();
}
this.refreshAction.update();
this.cancelAction.update();
super.updateActions();
}
@@ -517,13 +511,19 @@ export class SearchView extends ViewletPanel {
return;
}
const progressRunner = this.progressService.show(100);
const occurrences = this.viewModel.searchResult.count();
const fileCount = this.viewModel.searchResult.fileCount();
const replaceValue = this.searchWidget.getReplaceValue() || '';
const afterReplaceAllMessage = this.buildAfterReplaceAllMessage(occurrences, fileCount, replaceValue);
let progressComplete: () => void;
let progressReporter: IProgress<IProgressStep>;
this.progressService.withProgress({ location: VIEWLET_ID, delay: 100, total: occurrences }, p => {
progressReporter = p;
return new Promise(resolve => progressComplete = resolve);
});
const confirmation: IConfirmation = {
title: nls.localize('replaceAll.confirmation.title', "Replace All"),
message: this.buildReplaceAllConfirmationMessage(occurrences, fileCount, replaceValue),
@@ -534,12 +534,12 @@ export class SearchView extends ViewletPanel {
this.dialogService.confirm(confirmation).then(res => {
if (res.confirmed) {
this.searchWidget.setReplaceAllActionState(false);
this.viewModel.searchResult.replaceAll(progressRunner).then(() => {
progressRunner.done();
this.viewModel.searchResult.replaceAll(progressReporter).then(() => {
progressComplete();
const messageEl = this.clearMessage();
dom.append(messageEl, $('p', undefined, afterReplaceAllMessage));
}, (error) => {
progressRunner.done();
progressComplete();
errors.isPromiseCanceledError(error);
this.notificationService.error(error);
});
@@ -693,23 +693,17 @@ export class SearchView extends ViewletPanel {
e.browserEvent.preventDefault();
e.browserEvent.stopPropagation();
const actions: IAction[] = [];
const actionsDisposable = createAndFillInContextMenuActions(this.contextMenu, { shouldForwardArgs: true }, actions, this.contextMenuService);
this.contextMenuService.showContextMenu({
getAnchor: () => e.anchor,
getActions: () => {
const actions: IAction[] = [];
fillInContextMenuActions(this.contextMenu, { shouldForwardArgs: true }, actions, this.contextMenuService);
return actions;
},
getActionsContext: () => e.element
getActions: () => actions,
getActionsContext: () => e.element,
onHide: () => dispose(actionsDisposable)
});
}
selectCurrentMatch(): void {
const focused = this.tree.getFocus()[0];
const fakeKeyboardEvent = getSelectionKeyboardEvent(undefined, false);
this.tree.setSelection([focused], fakeKeyboardEvent);
}
selectNextMatch(): void {
const [selected] = this.tree.getSelection();
@@ -743,7 +737,6 @@ export class SearchView extends ViewletPanel {
if (next) {
this.tree.setFocus([next], getSelectionKeyboardEvent(undefined, false));
this.tree.reveal(next);
this.selectCurrentMatchEmitter.fire(undefined);
}
}
@@ -783,7 +776,6 @@ export class SearchView extends ViewletPanel {
if (prev) {
this.tree.setFocus([prev], getSelectionKeyboardEvent(undefined, false));
this.tree.reveal(prev);
this.selectCurrentMatchEmitter.fire(undefined);
}
}
@@ -922,12 +914,8 @@ export class SearchView extends ViewletPanel {
return this.tree;
}
isSearchSubmitted(): boolean {
return this.searchSubmitted;
}
isSearching(): boolean {
return this.searching;
isSlowSearch(): boolean {
return this.state === SearchUIState.SlowSearch;
}
allSearchFieldsClear(): boolean {
@@ -1193,7 +1181,7 @@ export class SearchView extends ViewletPanel {
const options: ITextQueryBuilderOptions = {
_reason: 'searchView',
extraFileResources: getOutOfWorkspaceEditorResources(this.editorService, this.contextService),
extraFileResources: this.instantiationService.invokeFunction(getOutOfWorkspaceEditorResources),
maxResults: SearchView.MAX_TEXT_RESULTS,
disregardIgnoreFiles: !useExcludesAndIgnoreFiles || undefined,
disregardExcludeSettings: !useExcludesAndIgnoreFiles || undefined,
@@ -1265,22 +1253,26 @@ export class SearchView extends ViewletPanel {
}
private doSearch(query: ITextQuery, options: ITextQueryBuilderOptions, excludePatternText: string, includePatternText: string): Thenable<void> {
const progressRunner = this.progressService.show(/*infinite=*/true);
let progressComplete: () => void;
this.progressService.withProgress({ location: VIEWLET_ID }, _progress => {
return new Promise(resolve => progressComplete = resolve);
});
this.searchWidget.searchInput.clearMessage();
this.searching = true;
setTimeout(() => {
if (this.searching) {
this.updateActions();
}
}, 2000);
this.state = SearchUIState.Searching;
this.showEmptyStage();
const slowTimer = setTimeout(() => {
this.state = SearchUIState.SlowSearch;
this.updateActions();
}, 2000);
const onComplete = (completed?: ISearchComplete) => {
this.searching = false;
clearTimeout(slowTimer);
this.state = SearchUIState.Idle;
// Complete up to 100% as needed
progressRunner.done();
progressComplete();
// Do final render, then expand if just 1 file with less than 50 matches
this.onSearchResultsChanged();
@@ -1295,7 +1287,6 @@ export class SearchView extends ViewletPanel {
this.viewModel.replaceString = this.searchWidget.getReplaceValue();
this.searchSubmitted = true;
this.updateActions();
const hasResults = !this.viewModel.searchResult.isEmpty();
@@ -1370,12 +1361,13 @@ export class SearchView extends ViewletPanel {
};
const onError = (e: any) => {
clearTimeout(slowTimer);
this.state = SearchUIState.Idle;
if (errors.isPromiseCanceledError(e)) {
return onComplete(undefined);
} else {
this.searching = false;
this.updateActions();
progressRunner.done();
progressComplete();
this.searchWidget.searchInput.showMessage({ content: e.message, type: MessageType.ERROR });
this.viewModel.searchResult.clear();
@@ -1393,7 +1385,7 @@ export class SearchView extends ViewletPanel {
// Handle UI updates in an interval to show frequent progress and results
const uiRefreshHandle: any = setInterval(() => {
if (!this.searching) {
if (this.state === SearchUIState.Idle) {
window.clearInterval(uiRefreshHandle);
return;
}
@@ -1507,7 +1499,7 @@ export class SearchView extends ViewletPanel {
this.searchWithoutFolderMessageElement = this.clearMessage();
const textEl = dom.append(this.searchWithoutFolderMessageElement,
$('p', undefined, nls.localize('searchWithoutFolder', "You have not yet opened a folder. Only open files are currently searched - ")));
$('p', undefined, nls.localize('searchWithoutFolder', "You have not opened or specified a folder. Only open files are currently searched - ")));
const openFolderLink = dom.append(textEl,
$('a.pointer.prominent', { tabindex: 0 }, nls.localize('openFolder', "Open Folder")));
@@ -1527,9 +1519,7 @@ export class SearchView extends ViewletPanel {
}
private showEmptyStage(): void {
// disable 'result'-actions
this.searchSubmitted = false;
this.updateActions();
// clean up ui
@@ -1539,12 +1529,7 @@ export class SearchView extends ViewletPanel {
this.currentSelectedFileMatch = undefined;
}
private onFocus(lineMatch: any, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Promise<any> {
if (!(lineMatch instanceof Match)) {
this.viewModel.searchResult.rangeHighlightDecorations.removeHighlightRange();
return Promise.resolve(true);
}
private onFocus(lineMatch: Match, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Promise<any> {
const useReplacePreview = this.configurationService.getValue<ISearchConfiguration>().search.useReplacePreview;
return (useReplacePreview && this.viewModel.isReplaceActive() && !!this.viewModel.replaceString) ?
this.replaceService.openReplacePreview(lineMatch, preserveFocus, sideBySide, pinned) :
@@ -1634,7 +1619,7 @@ export class SearchView extends ViewletPanel {
getActions(): IAction[] {
return [
this.searching ?
this.state === SearchUIState.SlowSearch ?
this.cancelAction :
this.refreshAction,
...this.actions
@@ -1695,21 +1680,9 @@ export class SearchView extends ViewletPanel {
super.saveState();
}
private _toDispose: IDisposable[] = [];
protected _register<T extends IDisposable>(t: T): T {
if (this.isDisposed) {
console.warn('Registering disposable on object that has already been disposed.');
t.dispose();
} else {
this._toDispose.push(t);
}
return t;
}
dispose(): void {
this.isDisposed = true;
this.saveState();
this._toDispose = dispose(this._toDispose);
super.dispose();
}
}