highlightjs-move 0.1.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/LICENSE +21 -0
- package/README.md +148 -0
- package/package.json +49 -0
- package/src/languages/move.js +480 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Greg Nazario
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# highlightjs-move
|
|
2
|
+
|
|
3
|
+
[Highlight.js](https://highlightjs.org/) grammar definition for the
|
|
4
|
+
[Move](https://aptos.dev/build/smart-contracts/book) programming language on
|
|
5
|
+
[Aptos](https://aptos.dev).
|
|
6
|
+
|
|
7
|
+
Supports Move 2.x features including enums, pattern matching, lambdas, function
|
|
8
|
+
values, signed integers, and the Move Specification Language.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
### npm
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install highlightjs-move highlight.js
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### CDN (unpkg)
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<script src="https://unpkg.com/highlightjs-move"></script>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Node.js (ESM)
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
import hljs from 'highlight.js/lib/core';
|
|
30
|
+
import move from 'highlightjs-move';
|
|
31
|
+
|
|
32
|
+
hljs.registerLanguage('move', move);
|
|
33
|
+
|
|
34
|
+
const code = `
|
|
35
|
+
module 0x1::example {
|
|
36
|
+
public fun hello(): u64 { 42 }
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
const highlighted = hljs.highlight(code, { language: 'move' });
|
|
41
|
+
console.log(highlighted.value);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Browser
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
|
|
48
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
49
|
+
<script src="https://unpkg.com/highlightjs-move"></script>
|
|
50
|
+
<script>
|
|
51
|
+
hljs.registerLanguage('move', hljsDefineMove);
|
|
52
|
+
hljs.highlightAll();
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<pre><code class="language-move">
|
|
56
|
+
module 0x1::coin {
|
|
57
|
+
struct Coin<phantom CoinType> has key, store {
|
|
58
|
+
value: u64,
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
</code></pre>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Language Aliases
|
|
65
|
+
|
|
66
|
+
The grammar registers with the canonical name `Move` and the following aliases:
|
|
67
|
+
|
|
68
|
+
- `move`
|
|
69
|
+
- `aptos-move`
|
|
70
|
+
- `move-on-aptos`
|
|
71
|
+
- `move-lang`
|
|
72
|
+
|
|
73
|
+
Any of these can be used in fenced code blocks (e.g., `` ```move ``) or in
|
|
74
|
+
`class="language-move"` attributes.
|
|
75
|
+
|
|
76
|
+
## Supported Syntax
|
|
77
|
+
|
|
78
|
+
### Keywords
|
|
79
|
+
|
|
80
|
+
Declarations, visibility modifiers, control flow, ownership, and more:
|
|
81
|
+
|
|
82
|
+
`module` `script` `struct` `enum` `fun` `const` `use` `spec` `schema`
|
|
83
|
+
`public` `entry` `native` `inline` `friend` `package`
|
|
84
|
+
`if` `else` `while` `loop` `for` `in` `match` `break` `continue` `return` `abort`
|
|
85
|
+
`let` `mut` `move` `copy` `has` `acquires` `as` `Self` `phantom` `is`
|
|
86
|
+
|
|
87
|
+
### Specification Language
|
|
88
|
+
|
|
89
|
+
`pragma` `invariant` `ensures` `requires` `aborts_if` `aborts_with`
|
|
90
|
+
`include` `assume` `assert` `modifies` `emits` `apply` `axiom`
|
|
91
|
+
`forall` `exists` `choose` `old` `global` `with`
|
|
92
|
+
|
|
93
|
+
### Built-in Types
|
|
94
|
+
|
|
95
|
+
Unsigned integers: `u8` `u16` `u32` `u64` `u128` `u256`
|
|
96
|
+
|
|
97
|
+
Signed integers (Move 2.3+): `i8` `i16` `i32` `i64` `i128` `i256`
|
|
98
|
+
|
|
99
|
+
Other: `bool` `address` `signer` `vector`
|
|
100
|
+
|
|
101
|
+
### Built-in Functions & Macros
|
|
102
|
+
|
|
103
|
+
`assert!` `move_to` `move_from` `borrow_global` `borrow_global_mut` `freeze`
|
|
104
|
+
|
|
105
|
+
### Syntax Modes
|
|
106
|
+
|
|
107
|
+
| Feature | Examples |
|
|
108
|
+
|---|---|
|
|
109
|
+
| Doc comments | `/// documentation` |
|
|
110
|
+
| Line comments | `// comment` |
|
|
111
|
+
| Block comments | `/* ... */` (nested) |
|
|
112
|
+
| Byte strings | `b"hello\n"` |
|
|
113
|
+
| Hex strings | `x"DEADBEEF"` |
|
|
114
|
+
| Number literals | `42u64`, `0xCAFE`, `1_000_000u128`, `-1i8` |
|
|
115
|
+
| Address literals | `@0x1`, `@aptos_framework` |
|
|
116
|
+
| Attributes | `#[test]`, `#[resource_group_member(...)]` |
|
|
117
|
+
| Module declarations | `module 0x1::name { ... }` |
|
|
118
|
+
| Function declarations | `public entry fun name(...)` |
|
|
119
|
+
| Struct/Enum declarations | `struct Coin<T> has key { ... }` |
|
|
120
|
+
| Abilities (contextual) | `has copy, drop, key, store` |
|
|
121
|
+
| Module paths | `0x1::module::function` |
|
|
122
|
+
| Lambda expressions | `\|x\| x + 1`, `\|val: &u8\| { *val }` |
|
|
123
|
+
| vector constructor | `vector[1, 2, 3]` |
|
|
124
|
+
| `self` receiver | `fun method(self: &T)` |
|
|
125
|
+
| Function invocations | `foo()`, `obj.method()` |
|
|
126
|
+
|
|
127
|
+
## Development
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
git clone https://github.com/gregnazario/highlightjs-move.git
|
|
131
|
+
cd highlightjs-move
|
|
132
|
+
npm install
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Test files are located in `test/`:
|
|
136
|
+
- `test/detect/move/default.txt` -- comprehensive detection test
|
|
137
|
+
- `test/markup/move/short.move` -- markup/rendering test
|
|
138
|
+
|
|
139
|
+
## References
|
|
140
|
+
|
|
141
|
+
- [Aptos Documentation](https://aptos.dev)
|
|
142
|
+
- [The Move Book](https://aptos.dev/build/smart-contracts/book)
|
|
143
|
+
- [Move Specification Language](https://aptos.dev/build/smart-contracts/prover/spec-lang)
|
|
144
|
+
- [Highlight.js Language Definition Guide](https://highlightjs.readthedocs.io/en/latest/language-guide.html)
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
[MIT](LICENSE)
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "highlightjs-move",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Highlight.js grammar for the Move programming language (Aptos blockchain)",
|
|
5
|
+
"homepage": "https://github.com/gregnazario/highlightjs-move#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/gregnazario/highlightjs-move/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/gregnazario/highlightjs-move.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"highlightjs",
|
|
15
|
+
"highlight.js",
|
|
16
|
+
"aptos",
|
|
17
|
+
"move",
|
|
18
|
+
"syntax",
|
|
19
|
+
"highlighting",
|
|
20
|
+
"smart-contracts"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "Greg Nazario <greg@gnazar.io>",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "src/languages/move.js",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": "./src/languages/move.js"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"src/languages/move.js",
|
|
31
|
+
"README.md",
|
|
32
|
+
"LICENSE"
|
|
33
|
+
],
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"highlight.js": ">=11.0.0"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"lint": "biome lint",
|
|
39
|
+
"lint:fix": "biome lint --fix",
|
|
40
|
+
"format": "biome format --write",
|
|
41
|
+
"format:check": "biome format",
|
|
42
|
+
"check": "biome check",
|
|
43
|
+
"check:fix": "biome check --fix",
|
|
44
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@biomejs/biome": "2.3.14"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,480 @@
|
|
|
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 language definition for Aptos Move.
|
|
13
|
+
*
|
|
14
|
+
* Built from the Aptos Move Book (https://aptos.dev/build/smart-contracts/book)
|
|
15
|
+
* and the Move Specification Language reference.
|
|
16
|
+
*
|
|
17
|
+
* @type {import('highlight.js').LanguageFn}
|
|
18
|
+
*/
|
|
19
|
+
export default function move(hljs) {
|
|
20
|
+
const regex = hljs.regex;
|
|
21
|
+
|
|
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
|
|
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
|
+
scope: 'doctag',
|
|
163
|
+
match: /@\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
|
+
scope: 'string',
|
|
179
|
+
begin: /b"/,
|
|
180
|
+
end: /"/,
|
|
181
|
+
contains: [
|
|
182
|
+
{ match: /\\./ }, // 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
|
+
scope: '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
|
+
scope: 'number',
|
|
207
|
+
relevance: 0,
|
|
208
|
+
variants: [
|
|
209
|
+
// Hex literals with optional type suffix
|
|
210
|
+
{ match: /\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
|
+
{ match: /\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
|
+
scope: 'symbol',
|
|
224
|
+
match: /@(?: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
|
+
scope: 'meta',
|
|
236
|
+
begin: /#\[/,
|
|
237
|
+
end: /\]/,
|
|
238
|
+
contains: [
|
|
239
|
+
{
|
|
240
|
+
// Attribute name
|
|
241
|
+
scope: 'keyword',
|
|
242
|
+
match: /[a-zA-Z_]\w*/,
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
// Parenthesized arguments
|
|
246
|
+
begin: /\(/,
|
|
247
|
+
end: /\)/,
|
|
248
|
+
contains: [
|
|
249
|
+
{ scope: 'string', begin: /"/, end: /"/ },
|
|
250
|
+
{ scope: 'number', match: /\b\d+\b/ },
|
|
251
|
+
// Allow nested identifiers and :: paths inside attribute args
|
|
252
|
+
{ match: /[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*/ },
|
|
253
|
+
{ match: /=/ },
|
|
254
|
+
],
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
relevance: 5,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Module declaration.
|
|
262
|
+
* `module address::name { ... }` or `module 0x1::name { ... }`
|
|
263
|
+
* Highlights the module path and name.
|
|
264
|
+
*/
|
|
265
|
+
const MODULE_DECLARATION = {
|
|
266
|
+
begin: [
|
|
267
|
+
/\b(?:module)\b/,
|
|
268
|
+
/\s+/,
|
|
269
|
+
// Module path: addr::name (possibly multiple :: segments)
|
|
270
|
+
/(?:0x[0-9a-fA-F_]+|[a-zA-Z_]\w*)(?:::[a-zA-Z_]\w*)*/,
|
|
271
|
+
],
|
|
272
|
+
beginScope: {
|
|
273
|
+
1: 'keyword',
|
|
274
|
+
3: 'title.class',
|
|
275
|
+
},
|
|
276
|
+
relevance: 10,
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Function declarations.
|
|
281
|
+
* Matches patterns like:
|
|
282
|
+
* fun name(...)
|
|
283
|
+
* public fun name(...)
|
|
284
|
+
* public entry fun name(...)
|
|
285
|
+
* native public fun name(...)
|
|
286
|
+
* inline fun name(...)
|
|
287
|
+
* Highlights the function name as title.function.
|
|
288
|
+
*/
|
|
289
|
+
const FUNCTION_DECLARATION = {
|
|
290
|
+
begin: [/\bfun\b/, /\s+/, /[a-zA-Z_]\w*/],
|
|
291
|
+
beginScope: {
|
|
292
|
+
1: 'keyword',
|
|
293
|
+
3: 'title.function',
|
|
294
|
+
},
|
|
295
|
+
relevance: 10,
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Struct declarations.
|
|
300
|
+
* `struct Name` or `public struct Name`
|
|
301
|
+
* Highlights the struct name as title.class.
|
|
302
|
+
*/
|
|
303
|
+
const STRUCT_DECLARATION = {
|
|
304
|
+
begin: [/\bstruct\b/, /\s+/, /[A-Z]\w*/],
|
|
305
|
+
beginScope: {
|
|
306
|
+
1: 'keyword',
|
|
307
|
+
3: 'title.class',
|
|
308
|
+
},
|
|
309
|
+
relevance: 10,
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Enum declarations (Move 2.0+).
|
|
314
|
+
* `enum Name` with optional abilities and type parameters.
|
|
315
|
+
* Highlights the enum name as title.class.
|
|
316
|
+
*/
|
|
317
|
+
const ENUM_DECLARATION = {
|
|
318
|
+
begin: [/\benum\b/, /\s+/, /[A-Z]\w*/],
|
|
319
|
+
beginScope: {
|
|
320
|
+
1: 'keyword',
|
|
321
|
+
3: 'title.class',
|
|
322
|
+
},
|
|
323
|
+
relevance: 10,
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Abilities after `has` keyword.
|
|
328
|
+
* Matches patterns like `has copy, drop, key, store` in struct/enum declarations.
|
|
329
|
+
* Highlights the ability names as built_in.
|
|
330
|
+
*/
|
|
331
|
+
const ABILITIES = {
|
|
332
|
+
begin: /\bhas\b/,
|
|
333
|
+
beginScope: 'keyword',
|
|
334
|
+
end: /[{;,)]/,
|
|
335
|
+
returnEnd: true,
|
|
336
|
+
contains: [
|
|
337
|
+
{
|
|
338
|
+
scope: 'built_in',
|
|
339
|
+
match: /\b(?:copy|drop|key|store)\b/,
|
|
340
|
+
},
|
|
341
|
+
// Allow + separator for function type abilities: `has copy + drop`
|
|
342
|
+
{ match: /[+,]/ },
|
|
343
|
+
],
|
|
344
|
+
relevance: 5,
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Module paths with :: separator.
|
|
349
|
+
* Matches qualified paths like `0x1::module_name::function_name` or
|
|
350
|
+
* `aptos_framework::coin::CoinStore`.
|
|
351
|
+
* Highlights the path segments as title.class.
|
|
352
|
+
*/
|
|
353
|
+
const MODULE_PATH = {
|
|
354
|
+
scope: 'title.class',
|
|
355
|
+
match: /\b(?:0x[0-9a-fA-F_]+|[a-zA-Z_]\w*)(?:::[a-zA-Z_]\w*)+/,
|
|
356
|
+
relevance: 0,
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Function invocations.
|
|
361
|
+
* Matches `identifier(` patterns but excludes keywords that look like
|
|
362
|
+
* function calls (if, while, match, etc.).
|
|
363
|
+
*/
|
|
364
|
+
const FUNCTION_INVOKE = {
|
|
365
|
+
scope: 'title.function.invoke',
|
|
366
|
+
relevance: 0,
|
|
367
|
+
begin: regex.concat(
|
|
368
|
+
/\b/,
|
|
369
|
+
/(?!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)/,
|
|
370
|
+
hljs.IDENT_RE,
|
|
371
|
+
regex.lookahead(/\s*(?:<[^>]*>)?\s*\(/),
|
|
372
|
+
),
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* `self` as a receiver parameter / variable reference.
|
|
377
|
+
* In Move, `self` is used as the receiver in method-style function declarations
|
|
378
|
+
* (e.g., `fun is_eq(self: &Ordering): bool`) and in expressions (`self.field`).
|
|
379
|
+
*/
|
|
380
|
+
const SELF_VARIABLE = {
|
|
381
|
+
scope: 'variable.language',
|
|
382
|
+
match: /\bself\b/,
|
|
383
|
+
relevance: 0,
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* vector literal constructor syntax.
|
|
388
|
+
* `vector[1, 2, 3]` or `vector<u8>[1, 2, 3]`.
|
|
389
|
+
* Highlights `vector` as a built-in keyword.
|
|
390
|
+
*/
|
|
391
|
+
const VECTOR_LITERAL = {
|
|
392
|
+
match: /\bvector\s*(?:<[^>]*>)?\s*\[/,
|
|
393
|
+
scope: 'built_in',
|
|
394
|
+
returnEnd: true,
|
|
395
|
+
relevance: 5,
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Lambda / closure parameters within pipe delimiters.
|
|
400
|
+
* Matches `|param1, param2|` and `||` (empty closures) in lambda expressions
|
|
401
|
+
* and function type annotations.
|
|
402
|
+
* Highlights the pipes as punctuation and parameters as params.
|
|
403
|
+
*/
|
|
404
|
+
const LAMBDA_PARAMS = {
|
|
405
|
+
begin: /\|/,
|
|
406
|
+
end: /\|/,
|
|
407
|
+
scope: 'params',
|
|
408
|
+
relevance: 0,
|
|
409
|
+
contains: [
|
|
410
|
+
{
|
|
411
|
+
scope: 'type',
|
|
412
|
+
match:
|
|
413
|
+
/\b(?:u8|u16|u32|u64|u128|u256|i8|i16|i32|i64|i128|i256|bool|address|signer|vector)\b/,
|
|
414
|
+
},
|
|
415
|
+
{ match: /&\s*mut\b/, scope: 'keyword' },
|
|
416
|
+
{ match: /&/, scope: 'keyword' },
|
|
417
|
+
NUMBER,
|
|
418
|
+
],
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
// ---------------------------------------------------------------------------
|
|
422
|
+
// Language definition
|
|
423
|
+
// ---------------------------------------------------------------------------
|
|
424
|
+
|
|
425
|
+
return {
|
|
426
|
+
name: 'Move',
|
|
427
|
+
aliases: ['move', 'aptos-move', 'move-on-aptos', 'move-lang'],
|
|
428
|
+
unicodeRegex: true,
|
|
429
|
+
keywords: {
|
|
430
|
+
$pattern: `${hljs.IDENT_RE}!?`,
|
|
431
|
+
keyword: KEYWORDS,
|
|
432
|
+
literal: LITERALS,
|
|
433
|
+
type: TYPES,
|
|
434
|
+
built_in: BUILTINS,
|
|
435
|
+
},
|
|
436
|
+
contains: [
|
|
437
|
+
// Comments (doc comments must come before line comments to match first)
|
|
438
|
+
DOC_COMMENT,
|
|
439
|
+
LINE_COMMENT,
|
|
440
|
+
BLOCK_COMMENT,
|
|
441
|
+
|
|
442
|
+
// Strings
|
|
443
|
+
BYTE_STRING,
|
|
444
|
+
HEX_STRING,
|
|
445
|
+
|
|
446
|
+
// Numbers
|
|
447
|
+
NUMBER,
|
|
448
|
+
|
|
449
|
+
// Address literals (@0x1, @named)
|
|
450
|
+
ADDRESS_LITERAL,
|
|
451
|
+
|
|
452
|
+
// Attributes (#[test], #[resource_group_member(...)])
|
|
453
|
+
ATTRIBUTE,
|
|
454
|
+
|
|
455
|
+
// Declarations (order matters: more specific patterns first)
|
|
456
|
+
MODULE_DECLARATION,
|
|
457
|
+
FUNCTION_DECLARATION,
|
|
458
|
+
STRUCT_DECLARATION,
|
|
459
|
+
ENUM_DECLARATION,
|
|
460
|
+
|
|
461
|
+
// Abilities after `has`
|
|
462
|
+
ABILITIES,
|
|
463
|
+
|
|
464
|
+
// Module-qualified paths (0x1::module::item)
|
|
465
|
+
MODULE_PATH,
|
|
466
|
+
|
|
467
|
+
// vector[...] constructor
|
|
468
|
+
VECTOR_LITERAL,
|
|
469
|
+
|
|
470
|
+
// Lambda / closure params
|
|
471
|
+
LAMBDA_PARAMS,
|
|
472
|
+
|
|
473
|
+
// self as variable.language
|
|
474
|
+
SELF_VARIABLE,
|
|
475
|
+
|
|
476
|
+
// Function invocations
|
|
477
|
+
FUNCTION_INVOKE,
|
|
478
|
+
],
|
|
479
|
+
};
|
|
480
|
+
}
|