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

add controller, add navigation functions, add commands

上级 5207eade
......@@ -29,6 +29,26 @@ export abstract class TreeElement {
}
}
// todo@joh sort by position!
firstChild(): TreeElement | undefined {
const [first] = Object.keys(this.children);
return this.children[first];
}
lastChild(): TreeElement | undefined {
const [last] = Object.keys(this.children).slice(-1);
return this.children[last];
}
sibling(next: boolean): TreeElement | undefined {
if (!this.parent) {
return undefined;
}
const all = Object.keys(this.parent.children);
const index = all.indexOf(this.id) + (next ? +1 : -1);
return this.parent.children[all[index]];
}
static findId(candidate: DocumentSymbol | string, container: TreeElement): string {
// complex id-computation which contains the origin/extension,
// the parent path, and some dedupe logic when names collide
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/outlineTree';
import 'vs/css!./media/symbol-icons';
import { Range } from 'vs/editor/common/core/range';
import { OutlineElement, OutlineModel } from 'vs/editor/contrib/documentSymbols/outlineModel';
import { localize } from 'vs/nls';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { EditorStateCancellationTokenSource, CodeEditorStateFlag } from 'vs/editor/browser/core/editorState';
import { EditorAction, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
export class OutlineNavigation implements IEditorContribution {
public static readonly ID = 'editor.contrib.OutlineNavigation';
public static get(editor: ICodeEditor): OutlineNavigation {
return editor.getContribution<OutlineNavigation>(OutlineNavigation.ID);
}
private readonly _editor: ICodeEditor;
private _cts?: CancellationTokenSource;
constructor(
editor: ICodeEditor,
) {
this._editor = editor;
}
dispose(): void {
if (this._cts) {
this._cts.dispose(true);
}
}
async goto(next: boolean) {
if (this._cts) {
this._cts.cancel();
}
if (!this._editor.hasModel()) {
return;
}
const textModel = this._editor.getModel();
const position = this._editor.getPosition();
this._cts = new EditorStateCancellationTokenSource(this._editor, CodeEditorStateFlag.Position | CodeEditorStateFlag.Value | CodeEditorStateFlag.Scroll);
const outlineModel = await OutlineModel.create(textModel, this._cts.token);
const element = outlineModel.getItemEnclosingPosition(position);
if (!element) {
return;
}
let nextElement = element.sibling(next);
if (!nextElement && element.parent) {
let nextParent = element.parent.sibling(next);
if (nextParent) {
nextElement = next ? nextParent.firstChild() : nextParent.lastChild();
}
}
if (!(nextElement instanceof OutlineElement)) {
return;
}
this._editor.setPosition(Range.lift(nextElement.symbol.selectionRange).getStartPosition());
}
}
registerEditorContribution(OutlineNavigation.ID, OutlineNavigation);
registerEditorAction(class extends EditorAction {
constructor() {
super({
id: 'editor.action.gotoNextSymbol',
label: localize('label.next', "Go to Next Symbol"),
alias: 'Go to Next Symbol',
precondition: EditorContextKeys.hasDocumentSymbolProvider,
});
}
run(_accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
OutlineNavigation.get(editor).goto(true);
}
});
registerEditorAction(class extends EditorAction {
constructor() {
super({
id: 'editor.action.gotoPrevSymbol',
label: localize('label.prev', "Go to Previous Symbol"),
alias: 'Go to Previous Symbol',
precondition: EditorContextKeys.hasDocumentSymbolProvider,
});
}
run(_accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
OutlineNavigation.get(editor).goto(false);
}
});
......@@ -18,6 +18,7 @@ import 'vs/editor/contrib/comment/comment';
import 'vs/editor/contrib/contextmenu/contextmenu';
import 'vs/editor/contrib/cursorUndo/cursorUndo';
import 'vs/editor/contrib/dnd/dnd';
import 'vs/editor/contrib/documentSymbols/outlineNavigation';
import 'vs/editor/contrib/find/findController';
import 'vs/editor/contrib/folding/folding';
import 'vs/editor/contrib/fontZoom/fontZoom';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册