From 350c9b249b7c1762f75d6bcf266ec6a1cf8ada85 Mon Sep 17 00:00:00 2001 From: Anas Shahid Date: Mon, 13 Jul 2020 15:47:18 -0400 Subject: [PATCH] [markers] Sync problem markers with active editor Fixes: https://github.com/eclipse-theia/theia/issues/7436 Reveals and expands the markers for the active editor. Added a preference `problems.autoReveal` to control this behavior. Signed-off-by: Muhammad Anas Shahid --- .../browser/problem/problem-preferences.ts | 8 ++- .../src/browser/problem/problem-widget.tsx | 53 ++++++++++++++++++- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/packages/markers/src/browser/problem/problem-preferences.ts b/packages/markers/src/browser/problem/problem-preferences.ts index 7f3b18f1ea0f4..b6e0da94d1ae8 100644 --- a/packages/markers/src/browser/problem/problem-preferences.ts +++ b/packages/markers/src/browser/problem/problem-preferences.ts @@ -29,13 +29,19 @@ export const ProblemConfigSchema: PreferenceSchema = { 'type': 'boolean', 'description': 'Show problem decorators (diagnostic markers) in the tab bars.', 'default': true + }, + 'problems.autoReveal': { + 'type': 'boolean', + 'description': 'Controls whether Problems view should reveal markers when file is opened.', + 'default': true } } }; export interface ProblemConfiguration { 'problems.decorations.enabled': boolean, - 'problems.decorations.tabbar.enabled': boolean + 'problems.decorations.tabbar.enabled': boolean, + 'problems.autoReveal': boolean } export const ProblemPreferences = Symbol('ProblemPreferences'); diff --git a/packages/markers/src/browser/problem/problem-widget.tsx b/packages/markers/src/browser/problem/problem-widget.tsx index bf10b96c515f9..c5a35bf0eebf4 100644 --- a/packages/markers/src/browser/problem/problem-widget.tsx +++ b/packages/markers/src/browser/problem/problem-widget.tsx @@ -14,20 +14,33 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { injectable, inject } from 'inversify'; +import { injectable, inject, postConstruct } from 'inversify'; import { ProblemManager } from './problem-manager'; import { ProblemMarker } from '../../common/problem-marker'; import { ProblemTreeModel } from './problem-tree-model'; import { MarkerInfoNode, MarkerNode, MarkerRootNode } from '../marker-tree'; -import { TreeWidget, TreeProps, ContextMenuRenderer, TreeNode, NodeProps, TreeModel } from '@theia/core/lib/browser'; +import { + TreeWidget, TreeProps, ContextMenuRenderer, TreeNode, NodeProps, TreeModel, + ApplicationShell, Navigatable, ExpandableTreeNode, SelectableTreeNode +} from '@theia/core/lib/browser'; import { DiagnosticSeverity } from 'vscode-languageserver-types'; import * as React from 'react'; +import { ProblemPreferences } from './problem-preferences'; +import { DisposableCollection } from '@theia/core/lib/common/disposable'; export const PROBLEMS_WIDGET_ID = 'problems'; @injectable() export class ProblemWidget extends TreeWidget { + protected readonly toDisposeOnCurrentWidgetChanged = new DisposableCollection(); + + @inject(ProblemPreferences) + protected readonly preferences: ProblemPreferences; + + @inject(ApplicationShell) + protected readonly shell: ApplicationShell; + constructor( @inject(ProblemManager) protected readonly problemManager: ProblemManager, @inject(TreeProps) readonly treeProps: TreeProps, @@ -46,6 +59,42 @@ export class ProblemWidget extends TreeWidget { this.addClipboardListener(this.node, 'copy', e => this.handleCopy(e)); } + @postConstruct() + protected init(): void { + super.init(); + this.updateFollowActiveEditor(); + this.toDispose.push(this.preferences.onPreferenceChanged(e => { + if (e.preferenceName === 'problems.autoReveal') { + this.updateFollowActiveEditor(); + } + })); + } + + protected updateFollowActiveEditor(): void { + this.toDisposeOnCurrentWidgetChanged.dispose(); + this.toDispose.push(this.toDisposeOnCurrentWidgetChanged); + if (this.preferences.get('problems.autoReveal')) { + this.followActiveEditor(); + } + } + + protected followActiveEditor(): void { + this.autoRevealFromActiveEditor(); + this.toDisposeOnCurrentWidgetChanged.push(this.shell.onDidChangeCurrentWidget(() => this.autoRevealFromActiveEditor())); + } + + protected autoRevealFromActiveEditor(): void { + const widget = this.shell.currentWidget; + if (widget && Navigatable.is(widget)) { + const uri = widget.getResourceUri(); + const node = uri && this.model.getNode(uri.toString()); + if (ExpandableTreeNode.is(node) && SelectableTreeNode.is(node)) { + this.model.expandNode(node); + this.model.selectNode(node); + } + } + } + storeState(): object { // no-op return {};