Skip to content

Commit

Permalink
Multiline match hint UI for #13155. Implement search.showLineNumbers to
Browse files Browse the repository at this point in the history
fix #39219
  • Loading branch information
roblourens committed Oct 10, 2018
1 parent f3f7d97 commit cc5e2b4
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/vs/platform/search/common/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ export interface ISearchConfigurationProperties {
globalFindClipboard: boolean;
location: 'sidebar' | 'panel';
useReplacePreview: boolean;
showLineNumbers: boolean;
}

export interface ISearchConfiguration extends IFilesConfiguration {
Expand Down
16 changes: 16 additions & 0 deletions src/vs/workbench/parts/search/browser/media/searchview.css
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,18 @@
text-overflow: ellipsis;
}

.search-view .linematch .matchLineNum {
margin-left: 7px;
margin-right: 4px;
opacity: .7;
font-size: 0.9em;
display: none;
}

.search-view .linematch .matchLineNum.show {
display: block;
}

.search-view .linematch.changedOrRemoved {
font-style: italic;
}
Expand Down Expand Up @@ -241,6 +253,10 @@
flex: 1;
}

.search-view:not(.wide) .monaco-tree .monaco-tree-row .monaco-action-bar {
float: right;
}

.search-view .monaco-tree .monaco-tree-row .monaco-action-bar .action-label {
margin-right: 0.2em;
margin-top: 4px;
Expand Down
69 changes: 49 additions & 20 deletions src/vs/workbench/parts/search/browser/searchResultsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,32 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as nls from 'vs/nls';
import * as resources from 'vs/base/common/resources';
import * as paths from 'vs/base/common/paths';
import * as DOM from 'vs/base/browser/dom';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base';
import { IAction, IActionRunner } from 'vs/base/common/actions';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { FileLabel } from 'vs/workbench/browser/labels';
import { ITree, IDataSource, IAccessibilityProvider, IFilter, IRenderer, ContextMenuEvent, ISorter } from 'vs/base/parts/tree/browser/tree';
import { Match, SearchResult, FileMatch, FileMatchOrMatch, SearchModel, FolderMatch, searchMatchComparer, RenderableMatch } from 'vs/workbench/parts/search/common/searchModel';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { SearchView } from 'vs/workbench/parts/search/browser/searchView';
import { RemoveAction, ReplaceAllAction, ReplaceAction, ReplaceAllInFolderAction } from 'vs/workbench/parts/search/browser/searchActions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { FileKind } from 'vs/platform/files/common/files';
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';
import { IMenu, IMenuService, MenuId } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions';
import { WorkbenchTreeController, WorkbenchTree } from 'vs/platform/list/browser/listService';
import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem';
import { FileKind } from 'vs/platform/files/common/files';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILabelService } from 'vs/platform/label/common/label';
import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService';
import { ISearchConfigurationProperties } from 'vs/platform/search/common/search';
import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { FileLabel } from 'vs/workbench/browser/labels';
import { RemoveAction, ReplaceAction, ReplaceAllAction, ReplaceAllInFolderAction } from 'vs/workbench/parts/search/browser/searchActions';
import { SearchView } from 'vs/workbench/parts/search/browser/searchView';
import { FileMatch, FileMatchOrMatch, FolderMatch, Match, RenderableMatch, searchMatchComparer, SearchModel, SearchResult } from 'vs/workbench/parts/search/common/searchModel';

