1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | function powershell(hljs) {
|
10 | const TYPES = [
|
11 | "string",
|
12 | "char",
|
13 | "byte",
|
14 | "int",
|
15 | "long",
|
16 | "bool",
|
17 | "decimal",
|
18 | "single",
|
19 | "double",
|
20 | "DateTime",
|
21 | "xml",
|
22 | "array",
|
23 | "hashtable",
|
24 | "void"
|
25 | ];
|
26 |
|
27 |
|
28 | const VALID_VERBS =
|
29 | 'Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|'
|
30 | + 'Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|'
|
31 | + 'Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|'
|
32 | + 'Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|'
|
33 | + 'ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|'
|
34 | + 'Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|'
|
35 | + 'Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|'
|
36 | + 'Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|'
|
37 | + 'Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|'
|
38 | + 'Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|'
|
39 | + 'Unprotect|Use|ForEach|Sort|Tee|Where';
|
40 |
|
41 | const COMPARISON_OPERATORS =
|
42 | '-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|'
|
43 | + '-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|'
|
44 | + '-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|'
|
45 | + '-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|'
|
46 | + '-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|'
|
47 | + '-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|'
|
48 | + '-split|-wildcard|-xor';
|
49 |
|
50 | const KEYWORDS = {
|
51 | $pattern: /-?[A-z\.\-]+\b/,
|
52 | keyword:
|
53 | 'if else foreach return do while until elseif begin for trap data dynamicparam '
|
54 | + 'end break throw param continue finally in switch exit filter try process catch '
|
55 | + 'hidden static parameter',
|
56 |
|
57 | built_in:
|
58 | 'ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp '
|
59 | + 'cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx '
|
60 | + 'fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group '
|
61 | + 'gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi '
|
62 | + 'iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh '
|
63 | + 'popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp '
|
64 | + 'rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp '
|
65 | + 'spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write'
|
66 |
|
67 | };
|
68 |
|
69 | const TITLE_NAME_RE = /\w[\w\d]*((-)[\w\d]+)*/;
|
70 |
|
71 | const BACKTICK_ESCAPE = {
|
72 | begin: '`[\\s\\S]',
|
73 | relevance: 0
|
74 | };
|
75 |
|
76 | const VAR = {
|
77 | className: 'variable',
|
78 | variants: [
|
79 | { begin: /\$\B/ },
|
80 | {
|
81 | className: 'keyword',
|
82 | begin: /\$this/
|
83 | },
|
84 | { begin: /\$[\w\d][\w\d_:]*/ }
|
85 | ]
|
86 | };
|
87 |
|
88 | const LITERAL = {
|
89 | className: 'literal',
|
90 | begin: /\$(null|true|false)\b/
|
91 | };
|
92 |
|
93 | const QUOTE_STRING = {
|
94 | className: "string",
|
95 | variants: [
|
96 | {
|
97 | begin: /"/,
|
98 | end: /"/
|
99 | },
|
100 | {
|
101 | begin: /@"/,
|
102 | end: /^"@/
|
103 | }
|
104 | ],
|
105 | contains: [
|
106 | BACKTICK_ESCAPE,
|
107 | VAR,
|
108 | {
|
109 | className: 'variable',
|
110 | begin: /\$[A-z]/,
|
111 | end: /[^A-z]/
|
112 | }
|
113 | ]
|
114 | };
|
115 |
|
116 | const APOS_STRING = {
|
117 | className: 'string',
|
118 | variants: [
|
119 | {
|
120 | begin: /'/,
|
121 | end: /'/
|
122 | },
|
123 | {
|
124 | begin: /@'/,
|
125 | end: /^'@/
|
126 | }
|
127 | ]
|
128 | };
|
129 |
|
130 | const PS_HELPTAGS = {
|
131 | className: "doctag",
|
132 | variants: [
|
133 |
|
134 | { begin: /\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/ },
|
135 |
|
136 | { begin: /\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/ }
|
137 | ]
|
138 | };
|
139 |
|
140 | const PS_COMMENT = hljs.inherit(
|
141 | hljs.COMMENT(null, null),
|
142 | {
|
143 | variants: [
|
144 |
|
145 | {
|
146 | begin: /#/,
|
147 | end: /$/
|
148 | },
|
149 |
|
150 | {
|
151 | begin: /<#/,
|
152 | end: /#>/
|
153 | }
|
154 | ],
|
155 | contains: [ PS_HELPTAGS ]
|
156 | }
|
157 | );
|
158 |
|
159 | const CMDLETS = {
|
160 | className: 'built_in',
|
161 | variants: [ { begin: '('.concat(VALID_VERBS, ')+(-)[\\w\\d]+') } ]
|
162 | };
|
163 |
|
164 | const PS_CLASS = {
|
165 | className: 'class',
|
166 | beginKeywords: 'class enum',
|
167 | end: /\s*[{]/,
|
168 | excludeEnd: true,
|
169 | relevance: 0,
|
170 | contains: [ hljs.TITLE_MODE ]
|
171 | };
|
172 |
|
173 | const PS_FUNCTION = {
|
174 | className: 'function',
|
175 | begin: /function\s+/,
|
176 | end: /\s*\{|$/,
|
177 | excludeEnd: true,
|
178 | returnBegin: true,
|
179 | relevance: 0,
|
180 | contains: [
|
181 | {
|
182 | begin: "function",
|
183 | relevance: 0,
|
184 | className: "keyword"
|
185 | },
|
186 | {
|
187 | className: "title",
|
188 | begin: TITLE_NAME_RE,
|
189 | relevance: 0
|
190 | },
|
191 | {
|
192 | begin: /\(/,
|
193 | end: /\)/,
|
194 | className: "params",
|
195 | relevance: 0,
|
196 | contains: [ VAR ]
|
197 | }
|
198 |
|
199 | ]
|
200 | };
|
201 |
|
202 |
|
203 | const PS_USING = {
|
204 | begin: /using\s/,
|
205 | end: /$/,
|
206 | returnBegin: true,
|
207 | contains: [
|
208 | QUOTE_STRING,
|
209 | APOS_STRING,
|
210 | {
|
211 | className: 'keyword',
|
212 | begin: /(using|assembly|command|module|namespace|type)/
|
213 | }
|
214 | ]
|
215 | };
|
216 |
|
217 |
|
218 | const PS_ARGUMENTS = { variants: [
|
219 |
|
220 | {
|
221 | className: 'operator',
|
222 | begin: '('.concat(COMPARISON_OPERATORS, ')\\b')
|
223 | },
|
224 | {
|
225 | className: 'literal',
|
226 | begin: /(-){1,2}[\w\d-]+/,
|
227 | relevance: 0
|
228 | }
|
229 | ] };
|
230 |
|
231 | const HASH_SIGNS = {
|
232 | className: 'selector-tag',
|
233 | begin: /@\B/,
|
234 | relevance: 0
|
235 | };
|
236 |
|
237 |
|
238 |
|
239 | const PS_METHODS = {
|
240 | className: 'function',
|
241 | begin: /\[.*\]\s*[\w]+[ ]??\(/,
|
242 | end: /$/,
|
243 | returnBegin: true,
|
244 | relevance: 0,
|
245 | contains: [
|
246 | {
|
247 | className: 'keyword',
|
248 | begin: '('.concat(
|
249 | KEYWORDS.keyword.toString().replace(/\s/g, '|'
|
250 | ), ')\\b'),
|
251 | endsParent: true,
|
252 | relevance: 0
|
253 | },
|
254 | hljs.inherit(hljs.TITLE_MODE, { endsParent: true })
|
255 | ]
|
256 | };
|
257 |
|
258 | const GENTLEMANS_SET = [
|
259 |
|
260 | PS_METHODS,
|
261 | PS_COMMENT,
|
262 | BACKTICK_ESCAPE,
|
263 | hljs.NUMBER_MODE,
|
264 | QUOTE_STRING,
|
265 | APOS_STRING,
|
266 |
|
267 | CMDLETS,
|
268 | VAR,
|
269 | LITERAL,
|
270 | HASH_SIGNS
|
271 | ];
|
272 |
|
273 | const PS_TYPE = {
|
274 | begin: /\[/,
|
275 | end: /\]/,
|
276 | excludeBegin: true,
|
277 | excludeEnd: true,
|
278 | relevance: 0,
|
279 | contains: [].concat(
|
280 | 'self',
|
281 | GENTLEMANS_SET,
|
282 | {
|
283 | begin: "(" + TYPES.join("|") + ")",
|
284 | className: "built_in",
|
285 | relevance: 0
|
286 | },
|
287 | {
|
288 | className: 'type',
|
289 | begin: /[\.\w\d]+/,
|
290 | relevance: 0
|
291 | }
|
292 | )
|
293 | };
|
294 |
|
295 | PS_METHODS.contains.unshift(PS_TYPE);
|
296 |
|
297 | return {
|
298 | name: 'PowerShell',
|
299 | aliases: [
|
300 | "pwsh",
|
301 | "ps",
|
302 | "ps1"
|
303 | ],
|
304 | case_insensitive: true,
|
305 | keywords: KEYWORDS,
|
306 | contains: GENTLEMANS_SET.concat(
|
307 | PS_CLASS,
|
308 | PS_FUNCTION,
|
309 | PS_USING,
|
310 | PS_ARGUMENTS,
|
311 | PS_TYPE
|
312 | )
|
313 | };
|
314 | }
|
315 |
|
316 | module.exports = powershell;
|