Skip to content

Commit

Permalink
Restore split include/exclude boxes
Browse files Browse the repository at this point in the history
Revert "Fix #47157 - Focus include/exclude box when toggling open"

This reverts commit cf87ba3.

See #46315

Revert "Fix #46628 - wrong "no results found" message"

This reverts commit 0bd949c.

See #46315

Revert "Fix default search exclusions string"

This reverts commit 234d100.

See #46315

Revert "Improve migrating from split include/exclude inputs to the new merged one"

This reverts commit 22f49f8.

See #46315

Revert "Fix #45702 - merge include/exclude inputs"

This reverts commit 7fdf1e3.

See #46315
  • Loading branch information
roblourens committed Apr 19, 2018
1 parent cd55adf commit fac0095
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 105 deletions.
42 changes: 42 additions & 0 deletions src/vs/workbench/parts/search/browser/searchActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,48 @@ export class ShowPreviousSearchIncludeAction extends Action {
}
}

export class ShowNextSearchExcludeAction extends Action {

public static readonly ID = 'search.history.showNextExcludePattern';
public static readonly LABEL = nls.localize('nextSearchExcludePattern', "Show Next Search Exclude Pattern");

constructor(id: string, label: string,
@IViewletService private viewletService: IViewletService,
@IPanelService private panelService: IPanelService,
@IContextKeyService private contextKeyService: IContextKeyService
) {
super(id, label);
this.enabled = this.contextKeyService.contextMatchesRules(Constants.SearchViewVisibleKey);
}

public run(): TPromise<any> {
const searchView = getSearchView(this.viewletService, this.panelService);
searchView.searchExcludePattern.showNextTerm();
return TPromise.as(null);
}
}

export class ShowPreviousSearchExcludeAction extends Action {

public static readonly ID = 'search.history.showPreviousExcludePattern';
public static readonly LABEL = nls.localize('previousSearchExcludePattern', "Show Previous Search Exclude Pattern");

constructor(id: string, label: string,
@IViewletService private viewletService: IViewletService,
@IContextKeyService private contextKeyService: IContextKeyService,
@IPanelService private panelService: IPanelService
) {
super(id, label);
this.enabled = this.contextKeyService.contextMatchesRules(Constants.SearchViewVisibleKey);
}

public run(): TPromise<any> {
const searchView = getSearchView(this.viewletService, this.panelService);
searchView.searchExcludePattern.showPreviousTerm();
return TPromise.as(null);
}
}

