提交 bbe69609 编写于 作者: J Johannes Rieken

add message when no editor or no providers are available

上级 90d2232f
...@@ -12,7 +12,6 @@ import { fuzzyScore } from '../../../../base/common/filters'; ...@@ -12,7 +12,6 @@ import { fuzzyScore } from '../../../../base/common/filters';
import { IPosition } from 'vs/editor/common/core/position'; import { IPosition } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range'; import { Range } from 'vs/editor/common/core/range';
import { values } from 'vs/base/common/map'; import { values } from 'vs/base/common/map';
import URI from 'vs/base/common/uri';
export function getOutline(model: ITextModel): TPromise<OutlineItemGroup>[] { export function getOutline(model: ITextModel): TPromise<OutlineItemGroup>[] {
return DocumentSymbolProviderRegistry.ordered(model).map((provider, i) => { return DocumentSymbolProviderRegistry.ordered(model).map((provider, i) => {
...@@ -151,7 +150,7 @@ export class OutlineItemGroup { ...@@ -151,7 +150,7 @@ export class OutlineItemGroup {
export class OutlineModel { export class OutlineModel {
constructor( constructor(
readonly uri: URI, readonly buffer: ITextModel,
private _requests: TPromise<OutlineItemGroup>[] private _requests: TPromise<OutlineItemGroup>[]
) { ) {
// //
...@@ -177,7 +176,7 @@ export class OutlineModel { ...@@ -177,7 +176,7 @@ export class OutlineModel {
} }
merge(other: OutlineModel): boolean { merge(other: OutlineModel): boolean {
if (this.uri.toString() !== other.uri.toString()) { if (this.buffer.uri.toString() !== other.buffer.uri.toString()) {
return false; return false;
} }
this._cancelRequests(); this._cancelRequests();
......
...@@ -22,6 +22,25 @@ ...@@ -22,6 +22,25 @@
height: 100%; height: 100%;
} }
.monaco-workbench .outline-panel .outline-message {
display: none;
padding: 10px 22px 0 22px;
opacity: 0.5;
}
.monaco-workbench .outline-panel.empty .outline-message {
display: inherit;
}
.monaco-workbench .outline-panel .outline-content {
width: 100%;
height: 100%;
}
.monaco-workbench .outline-panel.empty .outline-content {
display: none;
}
.monaco-workbench .outline-panel .outline-element { .monaco-workbench .outline-panel .outline-element {
display: flex; display: flex;
flex-flow: row nowrap; flex-flow: row nowrap;
......
...@@ -8,7 +8,6 @@ import * as dom from 'vs/base/browser/dom'; ...@@ -8,7 +8,6 @@ import * as dom from 'vs/base/browser/dom';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { Action, IAction, RadioGroup } from 'vs/base/common/actions'; import { Action, IAction, RadioGroup } from 'vs/base/common/actions';
import { Emitter, Event } from 'vs/base/common/event';
import { defaultGenerator } from 'vs/base/common/idGenerator'; import { defaultGenerator } from 'vs/base/common/idGenerator';
import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
...@@ -34,30 +33,31 @@ import { OutlineItem, getOutline, OutlineModel } from './outlineModel'; ...@@ -34,30 +33,31 @@ import { OutlineItem, getOutline, OutlineModel } from './outlineModel';
import { OutlineDataSource, OutlineItemComparator, OutlineItemCompareType, OutlineItemFilter, OutlineRenderer, OutlineTreeState } from './outlineTree'; import { OutlineDataSource, OutlineItemComparator, OutlineItemCompareType, OutlineItemFilter, OutlineRenderer, OutlineTreeState } from './outlineTree';
import { KeyCode } from '../../../../base/common/keyCodes'; import { KeyCode } from '../../../../base/common/keyCodes';
import { LRUCache } from '../../../../base/common/map'; import { LRUCache } from '../../../../base/common/map';
import { escape } from '../../../../base/common/strings';
class ActiveEditorOracle { class RequestOracle {
private readonly _disposables = new Array<IDisposable>(); private _disposables = new Array<IDisposable>();
private readonly _onDidChangeActiveEditor = new Emitter<ICodeEditor>(); private _sessionDisposable: IDisposable;
private _editorListener: IDisposable;
readonly onDidChangeActiveEditor: Event<ICodeEditor> = this._onDidChangeActiveEditor.event;
constructor( constructor(
private readonly _callback: (editor: ICodeEditor) => any,
@IEditorGroupService editorGroupService: IEditorGroupService, @IEditorGroupService editorGroupService: IEditorGroupService,
@IWorkbenchEditorService private readonly _workbenchEditorService: IWorkbenchEditorService, @IWorkbenchEditorService private readonly _workbenchEditorService: IWorkbenchEditorService,
) { ) {
editorGroupService.onEditorsChanged(this._update, this, this._disposables); editorGroupService.onEditorsChanged(this._update, this, this._disposables);
DocumentSymbolProviderRegistry.onDidChange(this._update, this, this._disposables); DocumentSymbolProviderRegistry.onDidChange(this._update, this, this._disposables);
this._update();
} }
dispose(): void { dispose(): void {
dispose(this._disposables); dispose(this._disposables);
dispose(this._sessionDisposable);
} }
private _update(): void { private _update(): void {
dispose(this._editorListener); dispose(this._sessionDisposable);
let editor = this._workbenchEditorService.getActiveEditor(); let editor = this._workbenchEditorService.getActiveEditor();
let control = editor && editor.getControl(); let control = editor && editor.getControl();
let codeEditor: ICodeEditor = undefined; let codeEditor: ICodeEditor = undefined;
...@@ -66,8 +66,21 @@ class ActiveEditorOracle { ...@@ -66,8 +66,21 @@ class ActiveEditorOracle {
} else if (isDiffEditor(control)) { } else if (isDiffEditor(control)) {
codeEditor = control.getModifiedEditor(); codeEditor = control.getModifiedEditor();
} }
this._editorListener = codeEditor && codeEditor.onDidChangeModelContent(e => this._onDidChangeActiveEditor.fire(codeEditor));
this._onDidChangeActiveEditor.fire(codeEditor); this._callback(codeEditor);
if (codeEditor) {
let handle: number;
let listener = codeEditor.onDidChangeModelContent(_ => {
handle = setTimeout(() => this._callback, 50);
});
this._sessionDisposable = {
dispose() {
listener.dispose();
clearTimeout(handle);
}
};
}
} }
} }
...@@ -85,16 +98,18 @@ class SimpleToggleAction extends Action { ...@@ -85,16 +98,18 @@ class SimpleToggleAction extends Action {
export class OutlinePanel extends ViewsViewletPanel { export class OutlinePanel extends ViewsViewletPanel {
private readonly _disposables = new Array<IDisposable>(); private _disposables = new Array<IDisposable>();
private readonly _activeEditorOracle: ActiveEditorOracle;
private _editorDisposables = new Array<IDisposable>(); private _editorDisposables = new Array<IDisposable>();
private _requestOracle: RequestOracle;
private _domNode: HTMLElement;
private _message: HTMLDivElement;
private _input: InputBox; private _input: InputBox;
private _tree: Tree; private _tree: Tree;
private _treeFilter: OutlineItemFilter; private _treeFilter: OutlineItemFilter;
private _treeComparator: OutlineItemComparator; private _treeComparator: OutlineItemComparator;
private _treeStates = new LRUCache<string, OutlineTreeState>(10); private _treeStates = new LRUCache<string, OutlineTreeState>(10);
private _followCursor = true; private _followCursor = true;
constructor( constructor(
...@@ -106,10 +121,6 @@ export class OutlinePanel extends ViewsViewletPanel { ...@@ -106,10 +121,6 @@ export class OutlinePanel extends ViewsViewletPanel {
@IConfigurationService configurationService: IConfigurationService @IConfigurationService configurationService: IConfigurationService
) { ) {
super(options, keybindingService, contextMenuService, configurationService); super(options, keybindingService, contextMenuService, configurationService);
this._activeEditorOracle = _instantiationService.createInstance(ActiveEditorOracle);
this._disposables.push(this._activeEditorOracle.onDidChangeActiveEditor(this._onEditor, this));
this._disposables.push(this._activeEditorOracle);
} }
dispose(): void { dispose(): void {
...@@ -118,12 +129,16 @@ export class OutlinePanel extends ViewsViewletPanel { ...@@ -118,12 +129,16 @@ export class OutlinePanel extends ViewsViewletPanel {
} }
protected renderBody(container: HTMLElement): void { protected renderBody(container: HTMLElement): void {
this._domNode = container;
dom.addClass(container, 'outline-panel'); dom.addClass(container, 'outline-panel');
this._message = dom.$('.outline-message');
let contentContainer = dom.$('.outline-content');
dom.append(container, this._message, contentContainer);
let inputContainer = dom.$('.outline-input'); let inputContainer = dom.$('.outline-input');
let treeContainer = dom.$('.outline-tree'); let treeContainer = dom.$('.outline-tree');
dom.append(container, inputContainer, treeContainer); dom.append(contentContainer, inputContainer, treeContainer);
this._input = new InputBox(inputContainer, null, { placeholder: localize('filter', "Filter") }); this._input = new InputBox(inputContainer, null, { placeholder: localize('filter', "Filter") });
this._input.disable(); this._input.disable();
...@@ -140,7 +155,8 @@ export class OutlinePanel extends ViewsViewletPanel { ...@@ -140,7 +155,8 @@ export class OutlinePanel extends ViewsViewletPanel {
this._treeFilter = new OutlineItemFilter(); this._treeFilter = new OutlineItemFilter();
this._tree = this._instantiationService.createInstance(WorkbenchTree, treeContainer, { dataSource, renderer, sorter: this._treeComparator, filter: this._treeFilter }, {}); this._tree = this._instantiationService.createInstance(WorkbenchTree, treeContainer, { dataSource, renderer, sorter: this._treeComparator, filter: this._treeFilter }, {});
this._disposables.push(this._tree, this._input); this._requestOracle = this._instantiationService.createInstance(RequestOracle, editor => this._onEditor(editor));
this._disposables.push(this._tree, this._input, this._requestOracle);
} }
protected layoutBody(height: number): void { protected layoutBody(height: number): void {
...@@ -175,20 +191,25 @@ export class OutlinePanel extends ViewsViewletPanel { ...@@ -175,20 +191,25 @@ export class OutlinePanel extends ViewsViewletPanel {
} }
} }
private _showMessage(message: string) {
dom.addClass(this._domNode, 'empty');
this._message.innerText = escape(message);
}
private async _onEditor(editor: ICodeEditor): TPromise<void> { private async _onEditor(editor: ICodeEditor): TPromise<void> {
dispose(this._editorDisposables); dispose(this._editorDisposables);
this._editorDisposables = new Array(); this._editorDisposables = new Array();
this._input.disable(); this._input.disable();
if (!editor) { if (!editor || !DocumentSymbolProviderRegistry.has(editor.getModel())) {
// todo@joh show empty message return this._showMessage(localize('no-editor', "There are no editors open that can provide outline information."));
return undefined;
} }
let textModel = editor.getModel(); dom.removeClass(this._domNode, 'empty');
let buffer = editor.getModel();
let oldModel = <OutlineModel>this._tree.getInput(); let oldModel = <OutlineModel>this._tree.getInput();
let model = new OutlineModel(textModel.uri, getOutline(textModel)); let model = new OutlineModel(buffer, getOutline(buffer));
if (oldModel && oldModel.merge(model)) { if (oldModel && oldModel.merge(model)) {
model = oldModel; model = oldModel;
...@@ -198,10 +219,10 @@ export class OutlinePanel extends ViewsViewletPanel { ...@@ -198,10 +219,10 @@ export class OutlinePanel extends ViewsViewletPanel {
// persist state // persist state
if (oldModel) { if (oldModel) {
let state = OutlineTreeState.capture(this._tree); let state = OutlineTreeState.capture(this._tree);
this._treeStates.set(oldModel.uri.toString(), state); this._treeStates.set(oldModel.buffer.uri.toString(), state);
} }
await this._tree.setInput(model); await this._tree.setInput(model);
let state = this._treeStates.get(model.uri.toString()); let state = this._treeStates.get(model.buffer.uri.toString());
OutlineTreeState.restore(this._tree, state); OutlineTreeState.restore(this._tree, state);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册