highlightjs-move 0.1.0 → 0.2.0

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.
package/README.md CHANGED
@@ -23,6 +23,8 @@ npm install highlightjs-move highlight.js
23
23
 
24
24
  ## Usage
25
25
 
26
+ Both ESM (`import`) and CommonJS (`require`) are supported out of the box.
27
+
26
28
  ### Node.js (ESM)
27
29
 
28
30
  ```js
@@ -41,6 +43,15 @@ const highlighted = hljs.highlight(code, { language: 'move' });
41
43
  console.log(highlighted.value);
42
44
  ```
43
45
 
46
+ ### Node.js (CommonJS)
47
+
48
+ ```js
49
+ const hljs = require('highlight.js/lib/core');
50
+ const move = require('highlightjs-move');
51
+
52
+ hljs.registerLanguage('move', move);
53
+ ```
54
+
44
55
  ### Browser
45
56
 
46
57
  ```html
@@ -61,6 +72,28 @@ module 0x1::coin {
61
72
  </code></pre>
62
73
  ```
63
74
 
75
+ ### Highlight.js v10
76
+
77
+ A v10-compatible build is available for projects that haven't upgraded to v11 yet.
78
+ It uses the v10 grammar API (`className` instead of `scope`, etc.) but supports
79
+ all the same Move language features.
80
+
81
+ ```js
82
+ // ESM
83
+ import hljs from 'highlight.js/lib/core';
84
+ import move from 'highlightjs-move/v10';
85
+
86
+ hljs.registerLanguage('move', move);
87
+ ```
88
+
89
+ ```js
90
+ // CommonJS
91
+ const hljs = require('highlight.js/lib/core');
92
+ const move = require('highlightjs-move/v10');
93
+
94
+ hljs.registerLanguage('move', move);
95
+ ```
96
+
64
97
  ## Language Aliases
65
98
 
66
99
  The grammar registers with the canonical name `Move` and the following aliases:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "highlightjs-move",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Highlight.js grammar for the Move programming language (Aptos blockchain)",
5
5
  "homepage": "https://github.com/gregnazario/highlightjs-move#readme",
6
6
  "bugs": {
@@ -21,18 +21,27 @@
21
21
  ],
22
22
  "license": "MIT",
23
23
  "author": "Greg Nazario <greg@gnazar.io>",
24
- "type": "module",
25
24
  "main": "src/languages/move.js",
26
25
  "exports": {
27
- ".": "./src/languages/move.js"
26
+ ".": {
27
+ "import": "./src/languages/move.mjs",
28
+ "require": "./src/languages/move.js"
29
+ },
30
+ "./v10": {
31
+ "import": "./src/languages/move.v10.mjs",
32
+ "require": "./src/languages/move.v10.js"
33
+ }
28
34
  },
29
35
  "files": [
30
36
  "src/languages/move.js",
37
+ "src/languages/move.mjs",
38
+ "src/languages/move.v10.js",
39
+ "src/languages/move.v10.mjs",
31
40
  "README.md",
32
41
  "LICENSE"
33
42
  ],
34
43
  "peerDependencies": {
35
- "highlight.js": ">=11.0.0"
44
+ "highlight.js": ">=10.0.0"
36
45
  },
