mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-13 23:44:09 +01:00
add highligths to errors and warnings list. implements #1606
This commit is contained in:
@@ -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}] </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;
|
||||
}
|
||||
Reference in New Issue
Block a user