Skip to content

Commit

Permalink
psi view支持选中展开
Browse files Browse the repository at this point in the history
  • Loading branch information
CppCXY committed Apr 18, 2023
1 parent 22ee425 commit ae21d15
Showing 1 changed file with 81 additions and 15 deletions.
96 changes: 81 additions & 15 deletions src/tree_view/treeView.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as vscode from 'vscode';
import { LuaContext } from '../luaContext';
import { LanguageClient } from 'vscode-languageclient/node';

let LANGUAGE_ID = "lua"
let provider: EmmyLuaSyntaxTreeProvider | undefined = undefined;

class SyntaxNodeOrToken extends vscode.TreeItem {
constructor(
Expand All @@ -21,13 +21,20 @@ class SyntaxNodeOrToken extends vscode.TreeItem {
// };
}

interface PsiRange {
start: number,
end: number
}

interface PsiViewAttr {
simple_view: string
simple_view?: string,
range: PsiRange
}

interface PsiViewNode {
name: string;
attr?: PsiViewAttr;
attr: PsiViewAttr;
parent?: PsiViewNode;
children?: PsiViewNode[];
}

Expand All @@ -47,8 +54,20 @@ export class EmmyLuaSyntaxTreeProvider implements vscode.TreeDataProvider<PsiVie
const activeEditor = vscode.window.activeTextEditor;
if (!element) {
const params = { uri: activeEditor?.document.uri.toString() }
this.luaContext.client?.sendRequest<{ data: PsiViewNode }>("$/syntaxTree/nodes", params).then(psi => {
resolve([psi.data])
this.luaContext.client?.sendRequest<{ data: PsiViewNode }>("$/syntaxTree/nodes", params).then(result => {
this._psiRoot = result.data;
const walkList = [result.data]
while (walkList.length !== 0) {
const node = walkList.pop();
if (node?.children) {
for (const child of node.children) {
child.parent = node;
walkList.push(child);
}
}
}

resolve([this._psiRoot])
})
}
else {
Expand All @@ -57,42 +76,89 @@ export class EmmyLuaSyntaxTreeProvider implements vscode.TreeDataProvider<PsiVie
})
}

getParent(element: PsiViewNode): vscode.ProviderResult<PsiViewNode> | undefined {
return element.parent;
}

refresh(): void {
this._onDidChangeTreeData.fire();
}

find_node(offset: number): PsiViewNode | undefined {
const walkList = [this._psiRoot!]
while (walkList.length !== 0) {
const node = walkList.pop();
if (!node) {
break;
}
if (node.attr.range.start <= offset && node.attr.range.end >= offset) {
if (node.children) {
for (const child of node.children) {
walkList.push(child);
}
}
else {
return node;
}
}
}
return undefined;
}

private _psiRoot: PsiViewNode | undefined;
private _onDidChangeTreeData: vscode.EventEmitter<PsiViewNode | undefined | null | void> = new vscode.EventEmitter<PsiViewNode | undefined | null | void>();
readonly onDidChangeTreeData: vscode.Event<PsiViewNode | undefined | null | void> = this._onDidChangeTreeData.event;
}

function onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
function onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent, provider: EmmyLuaSyntaxTreeProvider) {
const activeEditor = vscode.window.activeTextEditor;
if (activeEditor
&& activeEditor.document === event.document
&& activeEditor.document.languageId === LANGUAGE_ID) {
provider?.refresh()
provider.refresh()
}
}

function onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
function onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined, provider: EmmyLuaSyntaxTreeProvider) {
if (editor
&& editor.document.languageId === LANGUAGE_ID) {
provider?.refresh()
provider.refresh()
}
}

function onDidChangeSelection(e: vscode.TextEditorSelectionChangeEvent, client: LanguageClient, tree: vscode.TreeView<PsiViewNode>, provider: EmmyLuaSyntaxTreeProvider) {
if (e.kind == vscode.TextEditorSelectionChangeKind.Mouse
|| e.kind == vscode.TextEditorSelectionChangeKind.Keyboard) {
e.selections[0].start

const params = { uri: e.textEditor.document.uri.toString(), pos: e.selections[0].start }
client.sendRequest<{ data: number }>("$/syntaxTree/select", params).then(result => {
const node = provider.find_node(result.data)
if (node) {
tree?.reveal(node, { expand: true, select: true });
}
})
}
}

export function active(luaContext: LuaContext) {
provider = new EmmyLuaSyntaxTreeProvider(luaContext)
const provider = new EmmyLuaSyntaxTreeProvider(luaContext)
const context = luaContext.extensionContext;
context.subscriptions.push(
vscode.commands.registerCommand('emmlua.syntax.view', () => {
vscode.window.createTreeView('emmylua.syntax.tree', {
treeDataProvider: provider!
const tree = vscode.window.createTreeView('emmylua.syntax.tree', {
treeDataProvider: provider
});

context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(onDidChangeTextDocument, null, context.subscriptions));
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(onDidChangeActiveTextEditor, null, context.subscriptions));
context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(editor => {
onDidChangeTextDocument(editor, provider);
}, null, context.subscriptions));
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => {
onDidChangeActiveTextEditor(editor, provider);
}, null, context.subscriptions));
context.subscriptions.push(vscode.window.onDidChangeTextEditorSelection(e => {
onDidChangeSelection(e, luaContext.client!, tree, provider);
}, null, context.subscriptions));
})
);

}

0 comments on commit ae21d15

Please sign in to comment.