Skip to content

Commit 92f28d5

Browse files
author
WebFreak001
committed
Added syntax highlighting & auto completion for DlangUI Markup Language
1 parent c3143b2 commit 92f28d5

6 files changed

Lines changed: 275 additions & 38 deletions

File tree

package.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"name": "code-d",
33
"description": "auto-complete, snippets, linter and formatter for dlang",
4-
"version": "0.6.0",
4+
"version": "0.7.0",
55
"publisher": "webfreak",
66
"repository": {
77
"type": "git",
8-
"url": "https://github.com/WebFreak001/code-d.git"
8+
"url": "https://github.com/Pure-D/code-d.git"
99
},
1010
"engines": {
1111
"vscode": "^0.10.1"
@@ -35,6 +35,15 @@
3535
"D"
3636
]
3737
},
38+
{
39+
"id": "dml",
40+
"aliases": [
41+
"DlangUI Markup Language"
42+
],
43+
"extensions": [
44+
".dml"
45+
]
46+
},
3847
{
3948
"id": "jade",
4049
"aliases": [
@@ -50,6 +59,11 @@
5059
"language": "d",
5160
"scopeName": "source.d",
5261
"path": "./syntaxes/d.json"
62+
},
63+
{
64+
"language": "dml",
65+
"scopeName": "source.dml",
66+
"path": "./syntaxes/dml.json"
5367
}
5468
],
5569
"snippets": [

src/dlangui.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as vscode from "vscode"
2+
import { WorkspaceD } from "./workspace-d"
3+
4+
export class DlangUIHandler implements vscode.CompletionItemProvider {
5+
constructor(public workspaced: WorkspaceD) {
6+
}
7+
8+
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable<vscode.CompletionItem[]> {
9+
let self = this.workspaced;
10+
console.log("provideCompletionItems(DlangUI)");
11+
return new Promise((resolve, reject) => {
12+
if (!self.dlanguiReady)
13+
return resolve(null);
14+
let offset = document.offsetAt(position);
15+
self.request({ cmd: "dlangui", subcmd: "list-completion", code: document.getText(), pos: offset }).then((completions) => {
16+
let items: vscode.CompletionItem[] = [];
17+
completions.forEach(item => {
18+
let i = new vscode.CompletionItem(item.value);
19+
i.kind = mapCompletionType(item.type);
20+
items.push(i);
21+
});
22+
console.log("resolve");
23+
console.log(items);
24+
resolve(items);
25+
}, reject);
26+
});
27+
}
28+
}
29+
30+
function mapCompletionType(type: number): vscode.CompletionItemKind {
31+
if (type == 1)
32+
return vscode.CompletionItemKind.Class;
33+
else if (type == 2)
34+
return vscode.CompletionItemKind.Property;
35+
else
36+
return vscode.CompletionItemKind.Text;
37+
}

src/dmode.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
import vscode = require("vscode");
22

3-
export const D_MODE: vscode.DocumentFilter = { language: "d", scheme: "file" }
3+
export const D_MODE: vscode.DocumentFilter = { language: "d", scheme: "file" }
4+
export const DML_MODE: vscode.DocumentFilter = { language: "dml", scheme: "file" }

src/extension.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as vscode from 'vscode';
2-
import { D_MODE } from "./dmode"
2+
import { D_MODE, DML_MODE } from "./dmode"
33
import { WorkspaceD } from "./workspace-d"
44
import { CompileButtons } from "./compile-buttons"
55
import { uploadCode } from "./util"
66
import * as statusbar from "./statusbar"
77
import * as path from "path"
8+
import { DlangUIHandler } from "./dlangui"
89

910
let diagnosticCollection: vscode.DiagnosticCollection;
1011

@@ -14,17 +15,20 @@ function config() {
1415

1516
export function activate(context: vscode.ExtensionContext) {
1617
if (!vscode.workspace.rootPath) {
17-
console.warn("Could not initialize code-d");
18+
console.warn("code-d requires a folder to be open to work");
1819
return;
1920
}
2021

2122
let workspaced = new WorkspaceD(vscode.workspace.rootPath);
23+
context.subscriptions.push(vscode.languages.registerCompletionItemProvider(DML_MODE, workspaced.getDlangUI()));
24+
25+
context.subscriptions.push(vscode.languages.registerCompletionItemProvider(D_MODE, workspaced, "."));
2226
context.subscriptions.push(vscode.languages.registerSignatureHelpProvider(D_MODE, workspaced, "(", ","));
23-
context.subscriptions.push(vscode.languages.registerCompletionItemProvider(D_MODE, workspaced));
2427
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(D_MODE, workspaced));
2528
context.subscriptions.push(vscode.languages.registerHoverProvider(D_MODE, workspaced));
2629
context.subscriptions.push(vscode.languages.registerDefinitionProvider(D_MODE, workspaced));
2730
context.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider(D_MODE, workspaced));
31+
2832
context.subscriptions.push(workspaced);
2933

3034
context.subscriptions.push(statusbar.setup(workspaced));
@@ -51,6 +55,39 @@ export function activate(context: vscode.ExtensionContext) {
5155
}
5256
});
5357

