add: Outline support for DEF and CDL files
This commit is contained in:
@@ -271,3 +271,180 @@ export function tclDocumentSymbolProvider(document: vscode.TextDocument): vscode
|
||||
|
||||
return collectSymbols(rootScope)
|
||||
}
|
||||
|
||||
export function cdlDocumentSymbolProvider(document: vscode.TextDocument): vscode.DocumentSymbol[] {
|
||||
const lines = document.getText().split("\n")
|
||||
|
||||
interface Scope {
|
||||
symbol: vscode.DocumentSymbol
|
||||
startLine: number
|
||||
}
|
||||
|
||||
const root = new vscode.DocumentSymbol(
|
||||
"root",
|
||||
"",
|
||||
vscode.SymbolKind.Namespace,
|
||||
new vscode.Range(0, 0, lines.length, 0),
|
||||
new vscode.Range(0, 0, 0, 0)
|
||||
)
|
||||
root.children = []
|
||||
const stack: Scope[] = [{ symbol: root, startLine: 0 }]
|
||||
|
||||
let pending: { name: string; kind: vscode.SymbolKind; startLine: number } | null = null
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i]
|
||||
const trimmed = line.trim()
|
||||
|
||||
const createSymbol = () => {
|
||||
if (!pending) {
|
||||
return
|
||||
}
|
||||
const startRange = new vscode.Range(
|
||||
pending.startLine,
|
||||
0,
|
||||
pending.startLine,
|
||||
lines[pending.startLine].length
|
||||
)
|
||||
const symbol = new vscode.DocumentSymbol(
|
||||
pending.name,
|
||||
"",
|
||||
pending.kind,
|
||||
startRange,
|
||||
startRange
|
||||
)
|
||||
symbol.children = []
|
||||
stack[stack.length - 1].symbol.children?.push(symbol)
|
||||
stack.push({ symbol, startLine: pending.startLine })
|
||||
pending = null
|
||||
}
|
||||
|
||||
if (pending && trimmed.includes("{")) {
|
||||
createSymbol()
|
||||
}
|
||||
|
||||
if (trimmed.startsWith("}")) {
|
||||
const scope = stack.pop()
|
||||
if (scope) {
|
||||
scope.symbol.range = new vscode.Range(scope.startLine, 0, i, line.length)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
let match
|
||||
if ((match = /^\s*EVENT\s+(\w+)/.exec(line))) {
|
||||
pending = {
|
||||
name: match[1],
|
||||
kind: vscode.SymbolKind.Event,
|
||||
startLine: i
|
||||
}
|
||||
if (line.includes("{")) {
|
||||
createSymbol()
|
||||
}
|
||||
} else if ((match = /^\s*PARAM\s+(\w+)/.exec(line))) {
|
||||
pending = {
|
||||
name: match[1],
|
||||
kind: vscode.SymbolKind.Field,
|
||||
startLine: i
|
||||
}
|
||||
if (line.includes("{")) {
|
||||
createSymbol()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return root.children || []
|
||||
}
|
||||
|
||||
export function defDocumentSymbolProvider(document: vscode.TextDocument): vscode.DocumentSymbol[] {
|
||||
const lines = document.getText().split("\n")
|
||||
|
||||
interface Scope {
|
||||
symbol: vscode.DocumentSymbol
|
||||
startLine: number
|
||||
}
|
||||
|
||||
const root = new vscode.DocumentSymbol(
|
||||
"root",
|
||||
"",
|
||||
vscode.SymbolKind.Namespace,
|
||||
new vscode.Range(0, 0, lines.length, 0),
|
||||
new vscode.Range(0, 0, 0, 0)
|
||||
)
|
||||
root.children = []
|
||||
const stack: Scope[] = [{ symbol: root, startLine: 0 }]
|
||||
|
||||
let pending: { name: string; kind: vscode.SymbolKind; startLine: number } | null = null
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i]
|
||||
const trimmed = line.trim()
|
||||
|
||||
const createSymbol = () => {
|
||||
if (!pending) {
|
||||
return
|
||||
}
|
||||
const startRange = new vscode.Range(
|
||||
pending.startLine,
|
||||
0,
|
||||
pending.startLine,
|
||||
lines[pending.startLine].length
|
||||
)
|
||||
const symbol = new vscode.DocumentSymbol(
|
||||
pending.name,
|
||||
"",
|
||||
pending.kind,
|
||||
startRange,
|
||||
startRange
|
||||
)
|
||||
symbol.children = []
|
||||
stack[stack.length - 1].symbol.children?.push(symbol)
|
||||
stack.push({ symbol, startLine: pending.startLine })
|
||||
pending = null
|
||||
}
|
||||
|
||||
if (pending && trimmed.includes("{")) {
|
||||
createSymbol()
|
||||
}
|
||||
|
||||
if (trimmed.startsWith("}")) {
|
||||
const scope = stack.pop()
|
||||
if (scope) {
|
||||
scope.symbol.range = new vscode.Range(scope.startLine, 0, i, line.length)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
let match
|
||||
if ((match = /^\s*FORMATTING\b/.exec(line))) {
|
||||
pending = {
|
||||
name: "FORMATTING",
|
||||
kind: vscode.SymbolKind.Module,
|
||||
startLine: i
|
||||
}
|
||||
if (line.includes("{")) {
|
||||
createSymbol()
|
||||
}
|
||||
} else if ((match = /^\s*ADDRESS\s+(\w+)/.exec(line))) {
|
||||
pending = {
|
||||
name: match[1],
|
||||
kind: vscode.SymbolKind.Field,
|
||||
startLine: i
|
||||
}
|
||||
if (line.includes("{")) {
|
||||
createSymbol()
|
||||
}
|
||||
} else if ((match = /^\s*BLOCK_TEMPLATE\s+(\w+)/.exec(line))) {
|
||||
pending = {
|
||||
name: match[1],
|
||||
kind: vscode.SymbolKind.Function,
|
||||
startLine: i
|
||||
}
|
||||
if (line.includes("{")) {
|
||||
createSymbol()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return root.children || []
|
||||
}
|
||||
|
||||
+21
-1
@@ -12,7 +12,8 @@ import {
|
||||
formatDefFile,
|
||||
isFirstLineMachine,
|
||||
diagnosticHandler,
|
||||
tclDocumentSymbolProvider
|
||||
cdlDocumentSymbolProvider,
|
||||
defDocumentSymbolProvider
|
||||
} from "./common/handlers"
|
||||
import { registerLogger, traceError, traceLog, traceVerbose } from "./common/log/logging"
|
||||
import {
|
||||
@@ -179,7 +180,26 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
context.subscriptions.push(formatDefProvider)
|
||||
|
||||
const cdlSymbolProvider = vscode.languages.registerDocumentSymbolProvider(
|
||||
{ scheme: "file", language: "cdl" },
|
||||
{
|
||||
provideDocumentSymbols(document: vscode.TextDocument) {
|
||||
return cdlDocumentSymbolProvider(document)
|
||||
}
|
||||
}
|
||||
)
|
||||
context.subscriptions.push(cdlSymbolProvider)
|
||||
|
||||
// Outline now provided by the language server (Document Symbols). Removing TS provider.
|
||||
const defSymbolProvider = vscode.languages.registerDocumentSymbolProvider(
|
||||
{ scheme: "file", language: "def" },
|
||||
{
|
||||
provideDocumentSymbols(document: vscode.TextDocument) {
|
||||
return defDocumentSymbolProvider(document)
|
||||
}
|
||||
}
|
||||
)
|
||||
context.subscriptions.push(defSymbolProvider)
|
||||
|
||||
// Diagnostics collection
|
||||
const diagnosticCollectionCdl = vscode.languages.createDiagnosticCollection("cdl")
|
||||
|
||||
Reference in New Issue
Block a user