Skip to content

Commit 3c620b4

Browse files
committed
1 parent 908db35 commit 3c620b4

File tree

4 files changed

+140
-80
lines changed

4 files changed

+140
-80
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,11 @@
12491249
"default": true,
12501250
"markdownDescription": "Show inline `Debug this method` CodeLens action for ClassMethods."
12511251
},
1252+
"objectscript.debug.runThisMethod": {
1253+
"type": "boolean",
1254+
"default": true,
1255+
"markdownDescription": "Show inline `Run this method in terminal` CodeLens action for ClassMethods."
1256+
},
12521257
"objectscript.studioActionDebugOutput": {
12531258
"type": "boolean",
12541259
"default": false,

src/extension.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import { ObjectScriptDefinitionProvider } from "./providers/ObjectScriptDefiniti
5858
import { ObjectScriptFoldingRangeProvider } from "./providers/ObjectScriptFoldingRangeProvider";
5959
import { ObjectScriptHoverProvider } from "./providers/ObjectScriptHoverProvider";
6060
import { ObjectScriptRoutineSymbolProvider } from "./providers/ObjectScriptRoutineSymbolProvider";
61-
import { ObjectScriptClassCodeLensProvider } from "./providers/ObjectScriptClassCodeLensProvider";
61+
import { ObjectScriptCodeLensProvider } from "./providers/ObjectScriptCodeLensProvider";
6262
import { XmlContentProvider } from "./providers/XmlContentProvider";
6363

6464
import { AtelierAPI } from "./api";
@@ -705,9 +705,15 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
705705
Promise.all(files.map((file) => importFileOrFolder(file, true)))
706706
),
707707
vscode.commands.registerCommand("vscode-objectscript.export", exportAll),
708+
vscode.commands.registerCommand("vscode-objectscript.runInTerminal", (command: string) => {
709+
if (vscode.window.activeTerminal) {
710+
vscode.window.activeTerminal.sendText(command, false);
711+
vscode.window.activeTerminal.show();
712+
}
713+
}),
708714
vscode.commands.registerCommand("vscode-objectscript.debug", (program: string, askArgs: boolean) => {
709715
const startDebugging = (args) => {
710-
const programWithArgs = program + `(${args})`;
716+
const programWithArgs = program + (program.includes("##class") || args.length ? `(${args})` : "");
711717
vscode.debug.startDebugging(undefined, {
712718
type: "objectscript",
713719
request: "launch",
@@ -848,8 +854,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
848854
vscode.debug.registerDebugAdapterDescriptorFactory("objectscript", debugAdapterFactory),
849855
debugAdapterFactory,
850856
vscode.languages.registerCodeLensProvider(
851-
documentSelector("objectscript-class"),
852-
new ObjectScriptClassCodeLensProvider()
857+
documentSelector("objectscript-class", "objectscript"),
858+
new ObjectScriptCodeLensProvider()
853859
),
854860
vscode.commands.registerCommand("vscode-objectscript.compileOnly", () => compileOnly(false)),
855861
vscode.commands.registerCommand("vscode-objectscript.compileOnlyWithFlags", () => compileOnly(true)),
@@ -1013,6 +1019,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
10131019
}
10141020
}
10151021
}),
1022+
vscode.window.onDidOpenTerminal((t) => {
1023+
console.log("openTerminal", t);
1024+
}),
10161025
vscode.window.onDidCloseTerminal((t) => {
10171026
const terminalIndex = terminals.findIndex((terminal) => terminal.name == t.name);
10181027
if (terminalIndex > -1) {

src/providers/ObjectScriptClassCodeLensProvider.ts

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import * as vscode from "vscode";
2+
import { config } from "../extension";
3+
import { currentFile } from "../utils";
4+
5+
export class ObjectScriptCodeLensProvider implements vscode.CodeLensProvider {
6+
public provideCodeLenses(
7+
document: vscode.TextDocument,
8+
token: vscode.CancellationToken
9+
): vscode.ProviderResult<vscode.CodeLens[]> {
10+
const result = new Array<vscode.CodeLens>();
11+
12+
if (document.fileName.toLowerCase().endsWith(".cls")) {
13+
result.push(...this.classMethods(document));
14+
}
15+
if (document.fileName.toLowerCase().endsWith(".mac")) {
16+
result.push(...this.routineLabels(document));
17+
}
18+
return result;
19+
}
20+
21+
private classMethods(document: vscode.TextDocument): vscode.CodeLens[] {
22+
const file = currentFile(document);
23+
const result = new Array<vscode.CodeLens>();
24+
25+
if (!file.name.match(/\.cls$/i)) {
26+
return result;
27+
}
28+
const className = file.name.split(".").slice(0, -1).join(".");
29+
30+
const { debugThisMethod, runThisMethod } = config("debug");
31+
let inComment = false;
32+
for (let i = 0; i < document.lineCount; i++) {
33+
const line = document.lineAt(i);
34+
const text = this.stripLineComments(line.text);
35+
36+
if (text.match(/\/\*/)) {
37+
inComment = true;
38+
}
39+
40+
if (inComment) {
41+
if (text.match(/\*\//)) {
42+
inComment = false;
43+
}
44+
continue;
45+
}
46+
47+
const methodMatch = text.match(/(?<=^ClassMethod\s)([^(]+)(\(.)/i);
48+
if (methodMatch) {
49+
const [, name, parens] = methodMatch;
50+
51+
debugThisMethod && result.push(this.addDebugThisMethod(i, [`##class(${className}).${name}`, parens !== "()"]));
52+
runThisMethod && result.push(this.addRunThisMethod(i, [`Do ##class(${className}).${name}()`]));
53+
}
54+
}
55+
return result;
56+
}
57+
58+
private routineLabels(document: vscode.TextDocument): vscode.CodeLens[] {
59+
const file = currentFile(document);
60+
const result = new Array<vscode.CodeLens>();
61+
62+
if (!file.name.match(/\.mac$/i)) {
63+
return result;
64+
}
65+
const routineName = file.name.split(".").slice(0, -1).join(".");
66+
67+
const { debugThisMethod, runThisMethod } = config("debug");
68+
69+
debugThisMethod && result.push(this.addDebugThisMethod(0, [`^${routineName}`, false]));
70+
runThisMethod && result.push(this.addRunThisMethod(0, [`Do ^${routineName}`]));
71+
72+
let inComment = false;
73+
for (let i = 1; i < document.lineCount; i++) {
74+
const line = document.lineAt(i);
75+
const text = this.stripLineComments(line.text);
76+
77+
if (text.match(/\/\*/)) {
78+
inComment = true;
79+
}
80+
81+
if (inComment) {
82+
if (text.match(/\*\//)) {
83+
inComment = false;
84+
}
85+
continue;
86+
}
87+
88+
const labelMatch = text.match(/^(\w[^(\n\s]+)(?:\(([^)]*)\))?/i);
89+
if (labelMatch) {
90+
const [, name, parens] = labelMatch;
91+
92+
debugThisMethod && result.push(this.addDebugThisMethod(i, [`${name}^${routineName}`, parens !== "()"]));
93+
runThisMethod && result.push(this.addRunThisMethod(i, [`Do ${name}^${routineName}`]));
94+
}
95+
}
96+
97+
return result;
98+
}
99+
100+
private addDebugThisMethod(line: number, args: any[]) {
101+
return new vscode.CodeLens(new vscode.Range(line, 0, line, 80), {
102+
title: `Debug this method`,
103+
command: "vscode-objectscript.debug",
104+
arguments: args,
105+
});
106+
}
107+
108+
private addRunThisMethod(line: number, args: any[]) {
109+
return new vscode.CodeLens(new vscode.Range(line, 0, line, 80), {
110+
title: `Run this method in terminal`,
111+
command: "vscode-objectscript.runInTerminal",
112+
arguments: args,
113+
});
114+
}
115+
116+
private stripLineComments(text: string) {
117+
text = text.replace(/\/\/.*$/, "");
118+
text = text.replace(/#+;.*$/, "");
119+
text = text.replace(/;.*$/, "");
120+
return text;
121+
}
122+
}

0 commit comments

Comments
 (0)