58+
vscode.languages.setLanguageConfiguration(DML_MODE.language, {
59+
__electricCharacterSupport: {
60+
brackets: [
61+
{ tokenType: 'delimiter.curly.ts', open: '{', close: '}', isElectric: true },
62+
{ tokenType: 'delimiter.square.ts', open: '[', close: ']', isElectric: true },
63+
{ tokenType: 'delimiter.paren.ts', open: '(', close: ')', isElectric: true }
64+
]
65+
},
66+
67+
__characterPairSupport: {
68+
autoClosingPairs: [
69+
{ open: '{', close: '}' },
70+
{ open: '[', close: ']' },
71+
{ open: '(', close: ')' },
72+
{ open: '`', close: '`', notIn: ['string'] },
73+
{ open: '"', close: '"', notIn: ['string'] },
74+
{ open: '\'', close: '\'', notIn: ['string', 'comment'] }
75+
]
76+
},
77+
78+
indentationRules: {
79+
decreaseIndentPattern: /\}/,
80+
increaseIndentPattern: /\{/
81+
},
82+
83+
wordPattern: /[a-zA-Z_][a-zA-Z0-9_]*/g,
84+
85+
brackets: [
86+
['{', '}'],
87+
['[', ']'],
88+
['(', ')'],
89+
]
90+
});
5491

5592
context.subscriptions.push(vscode.languages.registerWorkspaceSymbolProvider(workspaced));
5693

@@ -93,7 +130,7 @@ export function activate(context: vscode.ExtensionContext) {
93130
}));
94131

