@duet3d/monacotokens 3.7.0-alpha.1 → 3.7.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gcodeCNCLanguage = exports.gcodeFDMLanguage = void 0;
3
+ exports.gcodeLanguageConfiguration = exports.gcodeCNCLanguage = exports.gcodeFDMLanguage = void 0;
4
4
  /**
5
5
  * Generate a Monarch language for RRF-style G-code
6
6
  * @param cncMode If true, comments in parentheses are allowed
@@ -8,17 +8,26 @@ exports.gcodeCNCLanguage = exports.gcodeFDMLanguage = void 0;
8
8
  function generateMonarchLanguage(fdmMode) {
9
9
  return {
10
10
  consts: ["true", "false", "iterations", "line", "null", "pi", "result", "input"],
11
- functions: ["abs", "acos", "asin", "atan", "atan2", "cos", "degrees", "exists", "fileexists", "fileread", "floor", "isnan", "max",
12
- "min", "mod", "radians", "random", "sin", "square", "sqrt", "tan", "vector", "take", "drop", "find"],
13
- keywords: ["abort", "echo", "if", "elif", "while", "set"],
14
- noArgKeywords: ["else", "break", "continue"],
11
+ functions: ["abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "datetime", "degrees", "drop", "exists", "exp", "fileexists", "fileread",
12
+ "find", "floor", "isnan", "log", "max", "min", "mod", "pow", "radians", "random", "round", "sin", "sqrt", "square", "take", "tan", "vector"],
13
+ // Non-flow meta keywords that take an expression after (abort/echo/set) - render as regular keywords (blue)
14
+ keywords: ["abort", "echo", "set"],
15
+ // Flow-control keywords that take a condition/expression - render in Monaco's flow-keyword purple (matches VSCode)
16
+ flowExprKeywords: ["if", "elif", "while"],
17
+ // Flow-control keywords that stand alone - render in the same purple as flowExprKeywords
18
+ flowNoArgKeywords: ["else", "break", "continue"],
15
19
  varKeywords: ["global", "var"],
16
20
  symbols: /[=><!~?:&|+\-*#\/\^%]+/,
17
21
  operators: ['*', '/', '+', '-', "==", "!=", '=', "<=", '<', ">=", ">>>", ">>", '>', '!', "&&", '&', "||", '|', '^', '?', ':'],
18
22
  includeLF: true,
19
23
  tokenizer: {
20
24
  root: [
21
- // G/M/T-codes
25
+ // line numbers
26
+ [/[nN]\d+/, "type"],
27
+ // G53 acting as a same-line prefix (e.g. "G53 G1 X10") - highlight as a modifier, distinct from both
28
+ // line numbers (type) and regular codes (keyword)
29
+ [/[gG]53(?=[\s]+[gGmMtT][0-9-])/, "regexp", "afterG53"],
30
+ // G/M/T-codes (including bare G53 on its own line, which behaves like a regular command)
22
31
  [/[gG][0123](?=\D)/, "keyword", fdmMode ? "normalGcode" : "moveGcode"],
23
32
  [/[gGmM]\d+(\.\d+)?/, "keyword", "normalGcode"],
24
33
  [/[tT](?=\{)/, "keyword", "normalGcodeWithT"],
@@ -27,7 +36,8 @@ function generateMonarchLanguage(fdmMode) {
27
36
  [/[a-z_$][\w$]*/, {
28
37
  cases: {
29
38
  "@keywords": { token: "keyword", next: "@lineExpression" },
30
- "@noArgKeywords": { token: "keyword" },
39
+ "@flowExprKeywords": { token: "keyword.flow", next: "@lineExpression" },
40
+ "@flowNoArgKeywords": { token: "keyword.flow" },
31
41
  "@varKeywords": { token: "keyword", next: "varName" }
32
42
  }
33
43
  }],
@@ -37,18 +47,28 @@ function generateMonarchLanguage(fdmMode) {
37
47
  [/\d+/, "number"],
38
48
  // strings
39
49
  [/"(.|\"\")*?"/, "string"],
50
+ [/"[^"\n]*/, "invalid"],
40
51
  // comments
41
52
  [/;.*/, "comment"],
42
53
  [/\(.*\)/, fdmMode ? "invalid" : "comment"]
