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)
|
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,
|
formatDefFile,
|
||||||
isFirstLineMachine,
|
isFirstLineMachine,
|
||||||
diagnosticHandler,
|
diagnosticHandler,
|
||||||
tclDocumentSymbolProvider
|
cdlDocumentSymbolProvider,
|
||||||
|
defDocumentSymbolProvider
|
||||||
} from "./common/handlers"
|
} from "./common/handlers"
|
||||||
import { registerLogger, traceError, traceLog, traceVerbose } from "./common/log/logging"
|
import { registerLogger, traceError, traceLog, traceVerbose } from "./common/log/logging"
|
||||||
import {
|
import {
|
||||||
@@ -179,7 +180,26 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||||||
|
|
||||||
context.subscriptions.push(formatDefProvider)
|
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.
|
// 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
|
// Diagnostics collection
|
||||||
const diagnosticCollectionCdl = vscode.languages.createDiagnosticCollection("cdl")
|
const diagnosticCollectionCdl = vscode.languages.createDiagnosticCollection("cdl")
|
||||||
|
|||||||
Reference in New Issue
Block a user