95132
context.subscriptions.push(vscode.commands.registerCommand("code-d.uploadSelection", () => {
96-
if(vscode.window.activeTextEditor.selection.isEmpty)
133+
if (vscode.window.activeTextEditor.selection.isEmpty)
97134
vscode.window.showErrorMessage("No code selected");
98135
else {
99136
let code = vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection);

src/workspace-d.ts

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import * as ChildProcess from "child_process"
22
import * as vscode from "vscode"
33
import * as path from "path"
44
import { EventEmitter } from "events"
5+
import { DlangUIHandler } from "./dlangui"
56

67
function config() {
78
return vscode.workspace.getConfiguration("d");
89
}
910

10-
const TARGET_VERSION = [2, 2, 0];
11+
const TARGET_VERSION = [2, 3, 0];
1112

1213
export class WorkspaceD extends EventEmitter implements
1314
vscode.CompletionItemProvider,
@@ -17,7 +18,7 @@ export class WorkspaceD extends EventEmitter implements
1718
vscode.DefinitionProvider,
1819
vscode.DocumentFormattingEditProvider,
1920
vscode.HoverProvider {
20-
constructor(private projectRoot: string) {
21+
constructor(public projectRoot: string) {
2122
super();
2223
let self = this;
2324
this.on("error", function(err) {
@@ -384,7 +385,11 @@ export class WorkspaceD extends EventEmitter implements
384385
});
385386
}
386387

387-
private mapLintType(type: string): vscode.DiagnosticSeverity {
388+
getDlangUI(): DlangUIHandler {
389+
return new DlangUIHandler(this);
390+
}
391+
392+
public mapLintType(type: string): vscode.DiagnosticSeverity {
388393
switch (type) {
389394
case "warn":
390395
return vscode.DiagnosticSeverity.Warning;
@@ -394,7 +399,7 @@ export class WorkspaceD extends EventEmitter implements
394399
}
395400
}
396401

397-
private mapDubLintType(type: number): vscode.DiagnosticSeverity {
402+
public mapDubLintType(type: number): vscode.DiagnosticSeverity {
398403
switch (type) {
399404
case 2:
400405
return vscode.DiagnosticSeverity.Information;
@@ -406,21 +411,21 @@ export class WorkspaceD extends EventEmitter implements
406411
}
407412
}
408413

409-
private checkVersion() {
414+
public checkVersion() {
410415
this.request({ cmd: "version" }).then(version => {
411416
if (version.major < TARGET_VERSION[0])
412-
return vscode.window.showErrorMessage("workspace-d is outdated! (target=" + formatVersion(TARGET_VERSION) + ", workspaced=" + formatVersion([version.major, version.minor, version.patch]) + ")");
413-
if (version.minor < TARGET_VERSION[1])
414-
return vscode.window.showErrorMessage("workspace-d is outdated! (target=" + formatVersion(TARGET_VERSION) + ", workspaced=" + formatVersion([version.major, version.minor, version.patch]) + ")");
415-
if (version.path < TARGET_VERSION[2])
416-
return vscode.window.showErrorMessage("workspace-d is outdated! (target=" + formatVersion(TARGET_VERSION) + ", workspaced=" + formatVersion([version.major, version.minor, version.patch]) + ")");
417+
return vscode.window.showErrorMessage("workspace-d is outdated! Please update to continue using this plugin. (target=" + formatVersion(TARGET_VERSION) + ", workspaced=" + formatVersion([version.major, version.minor, version.patch]) + ")");
418+
if (version.major == TARGET_VERSION[0] && version.minor < TARGET_VERSION[1])
419+
vscode.window.showWarningMessage("workspace-d might be outdated! Please update if things are not working as expected. (target=" + formatVersion(TARGET_VERSION) + ", workspaced=" + formatVersion([version.major, version.minor, version.patch]) + ")");
420+
if (version.major == TARGET_VERSION[0] && version.minor == TARGET_VERSION[1] && version.path < TARGET_VERSION[2])
421+
vscode.window.showInformationMessage("workspace-d has a new optional update! Please update before submitting a bug report. (target=" + formatVersion(TARGET_VERSION) + ", workspaced=" + formatVersion([version.major, version.minor, version.patch]) + ")");
417422
this.setupDub();
418423
}, () => {
419424
vscode.window.showErrorMessage("Could not identify workspace-d version. Please update workspace-d!");
420425
});
421426
}
422427

423-
private setupDub() {
428+
public setupDub() {
424429
let self = this;
425430
this.request({ cmd: "load", components: ["dub"], dir: this.projectRoot }).then((data) => {
426431
console.log("dub is ready");
@@ -429,6 +434,7 @@ export class WorkspaceD extends EventEmitter implements
429434
self.setupDCD();
430435
self.setupDScanner();
431436
self.setupDfmt();
437+
self.setupDlangUI();
432438
self.listConfigurations().then((configs) => {
433439
if (configs.length == 0) {
434440
vscode.window.showInformationMessage("No configurations available for this project. Autocompletion could be broken!");
@@ -441,7 +447,7 @@ export class WorkspaceD extends EventEmitter implements
441447
});
442448
}
443449

444-
private setupDScanner() {
450+
public setupDScanner() {
445451
let self = this;
446452
this.request({ cmd: "load", components: ["dscanner"], dir: this.projectRoot, dscannerPath: config().get("dscannerPath", "dscanner") }).then((data) => {
447453
console.log("DScanner is ready");
@@ -450,7 +456,7 @@ export class WorkspaceD extends EventEmitter implements
450456
});
451457
}
452458

453-
private setupDCD() {
459+
public setupDCD() {
454460
if (config().get("enableAutoComplete", true))
455461
this.request({
456462
cmd: "load",
@@ -466,7 +472,7 @@ export class WorkspaceD extends EventEmitter implements
466472
});
467473
}
468474

469-
private setupDfmt() {
475+
public setupDfmt() {
470476
let self = this;
471477
this.request({ cmd: "load", components: ["dfmt"], dir: this.projectRoot, dfmtPath: config().get("dfmtPath", "dfmt") }).then((data) => {
472478
console.log("Dfmt is ready");
@@ -475,7 +481,16 @@ export class WorkspaceD extends EventEmitter implements
475481
});
476482
}
477483

478-
private ensureDCDRunning() {
484+
public setupDlangUI() {
485+
let self = this;
486+
this.request({ cmd: "load", components: ["dlangui"] }).then((data) => {
487+
console.log("DlangUI is ready");
488+
self.emit("dlangui-ready");
489+
self.dlanguiReady = true;
490+
});
491+
}
492+
493+
public ensureDCDRunning() {
479494
if (!this.dcdReady)
480495
return;
481496
if (!this.shouldRestart)
@@ -494,7 +509,7 @@ export class WorkspaceD extends EventEmitter implements
494509
}).bind(this), 500);
495510
}
496511

497-
private startDCD() {
512+
public startDCD() {
498513
this.request({
499514
cmd: "dcd",
500515
subcmd: "find-and-select-port",
@@ -516,7 +531,7 @@ export class WorkspaceD extends EventEmitter implements
516531
});
517532
}
518533

519-
private request(data): Thenable<any> {
534+
public request(data): Thenable<any> {
520535
let lengthBuffer = new Buffer(4);
521536
let idBuffer = new Buffer(4);
522537
let dataStr = JSON.stringify(data);
@@ -536,12 +551,12 @@ export class WorkspaceD extends EventEmitter implements
536551
});
537552
}
538553

539-
private handleData(chunk) {
554+
public handleData(chunk) {
540555
this.totalData = Buffer.concat([this.totalData, chunk]);
541556
while (this.handleChunks());
542557
}
543558

544-
private handleChunks() {
559+
public handleChunks() {
545560
if (this.totalData.length < 8)
546561
return false;
547562
let len = this.totalData.readInt32BE(0);
@@ -564,17 +579,18 @@ export class WorkspaceD extends EventEmitter implements
564579
return false;
565580
}
566581

567-
private runCheckTimeout = -1;
568-
private workspaced: boolean = true;
569-
private dubReady: boolean = false;
570-
private dcdReady: boolean = false;
571-
private dfmtReady: boolean = false;
572-
private dscannerReady: boolean = false;
573-
private shouldRestart: boolean = true;
574-
private totalData: Buffer;
575-
private requestNum = 0;
576-
private instance: ChildProcess.ChildProcess;
577-
private scanTypes = {
582+
public runCheckTimeout = -1;
583+
public workspaced: boolean = true;
584+
public dubReady: boolean = false;
585+
public dcdReady: boolean = false;
586+
public dfmtReady: boolean = false;
587+
public dlanguiReady: boolean = false;
588+
public dscannerReady: boolean = false;
589+
public shouldRestart: boolean = true;
590+
public totalData: Buffer;
591+
public requestNum = 0;
592+
public instance: ChildProcess.ChildProcess;
593+
public scanTypes = {
578594
g: vscode.SymbolKind.Enum,
579595
e: vscode.SymbolKind.Field,
580596
v: vscode.SymbolKind.Variable,
@@ -586,7 +602,7 @@ export class WorkspaceD extends EventEmitter implements
586602
T: vscode.SymbolKind.Property,
587603
a: vscode.SymbolKind.Field
588604
};
589-
private types = {
605+
public types = {
590606
c: vscode.CompletionItemKind.Class,
591607
i: vscode.CompletionItemKind.Interface,
592608
s: vscode.CompletionItemKind.Unit,

0 commit comments

Comments
 (0)