Skip to content

Commit

Permalink
#1927 Global action to toggle multi line messages
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Dec 18, 2018
1 parent ad0bf30 commit a44ca00
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 45 deletions.
26 changes: 10 additions & 16 deletions src/vs/workbench/parts/markers/electron-browser/markersModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import * as paths from 'vs/base/common/paths';
import { URI } from 'vs/base/common/uri';
import { Range, IRange } from 'vs/editor/common/core/range';
import { IMarker, MarkerSeverity, IRelatedInformation } from 'vs/platform/markers/common/markers';
import { IMarker, MarkerSeverity, IRelatedInformation, IMarkerData } from 'vs/platform/markers/common/markers';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { values } from 'vs/base/common/map';
import { memoize } from 'vs/base/common/decorators';
Expand Down Expand Up @@ -64,30 +64,24 @@ export class Marker {
get resource(): URI { return this.marker.resource; }
get range(): IRange { return this.marker; }

private _lines: string[];
get lines(): string[] {
if (!this._lines) {
this._lines = this.marker.message.split(/\r\n|\r|\n/g);
}
return this._lines;
}

@memoize
get hash(): string {
const hasher = new Hasher();
hasher.hash(this.resource.toString());
hasher.hash(this.marker.startLineNumber);
hasher.hash(this.marker.startColumn);
hasher.hash(this.marker.endLineNumber);
hasher.hash(this.marker.endColumn);
return `${hasher.value}`;
return IMarkerData.makeKey(this.marker);
}

constructor(
readonly marker: IMarker,
readonly relatedInformation: RelatedInformation[] = []
) { }

private _lines: string[];
get lines(): string[] {
if (!this._lines) {
this._lines = this.marker.message.split(/\r\n|\r|\n/g);
}
return this._lines;
}

toString(): string {
return JSON.stringify({
...this.marker,
Expand Down
33 changes: 29 additions & 4 deletions src/vs/workbench/parts/markers/electron-browser/markersPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/
import Constants from 'vs/workbench/parts/markers/electron-browser/constants';
import { Marker, ResourceMarkers, RelatedInformation, MarkersModel } from 'vs/workbench/parts/markers/electron-browser/markersModel';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { MarkersFilterActionItem, MarkersFilterAction, QuickFixAction, QuickFixActionItem, IMarkersFilterActionChangeEvent, IMarkerFilterController } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions';
import { MarkersFilterActionItem, MarkersFilterAction, QuickFixAction, QuickFixActionItem, IMarkersFilterActionChangeEvent, IMarkerFilterController, ToggleLineModeAction } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import Messages from 'vs/workbench/parts/markers/electron-browser/messages';
import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/rangeDecorations';
Expand All @@ -41,6 +41,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { domEvent } from 'vs/base/browser/event';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';

function createModelIterator(model: MarkersModel): Iterator<ITreeElement<TreeElement>> {
const resourcesIt = Iterator.fromArray(model.resourceMarkers);
Expand Down Expand Up @@ -85,6 +86,8 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
private cachedFilterStats: { total: number; filtered: number; } | undefined = undefined;

private currentResourceGotAddedToMarkersData: boolean = false;
private markersViewState: MarkersViewState;
private disposables: IDisposable[] = [];

constructor(
@IInstantiationService private instantiationService: IInstantiationService,
Expand All @@ -103,6 +106,8 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
super(Constants.MARKERS_PANEL_ID, telemetryService, themeService, storageService);
this.panelFoucusContextKey = Constants.MarkerPanelFocusContextKey.bindTo(contextKeyService);
this.panelState = this.getMemento(StorageScope.WORKSPACE);
this.markersViewState = new MarkersViewState();
this.markersViewState.onDidChangeViewState(this.refreshPanel, this, this.disposables);
this.setCurrentActiveEditor();
}

Expand Down Expand Up @@ -278,11 +283,11 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {

const onDidChangeRenderNodeCount = new Relay<ITreeNode<any, any>>();

const virtualDelegate = new VirtualDelegate();
const virtualDelegate = new VirtualDelegate(this.markersViewState);
const renderers = [
this.instantiationService.createInstance(FileResourceMarkersRenderer, onDidChangeRenderNodeCount.event),
this.instantiationService.createInstance(ResourceMarkersRenderer, onDidChangeRenderNodeCount.event),
this.instantiationService.createInstance(MarkerRenderer, a => this.getActionItem(a)),
this.instantiationService.createInstance(MarkerRenderer, this.markersViewState, a => this.getActionItem(a)),
this.instantiationService.createInstance(RelatedInformationRenderer)
];
this.filter = new Filter();
Expand Down Expand Up @@ -350,7 +355,7 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
});

this.filterAction = this.instantiationService.createInstance(MarkersFilterAction, { filterText: this.panelState['filter'] || '', filterHistory: this.panelState['filterHistory'] || [], useFilesExclude: !!this.panelState['useFilesExclude'] });
this.actions = [this.filterAction, this.collapseAllAction];
this.actions = [this.filterAction, this.instantiationService.createInstance(ToggleLineModeAction, this.markersViewState), this.collapseAllAction];
}

private createListeners(): void {
Expand Down Expand Up @@ -656,5 +661,25 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
public dispose(): void {
super.dispose();
this.tree.dispose();
this.markersViewState.dispose();
this.disposables = dispose(this.disposables);
}
}

export class MarkersViewState extends Disposable {

private readonly _onDidChangeViewState: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChangeViewState: Event<void> = this._onDidChangeViewState.event;

private _multiline: boolean = true;
get multiline(): boolean {
return this._multiline;
}

set multiline(value: boolean) {
if (this._multiline !== value) {
this._multiline = value;
this._onDidChangeViewState.fire();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c
import { Event } from 'vs/base/common/event';
import { FilterOptions } from 'vs/workbench/parts/markers/electron-browser/markersFilterOptions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { MarkersViewState } from 'vs/workbench/parts/markers/electron-browser/markersPanel';

export class ToggleMarkersPanelAction extends TogglePanelAction {

Expand Down Expand Up @@ -289,6 +290,34 @@ export class MarkersFilterActionItem extends BaseActionItem {
}
}

export class ToggleLineModeAction extends Action {

public static readonly ID: string = 'workbench.actions.problems.toggleLineMode';

private disposables: IDisposable[] = [];

constructor(private readonly viewState: MarkersViewState) {
super(ToggleLineModeAction.ID);
this.update();
viewState.onDidChangeViewState(this.update, this, this.disposables);
}

private update(): void {
this.tooltip = this.viewState.multiline ? localize('singleline', "Show message in single line") : localize('multiline', "Show message in multiple lines");
this.class = this.viewState.multiline ? 'octicon octicon-fold' : 'octicon octicon-unfold';
}

run(): Promise<void> {
this.viewState.multiline = !this.viewState.multiline;
return Promise.resolve();
}

dispose(): void {
dispose(this.disposables);
}

}

export class QuickFixAction extends Action {

public static readonly ID: string = 'workbench.actions.problems.quickfix';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { IMatch } from 'vs/base/common/filters';
import { Event } from 'vs/base/common/event';
import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { MarkersViewState } from 'vs/workbench/parts/markers/electron-browser/markersPanel';

export type TreeElement = ResourceMarkers | Marker | RelatedInformation;

Expand Down Expand Up @@ -74,8 +75,10 @@ const enum TemplateId {

export class VirtualDelegate implements IListVirtualDelegate<TreeElement> {

constructor(private readonly markersViewState: MarkersViewState) { }

getHeight(element: TreeElement): number {
if (element instanceof Marker) {
if (element instanceof Marker && this.markersViewState.multiline) {
return element.lines.length * 22;
}
return 22;
Expand Down Expand Up @@ -209,6 +212,7 @@ export class FileResourceMarkersRenderer extends ResourceMarkersRenderer {
export class MarkerRenderer implements ITreeRenderer<Marker, MarkerFilterData, IMarkerTemplateData> {

constructor(
private readonly markersViewState: MarkersViewState,
private actionItemProvider: IActionItemProvider,
@IInstantiationService protected instantiationService: IInstantiationService
) { }
Expand All @@ -217,7 +221,7 @@ export class MarkerRenderer implements ITreeRenderer<Marker, MarkerFilterData, I

renderTemplate(container: HTMLElement): IMarkerTemplateData {
const data: IMarkerTemplateData = Object.create(null);
data.markerWidget = new MarkerWidget(container, this.actionItemProvider, this.instantiationService);
data.markerWidget = new MarkerWidget(container, this.markersViewState, this.actionItemProvider, this.instantiationService);
return data;
}

Expand All @@ -235,18 +239,19 @@ class MarkerWidget extends Disposable {

private readonly actionBar: ActionBar;
private readonly icon: HTMLElement;
private readonly messageContainer: HTMLElement;
private readonly messageAndDetailsContainer: HTMLElement;
private disposables: IDisposable[] = [];

constructor(
parent: HTMLElement, actionItemProvider: IActionItemProvider,
parent: HTMLElement,
private readonly markersViewState: MarkersViewState,
actionItemProvider: IActionItemProvider,
private instantiationService: IInstantiationService
) {
super();
const actionsContainer = dom.append(parent, dom.$('.actions'));
this.actionBar = this._register(new ActionBar(actionsContainer, { actionItemProvider }));
this.actionBar = this._register(new ActionBar(dom.append(parent, dom.$('.actions')), { actionItemProvider }));
this.icon = dom.append(parent, dom.$('.icon'));
this.messageContainer = dom.append(parent, dom.$('.marker-message'));
this.messageAndDetailsContainer = dom.append(parent, dom.$('.marker-message-details'));
this._register(toDisposable(() => this.disposables = dispose(this.disposables)));
}

Expand All @@ -255,9 +260,9 @@ class MarkerWidget extends Disposable {
if (this.disposables.length) {
this.disposables = dispose(this.disposables);
}
dom.clearNode(this.messageContainer);
dom.clearNode(this.messageAndDetailsContainer);

this.icon.className = 'icon ' + MarkerWidget.iconClassNameFor(marker);
this.icon.className = 'marker-icon ' + MarkerWidget.iconClassNameFor(marker);

this.actionBar.clear();
const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element);
Expand All @@ -270,15 +275,17 @@ class MarkerWidget extends Disposable {
}, this, this.disposables);

const lineMatches = filterData && filterData.lineMatches || [];
let lastLineElement = this.messageContainer;
const messageContainer = dom.append(this.messageAndDetailsContainer, dom.$('.marker-message'));
dom.toggleClass(messageContainer, 'multiline', this.markersViewState.multiline);

let lastLineElement = messageContainer;
for (let index = 0; index < lines.length; index++) {
lastLineElement = dom.append(this.messageContainer, dom.$('.marker-message-line'));
lastLineElement = dom.append(messageContainer, dom.$('.marker-message-line'));
const highlightedLabel = new HighlightedLabel(lastLineElement, false);
highlightedLabel.set(lines[index], lineMatches[index]);
this.disposables.push(highlightedLabel);
}

this.renderDetails(marker, filterData, lastLineElement);
this.renderDetails(marker, filterData, this.markersViewState.multiline ? lastLineElement : this.messageAndDetailsContainer);
}

private onDidQuickFixesActionEnable(enabled: boolean): void {
Expand Down
33 changes: 21 additions & 12 deletions src/vs/workbench/parts/markers/electron-browser/media/markers.css
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,22 @@
margin-left: 10px;
}

.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message {
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details,
.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message:not(.multiline) {
display: flex;
flex-direction: column;
overflow: hidden;
}

.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message.multiline {
white-space: pre;
flex: 1;
}

.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message:not(.multiline) .marker-message-line {
overflow: hidden;
text-overflow: ellipsis;
}

.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message .details-container {
display: flex;
}
Expand Down Expand Up @@ -146,32 +155,32 @@
font-weight: bold;
}

.markers-panel .monaco-tl-contents > .icon {
.markers-panel .monaco-tl-contents .marker-icon {
height: 22px;
flex: 0 0 16px;
}

.markers-panel .icon.warning {
.markers-panel .marker-icon.warning {
background: url('status-warning.svg') center center no-repeat;
}

.markers-panel .icon.error {
.markers-panel .marker-icon.error {
background: url('status-error.svg') center center no-repeat;
}

.markers-panel .icon.info {
.markers-panel .marker-icon.info {
background: url('status-info.svg') center center no-repeat;
}

.vs-dark .markers-panel .icon.warning {
.vs-dark .markers-panel .marker-icon.warning {
background: url('status-warning-inverse.svg') center center no-repeat;
}

.vs-dark .markers-panel .icon.error {
.vs-dark .markers-panel .marker-icon.error {
background: url('status-error-inverse.svg') center center no-repeat;
}

.vs-dark .markers-panel .icon.info {
.vs-dark .markers-panel .marker-icon.info {
background: url('status-info-inverse.svg') center center no-repeat;
}

Expand All @@ -188,9 +197,9 @@
display: none;
}

.markers-panel .monaco-list-row:hover .monaco-tl-contents > .icon.quickFix,
.markers-panel .monaco-list-row.selected .monaco-tl-contents > .icon.quickFix,
.markers-panel .monaco-list-row.focused .monaco-tl-contents > .icon.quickFix {
.markers-panel .monaco-list-row:hover .monaco-tl-contents > .marker-icon.quickFix,
.markers-panel .monaco-list-row.selected .monaco-tl-contents > .marker-icon.quickFix,
.markers-panel .monaco-list-row.focused .monaco-tl-contents > .marker-icon.quickFix {
display: none;
}

Expand Down

0 comments on commit a44ca00

Please sign in to comment.