提交 b171e8f5 编写于 作者: R Rob Lourens

Fix #49673 - "Clear search history" doesn't work when search viewlet is not active

上级 a03c4b62
......@@ -4,19 +4,20 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { PPromise, TPromise } from 'vs/base/common/winjs.base';
import uri, { UriComponents } from 'vs/base/common/uri';
import { Event } from 'vs/base/common/event';
import * as glob from 'vs/base/common/glob';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as objects from 'vs/base/common/objects';
import * as paths from 'vs/base/common/paths';
import * as glob from 'vs/base/common/glob';
import uri, { UriComponents } from 'vs/base/common/uri';
import { PPromise, TPromise } from 'vs/base/common/winjs.base';
import { IFilesConfiguration } from 'vs/platform/files/common/files';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IDisposable } from 'vs/base/common/lifecycle';
export const ID = 'searchService';
export const VIEW_ID = 'workbench.view.search';
export const ISearchService = createDecorator<ISearchService>(ID);
export const ISearchHistoryService = createDecorator<ISearchHistoryService>('searchHistoryService');
export const ISearchService = createDecorator<ISearchService>('searchService');
/**
* A service that enables to search for files or with in files.
......@@ -29,6 +30,21 @@ export interface ISearchService {
registerSearchResultProvider(provider: ISearchResultProvider): IDisposable;
}
export interface ISearchHistoryValues {
search?: string[];
replace?: string[];
include?: string[];
exclude?: string[];
}
export interface ISearchHistoryService {
_serviceBrand: any;
onDidClearHistory: Event<void>;
clearHistory(): void;
load(): ISearchHistoryValues;
save(history: ISearchHistoryValues): void;
}
export interface ISearchResultProvider {
search(query: ISearchQuery): PPromise<ISearchComplete, ISearchProgressItem>;
}
......
......@@ -51,7 +51,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
import { ILifecycleService, LifecyclePhase, ShutdownReason, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ISearchService } from 'vs/platform/search/common/search';
import { ISearchService, ISearchHistoryService } from 'vs/platform/search/common/search';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { CommandService } from 'vs/workbench/services/commands/common/commandService';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
......@@ -96,6 +96,7 @@ import { DialogChannel } from 'vs/platform/dialogs/common/dialogIpc';
import { EventType, addDisposableListener, addClass, getClientArea } from 'vs/base/browser/dom';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { OpenerService } from 'vs/editor/browser/services/openerService';
import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHistoryService';
/**
* Services that we require for the Shell
......@@ -446,6 +447,8 @@ export class WorkbenchShell {
serviceCollection.set(ISearchService, new SyncDescriptor(SearchService));
serviceCollection.set(ISearchHistoryService, new SyncDescriptor(SearchHistoryService));
serviceCollection.set(IWorkbenchIssueService, new SyncDescriptor(WorkbenchIssueService));
serviceCollection.set(ICodeEditorService, new SyncDescriptor(CodeEditorService));
......
......@@ -3,30 +3,30 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import * as DOM from 'vs/base/browser/dom';
import { TPromise } from 'vs/base/common/winjs.base';
import { Action } from 'vs/base/common/actions';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ITree } from 'vs/base/parts/tree/browser/tree';
import { INavigator } from 'vs/base/common/iterator';
import { createKeybinding, ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { getPathLabel } 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';
import { ICommandHandler } from 'vs/platform/commands/common/commands';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ISearchHistoryService, VIEW_ID } from 'vs/platform/search/common/search';
import { SearchView } from 'vs/workbench/parts/search/browser/searchView';
import { Match, FileMatch, FileMatchOrMatch, FolderMatch, RenderableMatch, SearchResult, searchMatchComparer } from 'vs/workbench/parts/search/common/searchModel';
import { IReplaceService } from 'vs/workbench/parts/search/common/replace';
import * as Constants from 'vs/workbench/parts/search/common/constants';
import { IReplaceService } from 'vs/workbench/parts/search/common/replace';
import { FileMatch, FileMatchOrMatch, FolderMatch, Match, RenderableMatch, searchMatchComparer, SearchResult } from 'vs/workbench/parts/search/common/searchModel';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ResolvedKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { OS, isWindows } from 'vs/base/common/platform';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { VIEW_ID } from 'vs/platform/search/common/search';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { ICommandHandler } from 'vs/platform/commands/common/commands';
import { Schemas } from 'vs/base/common/network';
import { getPathLabel } from 'vs/base/common/labels';
import URI from 'vs/base/common/uri';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
export function isSearchViewFocused(viewletService: IViewletService, panelService: IPanelService): boolean {
let searchView = getSearchView(viewletService, panelService);
......@@ -830,9 +830,6 @@ export const copyAllCommand: ICommandHandler = accessor => {
};
export const clearHistoryCommand: ICommandHandler = accessor => {
const viewletService = accessor.get(IViewletService);
const panelService = accessor.get(IPanelService);
const searchView = getSearchView(viewletService, panelService);
searchView.clearHistory();
};
\ No newline at end of file
const searchHistoryService = accessor.get(ISearchHistoryService);
searchHistoryService.clearHistory();
};
......@@ -5,62 +5,62 @@
'use strict';
import 'vs/css!./media/searchview';
import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { Emitter, debounceEvent } from 'vs/base/common/event';
import * as errors from 'vs/base/common/errors';
import * as aria from 'vs/base/browser/ui/aria/aria';
import * as env from 'vs/base/common/platform';
import { Delayer } from 'vs/base/common/async';
import URI from 'vs/base/common/uri';
import * as strings from 'vs/base/common/strings';
import * as paths from 'vs/base/common/paths';
import { $, Builder } from 'vs/base/browser/builder';
import * as dom from 'vs/base/browser/dom';
import { IAction } from 'vs/base/common/actions';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Builder, $ } from 'vs/base/browser/builder';
import * as aria from 'vs/base/browser/ui/aria/aria';
import { FindInput } from 'vs/base/browser/ui/findinput/findInput';
import { ITree, IFocusEvent } from 'vs/base/parts/tree/browser/tree';
import { Scope } from 'vs/workbench/common/memento';
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { FileChangeType, FileChangesEvent, IFileService } from 'vs/platform/files/common/files';
import { Match, FileMatch, SearchModel, FileMatchOrMatch, IChangeEvent, ISearchWorkbenchService, FolderMatch } from 'vs/workbench/parts/search/common/searchModel';
import { QueryBuilder } from 'vs/workbench/parts/search/common/queryBuilder';
import { MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
import { ISearchProgressItem, ISearchComplete, ISearchQuery, IQueryOptions, ISearchConfiguration, IPatternInfo, VIEW_ID } from 'vs/platform/search/common/search';
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IAction } from 'vs/base/common/actions';
import { Delayer } from 'vs/base/common/async';
import * as errors from 'vs/base/common/errors';
import { debounceEvent, Emitter } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
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 { IFocusEvent, ITree } from 'vs/base/parts/tree/browser/tree';
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 { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IConfirmation, IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { FileChangesEvent, FileChangeType, IFileService } from 'vs/platform/files/common/files';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TreeResourceNavigator, WorkbenchTree } from 'vs/platform/list/browser/listService';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IPatternInfo, IQueryOptions, ISearchComplete, ISearchConfiguration, ISearchHistoryService, ISearchProgressItem, ISearchQuery, VIEW_ID } from 'vs/platform/search/common/search';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { KeyCode } from 'vs/base/common/keyCodes';
import { PatternInputWidget, ExcludePatternInputWidget } from 'vs/workbench/parts/search/browser/patternInputWidget';
import { SearchRenderer, SearchDataSource, SearchAccessibilityProvider, SearchFilter, SearchTreeController, SearchSorter } from 'vs/workbench/parts/search/browser/searchResultsView';
import { SearchWidget, ISearchWidgetOptions } from 'vs/workbench/parts/search/browser/searchWidget';
import { RefreshAction, CollapseDeepestExpandedLevelAction, ClearSearchResultsAction, CancelSearchAction } from 'vs/workbench/parts/search/browser/searchActions';
import { IReplaceService } from 'vs/workbench/parts/search/common/replace';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/workspaceActions';
import * as Constants from 'vs/workbench/parts/search/common/constants';
import { IThemeService, ITheme, ICssStyleCollector, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { editorFindMatchHighlight, diffInserted, diffRemoved, diffInsertedOutline, diffRemovedOutline, editorFindMatchHighlightBorder } from 'vs/platform/theme/common/colorRegistry';
import { getOutOfWorkspaceEditorResources } from 'vs/workbench/parts/search/common/search';
import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor';
import { isDiffEditor, isCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { TreeResourceNavigator, WorkbenchTree } from 'vs/platform/list/browser/listService';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { diffInserted, diffInsertedOutline, diffRemoved, diffRemovedOutline, editorFindMatchHighlight, editorFindMatchHighlightBorder } from 'vs/platform/theme/common/colorRegistry';
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { OpenFileFolderAction, OpenFolderAction } from 'vs/workbench/browser/actions/workspaceActions';
import { SimpleFileResourceDragAndDrop } from 'vs/workbench/browser/dnd';
import { IConfirmation, IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { Viewlet } from 'vs/workbench/browser/viewlet';
import { Scope } from 'vs/workbench/common/memento';
import { IPanel } from 'vs/workbench/common/panel';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { Viewlet } from 'vs/workbench/browser/viewlet';
import { PreferencesEditor } from 'vs/workbench/parts/preferences/browser/preferencesEditor';
import { ExcludePatternInputWidget, PatternInputWidget } from 'vs/workbench/parts/search/browser/patternInputWidget';
import { CancelSearchAction, ClearSearchResultsAction, CollapseDeepestExpandedLevelAction, RefreshAction } from 'vs/workbench/parts/search/browser/searchActions';
import { SearchAccessibilityProvider, SearchDataSource, SearchFilter, SearchRenderer, SearchSorter, SearchTreeController } from 'vs/workbench/parts/search/browser/searchResultsView';
import { ISearchWidgetOptions, SearchWidget } from 'vs/workbench/parts/search/browser/searchWidget';
import * as Constants from 'vs/workbench/parts/search/common/constants';
import { QueryBuilder } from 'vs/workbench/parts/search/common/queryBuilder';
import { IReplaceService } from 'vs/workbench/parts/search/common/replace';
import { getOutOfWorkspaceEditorResources } from 'vs/workbench/parts/search/common/search';
import { FileMatch, FileMatchOrMatch, FolderMatch, IChangeEvent, ISearchWorkbenchService, Match, SearchModel } from 'vs/workbench/parts/search/common/searchModel';
import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
export class SearchView extends Viewlet implements IViewlet, IPanel {
......@@ -130,7 +130,8 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
@IReplaceService private replaceService: IReplaceService,
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
@IPreferencesService private preferencesService: IPreferencesService,
@IThemeService protected themeService: IThemeService
@IThemeService protected themeService: IThemeService,
@ISearchHistoryService private searchHistoryService: ISearchHistoryService
) {
super(VIEW_ID, partService, telemetryService, themeService);
......@@ -152,6 +153,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
this.toUnbind.push(this.fileService.onFileChanges(e => this.onFilesChanged(e)));
this.toUnbind.push(this.untitledEditorService.onDidChangeDirty(e => this.onUntitledDidChangeDirty(e)));
this.toUnbind.push(this.contextService.onDidChangeWorkbenchState(() => this.onDidChangeWorkbenchState()));
this._register(this.searchHistoryService.onDidClearHistory(() => this.clearHistory()));
this.selectCurrentMatchEmitter = new Emitter<string>();
debounceEvent(this.selectCurrentMatchEmitter.event, (l, e) => e, 100, /*leading=*/true)
......@@ -182,11 +184,12 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
});
this.createSearchWidget(this.searchWidgetsContainer);
const history = this.searchHistoryService.load();
const filePatterns = this.viewletSettings['query.filePatterns'] || '';
let patternExclusions = this.viewletSettings['query.folderExclusions'] || '';
const patternExclusionsHistory: string[] = this.viewletSettings['query.folderExclusionsHistory'] || [];
const patternExclusionsHistory: string[] = history.exclude || [];
let patternIncludes = this.viewletSettings['query.folderIncludes'] || '';
let patternIncludesHistory: string[] = this.viewletSettings['query.folderIncludesHistory'] || [];
let patternIncludesHistory: string[] = history.include || [];
const queryDetailsExpanded = this.viewletSettings['query.queryDetailsExpanded'] || '';
const useExcludesAndIgnoreFiles = typeof this.viewletSettings['query.useExcludesAndIgnoreFiles'] === 'boolean' ?
this.viewletSettings['query.useExcludesAndIgnoreFiles'] : true;
......@@ -328,8 +331,9 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
let isRegex = this.viewletSettings['query.regex'] === true;
let isWholeWords = this.viewletSettings['query.wholeWords'] === true;
let isCaseSensitive = this.viewletSettings['query.caseSensitive'] === true;
let searchHistory = this.viewletSettings['query.searchHistory'] || [];
let replaceHistory = this.viewletSettings['query.replaceHistory'] || [];
const history = this.searchHistoryService.load();
let searchHistory = history.search || [];
let replaceHistory = history.replace || [];
this.searchWidget = this.instantiationService.createInstance(SearchWidget, builder, <ISearchWidgetOptions>{
value: contentPattern,
......@@ -1509,7 +1513,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
this.updateTitleArea();
}
public clearHistory(): void {
private clearHistory(): void {
this.searchWidget.clearHistory();
this.inputPatternExcludes.clearHistory();
this.inputPatternIncludes.clearHistory();
......@@ -1523,24 +1527,23 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
const patternExcludes = this.inputPatternExcludes.getValue().trim();
const patternIncludes = this.inputPatternIncludes.getValue().trim();
const useExcludesAndIgnoreFiles = this.inputPatternExcludes.useExcludesAndIgnoreFiles();
const searchHistory = this.searchWidget.getSearchHistory();
const replaceHistory = this.searchWidget.getReplaceHistory();
const patternExcludesHistory = this.inputPatternExcludes.getHistory();
const patternIncludesHistory = this.inputPatternIncludes.getHistory();
// store memento
this.viewletSettings['query.contentPattern'] = contentPattern;
this.viewletSettings['query.searchHistory'] = searchHistory;
this.viewletSettings['query.replaceHistory'] = replaceHistory;
this.viewletSettings['query.regex'] = isRegex;
this.viewletSettings['query.wholeWords'] = isWholeWords;
this.viewletSettings['query.caseSensitive'] = isCaseSensitive;
this.viewletSettings['query.folderExclusions'] = patternExcludes;
this.viewletSettings['query.folderIncludes'] = patternIncludes;
this.viewletSettings['query.folderExclusionsHistory'] = patternExcludesHistory;
this.viewletSettings['query.folderIncludesHistory'] = patternIncludesHistory;
this.viewletSettings['query.useExcludesAndIgnoreFiles'] = useExcludesAndIgnoreFiles;
this.searchHistoryService.save({
search: this.searchWidget.getSearchHistory(),
replace: this.searchWidget.getReplaceHistory(),
exclude: this.inputPatternExcludes.getHistory(),
include: this.inputPatternIncludes.getHistory()
});
super.shutdown();
}
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Emitter, Event } from 'vs/base/common/event';
import { ISearchHistoryValues, ISearchHistoryService } from 'vs/platform/search/common/search';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
export class SearchHistoryService implements ISearchHistoryService {
public _serviceBrand: any;
private static readonly SEARCH_HISTORY_KEY = 'workbench.search.history';
private readonly _onDidClearHistory: Emitter<void> = new Emitter<void>();
public readonly onDidClearHistory: Event<void> = this._onDidClearHistory.event;
constructor(
@IStorageService private storageService: IStorageService
) { }
public clearHistory(): void {
this.storageService.remove(SearchHistoryService.SEARCH_HISTORY_KEY, StorageScope.WORKSPACE);
this._onDidClearHistory.fire();
}
public load(): ISearchHistoryValues {
let result: ISearchHistoryValues;
const raw = this.storageService.get(SearchHistoryService.SEARCH_HISTORY_KEY, StorageScope.WORKSPACE);
if (raw) {
try {
result = JSON.parse(raw);
} catch (e) {
// Invalid data
}
}
return result || {};
}
public save(history: ISearchHistoryValues): void {
this.storageService.store(SearchHistoryService.SEARCH_HISTORY_KEY, JSON.stringify(history), StorageScope.WORKSPACE);
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册