From f82ea07ca014e75992a6a8ff04df28637c1ec147 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 23 Dec 2015 09:31:02 +0100 Subject: [PATCH] add highligths to errors and warnings list. implements #1606 --- .../ui/highlightedlabel/highlightedLabel.ts | 35 +++--- .../parts/quickopen/browser/markersHandler.ts | 113 +++++++++--------- .../quickopen/browser/media/markerHandler.css | 16 +-- 3 files changed, 84 insertions(+), 80 deletions(-) diff --git a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts index 552af4e55cd..b1931c90779 100644 --- a/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts +++ b/src/vs/base/browser/ui/highlightedlabel/highlightedLabel.ts @@ -4,25 +4,24 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import strings = require('vs/base/common/strings'); +import * as strings from 'vs/base/common/strings'; import { IDisposable } from 'vs/base/common/lifecycle'; -import builder = require('vs/base/browser/builder'); -import dom = require('vs/base/browser/dom'); -import objects = require('vs/base/common/objects'); +import * as dom from 'vs/base/browser/dom'; +import * as objects from 'vs/base/common/objects'; export interface IHighlight { - start:number; - end:number; + start: number; + end: number; } export class HighlightedLabel implements IDisposable { - private domNode:HTMLElement; - private text:string; - private highlights:IHighlight[]; - private didEverRender:boolean; + private domNode: HTMLElement; + private text: string; + private highlights: IHighlight[]; + private didEverRender: boolean; - constructor(container:HTMLElement) { + constructor(container: HTMLElement) { this.domNode = document.createElement('span'); this.domNode.className = 'monaco-highlighted-label'; this.didEverRender = false; @@ -33,11 +32,15 @@ export class HighlightedLabel implements IDisposable { return this.domNode; } - set(text:string = '', highlights:IHighlight[] = []) { - if(this.didEverRender && this.text === text && objects.equals(this.highlights, text)) { + set(text: string = '', highlights?: IHighlight[]) { + if (this.didEverRender && this.text === text && objects.equals(this.highlights, highlights)) { return; } + if (!Array.isArray(highlights)) { + highlights = []; + } + this.text = text; this.highlights = highlights; this.render(); @@ -46,11 +49,11 @@ export class HighlightedLabel implements IDisposable { private render() { dom.clearNode(this.domNode); - var htmlContent:string[] = [], - highlight:IHighlight, + let htmlContent: string[] = [], + highlight: IHighlight, pos = 0; - for (var i = 0; i < this.highlights.length; i++) { + for (let i = 0; i < this.highlights.length; i++) { highlight = this.highlights[i]; if (highlight.end === highlight.start) { continue; diff --git a/src/vs/workbench/parts/quickopen/browser/markersHandler.ts b/src/vs/workbench/parts/quickopen/browser/markersHandler.ts index 450f9777e89..15ba61ee37c 100644 --- a/src/vs/workbench/parts/quickopen/browser/markersHandler.ts +++ b/src/vs/workbench/parts/quickopen/browser/markersHandler.ts @@ -9,7 +9,6 @@ import {TPromise} from 'vs/base/common/winjs.base'; import * as strings from 'vs/base/common/strings'; import * as network from 'vs/base/common/network'; import * as errors from 'vs/base/common/errors'; -import * as paths from 'vs/base/common/paths'; import * as dom from 'vs/base/browser/dom'; import * as nls from 'vs/nls'; import {ICommonCodeEditor, IEditorViewState} from 'vs/editor/common/editorCommon'; @@ -25,22 +24,45 @@ import {IMarkerService, IMarker} from 'vs/platform/markers/common/markers'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpenService'; import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService'; +import {IFilter, or, matchesContiguousSubString, matchesPrefix} from 'vs/base/common/filters'; +import {HighlightedLabel} from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; class MarkerEntry extends QuickOpenEntryItem { - private _editorService: IWorkbenchEditorService; private _codeEditorService: ICodeEditorService; private _labelProvider: PathLabelProvider; - marker: IMarker; + private _marker: IMarker; + private _label: string; + private _description: string; constructor(editorService: IWorkbenchEditorService, codeEditorService: ICodeEditorService, contextService: IWorkspaceContextService, marker: IMarker) { super(); this._editorService = editorService; this._codeEditorService = codeEditorService; this._labelProvider = new PathLabelProvider(contextService); - this.marker = marker; + this._marker = marker; + + const {message, source, resource, startLineNumber, startColumn} = marker; + this._label = source ? nls.localize('marker.msg', '[{0}] {1}', source, message) : message; + this._description = nls.localize('marker.desc', '{0}({1},{2})', this._labelProvider.getLabel(resource.fsPath), startLineNumber, startColumn); + } + + private static _filter: IFilter = or(matchesPrefix, matchesContiguousSubString); + + public update(query: string): void { + + if (this._marker.resource.scheme === network.schemas.inMemory) { + // ignore inmemory-models + this.setHidden(true); + return; + } + + const labelHighlights = MarkerEntry._filter(query, this._label); + const descHighlights = MarkerEntry._filter(query, this._description); + this.setHighlights(labelHighlights, descHighlights); + this.setHidden(!labelHighlights && !descHighlights); } public getHeight(): number { @@ -49,30 +71,31 @@ class MarkerEntry extends QuickOpenEntryItem { public render(tree: ITree, container: HTMLElement, previousCleanupFn: IElementCallback): IElementCallback { dom.clearNode(container); - let elements: string[] = []; - let {severity, message, source, resource, startLineNumber, startColumn} = this.marker; - elements.push('
'); - elements.push(strings.format('
', Severity.toString(severity).toLowerCase())); - elements.push('
'); - elements.push('
'); - elements.push('
'); - if (source) { - elements.push(strings.format('[{0}] ', source)); - } - elements.push(strings.format('{0}', message)); - elements.push('
'); - elements.push('
'); - elements.push(strings.format( - '{0} ({1},{2}){3}', - paths.basename(resource.fsPath), - startLineNumber, - startColumn, - this._labelProvider.getLabel(paths.dirname(resource.fsPath)) - )); - elements.push('
'); - elements.push('
'); - container.innerHTML = elements.join(''); - return null; + + let [labelHighlights, descHighlights] = this.getHighlights(); + const row1 = document.createElement('div'); + dom.addClass(row1, 'row'); + const row2 = document.createElement('div'); + dom.addClass(row2, 'row'); + + // fill first row with icon and label + const icon = document.createElement('div'); + dom.addClass(icon, `severity ${Severity.toString(this._marker.severity).toLowerCase()}`); + row1.appendChild(icon); + const labelContainer = document.createElement('div'); + dom.addClass(labelContainer, 'inline') + new HighlightedLabel(labelContainer).set(this._label, labelHighlights); + row1.appendChild(labelContainer); + + // fill second row with descriptions + const descContainer = document.createElement('div'); + dom.addClass(descContainer, 'inline description') + new HighlightedLabel(descContainer).set(this._description, descHighlights); + row2.appendChild(descContainer); + + container.appendChild(row1); + container.appendChild(row2); + return; } public run(mode: Mode, context: IContext): boolean { @@ -90,13 +113,13 @@ class MarkerEntry extends QuickOpenEntryItem { private _open(): void { this._editorService.openEditor({ - resource: this.marker.resource, + resource: this._marker.resource, options: { selection: { - startLineNumber: this.marker.startLineNumber, - startColumn: this.marker.startColumn, - endLineNumber: this.marker.endLineNumber, - endColumn: this.marker.endColumn + startLineNumber: this._marker.startLineNumber, + startColumn: this._marker.startColumn, + endLineNumber: this._marker.endLineNumber, + endColumn: this._marker.endColumn } } }).done(null, errors.onUnexpectedError); @@ -107,7 +130,7 @@ class MarkerEntry extends QuickOpenEntryItem { let editor: ICommonCodeEditor; for (let candidate of editors) { if (!candidate.getModel() - || candidate.getModel().getAssociatedResource().toString() !== this.marker.resource.toString()) { + || candidate.getModel().getAssociatedResource().toString() !== this._marker.resource.toString()) { continue; } @@ -120,7 +143,7 @@ class MarkerEntry extends QuickOpenEntryItem { } if (editor) { - editor.revealRangeInCenter(this.marker); + editor.revealRangeInCenter(this._marker); } } } @@ -166,8 +189,7 @@ export class MarkersHandler extends QuickOpenHandler { searchValue = searchValue.trim(); const [model] = this._activeSession; for (let entry of model.entries) { - const accepted = MarkersHandler._accept((entry).marker, searchValue); - entry.setHidden(!accepted); + (entry).update(searchValue); } return TPromise.as(model); @@ -222,23 +244,6 @@ export class MarkersHandler extends QuickOpenHandler { return 0; } - private static _accept(marker: IMarker, query: string): boolean { - - if (marker.resource.scheme === network.schemas.inMemory) { - // ignore inmemory-models - return false; - } - - let regexp = new RegExp(strings.convertSimple2RegExpPattern(query), 'i'), - inputs = [ - marker.message, - marker.resource.fsPath, - Severity.toString(marker.severity), - String(marker.startLineNumber), String(marker.startColumn), String(marker.endLineNumber), String(marker.endColumn)]; - - return inputs.some(input => regexp.test(input)); - } - public getClass(): string { return 'marker-handler'; } diff --git a/src/vs/workbench/parts/quickopen/browser/media/markerHandler.css b/src/vs/workbench/parts/quickopen/browser/media/markerHandler.css index ffe80bfd121..3625872976c 100644 --- a/src/vs/workbench/parts/quickopen/browser/media/markerHandler.css +++ b/src/vs/workbench/parts/quickopen/browser/media/markerHandler.css @@ -8,6 +8,10 @@ vertical-align: top; } +.quick-open-widget.marker-handler .row { + height: 24px; +} + .quick-open-widget.marker-handler .severity { display: inline-block; width: 16px; @@ -39,14 +43,6 @@ background: url('status-info-inverse.svg') center center no-repeat; } -.quick-open-widget.marker-handler .entry .path { - opacity: 0.7; -} - -.quick-open-widget.marker-handler .entry .path .basename { - margin-right: 0.7em; -} - -.quick-open-widget.marker-handler .entry .path .dirname { - opacity: 0.6; +.quick-open-widget.marker-handler .description { + margin-left: 20px; } \ No newline at end of file