43
54
  ],
55
+ afterG53: [
56
+ // whitespace between the G53 prefix and the following G/M/T-code
57
+ [/[ \t]+/, ""],
58
+ // next G/M/T-code - replace this state with the code's own state so its parameters
59
+ // are parsed normally and any trailing T letters are treated as parameters, not T-codes
60
+ [/[gG][0123](?=\D)/, { token: "keyword", switchTo: fdmMode ? "@normalGcode" : "@moveGcode" }],
61
+ [/[gGmM]\d+(\.\d+)?/, { token: "keyword", switchTo: "@normalGcode" }],
62
+ [/[tT](?=\{)/, { token: "keyword", switchTo: "@normalGcodeWithT" }],
63
+ [/[tT]-?\d+/, { token: "keyword", switchTo: "@normalGcodeWithT" }]
64
+ ],
44
65
  gcode: [
45
- // next G/M/T-code
46
- [/[gG][0123](?=\D)/, "keyword", "moveGcode"],
47
- [/[gGmM]\d+(\.\d*)?/, "keyword", "normalGcode"],
48
- [/[tT](?=\{)/, "keyword", "normalGcodeWithT"],
49
- [/[tT]-?\d+/, "keyword", "normalGcodeWithT"],
66
+ // checksums
67
+ [/\*\d+/, "type"],
50
68
  // parameter letters
51
69
  [/'?[a-zA-Z]/, "keyword"],
70
+ // unterminated expression (no closing brace before end of line)
71
+ [/\{(?![^\n]*\})/, "invalid", "@unterminatedCurly"],
52
72
  // expressions
53
73
  [/{/, "operator", "@curlyBracket"],
54
74
  // enclosed comments
@@ -79,15 +99,30 @@ function generateMonarchLanguage(fdmMode) {
79
99
  expression: [
80
100
  // variables
81
101
  [/(global|param|var)\.[a-zA-Z_$][\w$]*/, "variable.name"],
82
- // object model properties
83
- [/\w+(\.\w+)*/, "variable"],
84
- // consts and functions
102
+ // Member access after `]` or any other punctuator (e.g. `fans[1].max`): always a property name,
103
+ // not a function call - so it must win over the function rule below even if the member name
104
+ // happens to match a function identifier (`max`, `min`, ...).
105
+ [/(\.)([a-zA-Z_$][\w$]*)/, ["delimiter", "variable"]],
106
+ // consts and functions need to match before the generic identifier rule below, otherwise
107
+ // `cos` / `pi` / etc. get consumed as plain variables and never reach this check
108
+ // `support.function` is the TextMate scope used by VSCode's Dark+/Light+ themes for built-in
109
+ // function calls; Monaco's default themes have no rule for it, so our `registerDuetLanguages`
110
+ // theme overrides are unambiguously applied (yellow #DCDCAA dark / #795E26 light).
85
111
  [/[a-z]\w*/, {
86
112
  cases: {
87
113
  "@consts": "constant",
88
- "@functions": "keyword"
114
+ "@functions": "support.function",
115
+ "@default": "variable"
89
116
  }
90
117
  }],
118
+ // object model properties with dotted paths (e.g. move.axes)
119
+ [/\w+(\.\w+)*/, "variable"],
120
+ // unterminated nested expressions
121
+ [/\{(?![^\n]*\})/, "invalid", "@unterminatedCurly"],
122
+ [/\[(?![^\n]*\])/, "invalid", "@unterminatedSquare"],
123
+ // unterminated nested expressions
124
+ [/\{(?![^\n]*\})/, "invalid", "@unterminatedCurly"],
125
+ [/\[(?![^\n]*\])/, "invalid", "@unterminatedSquare"],
91
126
  // nested expressions
92
127
  [/{/, "operator", "@curlyBracket"],
93
128
  [/\[/, "operator", "@squareBracket"],
@@ -97,6 +132,7 @@ function generateMonarchLanguage(fdmMode) {
97
132
  [/\d+/, "number"],
98
133
  // strings and chars
99
134
  [/"(.|\"\")*?"/, "string"],
135
+ [/"[^"\n]*/, "invalid"],
100
136
  [/'.'/, "string"],
101
137
  // operators
102
138
  [/@symbols/, {
@@ -117,20 +153,33 @@ function generateMonarchLanguage(fdmMode) {
117
153
  { include: "expression" }
118
154
  ],
119
155
  curlyBracket: [
156
+ // unterminated brace
157
+ [/\n/, "invalid", "@popall"],
120
158
  // curly brackets contain expressions
121
159
  { include: "expression" },
122
- // terminate whern reaching a closing bracket
160
+ // terminate when reaching a closing bracket
123
161
  [/}/, "operator", "@pop"],
124
162
  ],
125
163
  squareBracket: [
164
+ // unterminated bracket
165
+ [/\n/, "invalid", "@popall"],
126
166
  // square brackets contain expressions
127
167
  { include: "expression" },
128
- // terminate whern reaching a closing bracket
168
+ // terminate when reaching a closing bracket
129
169
  [/\]/, "operator", "@pop"],
130
170
  ],
171
+ unterminatedCurly: [
172
+ // color remainder of line as invalid, then pop
173
+ [/[^\n]+/, "invalid"],
174
+ [/\n/, "", "@popall"]
175
+ ],
176
+ unterminatedSquare: [
177
+ [/[^\n]+/, "invalid"],
178
+ [/\n/, "", "@popall"]
179
+ ],
131
180
  varName: [
132
- // variable name
133
- [/[a-zA-Z_$][\w$]*/, "variable.name", "@expression"],
181
+ // variable name being declared by `var` / `global` - render as a parameter so the name stands out from generic identifier colour
182
+ [/[a-zA-Z_$][\w$]*/, "variable.parameter", "@expression"],
134
183
  // EOL
135
184
  [/\n/, "", "@popall"]
136
185
  ]
@@ -139,3 +188,31 @@ function generateMonarchLanguage(fdmMode) {
139
188
  }
140
189
  exports.gcodeFDMLanguage = generateMonarchLanguage(true);
141
190
  exports.gcodeCNCLanguage = generateMonarchLanguage(false);
191
+ exports.gcodeLanguageConfiguration = {
192
+ comments: {
193
+ lineComment: ";"
194
+ },
195
+ brackets: [
196
+ ["{", "}"],
197
+ ["[", "]"],
198
+ ["(", ")"]
199
+ ],
200
+ autoClosingPairs: [
201
+ { open: "{", close: "}" },
202
+ { open: "[", close: "]" },
203
+ { open: "(", close: ")" },
204
+ { open: "\"", close: "\"" }
205
+ ],
206
+ surroundingPairs: [
207
+ { open: "{", close: "}" },
208
+ { open: "[", close: "]" },
209
+ { open: "(", close: ")" },
210
+ { open: "\"", close: "\"" }
211
+ ],
212
+ // Python-style block indentation: pressing Enter after if/elif/else/while indents the next line one level deeper
213
+ indentationRules: {
214
+ increaseIndentPattern: /^\s*(if|elif|else|while)\b.*$/,
215
+ // `elif|else` dedent so they align with the matching `if`; `break|continue` end the surrounding while-block
216
+ decreaseIndentPattern: /^\s*(elif|else|break|continue)\b.*$/
217
+ }
218
+ };
@@ -0,0 +1,3 @@
1
+ import type * as monaco from "monaco-editor/esm/vs/editor/editor.api";
2
+ export declare const menuLanguage: monaco.languages.IMonarchLanguage;
3
+ export declare const menuLanguageConfiguration: monaco.languages.LanguageConfiguration;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.menuLanguageConfiguration = exports.menuLanguage = void 0;
4
+ exports.menuLanguage = {
5
+ keywords: ["image", "text", "button", "value", "alter", "files"],
6
+ symbols: /[=><!~?:&|+\-*#\/\^%]+/,
7
+ operators: ['*', '/', '+', '-', "==", "!=", '=', "<=", '<', ">=", ">>>", ">>", '>', '!', "&&", '&', "||", '|', '^', '?', ':'],
8
+ includeLF: true,
9
+ tokenizer: {
10
+ root: [
11
+ // keywords
12
+ [/[a-z_$][\w$]*/, {
13
+ cases: {
14
+ "@keywords": { token: "keyword" }
15
+ }
16
+ }],
17
+ // numbers
18
+ [/\d*\.\d+([eE][\-+]?\d+)?/, "number.float"],
19
+ [/0[xX][0-9a-fA-F]+/, "number.hex"],
20
+ [/\d+/, "number"],
21
+ // strings
22
+ [/"(.|\"\")*?"/, "string"],
23
+ // comments
24
+ [/;.*/, "comment"],
25
+ // parameter letters
26
+ [/'?[A-Z]/, "keyword"],
27
+ [/'[a-z]/, "keyword"]
28
+ ]
29
+ }
30
+ };
31
+ exports.menuLanguageConfiguration = {
32
+ comments: {
33
+ lineComment: ";"
34
+ }
35
+ };
@@ -0,0 +1,3 @@
1
+ import type * as monaco from "monaco-editor/esm/vs/editor/editor.api";
2
+ export declare const stm32Language: monaco.languages.IMonarchLanguage;
3
+ export declare const stm32LanguageConfiguration: monaco.languages.LanguageConfiguration;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stm32LanguageConfiguration = exports.stm32Language = void 0;
4
+ exports.stm32Language = {
5
+ keywordsPrimary: ["8266wifi", "accelerometer", "atx", "board", "heat", "lcd", "led", "leds", "pins", "power", "sbc", "sdCard", "serial", "SPI0", "SPI1", "SPI2", "SPI3", "SPI4", "SPI5", "SPI6", "SPI7", "SPI8", "stepper"],
6
+ keywordsSecondary: ["clockReg", "csPin", "espDataReadyPin", "espResetPin", "TfrReadyPin", "serialRxTxPins", "spiChannel", "initialPowerOn", "powerPin", "powerPinInverted", "spiTempSensorChannel", "spiTempSensorCSPins", "tempSensePins", "thermistorSeriesResistor", "encoderPinA", "encoderPinB", "encoderPinSw", "lcdBeepPin", "lcdCSPin", "lcdDCPin", "panelButtonPin", "neopixelPin", "activity", "activityOn", "diagnostic", "diagnosticOn", "SetHigh", "SetLow", "VInDetectPin", "voltage", "loadConfig", "external", "internal", "aux", "aux2", "pins", "directionPins", "enablePins", "numSmartDrivers", "num5160Drivers", "stepPins", "TmcDiagPins", "TmcUartPins"],
7
+ keywordsTertiary: ["cardDetectPin", "csPin", "spiChannel", "spiFrequencyHz", "spiFrequencyHz", "rxTxPins", "rxTxPins"],
8
+ symbols: /[=><!~?:&|+\-*#\/\^%]+/,
9
+ operators: ['*', '/', '+', '-', "==", "!=", '=', "<=", '<', ">=", ">>>", ">>", '>', '!', "&&", '&', "||", '|', '^', '?', ':'],
10
+ includeLF: true,
11
+ tokenizer: {
12
+ root: [
13
+ // keywords
14
+ [/[a-zA-Z0-9_$][\w$]*/, {
15
+ cases: {
16
+ "@keywordsPrimary": { token: "keyword" },
17
+ "@keywordsSecondary": { token: "keyword" },
18
+ "@keywordsTertiary": { token: "keyword" }
19
+ }
20
+ }],
21
+ // comments
22
+ [/\/\/.*/, "comment"],
23
+ [/;.*/, "comment"],
24
+ // expressions
25
+ [/{/, "operator", "@curlyBracket"],
26
+ // expressions
27
+ [/=/, "operator", "@equals"],
28
+ ],
29
+ expression: [
30
+ // numbers
31
+ [/\d+/, "number"],
32
+ // Pin Numbers
33
+ [/[a-iA-I]\.\d+/, "string"],
34
+ [/[a-iA-I]\_\d+/, "string"],
35
+ [/[a-iA-I]\d+/, "string"],
36
+ [/P[a-iA-I]\.\d+/, "string"],
37
+ [/P[a-iA-I]\_\d+/, "string"],
38
+ [/P[a-iA-I]\d+/, "string"],
39
+ [/NoPin/, "string"],
40
+ // strings
41
+ [/"(.|\"\")*?"/, "string"],
42
+ [/[a-zA-Z0-9_$][\w$]*/, "string"],
43
+ // operators
44
+ [/@symbols/, {
45
+ cases: {
46
+ "@operators": "operator",
47
+ "@default": ""
48
+ }
49
+ }],
50
+ // comments
51
+ [/;.*/, "comment"],
52
+ // EOL
53
+ [/\n/, "", "@popall"],
54
+ ],
55
+ curlyBracket: [
56
+ // curly brackets contain expressions
57
+ { include: "expression" },
58
+ // terminate when reaching a closing bracket
59
+ [/}/, "operator", "@pop"],
60
+ ],
61
+ equals: [
62
+ // curly brackets contain expressions
63
+ { include: "expression" },
64
+ // EOL
65
+ [/\n/, "", "@popall"],
66
+ ]
67
+ }
68
+ };
69
+ exports.stm32LanguageConfiguration = {
70
+ comments: {
71
+ lineComment: ";"
72
+ },
73
+ brackets: [
74
+ ["{", "}"]
75
+ ],
76
+ autoClosingPairs: [
77
+ { open: "{", close: "}" },
78
+ { open: "\"", close: "\"" }
79
+ ],
80
+ surroundingPairs: [
81
+ { open: "{", close: "}" },
82
+ { open: "\"", close: "\"" }
83
+ ]
84
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Look up the deprecation message for a full object-model path (with literal numeric indices) or any of its
3
+ * prefixes. Returns the deprecation message when the path itself or a containing path is deprecated (the
4
+ * shallowest match wins so the user sees the root cause, e.g. `move.rotation.angle` reports `move.rotation`
5
+ * as deprecated). Returns null when neither the path nor any prefix is deprecated.
6
+ */
7
+ export declare function getPathDeprecation(path: string): string | null;
8
+ /**
9
+ * Look up the deprecation message for `parentPath + "." + field`. `parentPath` is the dotted path of the parent
10
+ * value from the root (e.g. `move.extruders[0]`), or empty for a top-level field. Returns null if not deprecated.
11
+ */
12
+ export declare function getMemberDeprecation(parentPath: string, field: string): string | null;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getPathDeprecation = getPathDeprecation;
7
+ exports.getMemberDeprecation = getMemberDeprecation;
8
+ const deprecations_json_1 = __importDefault(require("@duet3d/objectmodel/dist/deprecations.json"));
9
+ const paths_1 = require("./paths");
10
+ /**
11
+ * Map of full object-model paths (with `[]` standing for any array index) to the deprecation message extracted
12
+ * from the property's `@deprecated` JSDoc tag. Built by @duet3d/objectmodel's build script from its TS sources.
13
+ */
14
+ const deprecations = deprecations_json_1.default;
15
+ /**
16
+ * Look up the deprecation message for a full object-model path (with literal numeric indices) or any of its
17
+ * prefixes. Returns the deprecation message when the path itself or a containing path is deprecated (the
18
+ * shallowest match wins so the user sees the root cause, e.g. `move.rotation.angle` reports `move.rotation`
19
+ * as deprecated). Returns null when neither the path nor any prefix is deprecated.
20
+ */
21
+ function getPathDeprecation(path) {
22
+ if (!path) {
23
+ return null;
24
+ }
25
+ const key = (0, paths_1.normalisePath)(path);
26
+ // Walk prefixes from shallowest to deepest; first hit wins
27
+ let cursor = 0;
28
+ while (cursor < key.length) {
29
+ // Advance to the next boundary (dot or closing bracket that ends a step)
30
+ let next = key.indexOf(".", cursor);
31
+ if (next < 0) {
32
+ next = key.length;
33
+ }
34
+ const prefix = key.substring(0, next);
35
+ if (Object.prototype.hasOwnProperty.call(deprecations, prefix)) {
36
+ return deprecations[prefix];
37
+ }
38
+ cursor = next + 1;
39
+ }
40
+ return null;
41
+ }
42
+ /**
43
+ * Look up the deprecation message for `parentPath + "." + field`. `parentPath` is the dotted path of the parent
44
+ * value from the root (e.g. `move.extruders[0]`), or empty for a top-level field. Returns null if not deprecated.
45
+ */
46
+ function getMemberDeprecation(parentPath, field) {
47
+ const fullPath = parentPath ? `${parentPath}.${field}` : field;
48
+ return getPathDeprecation(fullPath);
49
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Return the list of valid values for a given object-model path, or null if the path has no known enum values.
3
+ */
4
+ export declare function getEnumValuesForPath(path: string): string[] | null;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getEnumValuesForPath = getEnumValuesForPath;
7
+ const enums_json_1 = __importDefault(require("@duet3d/objectmodel/dist/enums.json"));
8
+ const paths_1 = require("./paths");
9
+ /**
10
+ * Map of full object-model paths (with `[]` standing for any array index) to the list of valid enum / string-
11
+ * literal values the field can take. Generated by @duet3d/objectmodel's build script from its TS sources.
12
+ */
13
+ const enumValues = enums_json_1.default;
14
+ /**
15
+ * Return the list of valid values for a given object-model path, or null if the path has no known enum values.
16
+ */
17
+ function getEnumValuesForPath(path) {
18
+ if (!path) {
19
+ return null;
20
+ }
21
+ const key = (0, paths_1.normalisePath)(path);
22
+ return Object.prototype.hasOwnProperty.call(enumValues, key) ? enumValues[key] : null;
23
+ }
@@ -0,0 +1,33 @@
1
+ import type { ObjectModel } from "@duet3d/objectmodel";
2
+ /**
3
+ * Runtime context describing the currently connected machine. Completion and hover providers read this to surface
4
+ * machine-specific information (visible axes, configured extruders, object-model fields) alongside the static
5
+ * gcode/expression datasets bundled with this package.
6
+ *
7
+ * Framework-agnostic: Vue, React, or any other consumer just calls `setMachineContext` when its model reference
8
+ * becomes available or changes. The reference is expected to stay stable - providers read field values through
9
+ * the reference at completion time so state mutations inside the object model are picked up automatically.
10
+ */
11
+ export interface MachineContext {
12
+ /** Live machine object-model reference. */
13
+ readonly model: ObjectModel;
14
+ /**
15
+ * Optional callback that returns a Markdown/HTML description for an object-model path (with `[]` placeholders
16
+ * for collection items, e.g. `move.extruders[].pressureAdvance`). Used by the hover provider to surface the
17
+ * DuetAPI.xml documentation. Return `null` when no description is available. May be async - the hover provider
18
+ * awaits the result so callbacks can lazily fetch the docs on first hover without losing the popup.
19
+ */
20
+ readonly getObjectModelDescription?: (path: string) => string | null | Promise<string | null>;
21
+ }
22
+ /**
23
+ * Set (or clear) the runtime machine context. Pass `null` when the machine is disconnected.
24
+ */
25
+ export declare function setMachineContext(context: MachineContext | null): void;
26
+ /**
27
+ * Get the currently installed machine context, or null when no machine is connected.
28
+ */
29
+ export declare function getMachineContext(): MachineContext | null;
30
+ /**
31
+ * Subscribe to machine-context changes. Returns an unsubscribe function.
32
+ */
33
+ export declare function onMachineContextChange(listener: () => void): () => void;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setMachineContext = setMachineContext;
4
+ exports.getMachineContext = getMachineContext;
5
+ exports.onMachineContextChange = onMachineContextChange;
6
+ let current = null;
7
+ const listeners = new Set();
8
+ /**
9
+ * Set (or clear) the runtime machine context. Pass `null` when the machine is disconnected.
10
+ */
11
+ function setMachineContext(context) {
12
+ current = context;
13
+ for (const listener of listeners) {
14
+ try {
15
+ listener();
16
+ }
17
+ catch (e) {
18
+ // Listener threw - don't let it break other listeners
19
+ console.error("[monacotokens] machine-context listener threw:", e);
20
+ }
21
+ }
22
+ }
23
+ /**
24
+ * Get the currently installed machine context, or null when no machine is connected.
25
+ */
26
+ function getMachineContext() {
27
+ return current;
28
+ }
29
+ /**
30
+ * Subscribe to machine-context changes. Returns an unsubscribe function.
31
+ */
32
+ function onMachineContextChange(listener) {
33
+ listeners.add(listener);
34
+ return () => listeners.delete(listener);
35
+ }
@@ -0,0 +1,3 @@
1
+ /** Normalise a runtime object-model path (with literal numeric indices) to the lookup form used by
2
+ * the deprecations / enums maps, where `[]` stands in for any array index. */
3
+ export declare function normalisePath(path: string): string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalisePath = normalisePath;
4
+ /** Normalise a runtime object-model path (with literal numeric indices) to the lookup form used by
5
+ * the deprecations / enums maps, where `[]` stands in for any array index. */
6
+ function normalisePath(path) {
7
+ return path.replace(/\[\d+\]/g, "[]");
8
+ }
@@ -0,0 +1,55 @@
1
+ import type * as monaco from "monaco-editor/esm/vs/editor/editor.api";
2
+ export { getMachineContext, onMachineContextChange } from "./objectmodel/machine-context";
3
+ /**
4
+ * Flatten a machine object-model snapshot into a list of dotted paths (with `[0]` placeholders for arrays).
5
+ * Walks the entire reachable subtree; arrays contribute a single representative `[0]` entry so the list
6
+ * doesn't explode on machines with many tools/axes. Cycles are guarded via a visited WeakSet.
7
+ */
8
+ export declare function flattenObjectModel(root: any): string[];
9
+ /**
10
+ * Detect whether the cursor sits inside an RRF expression context:
11
+ * - inside a balanced-but-still-open `{ ... }` span, OR
12
+ * - after an `=` on a `set|var|global` line (whole line is expression territory), OR
13
+ * - after `if|elif|while` (condition is an expression).
14
+ */
15
+ export declare function isInsideExpression(beforeCursor: string): boolean;
16
+ /**
17
+ * Find the closest G/M/T-code to the left of `column` on the given line.
18
+ * Returns the matched code (e.g. "G1") and the column where it starts, or null.
19
+ *
20
+ * A bare `T` is only treated as its own code when it's the first code on the line; otherwise it's a parameter
21
+ * letter of the preceding command (e.g. `M104 T1` - the T belongs to M104, not a separate `T` code).
22
+ */
23
+ export declare function findCodeAtCursor(line: string, column: number): {
24
+ code: string;
25
+ startColumn: number;
26
+ } | null;
27
+ /**
28
+ * Register Duet-specific completion and hover providers for a language id.
29
+ */
30
+ export declare function registerProvidersFor(monacoInstance: typeof monaco, languageId: string): monaco.IDisposable[];
31
+ /**
32
+ * Register Duet completion and hover providers for both gcode-fdm and gcode-cnc languages.
33
+ */
34
+ export declare function registerDuetProviders(monacoInstance: typeof monaco): monaco.IDisposable[];
35
+ /**
36
+ * Attach a per-editor cursor-position watcher that closes the signature-help tooltip immediately when the cursor
37
+ * moves to a position where our provider would return null (between parameters, before the code, on a different line).
38
+ * Monaco only re-invokes the signature-help provider on content changes, so this bridges arrow-key / click movement.
39
+ * Call this once per editor right after `monaco.editor.create(...)`.
40
+ */
41
+ export declare function attachGcodeSignatureHelpWatcher(editor: monaco.editor.IStandaloneCodeEditor): monaco.IDisposable;
42
+ /**
43
+ * Apply a strikethrough decoration (class `duet-deprecated-code`) to every occurrence of a deprecated G/M/T-code
44
+ * (e.g. `M557`) and to every deprecated parameter letter belonging to any G/M/T-code on that line (e.g. the `S` in
45
+ * `M84 S`). Re-runs on every content change; hover tooltip carries the deprecation reason.
46
+ * Call once per editor; the returned IDisposable removes the listener and clears the decorations.
47
+ */
48
+ export declare function attachGcodeDeprecationDecorations(editor: monaco.editor.IStandaloneCodeEditor): monaco.IDisposable;
49
+ /**
50
+ * Strike-through deprecated object-model paths that appear in the editor. Matches dotted chains like
51
+ * `move.extruders[0].pressureAdvance`, normalises the bracket indices to `[]`, and highlights the chain if
52
+ * the normalised path is present in the deprecations map shipped by @duet3d/objectmodel. Re-runs on every
53
+ * content change; hover tooltip carries the deprecation reason.
54
+ */
55
+ export declare function attachObjectModelDeprecationDecorations(editor: monaco.editor.IStandaloneCodeEditor): monaco.IDisposable;