@duet3d/monacotokens 3.6.1 → 3.7.0-alpha.10

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,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gcodeCNCLanguage = exports.gcodeFDMLanguage = void 0;
4
1
  /**
5
2
  * Generate a Monarch language for RRF-style G-code
6
3
  * @param cncMode If true, comments in parentheses are allowed
@@ -8,17 +5,26 @@ exports.gcodeCNCLanguage = exports.gcodeFDMLanguage = void 0;
8
5
  function generateMonarchLanguage(fdmMode) {
9
6
  return {
10
7
  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"],
8
+ functions: ["abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "datetime", "degrees", "drop", "exists", "exp", "fileexists", "fileread",
9
+ "find", "floor", "isnan", "log", "max", "min", "mod", "pow", "radians", "random", "round", "sin", "sqrt", "square", "take", "tan", "vector"],
10
+ // Non-flow meta keywords that take an expression after (abort/echo/set) - render as regular keywords (blue)
11
+ keywords: ["abort", "echo", "set"],
12
+ // Flow-control keywords that take a condition/expression - render in Monaco's flow-keyword purple (matches VSCode)
13
+ flowExprKeywords: ["if", "elif", "while"],
14
+ // Flow-control keywords that stand alone - render in the same purple as flowExprKeywords
15
+ flowNoArgKeywords: ["else", "break", "continue"],
15
16
  varKeywords: ["global", "var"],
16
17
  symbols: /[=><!~?:&|+\-*#\/\^%]+/,
17
18
  operators: ['*', '/', '+', '-', "==", "!=", '=', "<=", '<', ">=", ">>>", ">>", '>', '!', "&&", '&', "||", '|', '^', '?', ':'],
18
19
  includeLF: true,
19
20
  tokenizer: {
20
21
  root: [
21
- // G/M/T-codes
22
+ // line numbers
23
+ [/[nN]\d+/, "type"],
24
+ // G53 acting as a same-line prefix (e.g. "G53 G1 X10") - highlight as a modifier, distinct from both
25
+ // line numbers (type) and regular codes (keyword)
26
+ [/[gG]53(?=[\s]+[gGmMtT][0-9-])/, "regexp", "afterG53"],
27
+ // G/M/T-codes (including bare G53 on its own line, which behaves like a regular command)
22
28
  [/[gG][0123](?=\D)/, "keyword", fdmMode ? "normalGcode" : "moveGcode"],
23
29
  [/[gGmM]\d+(\.\d+)?/, "keyword", "normalGcode"],
24
30
  [/[tT](?=\{)/, "keyword", "normalGcodeWithT"],
@@ -27,7 +33,8 @@ function generateMonarchLanguage(fdmMode) {
27
33
  [/[a-z_$][\w$]*/, {
28
34
  cases: {
29
35
  "@keywords": { token: "keyword", next: "@lineExpression" },
30
- "@noArgKeywords": { token: "keyword" },
36
+ "@flowExprKeywords": { token: "keyword.flow", next: "@lineExpression" },
37
+ "@flowNoArgKeywords": { token: "keyword.flow" },
31
38
  "@varKeywords": { token: "keyword", next: "varName" }
32
39
  }
33
40
  }],
@@ -37,18 +44,28 @@ function generateMonarchLanguage(fdmMode) {
37
44
  [/\d+/, "number"],
38
45
  // strings
39
46
  [/"(.|\"\")*?"/, "string"],
47
+ [/"[^"\n]*/, "invalid"],
40
48
  // comments
41
49
  [/;.*/, "comment"],
42
50
  [/\(.*\)/, fdmMode ? "invalid" : "comment"]
43
51
  ],
