Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Language server #117

Draft
wants to merge 37 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6a6967c
Merge branch 'master' of https://github.com/BarryNolte/d2-vscode
BarryNolte Jun 16, 2023
a35eeac
Work In Progress
BarryNolte Jun 28, 2023
86faaa8
Bootstraping Language Server
BarryNolte Jul 7, 2023
8268aea
Change fixed path to path from settings file
BarryNolte Jul 8, 2023
4935810
Fixed up d2 path, again
BarryNolte Jul 8, 2023
689a24a
Checkpoint - File Import Completion Working
BarryNolte Jul 13, 2023
9958431
Checkpoint - File Import Completion Working
BarryNolte Jul 13, 2023
eddc7f7
CheckPoint
BarryNolte Jul 15, 2023
355fb28
Checkpoint
BarryNolte Jul 23, 2023
f5af735
Reconfigured directory structure
BarryNolte Jul 24, 2023
c8fb692
Checkpoint
BarryNolte Jul 25, 2023
74118df
Pre-Code Cleanup
BarryNolte Jul 29, 2023
6eaea67
Merge branch 'terrastruct:master' into LanguageServer
BarryNolte Aug 2, 2023
0a7c2c0
First Language Server PR
BarryNolte Aug 2, 2023
06899b9
Merge branch 'LanguageServer' of https://github.com/BarryNolte/d2-vsc…
BarryNolte Aug 2, 2023
6594075
Final push before pull request
BarryNolte Aug 8, 2023
7df1372
Get CI to work (maybe...)
BarryNolte Aug 10, 2023
313251f
Try again to get ci to work
BarryNolte Aug 10, 2023
748398b
Code Review Fixes
BarryNolte Nov 3, 2023
ccbe41f
Code review updates and general tweaks and fixes.
BarryNolte Nov 8, 2023
6b9dc75
Change prettier version to work with CI
BarryNolte Nov 8, 2023
9a20650
Reworked autocomplete, file linking and markdown embedding.
BarryNolte Dec 30, 2023
d8eaeee
Code clean-up
BarryNolte Dec 30, 2023
6b86fc1
Code Cleanup
BarryNolte Jan 1, 2024
ec25e38
Merge branch 'master' into LanguageServer
BarryNolte Jan 2, 2024
02fe37b
Fix formatting bugs
BarryNolte Jan 2, 2024
aeff708
Merge branch 'LanguageServer' of https://github.com/BarryNolte/d2-vsc…
BarryNolte Jan 2, 2024
c254965
eslint version mismatch
BarryNolte Jan 2, 2024
4f0ff39
Set eslint to specific version
BarryNolte Jan 2, 2024
7c95cc4
Fix for package generation
BarryNolte Feb 7, 2024
1976c65
Code review changes
BarryNolte Feb 8, 2024
909980b
Format and forgotten file
BarryNolte Feb 8, 2024
6d5aca9
Code Review Change
BarryNolte Feb 16, 2024
ed206a0
Change request was not the answer we were looking for.
BarryNolte Feb 16, 2024
b0f75cd
Work In Progress
BarryNolte Mar 21, 2024
86f1055
Update dependencies
BarryNolte Mar 30, 2024
99bbb27
Add a 'recompile' button
BarryNolte Mar 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Work In Progress
BarryNolte committed Mar 21, 2024
commit b0f75cd1d85641192d6b9c0896512100aa3e3917
9 changes: 5 additions & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -3,22 +3,23 @@

