Skip to content

Commit

Permalink
Filter debug console outputs by severity
Browse files Browse the repository at this point in the history
Signed-off-by: Anatoliy Bazko <abazko@redhat.com>
  • Loading branch information
tolusha committed Nov 5, 2019
1 parent bc11e2c commit f2b3556
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 77 deletions.
4 changes: 2 additions & 2 deletions packages/console/src/browser/ansi-console-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
********************************************************************************/

import * as React from 'react';
import { MessageType } from '@theia/core/lib/common';
import { ConsoleItem } from './console-session';
import { ansiToHtml } from 'anser';
import { Severity } from '@theia/core/lib/common/severity';

export class AnsiConsoleItem implements ConsoleItem {

protected readonly htmlContent: string;

constructor(
public readonly content: string,
public readonly severity?: MessageType
public readonly severity?: Severity
) {
this.htmlContent = ansiToHtml(this.content, {
use_classes: true,
Expand Down
11 changes: 6 additions & 5 deletions packages/console/src/browser/console-content-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@

import { Message } from '@phosphor/messaging';
import { interfaces, Container, injectable } from 'inversify';
import { MenuPath, MessageType } from '@theia/core';
import { MenuPath } from '@theia/core';
import { TreeProps } from '@theia/core/lib/browser/tree';
import { TreeSourceNode } from '@theia/core/lib/browser/source-tree';
import { SourceTreeWidget, TreeElementNode } from '@theia/core/lib/browser/source-tree';
import { ConsoleItem } from './console-session';
import { Severity } from '@theia/core/lib/common/severity';

@injectable()
export class ConsoleContentWidget extends SourceTreeWidget {
Expand Down Expand Up @@ -73,16 +74,16 @@ export class ConsoleContentWidget extends SourceTreeWidget {
return classNames;
}
protected toClassName(item: ConsoleItem): string | undefined {
if (item.severity === MessageType.Error) {
if (item.severity === Severity.Error) {
return ConsoleItem.errorClassName;
}
if (item.severity === MessageType.Warning) {
if (item.severity === Severity.Warning) {
return ConsoleItem.warningClassName;
}
if (item.severity === MessageType.Info) {
if (item.severity === Severity.Info) {
return ConsoleItem.infoClassName;
}
if (item.severity === MessageType.Log) {
if (item.severity === Severity.Log) {
return ConsoleItem.logClassName;
}
return undefined;
Expand Down
23 changes: 21 additions & 2 deletions packages/console/src/browser/console-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@

import { injectable } from 'inversify';
import { MaybePromise } from '@theia/core/lib/common/types';
import { MessageType } from '@theia/core/lib/common/message-service-protocol';
import { TreeSource, TreeElement, CompositeTreeElement } from '@theia/core/lib/browser/source-tree';
import { Emitter } from '@theia/core/lib/common/event';
import { Severity } from '@theia/core/lib/common/severity';

export interface ConsoleItem extends TreeElement {
readonly severity?: MessageType
readonly severity?: Severity;
}
export namespace ConsoleItem {
export const errorClassName = 'theia-console-error';
Expand All @@ -35,6 +36,24 @@ export interface CompositeConsoleItem extends ConsoleItem, CompositeTreeElement

@injectable()
export abstract class ConsoleSession extends TreeSource {
protected selectedSeverity?: Severity;
protected readonly selectionEmitter: Emitter<void> = new Emitter<void>();
readonly onSelectionChange = this.selectionEmitter.event;

get severity(): Severity | undefined {
return this.selectedSeverity;
}

set severity(severity: Severity | undefined) {
if (severity === this.selectedSeverity) {
return;
}

this.selectedSeverity = severity;
this.selectionEmitter.fire(undefined);
this.fireDidChange();
}

abstract getElements(): MaybePromise<IterableIterator<ConsoleItem>>;
abstract execute(value: string): MaybePromise<void>;
abstract clear(): MaybePromise<void>;
Expand Down
96 changes: 96 additions & 0 deletions packages/core/src/common/severity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/********************************************************************************
* Copyright (C) 2019 Ericsson and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { DiagnosticSeverity } from 'vscode-languageserver-types';

export enum Severity {
Ignore = 0,
Error = 1,
Warning = 2,
Info = 3,
Log = 4
}

export namespace Severity {
const error = 'Errors';
const warning = 'Warnings';
const info = 'Info';
const log = 'Log';
const ignore = 'All';

export function fromValue(value: string | undefined): Severity {
value = value && value.toLowerCase();

if (!value) {
return Severity.Ignore;
}
if (['error', 'errors'].indexOf(value) !== -1) {
return Severity.Error;
}
if (['warn', 'warning', 'warnings'].indexOf(value) !== -1) {
return Severity.Warning;
}
if (value === 'info') {
return Severity.Info;
}
if (value === 'log') {
return Severity.Log;
}

return Severity.Ignore;
}

export function toDiagnosticSeverity(value: Severity): DiagnosticSeverity {
switch (value) {
case Severity.Ignore:
return DiagnosticSeverity.Hint;
case Severity.Info:
return DiagnosticSeverity.Information;
case Severity.Log:
return DiagnosticSeverity.Information;
case Severity.Warning:
return DiagnosticSeverity.Warning;
case Severity.Error:
return DiagnosticSeverity.Error;
default:
return DiagnosticSeverity.Error;
}
}

export function toString(severity: Severity | undefined): string {
switch (severity) {
case Severity.Error:
return error;
case Severity.Warning:
return warning;
case Severity.Info:
return info;
case Severity.Log:
return log;
default:
return ignore;
}
}

export function toArray(): string[] {
return [ignore, error, warning, info, log];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { interfaces, injectable } from 'inversify';
import { AbstractViewContribution, bindViewContribution, WidgetFactory, Widget } from '@theia/core/lib/browser';
import { ContextKeyService, ContextKey } from '@theia/core/lib/browser/context-key-service';
import { ConsoleWidget, ConsoleOptions } from '@theia/console/lib/browser/console-widget';
import { DebugConsoleSession } from './debug-console-session';
import { Command, CommandRegistry } from '@theia/core/lib/common/command';
import { ConsoleOptions, ConsoleWidget } from '@theia/console/lib/browser/console-widget';
import { AbstractViewContribution, bindViewContribution, Widget, WidgetFactory } from '@theia/core/lib/browser';
import { ContextKey, ContextKeyService } from '@theia/core/lib/browser/context-key-service';
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
import { Command, CommandRegistry } from '@theia/core/lib/common/command';
import { Severity } from '@theia/core/lib/common/severity';
import { inject, injectable, interfaces } from 'inversify';
import * as React from 'react';
import { DebugConsoleSession } from './debug-console-session';

export type InDebugReplContextKey = ContextKey<boolean>;
export const InDebugReplContextKey = Symbol('inDebugReplContextKey');
Expand All @@ -38,6 +40,9 @@ export namespace DebugConsoleCommands {
@injectable()
export class DebugConsoleContribution extends AbstractViewContribution<ConsoleWidget> implements TabBarToolbarContribution {

@inject(DebugConsoleSession)
protected debugConsoleSession: DebugConsoleSession;

constructor() {
super({
widgetId: DebugConsoleContribution.options.id,
Expand All @@ -61,7 +66,14 @@ export class DebugConsoleContribution extends AbstractViewContribution<ConsoleWi
});
}

registerToolbarItems(toolbarRegistry: TabBarToolbarRegistry): void {
async registerToolbarItems(toolbarRegistry: TabBarToolbarRegistry): Promise<void> {
toolbarRegistry.registerItem({
id: 'debug-console-severity',
render: widget => this.renderSeveritySelector(widget),
isVisible: widget => this.withWidget(widget, () => true),
onDidChange: this.debugConsoleSession.onSelectionChange
});

toolbarRegistry.registerItem({
id: DebugConsoleCommands.CLEAR.id,
command: DebugConsoleCommands.CLEAR.id,
Expand Down Expand Up @@ -114,6 +126,25 @@ export class DebugConsoleContribution extends AbstractViewContribution<ConsoleWi
}));
}

protected renderSeveritySelector(widget: Widget | undefined): React.ReactNode {
const severityElements: React.ReactNode[] = [];
Severity.toArray().forEach(s => severityElements.push(<option value={s} key={s}>{s}</option>));
const selectedValue = Severity.toString(this.debugConsoleSession.severity || Severity.Ignore);

return <select
id={'debugConsoleSeverity'}
key={'debugConsoleSeverity'}
value={selectedValue}
onChange={this.changeSeverity}
>
{severityElements}
</select>;
}

protected changeSeverity = (event: React.ChangeEvent<HTMLSelectElement>) => {
this.debugConsoleSession.severity = Severity.fromValue(event.target.value);
}

protected withWidget<T>(widget: Widget | undefined = this.tryGetWidget(), fn: (widget: ConsoleWidget) => T): T | false {
if (widget instanceof ConsoleWidget && widget.id === DebugConsoleContribution.options.id) {
return fn(widget);
Expand Down
8 changes: 6 additions & 2 deletions packages/debug/src/browser/console/debug-console-items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@

import * as React from 'react';
import { DebugProtocol } from 'vscode-debugprotocol/lib/debugProtocol';
import { MessageType } from '@theia/core/lib/common';
import { SingleTextInputDialog } from '@theia/core/lib/browser';
import { ConsoleItem, CompositeConsoleItem } from '@theia/console/lib/browser/console-session';
import { DebugSession } from '../debug-session';
import { Severity } from '@theia/core/lib/common/severity';

export class ExpressionContainer implements CompositeConsoleItem {

Expand Down Expand Up @@ -104,7 +104,7 @@ export class ExpressionContainer implements CompositeConsoleItem {
}
} catch (e) {
result.push({
severity: MessageType.Error,
severity: Severity.Error,
visible: !!e.message,
render: () => e.message
});
Expand Down Expand Up @@ -256,6 +256,7 @@ export namespace VirtualVariableItem {

export class ExpressionItem extends ExpressionContainer {

severity?: Severity;
static notAvailable = 'not available';

protected _value = ExpressionItem.notAvailable;
Expand Down Expand Up @@ -299,14 +300,17 @@ export class ExpressionItem extends ExpressionContainer {
this.namedVariables = body.namedVariables;
this.indexedVariables = body.indexedVariables;
this.elements = undefined;
this.severity = Severity.Log;
}
} catch (err) {
this._value = err.message;
this._available = false;
this.severity = Severity.Error;
}
} else {
this._value = 'Please start a debug session to evaluate';
this._available = false;
this.severity = Severity.Error;
}
}

Expand Down
10 changes: 5 additions & 5 deletions packages/debug/src/browser/console/debug-console-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
import throttle = require('lodash.throttle');
import { injectable, inject, postConstruct } from 'inversify';
import { DebugProtocol } from 'vscode-debugprotocol/lib/debugProtocol';
import { MessageType } from '@theia/core/lib/common';
import { ConsoleSession, ConsoleItem } from '@theia/console/lib/browser/console-session';
import { AnsiConsoleItem } from '@theia/console/lib/browser/ansi-console-item';
import { DebugSession } from '../debug-session';
import { DebugSessionManager } from '../debug-session-manager';
import { Languages, CompletionItem, CompletionItemKind, Position, Range, TextEdit, Workspace, TextDocument, CompletionParams } from '@theia/languages/lib/browser';
import URI from '@theia/core/lib/common/uri';
import { ExpressionContainer, ExpressionItem } from './debug-console-items';
import { Severity } from '@theia/core/lib/common/severity';

@injectable()
export class DebugConsoleSession extends ConsoleSession {
Expand Down Expand Up @@ -83,7 +83,7 @@ export class DebugConsoleSession extends ConsoleSession {
}

getElements(): IterableIterator<ConsoleItem> {
return this.items[Symbol.iterator]();
return this.items.filter(e => !this.severity || e.severity === this.severity)[Symbol.iterator]();
}

protected async completions({ textDocument: { uri }, position }: CompletionParams): Promise<CompletionItem[]> {
Expand Down Expand Up @@ -142,12 +142,12 @@ export class DebugConsoleSession extends ConsoleSession {
this.uncompletedItemContent = value;
}

this.items.push(new AnsiConsoleItem(this.uncompletedItemContent, MessageType.Info));
this.items.push(new AnsiConsoleItem(this.uncompletedItemContent, Severity.Info));
this.fireDidChange();
}

appendLine(value: string): void {
this.items.push(new AnsiConsoleItem(value, MessageType.Info));
this.items.push(new AnsiConsoleItem(value, Severity.Info));
this.fireDidChange();
}

Expand All @@ -158,7 +158,7 @@ export class DebugConsoleSession extends ConsoleSession {
console.debug(`telemetry/${event.body.output}`, event.body.data);
return;
}
const severity = category === 'stderr' ? MessageType.Error : event.body.category === 'console' ? MessageType.Warning : MessageType.Info;
const severity = category === 'stderr' ? Severity.Error : event.body.category === 'console' ? Severity.Warning : Severity.Info;
if (variablesReference) {
const items = await new ExpressionContainer({ session, variablesReference }).getElements();
this.items.push(...items);
Expand Down
3 changes: 2 additions & 1 deletion packages/task/src/browser/task-problem-matcher-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import { inject, injectable, postConstruct } from 'inversify';
import { Event, Emitter } from '@theia/core/lib/common';
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
import {
ApplyToKind, FileLocationKind, NamedProblemMatcher, Severity,
ApplyToKind, FileLocationKind, NamedProblemMatcher,
ProblemPattern, ProblemMatcher, ProblemMatcherContribution, WatchingMatcher
} from '../common';
import { ProblemPatternRegistry } from './task-problem-pattern-registry';
import { Severity } from '@theia/core/lib/common/severity';

@injectable()
export class ProblemMatcherRegistry {
Expand Down
Loading

0 comments on commit f2b3556

Please sign in to comment.