Skip to content

Commit

Permalink
#20183 Show current problem in status
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Nov 8, 2019
1 parent cf65562 commit 745a2ea
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 7 deletions.
153 changes: 151 additions & 2 deletions src/vs/workbench/contrib/markers/browser/markers.contribution.ts
Expand Up @@ -25,10 +25,21 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { ActivePanelContext } from 'vs/workbench/common/panel';
import { Disposable } from 'vs/base/common/lifecycle';
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/common/statusbar';
import { IMarkerService, MarkerStatistics } from 'vs/platform/markers/common/markers';
import { IMarkerService, MarkerStatistics, IMarker, MarkerSeverity, IMarkerData } from 'vs/platform/markers/common/markers';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Event } from 'vs/base/common/event';
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { URI } from 'vs/base/common/uri';
import { isEqual } from 'vs/base/common/resources';
import { find } from 'vs/base/common/arrays';
import { Range } from 'vs/editor/common/core/range';
import { compare } from 'vs/base/common/strings';

registerSingleton(IMarkersWorkbenchService, MarkersWorkbenchService, false);

Expand Down Expand Up @@ -81,6 +92,11 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
'description': Messages.PROBLEMS_PANEL_CONFIGURATION_AUTO_REVEAL,
'type': 'boolean',
'default': true
},
'problems.showCurrentInStatus': {
'description': Messages.PROBLEMS_PANEL_CONFIGURATION_SHOW_CURRENT_STATUS,
'type': 'boolean',
'default': false
}
}
});
Expand Down Expand Up @@ -343,3 +359,136 @@ class MarkersStatusBarContributions extends Disposable implements IWorkbenchCont
}

workbenchRegistry.registerWorkbenchContribution(MarkersStatusBarContributions, LifecyclePhase.Restored);

class ShowCurrentMarkerInStatusbarContribution extends Disposable implements IEditorContribution {

public static readonly ID = 'editor.contrib.showCurrentMarkerInStatusbar';

private readonly rendererDisposable: MutableDisposable<ShowCurrentMarkerInStatusbarRenderer>;

constructor(
private readonly editor: ICodeEditor,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IInstantiationService private readonly instantiationService: IInstantiationService
) {
super();
this.rendererDisposable = new MutableDisposable<ShowCurrentMarkerInStatusbarRenderer>();
this.onDidConfigurationChange();
this._register(Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('problems.showCurrentInStatus'))(() => this.onDidConfigurationChange()));
}

private onDidConfigurationChange(): void {
this.rendererDisposable.clear();
if (this.configurationService.getValue<boolean>('problems.showCurrentInStatus')) {
this.rendererDisposable.value = this.instantiationService.createInstance(ShowCurrentMarkerInStatusbarRenderer, this.editor);
}
}
}

class ShowCurrentMarkerInStatusbarRenderer extends Disposable {

private readonly statusBarEntryAccessor: MutableDisposable<IStatusbarEntryAccessor>;
private markers: IMarker[] = [];
private currentMarker: IMarker | null = null;

constructor(
private readonly editor: ICodeEditor,
@IStatusbarService private readonly statusbarService: IStatusbarService,
@IMarkerService private readonly markerService: IMarkerService
) {
super();
this.statusBarEntryAccessor = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
this._register(markerService.onMarkerChanged(changedResources => this.onMarkerChanged(changedResources)));
this._register(editor.onDidChangeModel(() => this.updateMarkers()));
this._register(editor.onDidChangeCursorPosition(() => this.render()));
this.render();
}

private render(): void {
const previousMarker = this.currentMarker;
this.currentMarker = this.getMarker();
if (this.hasToUpdateStatus(previousMarker, this.currentMarker)) {
this.updateStatus();
}
}

private hasToUpdateStatus(previousMarker: IMarker | null, currentMarker: IMarker | null): boolean {
if (!currentMarker) {
return true;
}
if (!previousMarker) {
return true;
}
return IMarkerData.makeKey(previousMarker) !== IMarkerData.makeKey(currentMarker);
}

private updateStatus(): void {
if (this.currentMarker) {
const line = this.currentMarker.message.split(/\r\n|\r|\n/g)[0];
const text = `${this.getType(this.currentMarker)} ${line}`;
if (this.statusBarEntryAccessor.value) {
this.statusBarEntryAccessor.value.update({ text });
} else {
this.statusBarEntryAccessor.value = this.statusbarService.addEntry({ text }, 'statusbar.currentProblem', localize('currentProblem', "Current Problem"), StatusbarAlignment.LEFT);
}
} else {
this.statusBarEntryAccessor.clear();
}
}

private getType(marker: IMarker): string {
switch (marker.severity) {
case MarkerSeverity.Error: return '$(error)';
case MarkerSeverity.Warning: return '$(warning)';
case MarkerSeverity.Info: return '$(info)';
}
return '';
}

private getMarker(): IMarker | null {
const model = this.editor.getModel();
if (!model) {
return null;
}
const position = this.editor.getPosition();
if (!position) {
return null;
}
return find(this.markers, marker => Range.containsPosition(marker, position)) || null;
}

private onMarkerChanged(changedResources: ReadonlyArray<URI>): void {
const editorModel = this.editor.getModel();
if (editorModel && !changedResources.some(r => isEqual(editorModel.uri, r))) {
return;
}
this.updateMarkers();
}

private updateMarkers(): void {
const editorModel = this.editor.getModel();
if (editorModel) {
this.markers = this.markerService.read({
resource: editorModel.uri,
severities: MarkerSeverity.Error | MarkerSeverity.Warning | MarkerSeverity.Info
});
this.markers.sort(compareMarker);
} else {
this.markers = [];
}
this.render();
}
}

function compareMarker(a: IMarker, b: IMarker): number {
let res = compare(a.resource.toString(), b.resource.toString());
if (res === 0) {
res = MarkerSeverity.compare(a.severity, b.severity);
}
if (res === 0) {
res = Range.compareRangesUsingStarts(a, b);
}
return res;
}

registerEditorContribution(ShowCurrentMarkerInStatusbarContribution.ID, ShowCurrentMarkerInStatusbarContribution);
5 changes: 0 additions & 5 deletions src/vs/workbench/contrib/markers/browser/markers.ts
Expand Up @@ -18,11 +18,6 @@ import { ResourceMap } from 'vs/base/common/map';

export const IMarkersWorkbenchService = createDecorator<IMarkersWorkbenchService>('markersWorkbenchService');

export interface IFilter {
filterText: string;
useFilesExclude: boolean;
}

export interface IMarkersWorkbenchService {
_serviceBrand: undefined;
readonly markersModel: MarkersModel;
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/contrib/markers/browser/messages.ts
Expand Up @@ -16,6 +16,7 @@ export default class Messages {

public static PROBLEMS_PANEL_CONFIGURATION_TITLE: string = nls.localize('problems.panel.configuration.title', "Problems View");
public static PROBLEMS_PANEL_CONFIGURATION_AUTO_REVEAL: string = nls.localize('problems.panel.configuration.autoreveal', "Controls whether Problems view should automatically reveal files when opening them.");
public static PROBLEMS_PANEL_CONFIGURATION_SHOW_CURRENT_STATUS: string = nls.localize('problems.panel.configuration.showCurrentInStatus', "When enabled shows the current problem in the status bar.");

public static MARKERS_PANEL_TITLE_PROBLEMS: string = nls.localize('markers.panel.title.problems', "Problems");

Expand Down

0 comments on commit 745a2ea

Please sign in to comment.