"compounds": [
{
"name": "Server/Client",
"configurations": ["Attach to Server", "Launch Extension"],
"name": "1 Debug All",
"configurations": ["Extension Launch", "Server Attach"],
"stopAll": true
}
],
"configurations": [
{
"name": "Attach to Server",
"name": "Server Attach",
"port": 6009,
"timeout": 10000,
"request": "attach",
"skipFiles": ["<node_internals>/**"],
"type": "node"
},
{
"name": "Extension Launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"name": "Launch Extension",
"outFiles": [
"${workspaceFolder}/client/dist/**/*.js",
"${workspaceFolder}/server/dist/**/*.js"
3 changes: 3 additions & 0 deletions client/src/extension.ts
Original file line number Diff line number Diff line change
@@ -301,6 +301,9 @@ function startLanguageServer(): void {
);

langClient.start();
// langClient.onNotification("foo", (param: string) => {
// console.log(`OnNotification: ${param}`)
// });
}

/**
13 changes: 5 additions & 8 deletions server/src/completionHelpers.ts
Original file line number Diff line number Diff line change
@@ -122,8 +122,6 @@ export class CompletionHelper {

const node = astData.nodeAtPosition({ line: pos.line, character: charPos });

// console.info(`Node: ${charPos} -> \n${JSON.stringify(node, null, 2)}\n\n`);

if (node) {
const list: string[] = ItemTree.getListFromPath(node);

@@ -145,14 +143,13 @@ export class CompletionHelper {
static doOpenSpace(astData: AstReader, pos: Position): CompletionList {
const compItems: CompletionItem[] = [];

// THIS NEEDS SOME MORE WORK TO} DETECT WHAT COMPLETION HELPER SHOULD BE CALLED
// THIS NEEDS SOME MORE WORK TO DETECT WHICH COMPLETION HELPER SHOULD BE CALLED

const node = astData.nodeAtPosition({ line: pos.line, character: pos.character });
console.log(`Open Space: ${node}`);
// const node = astData.nodeAtPosition({ line: pos.line, character: pos.character });

for (const tItem of ItemTree.Root) {
compItems.push(CompletionItem.create(tItem.item));
}
// for (const tItem of ItemTree.Root) {
// compItems.push(CompletionItem.create(tItem.item));
// }

return CompletionList.create(compItems, false);
}
10 changes: 5 additions & 5 deletions server/src/completionTree.ts
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ export class ItemTree {
/**
*
*/
private static NumberRange(start: number, end: number): TreeItem[] {
private static NumberRangeInteger(start: number, end: number): TreeItem[] {
const tis: TreeItem[] = [];

for (let i = start; i <= end; i++) {
@@ -349,15 +349,15 @@ export class ItemTree {
new TreeItem("stroke", this.colorList),
new TreeItem("fill", this.colorList),
new TreeItem("fill-pattern", this.fillPattern),
new TreeItem("stroke-width", this.NumberRange(1, 15)),
new TreeItem("stroke-dash", this.NumberRange(0, 10)),
new TreeItem("border-radius", this.NumberRange(0, 20)),
new TreeItem("stroke-width", this.NumberRangeInteger(1, 15)),
new TreeItem("stroke-dash", this.NumberRangeInteger(0, 10)),
new TreeItem("border-radius", this.NumberRangeInteger(0, 20)),
new TreeItem("shadow", this.trueFalse),
new TreeItem("3D", this.trueFalse),
new TreeItem("multiple", this.trueFalse),
new TreeItem("double-border", this.trueFalse),
new TreeItem("font", this.fonts),
new TreeItem("font-size", this.NumberRange(8, 100)),
new TreeItem("font-size", this.NumberRangeInteger(8, 100)),
new TreeItem("font-color", this.colorList),
new TreeItem("bold", this.trueFalse),
new TreeItem("italic", this.trueFalse),
53 changes: 42 additions & 11 deletions server/src/d2Ast.ts
Original file line number Diff line number Diff line change
@@ -12,7 +12,13 @@ import {
PublishDiagnosticsParams,
} from "vscode-languageserver";

import { d2ExternalLink, d2Node, d2Range, d2StringAndRange } from "./dataContainers";
import {
d2ExternalLink,
d2Ir,
d2Node,
d2Range,
d2StringAndRange,
} from "./dataContainers";
import { Position } from "vscode-languageserver-textdocument";
import { connection } from "./server";

@@ -23,15 +29,19 @@ import { connection } from "./server";
export class AstReader {
constructor(astStr: string) {
try {
// console.log(astStr);
this.d2Info = JSON.parse(astStr);
} catch (err) {
connection.console.error("Possilble D2/VsCode version mismatch.");
connection.console.error(astStr);
}

// connection.sendNotification("foo", "bar");

this.range = this.d2Info?.Ast.range;

this.processNodes(this.d2Info?.Ast.nodes);
this.processIrFields(this.d2Info?.Ir.fields);
}

/**
@@ -40,6 +50,7 @@ export class AstReader {
private range: d2Range;
private d2Info: LSPAny;
private nodes: d2Node[] = [];
private fields: d2Ir[] = [];
private references: d2StringAndRange[] | undefined;

/**
@@ -95,16 +106,16 @@ export class AstReader {

for (const node of this.nodes) {
// Edges
if (node.hasEdges) {
for (const edge of node.Edges) {
if (edge.src.edgeNode) {
this.references.push(edge.src.edgeNode);
}
if (edge.dst.edgeNode) {
this.references.push(edge.dst.edgeNode);
}
}
}
// if (node.hasEdges) {
// for (const edge of node.Edges) {
// if (edge.src.edgeNode) {
// this.references.push(edge.src.edgeNode);
// }
// if (edge.dst.edgeNode) {
// this.references.push(edge.dst.edgeNode);
// }
// }
// }

if (node.hasKey) {
if (node.Key?.key) {
@@ -168,6 +179,10 @@ export class AstReader {
*/
private processNodes(nodes: LSPAny[]) {
for (const node of nodes ?? []) {
// It's a Comment, it's not quite a node
if (node.map_key === undefined) {
continue;
}
const n = new d2Node(node);
this.nodes.push(n);

@@ -180,6 +195,22 @@ export class AstReader {
}
}

/**
* Go through all the ir's field objects to get
* references.
*/
processIrFields(fields: LSPAny[]) {
for (const field of fields ?? []) {
const f = new d2Ir(field);
this.fields.push(f);
}

console.log("\n---------\nIR\n----------\n");
for (const f of this.fields) {
console.log(f.toString());
}
}

dump(): void {
console.log(`\n---------\nASTREADER: ${this.range.toString()}\n---------\n`);

213 changes: 159 additions & 54 deletions server/src/dataContainers.ts
Original file line number Diff line number Diff line change
@@ -453,56 +453,56 @@ export class d2Import extends d2Range {
/**
* An edge endpoint (eg. a -> b, 'a' and 'b' are both endpoints)
*/
export class d2EdgeEndpoint extends d2Range {
constructor(ep: LSPAny) {
super(ep?.range);
this.path = new d2Path(ep?.path);
}
// export class d2EdgeEndpoint extends d2Range {
// constructor(ep: LSPAny) {
// super(ep?.range);
// this.path = new d2Path(ep?.path);
// }

private path: d2Path;
// private path: d2Path;

get edgeNode(): d2StringAndRange | undefined {
return this.path.first?.value;
}
// get edgeNode(): d2StringAndRange | undefined {
// return this.path.first?.value;
// }

public toString(): string {
return `EndPoint: ${super.toString()} ${this.path}\n`;
}
}
// public toString(): string {
// return `EndPoint: ${super.toString()} ${this.path}\n`;
// }
// }

/**
* Describes a D2 edge, which is two edge endpoints
*/
export class d2Edge extends d2Range {
constructor(edge: LSPAny) {
super(edge?.range);
this.srcArrow = edge.src_arrow;
this.dstArrow = edge.dst_arrow;
// export class d2Edge extends d2Range {
// constructor(edge: LSPAny) {
// super(edge?.range);
// this.srcArrow = edge.src_arrow;
// this.dstArrow = edge.dst_arrow;

this.srcEndPt = new d2EdgeEndpoint(edge.src);
this.dstEndPt = new d2EdgeEndpoint(edge.dst);
}
// this.srcEndPt = new d2EdgeEndpoint(edge.src);
// this.dstEndPt = new d2EdgeEndpoint(edge.dst);
// }

private srcArrow: string;
private dstArrow: string;
// private srcArrow: string;
// private dstArrow: string;

private srcEndPt: d2EdgeEndpoint;
private dstEndPt: d2EdgeEndpoint;
// private srcEndPt: d2EdgeEndpoint;
// private dstEndPt: d2EdgeEndpoint;

get src(): d2EdgeEndpoint {
return this.srcEndPt;
}
// get src(): d2EdgeEndpoint {
// return this.srcEndPt;
// }

get dst(): d2EdgeEndpoint {
return this.dstEndPt;
}
// get dst(): d2EdgeEndpoint {
// return this.dstEndPt;
// }

public toString(): string {
return `Edge: ${super.toString()} ${this.srcEndPt}\n ${this.srcArrow}-${
this.dstArrow
}\n ${this.dstEndPt}\n`;
}
}
// public toString(): string {
// return `Edge: ${super.toString()} ${this.srcEndPt}\n ${this.srcArrow}-${
// this.dstArrow
// }\n ${this.dstEndPt}\n`;
// }
// }

/**
* A D2 node
@@ -513,12 +513,14 @@ export class d2Node extends d2Range {

if (n.map_key.key) {
this.key = new d2Key(n.map_key.key);
} else if (n.map_key.edges) {
for (const edge of n.map_key.edges) {
this.edges.push(new d2Edge(edge));
}
}

// else if (n.map_key.edges) {
// for (const edge of n.map_key.edges) {
// this.edges.push(new d2Edge(edge));
// }
// }

this.primary = new d2Primary(n.map_key.primary);

if (n.map_key.value?.map?.nodes) {
@@ -537,7 +539,7 @@ export class d2Node extends d2Range {
private primary: d2Primary | undefined;
private value: d2NodeValue | d2Value | d2Import | undefined;

private edges: d2Edge[] = [];
// private edges: d2Edge[] = [];

/**
* Properties
@@ -553,14 +555,14 @@ export class d2Node extends d2Range {
}

// Node has edges
get hasEdges(): boolean {
return Boolean(this.edges.length > 0);
}
// get hasEdges(): boolean {
// return Boolean(this.edges.length > 0);
// }

// List of edges
get Edges(): d2Edge[] {
return this.edges;
}
// get Edges(): d2Edge[] {
// return this.edges;
// }

// Node has a key
get hasKey(): boolean {
@@ -623,13 +625,14 @@ export class d2Node extends d2Range {

if (this.hasKey) {
strRet += `${this.key?.toString()}`;
} else if (this.hasEdges) {
let s = `\nEdges\n-----\n`;
for (const edge of this.edges) {
s += `${edge.toString()}`;
}
strRet += s + "\n";
}
// else if (this.hasEdges) {
// let s = `\nEdges\n-----\n`;
// for (const edge of this.edges) {
// s += `${edge.toString()}`;
// }
// strRet += s + "\n";
// }

strRet += this.hasPrimary ? `${this.primary?.toString()}` : "";
strRet += this.hasValue ? `${this.value?.toString()}` : "";
@@ -638,6 +641,108 @@ export class d2Node extends d2Range {
}
}

export class d2IrField {
constructor(n: string) {
this.group = n;
}

public group: string;
public references: d2Range[] = [];

public toString(): string {
let s = `Group: ${this.group}\n`;
for (const ref of this.references) {
s += ` ${ref.toString()}\n`;
}
return s;
}
}

export class d2IrReference extends d2Range {
constructor(ref: LSPAny) {
super(ref.string.range);
this.value = ref.string.value[0].string;
}

public value: string;

public toString(): string {
return ` Ref: ${this.value} - ${super.toString()}`;
}
}

export class d2Ir {
constructor(f: LSPAny) {
console.log("=====================");
console.log(JSON.stringify(f, null, 2));
console.log("=====================");

this.fields = [];
for (const ref of f.references) {
const r = new d2IrReference(ref);
this.references.push(r);
}

if (f.composite !== undefined) {
this.processComposite(f);
} else {
this.processSingle(f);
}
}

public references: d2IrReference[] = [];
public fields: d2IrField[] = [];

processSingle(f: LSPAny) {
console.group();
console.log(`Single: ${f.name}`);
const irf = new d2IrField(f.name);

for (const ref of f.references) {
console.log(` Ref: ${ref.string.range}`);
irf.references.push(ref.string.range);
}

this.fields.push(irf);

console.groupEnd();
}

processComposite(f: LSPAny) {
console.group();
console.log(`Comp: ${f.name} -- ${Boolean(f.composite != undefined)}`);
const irf = new d2IrField(f.name);

for (const ref of f.references) {
console.log(` Ref: ${ref.string.range}`);
irf.references.push(ref.string.range);
}

this.fields.push(irf);

for (const fld of f.composite.fields ?? []) {
if (fld.composite !== undefined) {
this.processComposite(fld);
}
}
console.groupEnd();
}

public toString(): string {
let s = "References: \n";
for (const r of this.references) {
s += ` --> ${r}`;
}
s += "\nFields: \n";

for (const f of this.fields) {
s += f.toString();
}

return s;
}
}

/**
***********************
* END OF FILE
122 changes: 64 additions & 58 deletions server/src/server.ts
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ import {
TextDocumentChangeEvent,
WorkspaceFolder,
DocumentLinkParams,
DidChangeConfigurationParams,
} from "vscode-languageserver/node";

import { URI } from "vscode-uri";
@@ -35,6 +36,7 @@ import { TextDocument } from "vscode-languageserver-textdocument";
import { spawnSync } from "child_process";
import { AstReader } from "./d2Ast";
import { CompletionHelper } from "./completionHelpers";
import { GetFullExePath } from "./utility";

// Holder of all parsed output from the D2 program
//
@@ -58,9 +60,9 @@ const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
connection.onInitialize((params: InitializeParams): InitializeResult => {
connection.console.log("\n***************************");
connection.console.log("D2 Language Server Starting\n");
connection.console.log(`Client: ${params.clientInfo?.name}`);
connection.console.log(`Version: ${params.clientInfo?.version}`);
connection.console.log(`PID: ${params.processId}`);
connection.console.log(`Client: ${params.clientInfo?.name}`);
connection.console.log(`Version: ${params.clientInfo?.version}`);
connection.console.log(`PID: ${params.processId}`);
connection.console.log("***************************\n");

// This is what the server supports
@@ -88,7 +90,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
},
serverInfo: {
name: "D2 Language Server",
version: "0.7",
version: "0.8",
},
};

@@ -98,7 +100,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
/*
* Pickup on configuration changes of the client
*/
connection.onDidChangeConfiguration((change): void => {
connection.onDidChangeConfiguration((change: DidChangeConfigurationParams): void => {
// We'll use the path to D2 so we don't get divergent
// functionality using two different d2 binaries.
d2ExePath = change.settings.D2.execPath;
@@ -109,64 +111,68 @@ connection.onDidChangeConfiguration((change): void => {
* The content of a text document has changed. This event is emitted
* when the text document first opened or when its content has changed.
*/
documents.onDidChangeContent((change: TextDocumentChangeEvent<TextDocument>): void => {
// This is where the D2 document is and is where d2 should assume
// everthing is relative to
const cwDir = URI.parse(path.dirname(change.document.uri)).fsPath;

// Get the workspace folders on a regular basis, because of async
connection.workspace.getWorkspaceFolders().then((folders: WorkspaceFolder[] | null) => {
workspaceFolders = [];
if (folders) {
workspaceFolders = folders;
documents.onDidChangeContent(
async (change: TextDocumentChangeEvent<TextDocument>): Promise<void> => {
// onDidChangeContent can be called before onDidChangeConfiguration, so in order
// to have the correct path to the configured d2 executable, this must be called
// after initialization, but before it has to be used.
d2ExePath = await GetFullExePath();

// This is where the D2 document is and is where d2 should assume
// everthing is relative to
const cwDir = URI.parse(path.dirname(change.document.uri)).fsPath;

// Get the workspace folders on a regular basis, because of async
workspaceFolders = (await connection.workspace.getWorkspaceFolders()) ?? [];

// Run D2 in the stdin/stdout mode
//
const args: string[] = ["-"];

/**
* Run D2 in the special "D2_LSP_MODE" mode.
*/
const proc = spawnSync(d2ExePath, args, {
input: change.document.getText(),
encoding: "utf-8",
maxBuffer: 1024 * 1024 * 2,
cwd: cwDir,
env: { ...process.env, D2_LSP_MODE: "1" },
});

// Pass error back to the client
if (proc.pid === 0) {
connection.window.showErrorMessage(
`Could not find D2 executable! Path: '${d2ExePath}'`
);
return;
}
});

// Run D2 in the stdin/stdout mode
//
const args: string[] = ["-"];

/**
* Run D2 in the special "D2_LSP_MODE" mode.
*/
const proc = spawnSync(d2ExePath, args, {
input: change.document.getText(),
encoding: "utf-8",
maxBuffer: 1024 * 1024 * 2,
cwd: cwDir,
env: { ...process.env, D2_LSP_MODE: "1" },
});

// Pass error back to the client
if (proc.pid === 0) {
connection.window.showErrorMessage(
`Could not find D2 executable! Path: '${d2ExePath}'`
);
return;
}

if (proc.status !== 42) {
connection.window.showErrorMessage(
`Error (${proc.status}) from d2:\n${proc.stderr}\n`
);
}
// If d2 enters D2_LSP_MODE correctly, it will set it's
// exit code to '42'
if (proc.status !== 42) {
connection.window.showErrorMessage(
`Error (${proc.status}) from d2:\n${proc.stderr}\n`
);
}

// Reset Document Data and Parse out the json from the D2 program
astData = new AstReader(proc.stdout);
// astData.dump();
// Reset Document Data and Parse out the json from the D2 program
astData = new AstReader(proc.stdout);
// astData.dump();

/**
* Handle any errors.
*/
const eret = astData.Errors;
/**
* Handle any errors.
*/
const eret = astData.Errors;

// Clear Errors
connection.sendDiagnostics({ uri: change.document.uri, diagnostics: [] });
if (eret) {
eret.uri = change.document.uri;
connection.sendDiagnostics(eret);
// Clear Errors
connection.sendDiagnostics({ uri: change.document.uri, diagnostics: [] });
if (eret) {
eret.uri = change.document.uri;
connection.sendDiagnostics(eret);
}
}
});
);

/**
* If a trigger character is pressed, this is called
@@ -203,7 +209,7 @@ connection.onDocumentLinks((params: DocumentLinkParams): DocumentLink[] => {
const retLinks: DocumentLink[] = [];
const cwDir = URI.parse(path.dirname(params.textDocument.uri)).fsPath;

for (const link of astData.LinksAndImports) {
for (const link of astData?.LinksAndImports ?? []) {
link.resolvePath(cwDir);

const docLink = DocumentLink.create(link.linkRange.Range);
10 changes: 9 additions & 1 deletion server/src/utility.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
import { R_OK } from "constants";
import { accessSync, readdirSync, statSync } from "fs";
import path = require("path");
import { d2Extension } from "./server";
import { connection, d2Extension } from "./server";

/**
* Given a directory, finds all d2 files in that directory
@@ -44,6 +44,14 @@ export function getD2FilesFromPaths(dirs: string[], files: string[] = []): strin
return files;
}

export function GetFullExePath(): Promise<string> {
return new Promise((resolve, reject) => {
connection.workspace.getConfiguration("D2.execPath").then((result) => {
resolve(result);
});
});
}

/**
***********************
* END OF FILE
27 changes: 26 additions & 1 deletion syntaxes/d2.tmLanguage.json
Original file line number Diff line number Diff line change
@@ -3,6 +3,9 @@
"name": "d2",
"scopeName": "source.d2",
"patterns": [
{
"include": "#block_comment"
},
{
"include": "#comment"
},
@@ -423,6 +426,9 @@
"begin": "\\[",
"end": "\\]",
"patterns": [
{
"include": "#block_comment"
},
{
"include": "#comment"
},
@@ -516,7 +522,26 @@
},
"comment": {
"name": "comment.line.number-sign.d2",
"match": "#.*"
"match": "#.*$"
},
"block_comment": {
"patterns": [
{
"name": "comment.block.d2",
"begin": "\"\"\"",
"end": "\"\"\"",
"beginCaptures": {
"0": {
"name": "punctuation.comment.start.d2"
}
},
"endCaptures": {
"0": {
"name": "punctuation.comment.end.d2"
}
}
}
]
},
"debug": {
"patterns": [
12 changes: 10 additions & 2 deletions syntaxes/d2.tmLanguage.yaml
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ name: d2
scopeName: source.d2
patterns:
# - include: '#debug'
- include: "#block_comment"
- include: "#comment"
- include: "#semicolon"
- include: "#spread_substitution"
@@ -219,6 +220,7 @@ repository:
begin: '\['
end: '\]'
patterns:
- include: "#block_comment"
- include: "#comment"
- include: "#semicolon"
- include: "#substitution"
@@ -257,8 +259,14 @@ repository:
match: ";"
comment:
name: comment.line.number-sign.d2
match: "#.*"

match: "#.*$"
block_comment:
patterns:
- name: comment.block.d2
begin: '"""'
end: '"""'
beginCaptures: { 0: { name: punctuation.comment.start.d2 }}
endCaptures: { 0: { name: punctuation.comment.end.d2 }}
# See comment near top for debug's purpose.
debug:
patterns:
257 changes: 175 additions & 82 deletions yarn.lock

Large diffs are not rendered by default.