export class ShowNextSearchTermAction extends Action {

public static readonly ID = 'search.history.showNext';
Expand Down
116 changes: 79 additions & 37 deletions src/vs/workbench/parts/search/browser/searchView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import { IPanel } from 'vs/workbench/common/panel';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { Viewlet } from 'vs/workbench/browser/viewlet';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { splitGlobAware } from 'vs/base/common/glob';

export class SearchView extends Viewlet implements IViewlet, IPanel {

Expand All @@ -80,6 +79,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
private viewletVisible: IContextKey<boolean>;
private inputBoxFocused: IContextKey<boolean>;
private inputPatternIncludesFocused: IContextKey<boolean>;
private inputPatternExclusionsFocused: IContextKey<boolean>;
private firstMatchFocused: IContextKey<boolean>;
private fileMatchOrMatchFocused: IContextKey<boolean>;
private fileMatchOrFolderMatchFocus: IContextKey<boolean>;
Expand All @@ -99,7 +99,8 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
private searchWidget: SearchWidget;
private size: dom.Dimension;
private queryDetails: HTMLElement;
private inputPatternIncludes: ExcludePatternInputWidget;
private inputPatternExcludes: ExcludePatternInputWidget;
private inputPatternIncludes: PatternInputWidget;
private results: Builder;

private currentSelectedFileMatch: FileMatch;
Expand Down Expand Up @@ -136,6 +137,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
this.viewletVisible = Constants.SearchViewVisibleKey.bindTo(contextKeyService);
this.inputBoxFocused = Constants.InputBoxFocusedKey.bindTo(this.contextKeyService);
this.inputPatternIncludesFocused = Constants.PatternIncludesFocusedKey.bindTo(this.contextKeyService);
this.inputPatternExclusionsFocused = Constants.PatternExcludesFocusedKey.bindTo(this.contextKeyService);
this.firstMatchFocused = Constants.FirstMatchFocusKey.bindTo(contextKeyService);
this.fileMatchOrMatchFocused = Constants.FileMatchOrMatchFocusKey.bindTo(contextKeyService);
this.fileMatchOrFolderMatchFocus = Constants.FileMatchOrFolderMatchFocusKey.bindTo(contextKeyService);
Expand Down Expand Up @@ -182,7 +184,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {

const filePatterns = this.viewletSettings['query.filePatterns'] || '';
const patternExclusions = this.viewletSettings['query.folderExclusions'] || '';
delete this.viewletSettings['query.folderExclusions']; // Migrating from versions that have dedicated exclusions persisted
const patternExclusionsHistory = this.viewletSettings['query.folderExclusionsHistory'] || [];
const patternIncludes = this.viewletSettings['query.folderIncludes'] || '';
const patternIncludesHistory = this.viewletSettings['query.folderIncludesHistory'] || [];
const queryDetailsExpanded = this.viewletSettings['query.queryDetailsExpanded'] || '';
Expand All @@ -193,43 +195,27 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
builder.div({ 'class': 'more', 'tabindex': 0, 'role': 'button', 'title': nls.localize('moreSearch', "Toggle Search Details") })
.on(dom.EventType.CLICK, (e) => {
dom.EventHelper.stop(e);
this.toggleQueryDetails();
this.toggleQueryDetails(true);
}).on(dom.EventType.KEY_UP, (e: KeyboardEvent) => {
let event = new StandardKeyboardEvent(e);

if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) {
dom.EventHelper.stop(e);
this.toggleQueryDetails(false);
this.toggleQueryDetails();
}
});

//folder includes list
builder.div({ 'class': 'file-types' }, (builder) => {
let title = nls.localize('searchIncludeExclude.label', "files to include/exclude");
let title = nls.localize('searchScope.includes', "files to include");
builder.element('h4', { text: title });

this.inputPatternIncludes = new ExcludePatternInputWidget(builder.getContainer(), this.contextViewService, this.themeService, {
ariaLabel: nls.localize('searchIncludeExclude.ariaLabel', 'Search Include/Exclude Patterns'),
placeholder: nls.localize('searchIncludeExclude.placeholder', "Examples: src, !*.ts, test/**/*.log")
this.inputPatternIncludes = new PatternInputWidget(builder.getContainer(), this.contextViewService, this.themeService, {
ariaLabel: nls.localize('label.includes', 'Search Include Patterns')
});

// For migrating from versions that have dedicated exclusions persisted
let mergedIncludeExcludes = patternIncludes;
if (patternExclusions) {
if (mergedIncludeExcludes) {
mergedIncludeExcludes += ', ';
}

mergedIncludeExcludes += splitGlobAware(patternExclusions, ',')
.map(s => s.trim())
.filter(s => !!s.length)
.map(s => '!' + s)
.join(', ');
}

this.inputPatternIncludes.setValue(mergedIncludeExcludes);
this.inputPatternIncludes.setValue(patternIncludes);
this.inputPatternIncludes.setHistory(patternIncludesHistory);
this.inputPatternIncludes.setUseExcludesAndIgnoreFiles(useExcludesAndIgnoreFiles);

this.inputPatternIncludes
.on(FindInput.OPTION_CHANGE, (e) => {
Expand All @@ -240,6 +226,30 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
this.inputPatternIncludes.onCancel(() => this.viewModel.cancelSearch()); // Cancel search without focusing the search widget
this.trackInputBox(this.inputPatternIncludes.inputFocusTracker, this.inputPatternIncludesFocused);
});

//pattern exclusion list
builder.div({ 'class': 'file-types' }, (builder) => {
let title = nls.localize('searchScope.excludes', "files to exclude");
builder.element('h4', { text: title });

this.inputPatternExcludes = new ExcludePatternInputWidget(builder.getContainer(), this.contextViewService, this.themeService, {
ariaLabel: nls.localize('label.excludes', 'Search Exclude Patterns')
});

this.inputPatternExcludes.setValue(patternExclusions);
this.inputPatternExcludes.setUseExcludesAndIgnoreFiles(useExcludesAndIgnoreFiles);
this.inputPatternExcludes.setHistory(patternExclusionsHistory);

this.inputPatternExcludes
.on(FindInput.OPTION_CHANGE, (e) => {
this.onQueryChanged(false);
});

this.inputPatternExcludes.onSubmit(() => this.onQueryChanged(true, true));
this.inputPatternExcludes.onSubmit(() => this.onQueryChanged(true, true));
this.inputPatternExcludes.onCancel(() => this.viewModel.cancelSearch()); // Cancel search without focusing the search widget
this.trackInputBox(this.inputPatternExcludes.inputFocusTracker, this.inputPatternExclusionsFocused);
});
}).getHTMLElement();

this.messages = builder.div({ 'class': 'messages' }).hide().clone();
Expand Down Expand Up @@ -272,6 +282,10 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
return this.inputPatternIncludes;
}

public get searchExcludePattern(): PatternInputWidget {
return this.inputPatternExcludes;
}

private updateActions(): void {
for (const action of this.actions) {
action.update();
Expand Down Expand Up @@ -328,7 +342,8 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
this.toUnbind.push(inputFocusTracker.onDidBlur(() => {
this.inputBoxFocused.set(this.searchWidget.searchInputHasFocus()
|| this.searchWidget.replaceInputHasFocus()
|| this.inputPatternIncludes.inputHasFocus());
|| this.inputPatternIncludes.inputHasFocus()
|| this.inputPatternExcludes.inputHasFocus());
if (contextKey) {
contextKey.set(false);
}
Expand Down Expand Up @@ -706,6 +721,12 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
}

if (this.inputPatternIncludes.inputHasFocus()) {
this.inputPatternExcludes.focus();
this.inputPatternExcludes.select();
return;
}

if (this.inputPatternExcludes.inputHasFocus()) {
this.selectTreeIfNotSelected();
return;
}
Expand Down Expand Up @@ -734,6 +755,12 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
return;
}

if (this.inputPatternExcludes.inputHasFocus()) {
this.inputPatternIncludes.focus();
this.inputPatternIncludes.select();
return;
}

if (this.tree.isDOMFocused()) {
this.moveFocusFromResults();
return;
Expand All @@ -742,7 +769,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {

private moveFocusFromResults(): void {
if (this.showsFileTypes()) {
this.toggleQueryDetails(true, true, false);
this.toggleQueryDetails(true, true, false, true);
} else {
this.searchWidget.focus(true, true);
}
Expand All @@ -761,6 +788,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {

this.searchWidget.setWidth(this.size.width - 28 /* container margin */);

this.inputPatternExcludes.setWidth(this.size.width - 28 /* container margin */);
this.inputPatternIncludes.setWidth(this.size.width - 28 /* container margin */);

const messagesSize = this.messages.isHidden() ? 0 : dom.getTotalHeight(this.messages.getHTMLElement());
Expand Down Expand Up @@ -881,7 +909,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
this.onQueryChanged(true, true);
}

public toggleQueryDetails(moveFocus = true, show?: boolean, skipLayout?: boolean): void {
public toggleQueryDetails(moveFocus?: boolean, show?: boolean, skipLayout?: boolean, reverse?: boolean): void {
let cls = 'more';
show = typeof show === 'undefined' ? !dom.hasClass(this.queryDetails, cls) : Boolean(show);
this.viewletSettings['query.queryDetailsExpanded'] = show;
Expand All @@ -890,8 +918,13 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
if (show) {
dom.addClass(this.queryDetails, cls);
if (moveFocus) {
this.inputPatternIncludes.focus();
this.inputPatternIncludes.select();
if (reverse) {
this.inputPatternExcludes.focus();
this.inputPatternExcludes.select();
} else {
this.inputPatternIncludes.focus();
this.inputPatternIncludes.select();
}
}
} else {
dom.removeClass(this.queryDetails, cls);
Expand Down Expand Up @@ -959,7 +992,9 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
const isWholeWords = this.searchWidget.searchInput.getWholeWords();
const isCaseSensitive = this.searchWidget.searchInput.getCaseSensitive();
const contentPattern = this.searchWidget.searchInput.getValue();
const useExcludesAndIgnoreFiles = this.inputPatternIncludes.useExcludesAndIgnoreFiles();
const excludePatternText = this.inputPatternExcludes.getValue().trim();
const includePatternText = this.inputPatternIncludes.getValue().trim();
const useExcludesAndIgnoreFiles = this.inputPatternExcludes.useExcludesAndIgnoreFiles();

if (!rerunQuery) {
return;
Expand Down Expand Up @@ -992,8 +1027,8 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
isSmartCase: this.configurationService.getValue<ISearchConfiguration>().search.smartCase
};

const includeExcludePattern = this.inputPatternIncludes.getValue().trim();
const { includePattern, excludePattern } = this.queryBuilder.parseIncludeExcludePattern(includeExcludePattern);
const excludePattern = this.inputPatternExcludes.getValue();
const includePattern = this.inputPatternIncludes.getValue();

const options: IQueryOptions = {
extraFileResources: getOutOfWorkspaceEditorResources(this.editorGroupService, this.contextService),
Expand All @@ -1019,7 +1054,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
}

this.validateQuery(query).then(() => {
this.onQueryTriggered(query, excludePattern, includePattern);
this.onQueryTriggered(query, excludePatternText, includePatternText);

if (!preserveFocus) {
this.searchWidget.focus(false); // focus back to input field
Expand Down Expand Up @@ -1050,6 +1085,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
}

private onQueryTriggered(query: ISearchQuery, excludePatternText: string, includePatternText: string): void {
this.inputPatternExcludes.onSearchSubmit();
this.inputPatternIncludes.onSearchSubmit();

this.viewModel.cancelSearch();
Expand Down Expand Up @@ -1110,8 +1146,8 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
}

if (!hasResults) {
const hasExcludes = !!excludePatternText;
const hasIncludes = !!includePatternText;
let hasExcludes = !!excludePatternText;
let hasIncludes = !!includePatternText;
let message: string;

if (!completed) {
Expand Down Expand Up @@ -1151,6 +1187,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
}).on(dom.EventType.CLICK, (e: MouseEvent) => {
dom.EventHelper.stop(e, false);

this.inputPatternExcludes.setValue('');
this.inputPatternIncludes.setValue('');

this.onQueryChanged(true);
Expand Down Expand Up @@ -1439,9 +1476,11 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
const isWholeWords = this.searchWidget.searchInput.getWholeWords();
const isCaseSensitive = this.searchWidget.searchInput.getCaseSensitive();
const contentPattern = this.searchWidget.searchInput.getValue();
const patternExcludes = this.inputPatternExcludes.getValue().trim();
const patternIncludes = this.inputPatternIncludes.getValue().trim();
const useExcludesAndIgnoreFiles = this.inputPatternIncludes.useExcludesAndIgnoreFiles();
const useExcludesAndIgnoreFiles = this.inputPatternExcludes.useExcludesAndIgnoreFiles();
const searchHistory = this.searchWidget.getHistory();
const patternExcludesHistory = this.inputPatternExcludes.getHistory();
const patternIncludesHistory = this.inputPatternIncludes.getHistory();

// store memento
Expand All @@ -1450,7 +1489,9 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
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;

Expand All @@ -1466,6 +1507,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {

this.searchWidget.dispose();
this.inputPatternIncludes.dispose();
this.inputPatternExcludes.dispose();

this.viewModel.dispose();

Expand Down
22 changes: 0 additions & 22 deletions src/vs/workbench/parts/search/common/queryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,28 +182,6 @@ export class QueryBuilder {
return Object.keys(excludeExpression).length ? excludeExpression : undefined;
}

/**
* A helper that splits positive and negative patterns from a string that combines both.
*/
public parseIncludeExcludePattern(pattern: string): { includePattern?: string, excludePattern?: string } {
const grouped = collections.groupBy(
splitGlobPattern(pattern),
s => strings.startsWith(s, '!') ? 'excludePattern' : 'includePattern');

const result = {};
if (grouped.includePattern) {
result['includePattern'] = grouped.includePattern.join(', ');
}

if (grouped.excludePattern) {
result['excludePattern'] = grouped.excludePattern
.map(s => strings.ltrim(s, '!'))
.join(', ');
}

return result;
}

private mergeExcludesFromFolderQueries(folderQueries: IFolderQuery[]): glob.IExpression | undefined {
const mergedExcludes = folderQueries.reduce((merged: glob.IExpression, fq: IFolderQuery) => {
if (fq.excludePattern) {
Expand Down
Loading

0 comments on commit fac0095

Please sign in to comment.