37
46
  "scripts": {
38
47
  "lint": "biome lint",
@@ -9,14 +9,14 @@ Category: smart-contracts
9
9
  */
10
10
 
11
11
  /**
12
- * Highlight.js language definition for Aptos Move.
12
+ * Highlight.js language definition for Aptos Move (v11+ API).
13
13
  *
14
14
  * Built from the Aptos Move Book (https://aptos.dev/build/smart-contracts/book)
15
15
  * and the Move Specification Language reference.
16
16
  *
17
17
  * @type {import('highlight.js').LanguageFn}
18
18
  */
19
- export default function move(hljs) {
19
+ module.exports = function move(hljs) {
20
20
  const regex = hljs.regex;
21
21
 
22
22
  // ---------------------------------------------------------------------------
@@ -477,4 +477,4 @@ export default function move(hljs) {
477
477
  FUNCTION_INVOKE,
478
478
  ],
479
479
  };
480
- }
480
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * ESM wrapper for the Move highlight.js grammar (v11+ API).
3
+ * @type {import('highlight.js').LanguageFn}
4
+ */
5
+ import move from './move.js';
6
+ export default move;
@@ -0,0 +1,485 @@
1
+ /*
2
+ Language: Move
3
+ Author: Greg Nazario <greg@gnazar.io>
4
+ Description: Move is a programming language for the Aptos blockchain, designed
5
+ for secure and flexible smart contract development. Supports Move 2.x
6
+ features including enums, lambdas, function values, and signed integers.
7
+ Website: https://aptos.dev
8
+ Category: smart-contracts
9
+ */
10
+
11
+ /**
12
+ * Highlight.js v10 compatible language definition for Aptos Move.
13
+ *
14
+ * This file uses the v10 grammar API (className instead of scope, begin instead
15
+ * of match, no beginScope/endScope, no hljs.regex). For highlight.js v11+,
16
+ * use the main entry point instead.
17
+ *
18
+ * Built from the Aptos Move Book (https://aptos.dev/build/smart-contracts/book)
19
+ * and the Move Specification Language reference.
20
+ */
21
+ module.exports = function move(hljs) {
22
+ // ---------------------------------------------------------------------------
23
+ // Keywords
24
+ // ---------------------------------------------------------------------------
25
+
26
+ /**
27
+ * Core language keywords from the Move Book.
28
+ * Includes declarations, visibility modifiers, control flow, ownership,
29
+ * abilities clause, imports, and spec-language keywords.
30
+ */
31
+ const KEYWORDS = [
32
+ // Declarations
33
+ 'module',
34
+ 'script',
35
+ 'struct',
36
+ 'enum',
37
+ 'fun',
38
+ 'const',
39
+ 'use',
40
+ 'spec',
41
+ 'schema',
42
+ // Visibility & modifiers
43
+ 'public',
44
+ 'entry',
45
+ 'native',
46
+ 'inline',
47
+ 'friend',
48
+ 'package',
49
+ // Control flow
50
+ 'if',
51
+ 'else',
52
+ 'while',
53
+ 'loop',
54
+ 'for',
55
+ 'in',
56
+ 'match',
57
+ 'break',
58
+ 'continue',
59
+ 'return',
60
+ 'abort',
61
+ // Variable & ownership
62
+ 'let',
63
+ 'mut',
64
+ 'move',
65
+ 'copy',
66
+ // Abilities clause
67
+ 'has',
68
+ // Resource annotation
69
+ 'acquires',
70
+ // Import aliasing
71
+ 'as',
72
+ 'Self',
73
+ // Phantom type parameter
74
+ 'phantom',
75
+ // Enum variant test operator (Move 2.0+)
76
+ 'is',
77
+ // Spec language keywords (treated as regular keywords)
78
+ 'pragma',
79
+ 'invariant',
80
+ 'ensures',
81
+ 'requires',
82
+ 'aborts_if',
83
+ 'aborts_with',
84
+ 'include',
85
+ 'assume',
86
+ 'assert',
87
+ 'modifies',
88
+ 'emits',
89
+ 'apply',
90
+ 'axiom',
91
+ 'forall',
92
+ 'exists',
93
+ 'choose',
94
+ 'old',
95
+ 'global',
96
+ 'with',
97
+ ];
98
+
99
+ /**
100
+ * Boolean literals.
101
+ */
102
+ const LITERALS = ['true', 'false'];
103
+
104
+ /**
105
+ * Built-in primitive types and the vector generic type.
106
+ * Unsigned integers (u8-u256), signed integers (i8-i256, Move 2.3+),
107
+ * bool, address, signer, and vector.
108
+ */
109
+ const TYPES = [
110
+ // Unsigned integers
111
+ 'u8',
112
+ 'u16',
113
+ 'u32',
114
+ 'u64',
115
+ 'u128',
116
+ 'u256',
117
+ // Signed integers (Move 2.3+)
118
+ 'i8',
119
+ 'i16',
120
+ 'i32',
121
+ 'i64',
122
+ 'i128',
123
+ 'i256',
124
+ // Other primitives
125
+ 'bool',
126
+ 'address',
127
+ 'signer',
128
+ 'vector',
129
+ ];
130
+
131
+ /**
132
+ * Built-in functions and macros.
133
+ * Global storage operators, the assert! macro, and freeze.
134
+ */
135
+ const BUILTINS = [
136
+ // Macros
137
+ 'assert!',
138
+ // Global storage operators
139
+ 'move_to',
140
+ 'move_from',
141
+ 'borrow_global',
142
+ 'borrow_global_mut',
143
+ // Freeze
144
+ 'freeze',
145
+ ];
146
+
147
+ // ---------------------------------------------------------------------------
148
+ // Modes (v10 compatible: uses className instead of scope, begin instead of match)
149
+ // ---------------------------------------------------------------------------
150
+
151
+ // Nested block comments: Move supports nesting, e.g.
152
+ // /* outer /* inner comment */ still outer */
153
+ const BLOCK_COMMENT = hljs.COMMENT(/\/\*/, /\*\//, { contains: ['self'] });
154
+
155
+ /**
156
+ * Doc comments: `///` triple-slash documentation comments.
157
+ * Supports @-style doc tags inside.
158
+ */
159
+ const DOC_COMMENT = hljs.COMMENT(/\/\/\//, /$/, {
160
+ contains: [
161
+ {
162
+ className: 'doctag',
163
+ begin: /@\w+/,
164
+ },
165
+ ],
166
+ });
167
+
168
+ /**
169
+ * Regular line comments: `// ...`
170
+ */
171
+ const LINE_COMMENT = hljs.COMMENT(/\/\//, /$/, {});
172
+
173
+ /**
174
+ * Byte string literals: `b"hello"` with backslash escape sequences.
175
+ * These are Move's UTF-8 byte string values.
176
+ */
177
+ const BYTE_STRING = {
178
+ className: 'string',
179
+ begin: /b"/,
180
+ end: /"/,
181
+ contains: [
182
+ { begin: /\\./ }, // escape sequences like \n, \\, \"
183
+ ],
184
+ relevance: 10,
185
+ };
186
+
187
+ /**
188
+ * Hex string literals: `x"DEADBEEF"`.
189
+ * These encode raw byte arrays from hex digits.
190
+ */
191
+ const HEX_STRING = {
192
+ className: 'string',
193
+ begin: /x"/,
194
+ end: /"/,
195
+ relevance: 10,
196
+ };
197
+
198
+ /**
199
+ * Number literals.
200
+ * Supports:
201
+ * - Hexadecimal: 0xDEAD_BEEF with optional type suffix
202
+ * - Decimal: 1_000_000 with optional type suffix
203
+ * - Type suffixes: u8, u16, u32, u64, u128, u256, i8, i16, i32, i64, i128, i256
204
+ */
205
+ const NUMBER = {
206
+ className: 'number',
207
+ relevance: 0,
208
+ variants: [
209
+ // Hex literals with optional type suffix
210
+ { begin: /\b0x[0-9a-fA-F][0-9a-fA-F_]*(?:[ui](?:8|16|32|64|128|256))?\b/ },
211
+ // Decimal literals with optional type suffix
212
+ { begin: /\b[0-9][0-9_]*(?:[ui](?:8|16|32|64|128|256))?\b/ },
213
+ ],
214
+ };
215
+
216
+ /**
217
+ * Address literals.
218
+ * In Move, addresses are prefixed with `@`:
219
+ * - Numeric: @0x1, @0xCAFE
220
+ * - Named: @aptos_framework, @my_addr
221
+ */
222
+ const ADDRESS_LITERAL = {
223
+ className: 'symbol',
224
+ begin: /@(?:0x[0-9a-fA-F][0-9a-fA-F_]*|[a-zA-Z_]\w*)/,
225
+ relevance: 10,
226
+ };
227
+
228
+ /**
229
+ * Attributes / annotations.
230
+ * Move uses `#[name]` and `#[name(...)]` syntax for attributes like
231
+ * #[test], #[test_only], #[view], #[event], #[resource_group_member(...)],
232
+ * #[expected_failure(...)], #[persistent], etc.
233
+ */
234
+ const ATTRIBUTE = {
235
+ className: 'meta',
236
+ begin: /#\[/,
237
+ end: /\]/,
238
+ contains: [
239
+ {
240
+ // Attribute name
241
+ className: 'keyword',
242
+ begin: /[a-zA-Z_]\w*/,
243
+ },
244
+ {
245
+ // Parenthesized arguments
246
+ begin: /\(/,
247
+ end: /\)/,
248
+ contains: [
249
+ { className: 'string', begin: /"/, end: /"/ },
250
+ { className: 'number', begin: /\b\d+\b/ },
251
+ // Allow nested identifiers and :: paths inside attribute args
252
+ { begin: /[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*/ },
253
+ { begin: /=/ },
254
+ ],
255
+ },
256
+ ],
257
+ relevance: 5,
258
+ };
259
+
260
+ /**
261
+ * Module declaration.
262
+ * `module address::name { ... }` or `module 0x1::name { ... }`
263
+ * In v10, we use beginKeywords to match `module` and a sub-mode for the path.
264
+ */
265
+ const MODULE_DECLARATION = {
266
+ beginKeywords: 'module',
267
+ end: /[{;]/,
268
+ returnEnd: true,
269
+ contains: [
270
+ {
271
+ className: 'title',
272
+ begin: /(?:0x[0-9a-fA-F_]+|[a-zA-Z_]\w*)(?:::[a-zA-Z_]\w*)*/,
273
+ relevance: 0,
274
+ },
275
+ ],
276
+ relevance: 10,
277
+ };
278
+
279
+ /**
280
+ * Function declarations.
281
+ * Matches `fun name` and highlights the function name.
282
+ * In v10, we use beginKeywords for `fun` and a sub-mode for the name.
283
+ */
284
+ const FUNCTION_DECLARATION = {
285
+ beginKeywords: 'fun',
286
+ end: /[({;]/,
287
+ returnEnd: true,
288
+ contains: [
289
+ {
290
+ className: 'title',
291
+ begin: /[a-zA-Z_]\w*/,
292
+ relevance: 0,
293
+ },
294
+ ],
295
+ relevance: 10,
296
+ };
297
+
298
+ /**
299
+ * Struct declarations.
300
+ * `struct Name` or `public struct Name`
301
+ * Highlights the struct name as title.
302
+ */
303
+ const STRUCT_DECLARATION = {
304
+ beginKeywords: 'struct',
305
+ end: /[{(;]|\bhas\b/,
306
+ returnEnd: true,
307
+ contains: [
308
+ {
309
+ className: 'title',
310
+ begin: /[A-Z]\w*/,
311
+ relevance: 0,
312
+ },
313
+ ],
314
+ relevance: 10,
315
+ };
316
+
317
+ /**
318
+ * Enum declarations (Move 2.0+).
319
+ * `enum Name` with optional abilities and type parameters.
320
+ * Highlights the enum name as title.
321
+ */
322
+ const ENUM_DECLARATION = {
323
+ beginKeywords: 'enum',
324
+ end: /[{]|\bhas\b/,
325
+ returnEnd: true,
326
+ contains: [
327
+ {
328
+ className: 'title',
329
+ begin: /[A-Z]\w*/,
330
+ relevance: 0,
331
+ },
332
+ ],
333
+ relevance: 10,
334
+ };
335
+
336
+ /**
337
+ * Abilities after `has` keyword.
338
+ * Matches patterns like `has copy, drop, key, store` in struct/enum declarations.
339
+ * Highlights the ability names as built_in.
340
+ */
341
+ const ABILITIES = {
342
+ begin: /\bhas\b/,
343
+ end: /[{;,)]/,
344
+ returnEnd: true,
345
+ keywords: 'has',
346
+ contains: [
347
+ {
348
+ className: 'built_in',
349
+ begin: /\b(?:copy|drop|key|store)\b/,
350
+ },
351
+ // Allow + separator for function type abilities: `has copy + drop`
352
+ { begin: /[+,]/ },
353
+ ],
354
+ relevance: 5,
355
+ };
356
+
357
+ /**
358
+ * Module paths with :: separator.
359
+ * Matches qualified paths like `0x1::module_name::function_name` or
360
+ * `aptos_framework::coin::CoinStore`.
361
+ * Highlights the path segments as title (maps to hljs-title).
362
+ */
363
+ const MODULE_PATH = {
364
+ className: 'title',
365
+ begin: /\b(?:0x[0-9a-fA-F_]+|[a-zA-Z_]\w*)(?:::[a-zA-Z_]\w*)+/,
366
+ relevance: 0,
367
+ };
368
+
369
+ /**
370
+ * Function invocations.
371
+ * Matches `identifier(` patterns but excludes keywords that look like
372
+ * function calls (if, while, match, etc.).
373
+ * In v10, we build the regex manually without hljs.regex.
374
+ */
375
+ const FUNCTION_INVOKE = {
376
+ className: 'title function_',
377
+ relevance: 0,
378
+ begin:
379
+ /\b(?!let\b|for\b|while\b|if\b|else\b|match\b|loop\b|return\b|abort\b|break\b|continue\b|use\b|module\b|struct\b|enum\b|fun\b|spec\b|const\b)[a-zA-Z_]\w*(?=\s*(?:<[^>]*>)?\s*\()/,
380
+ };
381
+
382
+ /**
383
+ * `self` as a receiver parameter / variable reference.
384
+ * In Move, `self` is used as the receiver in method-style function declarations
385
+ * (e.g., `fun is_eq(self: &Ordering): bool`) and in expressions (`self.field`).
386
+ */
387
+ const SELF_VARIABLE = {
388
+ className: 'variable language_',
389
+ begin: /\bself\b/,
390
+ relevance: 0,
391
+ };
392
+
393
+ /**
394
+ * vector literal constructor syntax.
395
+ * `vector[1, 2, 3]` or `vector<u8>[1, 2, 3]`.
396
+ * Highlights `vector` as a built-in keyword.
397
+ */
398
+ const VECTOR_LITERAL = {
399
+ begin: /\bvector\s*(?:<[^>]*>)?\s*\[/,
400
+ className: 'built_in',
401
+ returnEnd: true,
402
+ relevance: 5,
403
+ };
404
+
405
+ /**
406
+ * Lambda / closure parameters within pipe delimiters.
407
+ * Matches `|param1, param2|` and `||` (empty closures) in lambda expressions
408
+ * and function type annotations.
409
+ */
410
+ const LAMBDA_PARAMS = {
411
+ begin: /\|/,
412
+ end: /\|/,
413
+ className: 'params',
414
+ relevance: 0,
415
+ contains: [
416
+ {
417
+ className: 'type',
418
+ begin:
419
+ /\b(?:u8|u16|u32|u64|u128|u256|i8|i16|i32|i64|i128|i256|bool|address|signer|vector)\b/,
420
+ },
421
+ { begin: /&\s*mut\b/, className: 'keyword' },
422
+ { begin: /&/, className: 'keyword' },
423
+ NUMBER,
424
+ ],
425
+ };
426
+
427
+ // ---------------------------------------------------------------------------
428
+ // Language definition
429
+ // ---------------------------------------------------------------------------
430
+
431
+ return {
432
+ name: 'Move',
433
+ aliases: ['move', 'aptos-move', 'move-on-aptos', 'move-lang'],
434
+ keywords: {
435
+ $pattern: `${hljs.IDENT_RE}!?`,
436
+ keyword: KEYWORDS.join(' '),
437
+ literal: LITERALS.join(' '),
438
+ type: TYPES.join(' '),
439
+ built_in: BUILTINS.join(' '),
440
+ },
441
+ contains: [
442
+ // Comments (doc comments must come before line comments to match first)
443
+ DOC_COMMENT,
444
+ LINE_COMMENT,
445
+ BLOCK_COMMENT,
446
+
447
+ // Strings
448
+ BYTE_STRING,
449
+ HEX_STRING,
450
+
451
+ // Numbers
452
+ NUMBER,
453
+
454
+ // Address literals (@0x1, @named)
455
+ ADDRESS_LITERAL,
456
+
457
+ // Attributes (#[test], #[resource_group_member(...)])
458
+ ATTRIBUTE,
459
+
460
+ // Declarations (order matters: more specific patterns first)
461
+ MODULE_DECLARATION,
462
+ FUNCTION_DECLARATION,
463
+ STRUCT_DECLARATION,
464
+ ENUM_DECLARATION,
465
+
466
+ // Abilities after `has`
467
+ ABILITIES,
468
+
469
+ // Module-qualified paths (0x1::module::item)
470
+ MODULE_PATH,
471
+
472
+ // vector[...] constructor
473
+ VECTOR_LITERAL,
474
+
475
+ // Lambda / closure params
476
+ LAMBDA_PARAMS,
477
+
478
+ // self as variable.language
479
+ SELF_VARIABLE,
480
+
481
+ // Function invocations
482
+ FUNCTION_INVOKE,
483
+ ],
484
+ };
485
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * ESM wrapper for the Move highlight.js grammar (v10 API).
3
+ */
4
+ import move from './move.v10.js';
5
+ export default move;