export class SearchDataSource implements IDataSource {

Expand Down Expand Up @@ -147,6 +148,7 @@ interface IMatchTemplate {
match: HTMLElement;
replace: HTMLElement;
after: HTMLElement;
lineNumber: HTMLElement;
actions: ActionBar;
}

Expand All @@ -157,10 +159,10 @@ export class SearchRenderer extends Disposable implements IRenderer {
private static readonly MATCH_TEMPLATE_ID = 'match';

constructor(
actionRunner: IActionRunner,
private searchView: SearchView,
@IInstantiationService private instantiationService: IInstantiationService,
@IThemeService private themeService: IThemeService,
@IConfigurationService private configurationService: IConfigurationService,
@IWorkspaceContextService protected contextService: IWorkspaceContextService
) {
super();
Expand Down Expand Up @@ -233,6 +235,7 @@ export class SearchRenderer extends Disposable implements IRenderer {
const match = DOM.append(parent, DOM.$('span.findInFileMatch'));
const replace = DOM.append(parent, DOM.$('span.replaceMatch'));
const after = DOM.append(parent, DOM.$('span'));
const lineNumber = DOM.append(container, DOM.$('span.matchLineNum'));
const actionBarContainer = DOM.append(container, DOM.$('span.actionBarContainer'));
const actions = new ActionBar(actionBarContainer, { animated: false });

Expand All @@ -242,6 +245,7 @@ export class SearchRenderer extends Disposable implements IRenderer {
match,
replace,
after,
lineNumber,
actions
};
}
Expand Down Expand Up @@ -303,6 +307,16 @@ export class SearchRenderer extends Disposable implements IRenderer {
templateData.after.textContent = preview.after;
templateData.parent.title = (preview.before + (replace ? match.replaceString : preview.inside) + preview.after).trim().substr(0, 999);

const numLines = match.range().endLineNumber - match.range().startLineNumber;
const extraLinesStr = numLines > 0 ? `+${numLines}` : '';

const showLineNumbers = this.configurationService.getValue<ISearchConfigurationProperties>('search').showLineNumbers;
const lineNumberStr = showLineNumbers ? `:${match.range().startLineNumber}` : '';
DOM.toggleClass(templateData.lineNumber, 'show', (numLines > 0) || showLineNumbers);

templateData.lineNumber.textContent = lineNumberStr + extraLinesStr;
templateData.lineNumber.setAttribute('title', this.getMatchTitle(match, showLineNumbers));

templateData.actions.clear();
if (searchModel.isReplaceActive()) {
templateData.actions.push([this.instantiationService.createInstance(ReplaceAction, tree, match, this.searchView), new RemoveAction(tree, match)], { icon: true, label: false });
Expand All @@ -311,6 +325,21 @@ export class SearchRenderer extends Disposable implements IRenderer {
}
}

private getMatchTitle(match: Match, showLineNumbers: boolean): string {
const startLine = match.range().startLineNumber;
const numLines = match.range().endLineNumber - match.range().startLineNumber;

const lineNumStr = showLineNumbers ?
nls.localize('lineNumStr', "From line {0}", startLine, numLines) + ' ' :
'';

const numLinesStr = numLines > 0 ?
'+ ' + nls.localize('numLinesStr', "{0} more lines", numLines) :
'';

return lineNumStr + numLinesStr;
}

public disposeTemplate(tree: ITree, templateId: string, templateData: any): void {
if (SearchRenderer.FOLDER_MATCH_TEMPLATE_ID === templateId) {
const template = <IFolderMatchTemplate>templateData;
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/parts/search/browser/searchView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
private createSearchResultsView(container: HTMLElement): void {
this.resultsElement = dom.append(container, $('.results.show-file-icons'));
const dataSource = this._register(this.instantiationService.createInstance(SearchDataSource));
const renderer = this._register(this.instantiationService.createInstance(SearchRenderer, this.getActionRunner(), this));
const renderer = this._register(this.instantiationService.createInstance(SearchRenderer, this));
const dnd = this.instantiationService.createInstance(SimpleFileResourceDragAndDrop, (obj: any) => obj instanceof FileMatch ? obj.resource() : void 0);

this.tree = this._register(this.instantiationService.createInstance(WorkbenchTree, this.resultsElement, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,11 @@ configurationRegistry.registerConfiguration({
type: 'boolean',
default: true,
description: nls.localize('search.useReplacePreview', "Controls whether to open Replace Preview when selecting or replacing a match."),
},
'search.showLineNumbers': {
type: 'boolean',
default: false,
description: nls.localize('search.showLineNumbers', "Controls whether to show line numbers for search results."),
}
}
});
Expand Down

0 comments on commit cc5e2b4

Please sign in to comment.