add highligths to errors and warnings list. implements #1606

This commit is contained in:
Johannes Rieken
2015-12-23 09:31:02 +01:00
parent f45320474d
commit f82ea07ca0
3 changed files with 84 additions and 80 deletions
@@ -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;
@@ -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('<div class="inline">');
elements.push(strings.format('<div class="severity {0}"></div>', Severity.toString(severity).toLowerCase()));
elements.push('</div>');
elements.push('<div class="inline entry">');
elements.push('<div>');
if (source) {
elements.push(strings.format('<span class="source">[{0}]&nbsp;</span>', source));
}
elements.push(strings.format('<span class="message">{0}</span>', message));
elements.push('</div>');
elements.push('<div>');
elements.push(strings.format(
'<span class="path"><span class="basename">{0} ({1},{2})</span><span class="dirname">{3}</span></span>',
paths.basename(resource.fsPath),
startLineNumber,
startColumn,
this._labelProvider.getLabel(paths.dirname(resource.fsPath))
));
elements.push('</div>');
elements.push('<div>');
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((<MarkerEntry>entry).marker, searchValue);
entry.setHidden(!accepted);
(<MarkerEntry>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';
}
@@ -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;
}