52
+ afterG53: [
53
+ // whitespace between the G53 prefix and the following G/M/T-code
54
+ [/[ \t]+/, ""],
55
+ // next G/M/T-code - replace this state with the code's own state so its parameters
56
+ // are parsed normally and any trailing T letters are treated as parameters, not T-codes
57
+ [/[gG][0123](?=\D)/, { token: "keyword", switchTo: fdmMode ? "@normalGcode" : "@moveGcode" }],
58
+ [/[gGmM]\d+(\.\d+)?/, { token: "keyword", switchTo: "@normalGcode" }],
59
+ [/[tT](?=\{)/, { token: "keyword", switchTo: "@normalGcodeWithT" }],
60
+ [/[tT]-?\d+/, { token: "keyword", switchTo: "@normalGcodeWithT" }]
61
+ ],
44
62
  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"],
63
+ // checksums
64
+ [/\*\d+/, "type"],
50
65
  // parameter letters
51
66
  [/'?[a-zA-Z]/, "keyword"],
67
+ // unterminated expression (no closing brace before end of line)
68
+ [/\{(?![^\n]*\})/, "invalid", "@unterminatedCurly"],
52
69
  // expressions
53
70
  [/{/, "operator", "@curlyBracket"],
54
71
  // enclosed comments
@@ -79,15 +96,30 @@ function generateMonarchLanguage(fdmMode) {
79
96
  expression: [
80
97
  // variables
81
98
  [/(global|param|var)\.[a-zA-Z_$][\w$]*/, "variable.name"],
82
- // object model properties
83
- [/\w+(\.\w+)*/, "variable"],
84
- // consts and functions
99
+ // Member access after `]` or any other punctuator (e.g. `fans[1].max`): always a property name,
100
+ // not a function call - so it must win over the function rule below even if the member name
101
+ // happens to match a function identifier (`max`, `min`, ...).
102
+ [/(\.)([a-zA-Z_$][\w$]*)/, ["delimiter", "variable"]],
103
+ // consts and functions need to match before the generic identifier rule below, otherwise
104
+ // `cos` / `pi` / etc. get consumed as plain variables and never reach this check
105
+ // `support.function` is the TextMate scope used by VSCode's Dark+/Light+ themes for built-in
106
+ // function calls; Monaco's default themes have no rule for it, so our `registerDuetLanguages`
107
+ // theme overrides are unambiguously applied (yellow #DCDCAA dark / #795E26 light).
85
108
  [/[a-z]\w*/, {
86
109
  cases: {
87
110
  "@consts": "constant",
88
- "@functions": "keyword"
111
+ "@functions": "support.function",
112
+ "@default": "variable"
89
113
  }
90
114
  }],
115
+ // object model properties with dotted paths (e.g. move.axes)
116
+ [/\w+(\.\w+)*/, "variable"],
117
+ // unterminated nested expressions
118
+ [/\{(?![^\n]*\})/, "invalid", "@unterminatedCurly"],
119
+ [/\[(?![^\n]*\])/, "invalid", "@unterminatedSquare"],
120
+ // unterminated nested expressions
121
+ [/\{(?![^\n]*\})/, "invalid", "@unterminatedCurly"],
122
+ [/\[(?![^\n]*\])/, "invalid", "@unterminatedSquare"],
91
123
  // nested expressions
92
124
  [/{/, "operator", "@curlyBracket"],
93
125
  [/\[/, "operator", "@squareBracket"],
@@ -97,6 +129,7 @@ function generateMonarchLanguage(fdmMode) {
97
129
  [/\d+/, "number"],
98
130
  // strings and chars
99
131
  [/"(.|\"\")*?"/, "string"],
132
+ [/"[^"\n]*/, "invalid"],
100
133
  [/'.'/, "string"],
101
134
  // operators
102
135
  [/@symbols/, {
@@ -117,25 +150,66 @@ function generateMonarchLanguage(fdmMode) {
117
150
  { include: "expression" }
118
151
  ],
119
152
  curlyBracket: [
153
+ // unterminated brace
154
+ [/\n/, "invalid", "@popall"],
120
155
  // curly brackets contain expressions
121
156
  { include: "expression" },
122
- // terminate whern reaching a closing bracket
157
+ // terminate when reaching a closing bracket
123
158
  [/}/, "operator", "@pop"],
124
159
  ],
125
160
  squareBracket: [
161
+ // unterminated bracket
162
+ [/\n/, "invalid", "@popall"],
126
163
  // square brackets contain expressions
127
164
  { include: "expression" },
128
- // terminate whern reaching a closing bracket
165
+ // terminate when reaching a closing bracket
129
166
  [/\]/, "operator", "@pop"],
130
167
  ],
168
+ unterminatedCurly: [
169
+ // color remainder of line as invalid, then pop
170
+ [/[^\n]+/, "invalid"],
171
+ [/\n/, "", "@popall"]
172
+ ],
173
+ unterminatedSquare: [
174
+ [/[^\n]+/, "invalid"],
175
+ [/\n/, "", "@popall"]
176
+ ],
131
177
  varName: [
132
- // variable name
133
- [/[a-zA-Z_$][\w$]*/, "variable.name", "@expression"],
178
+ // variable name being declared by `var` / `global` - render as a parameter so the name stands out from generic identifier colour
179
+ [/[a-zA-Z_$][\w$]*/, "variable.parameter", "@expression"],
134
180
  // EOL
135
181
  [/\n/, "", "@popall"]
136
182
  ]
137
183
  }
138
184
  };
139
185
  }
140
- exports.gcodeFDMLanguage = generateMonarchLanguage(true);
141
- exports.gcodeCNCLanguage = generateMonarchLanguage(false);
186
+ export const gcodeFDMLanguage = generateMonarchLanguage(true);
187
+ export const gcodeCNCLanguage = generateMonarchLanguage(false);
188
+ export const gcodeLanguageConfiguration = {
189
+ comments: {
190
+ lineComment: ";"
191
+ },
192
+ brackets: [
193
+ ["{", "}"],
194
+ ["[", "]"],
195
+ ["(", ")"]
196
+ ],
197
+ autoClosingPairs: [
198
+ { open: "{", close: "}" },
199
+ { open: "[", close: "]" },
200
+ { open: "(", close: ")" },
201
+ { open: "\"", close: "\"" }
202
+ ],
203
+ surroundingPairs: [
204
+ { open: "{", close: "}" },
205
+ { open: "[", close: "]" },
206
+ { open: "(", close: ")" },
207
+ { open: "\"", close: "\"" }
208
+ ],
209
+ // Python-style block indentation: pressing Enter after if/elif/else/while indents the next line one level deeper
210
+ indentationRules: {
211
+ increaseIndentPattern: /^\s*(if|elif|else|while)\b.*$/,
212
+ // `elif|else` dedent so they align with the matching `if`; `break|continue` end the surrounding while-block
213
+ decreaseIndentPattern: /^\s*(elif|else|break|continue)\b.*$/
214
+ }
215
+ };
@@ -0,0 +1,3 @@
1
+ import type * as monaco from "monaco-editor-core/esm/vs/editor/editor.api.js";
2
+ export declare const menuLanguage: monaco.languages.IMonarchLanguage;
3
+ export declare const menuLanguageConfiguration: monaco.languages.LanguageConfiguration;
@@ -0,0 +1,32 @@
1
+ export const menuLanguage = {
2
+ keywords: ["image", "text", "button", "value", "alter", "files"],
3
+ symbols: /[=><!~?:&|+\-*#\/\^%]+/,
4
+ operators: ['*', '/', '+', '-', "==", "!=", '=', "<=", '<', ">=", ">>>", ">>", '>', '!', "&&", '&', "||", '|', '^', '?', ':'],
5
+ includeLF: true,
6
+ tokenizer: {
7
+ root: [
8
+ // keywords
9
+ [/[a-z_$][\w$]*/, {
10
+ cases: {
11
+ "@keywords": { token: "keyword" }
12
+ }
13
+ }],
14
+ // numbers
15
+ [/\d*\.\d+([eE][\-+]?\d+)?/, "number.float"],
16
+ [/0[xX][0-9a-fA-F]+/, "number.hex"],
17
+ [/\d+/, "number"],
18
+ // strings
19
+ [/"(.|\"\")*?"/, "string"],
20
+ // comments
21
+ [/;.*/, "comment"],
22
+ // parameter letters
23
+ [/'?[A-Z]/, "keyword"],
24
+ [/'[a-z]/, "keyword"]
25
+ ]
26
+ }
27
+ };
28
+ export const menuLanguageConfiguration = {
29
+ comments: {
30
+ lineComment: ";"
31
+ }
32
+ };
@@ -0,0 +1,3 @@
1
+ import type * as monaco from "monaco-editor-core/esm/vs/editor/editor.api.js";
2
+ export declare const stm32Language: monaco.languages.IMonarchLanguage;
3
+ export declare const stm32LanguageConfiguration: monaco.languages.LanguageConfiguration;
@@ -0,0 +1,81 @@
1
+ export const stm32Language = {
2
+ keywordsPrimary: ["8266wifi", "accelerometer", "atx", "board", "heat", "lcd", "led", "leds", "pins", "power", "sbc", "sdCard", "serial", "SPI0", "SPI1", "SPI2", "SPI3", "SPI4", "SPI5", "SPI6", "SPI7", "SPI8", "stepper"],
3
+ 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"],
4
+ keywordsTertiary: ["cardDetectPin", "csPin", "spiChannel", "spiFrequencyHz", "spiFrequencyHz", "rxTxPins", "rxTxPins"],
5
+ symbols: /[=><!~?:&|+\-*#\/\^%]+/,
6
+ operators: ['*', '/', '+', '-', "==", "!=", '=', "<=", '<', ">=", ">>>", ">>", '>', '!', "&&", '&', "||", '|', '^', '?', ':'],
7
+ includeLF: true,
8
+ tokenizer: {
9
+ root: [
10
+ // keywords
11
+ [/[a-zA-Z0-9_$][\w$]*/, {
12
+ cases: {
13
+ "@keywordsPrimary": { token: "keyword" },
14
+ "@keywordsSecondary": { token: "keyword" },
15
+ "@keywordsTertiary": { token: "keyword" }
16
+ }
17
+ }],
18
+ // comments
19
+ [/\/\/.*/, "comment"],
20
+ [/;.*/, "comment"],
21
+ // expressions
22
+ [/{/, "operator", "@curlyBracket"],
23
+ // expressions
24
+ [/=/, "operator", "@equals"],
25
+ ],
26
+ expression: [
27
+ // numbers
28
+ [/\d+/, "number"],
29
+ // Pin Numbers
30
+ [/[a-iA-I]\.\d+/, "string"],
31
+ [/[a-iA-I]\_\d+/, "string"],
32
+ [/[a-iA-I]\d+/, "string"],
33
+ [/P[a-iA-I]\.\d+/, "string"],
34
+ [/P[a-iA-I]\_\d+/, "string"],
35
+ [/P[a-iA-I]\d+/, "string"],
36
+ [/NoPin/, "string"],
37
+ // strings
38
+ [/"(.|\"\")*?"/, "string"],
39
+ [/[a-zA-Z0-9_$][\w$]*/, "string"],
40
+ // operators
41
+ [/@symbols/, {
42
+ cases: {
43
+ "@operators": "operator",
44
+ "@default": ""
45
+ }
46
+ }],
47
+ // comments
48
+ [/;.*/, "comment"],
49
+ // EOL
50
+ [/\n/, "", "@popall"],
51
+ ],
52
+ curlyBracket: [
53
+ // curly brackets contain expressions
54
+ { include: "expression" },
55
+ // terminate when reaching a closing bracket
56
+ [/}/, "operator", "@pop"],
57
+ ],
58
+ equals: [
59
+ // curly brackets contain expressions
60
+ { include: "expression" },
61
+ // EOL
62
+ [/\n/, "", "@popall"],
63
+ ]
64
+ }
65
+ };
66
+ export const stm32LanguageConfiguration = {
67
+ comments: {
68
+ lineComment: ";"
69
+ },
70
+ brackets: [
71
+ ["{", "}"]
72
+ ],
73
+ autoClosingPairs: [
74
+ { open: "{", close: "}" },
75
+ { open: "\"", close: "\"" }
76
+ ],
77
+ surroundingPairs: [
78
+ { open: "{", close: "}" },
79
+ { open: "\"", close: "\"" }
80
+ ]
81
+ };
@@ -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,42 @@
1
+ import deprecationsJson from "@duet3d/objectmodel/deprecations.json";
2
+ import { normalisePath } from "./paths";
3
+ /**
4
+ * Map of full object-model paths (with `[]` standing for any array index) to the deprecation message extracted
5
+ * from the property's `@deprecated` JSDoc tag. Built by @duet3d/objectmodel's build script from its TS sources.
6
+ */
7
+ const deprecations = deprecationsJson;
8
+ /**
9
+ * Look up the deprecation message for a full object-model path (with literal numeric indices) or any of its
10
+ * prefixes. Returns the deprecation message when the path itself or a containing path is deprecated (the
11
+ * shallowest match wins so the user sees the root cause, e.g. `move.rotation.angle` reports `move.rotation`
12
+ * as deprecated). Returns null when neither the path nor any prefix is deprecated.
13
+ */
14
+ export function getPathDeprecation(path) {
15
+ if (!path) {
16
+ return null;
17
+ }
18
+ const key = normalisePath(path);
19
+ // Walk prefixes from shallowest to deepest; first hit wins
20
+ let cursor = 0;
21
+ while (cursor < key.length) {
22
+ // Advance to the next boundary (dot or closing bracket that ends a step)
23
+ let next = key.indexOf(".", cursor);
24
+ if (next < 0) {
25
+ next = key.length;
26
+ }
27
+ const prefix = key.substring(0, next);
28
+ if (Object.prototype.hasOwnProperty.call(deprecations, prefix)) {
29
+ return deprecations[prefix];
30
+ }
31
+ cursor = next + 1;
32
+ }
33
+ return null;
34
+ }
35
+ /**
36
+ * Look up the deprecation message for `parentPath + "." + field`. `parentPath` is the dotted path of the parent
37
+ * value from the root (e.g. `move.extruders[0]`), or empty for a top-level field. Returns null if not deprecated.
38
+ */
39
+ export function getMemberDeprecation(parentPath, field) {
40
+ const fullPath = parentPath ? `${parentPath}.${field}` : field;
41
+ return getPathDeprecation(fullPath);
42
+ }
@@ -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,17 @@
1
+ import enumValuesJson from "@duet3d/objectmodel/enums.json";
2
+ import { normalisePath } from "./paths";
3
+ /**
4
+ * Map of full object-model paths (with `[]` standing for any array index) to the list of valid enum / string-
5
+ * literal values the field can take. Generated by @duet3d/objectmodel's build script from its TS sources.
6
+ */
7
+ const enumValues = enumValuesJson;
8
+ /**
9
+ * Return the list of valid values for a given object-model path, or null if the path has no known enum values.
10
+ */
11
+ export function getEnumValuesForPath(path) {
12
+ if (!path) {
13
+ return null;
14
+ }
15
+ const key = normalisePath(path);
16
+ return Object.prototype.hasOwnProperty.call(enumValues, key) ? enumValues[key] : null;
17
+ }
@@ -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,30 @@
1
+ let current = null;
2
+ const listeners = new Set();
3
+ /**
4
+ * Set (or clear) the runtime machine context. Pass `null` when the machine is disconnected.
5
+ */
6
+ export function setMachineContext(context) {
7
+ current = context;
8
+ for (const listener of listeners) {
9
+ try {
10
+ listener();
11
+ }
12
+ catch (e) {
13
+ // Listener threw - don't let it break other listeners
14
+ console.error("[monacotokens] machine-context listener threw:", e);
15
+ }
16
+ }
17
+ }
18
+ /**
19
+ * Get the currently installed machine context, or null when no machine is connected.
20
+ */
21
+ export function getMachineContext() {
22
+ return current;
23
+ }
24
+ /**
25
+ * Subscribe to machine-context changes. Returns an unsubscribe function.
26
+ */
27
+ export function onMachineContextChange(listener) {
28
+ listeners.add(listener);
29
+ return () => listeners.delete(listener);
30
+ }
@@ -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,5 @@
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 function normalisePath(path) {
4
+ return path.replace(/\[\d+\]/g, "[]");
5
+ }
@@ -0,0 +1,55 @@
1
+ import type * as monaco from "monaco-editor-core/esm/vs/editor/editor.api.js";
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;