powershell.js (7465B)
1 /* 2 Language: PowerShell 3 Description: PowerShell is a task-based command-line shell and scripting language built on .NET. 4 Author: David Mohundro <david@mohundro.com> 5 Contributors: Nicholas Blumhardt <nblumhardt@nblumhardt.com>, Victor Zhou <OiCMudkips@users.noreply.github.com>, Nicolas Le Gall <contact@nlegall.fr> 6 Website: https://docs.microsoft.com/en-us/powershell/ 7 */ 8 9 function powershell(hljs) { 10 11 var TYPES = 12 ["string", "char", "byte", "int", "long", "bool", "decimal", "single", 13 "double", "DateTime", "xml", "array", "hashtable", "void"]; 14 15 // https://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx 16 var VALID_VERBS = 17 'Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|' + 18 'Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|' + 19 'Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|' + 20 'Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|' + 21 'ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|' + 22 'Limit|Merge|New|Out|Publish|Restore|Save|Sync|Unpublish|Update|' + 23 'Approve|Assert|Complete|Confirm|Deny|Disable|Enable|Install|Invoke|Register|' + 24 'Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|' + 25 'Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|' + 26 'Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|' + 27 'Unprotect|Use|ForEach|Sort|Tee|Where'; 28 29 var COMPARISON_OPERATORS = 30 '-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|' + 31 '-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|' + 32 '-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|' + 33 '-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|' + 34 '-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|' + 35 '-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|' + 36 '-split|-wildcard|-xor'; 37 38 var KEYWORDS = { 39 $pattern: /-?[A-z\.\-]+\b/, 40 keyword: 'if else foreach return do while until elseif begin for trap data dynamicparam ' + 41 'end break throw param continue finally in switch exit filter try process catch ' + 42 'hidden static parameter', 43 // "echo" relevance has been set to 0 to avoid auto-detect conflicts with shell transcripts 44 built_in: 'ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp ' + 45 'cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx ' + 46 'fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group ' + 47 'gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi ' + 48 'iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh ' + 49 'popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp ' + 50 'rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp ' + 51 'spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write' 52 // TODO: 'validate[A-Z]+' can't work in keywords 53 }; 54 55 var TITLE_NAME_RE = /\w[\w\d]*((-)[\w\d]+)*/; 56 57 var BACKTICK_ESCAPE = { 58 begin: '`[\\s\\S]', 59 relevance: 0 60 }; 61 62 var VAR = { 63 className: 'variable', 64 variants: [ 65 { begin: /\$\B/ }, 66 { className: 'keyword', begin: /\$this/ }, 67 { begin: /\$[\w\d][\w\d_:]*/ } 68 ] 69 }; 70 71 var LITERAL = { 72 className: 'literal', 73 begin: /\$(null|true|false)\b/ 74 }; 75 76 var QUOTE_STRING = { 77 className: "string", 78 variants: [{ begin: /"/, end: /"/ }, { begin: /@"/, end: /^"@/ }], 79 contains: [ 80 BACKTICK_ESCAPE, 81 VAR, 82 { 83 className: 'variable', 84 begin: /\$[A-z]/, end: /[^A-z]/ 85 } 86 ] 87 }; 88 89 var APOS_STRING = { 90 className: 'string', 91 variants: [ 92 { begin: /'/, end: /'/ }, 93 { begin: /@'/, end: /^'@/ } 94 ] 95 }; 96 97 var PS_HELPTAGS = { 98 className: "doctag", 99 variants: [ 100 /* no paramater help tags */ 101 { 102 begin: /\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/ 103 }, 104 /* one parameter help tags */ 105 { begin: /\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/ } 106 ] 107 }; 108 109 var PS_COMMENT = hljs.inherit( 110 hljs.COMMENT(null, null), 111 { 112 variants: [ 113 /* single-line comment */ 114 { begin: /#/, end: /$/ }, 115 /* multi-line comment */ 116 { begin: /<#/, end: /#>/ } 117 ], 118 contains: [PS_HELPTAGS] 119 } 120 ); 121 122 var CMDLETS = { 123 className: 'built_in', 124 variants: [ 125 { begin: '('.concat(VALID_VERBS, ')+(-)[\\w\\d]+') } 126 ] 127 }; 128 129 var PS_CLASS = { 130 className: 'class', 131 beginKeywords: 'class enum', end: /\s*[{]/, excludeEnd: true, 132 relevance: 0, 133 contains: [hljs.TITLE_MODE] 134 }; 135 136 var PS_FUNCTION = { 137 className: 'function', 138 begin: /function\s+/, end: /\s*\{|$/, 139 excludeEnd: true, 140 returnBegin: true, 141 relevance: 0, 142 contains: [ 143 { begin: "function", relevance: 0, className: "keyword" }, 144 { className: "title", 145 begin: TITLE_NAME_RE, relevance:0 }, 146 { begin: /\(/, end: /\)/, className: "params", 147 relevance: 0, 148 contains: [VAR] } 149 // CMDLETS 150 ] 151 }; 152 153 // Using statment, plus type, plus assembly name. 154 var PS_USING = { 155 begin: /using\s/, end: /$/, 156 returnBegin: true, 157 contains: [ 158 QUOTE_STRING, 159 APOS_STRING, 160 { className: 'keyword', begin: /(using|assembly|command|module|namespace|type)/ } 161 ] 162 }; 163 164 // Comperison operators & function named parameters. 165 var PS_ARGUMENTS = { 166 variants: [ 167 // PS literals are pretty verbose so it's a good idea to accent them a bit. 168 { className: 'operator', begin: '('.concat(COMPARISON_OPERATORS, ')\\b') }, 169 { className: 'literal', begin: /(-)[\w\d]+/, relevance:0 } 170 ] 171 }; 172 173 var HASH_SIGNS = { 174 className: 'selector-tag', 175 begin: /\@\B/, 176 relevance: 0 177 }; 178 179 // It's a very general rule so I'll narrow it a bit with some strict boundaries 180 // to avoid any possible false-positive collisions! 181 var PS_METHODS = { 182 className: 'function', 183 begin: /\[.*\]\s*[\w]+[ ]??\(/, end: /$/, 184 returnBegin: true, 185 relevance: 0, 186 contains: [ 187 { 188 className: 'keyword', begin: '('.concat( 189 KEYWORDS.keyword.toString().replace(/\s/g, '|' 190 ), ')\\b'), 191 endsParent: true, 192 relevance: 0 193 }, 194 hljs.inherit(hljs.TITLE_MODE, { endsParent: true }) 195 ] 196 }; 197 198 var GENTLEMANS_SET = [ 199 // STATIC_MEMBER, 200 PS_METHODS, 201 PS_COMMENT, 202 BACKTICK_ESCAPE, 203 hljs.NUMBER_MODE, 204 QUOTE_STRING, 205 APOS_STRING, 206 // PS_NEW_OBJECT_TYPE, 207 CMDLETS, 208 VAR, 209 LITERAL, 210 HASH_SIGNS 211 ]; 212 213 var PS_TYPE = { 214 begin: /\[/, end: /\]/, 215 excludeBegin: true, 216 excludeEnd: true, 217 relevance: 0, 218 contains: [].concat( 219 'self', 220 GENTLEMANS_SET, 221 { begin: "(" + TYPES.join("|") + ")", className: "built_in", relevance:0 }, 222 { className: 'type', begin: /[\.\w\d]+/, relevance: 0 } 223 ) 224 }; 225 226 PS_METHODS.contains.unshift(PS_TYPE); 227 228 return { 229 name: 'PowerShell', 230 aliases: ["ps", "ps1"], 231 case_insensitive: true, 232 keywords: KEYWORDS, 233 contains: GENTLEMANS_SET.concat( 234 PS_CLASS, 235 PS_FUNCTION, 236 PS_USING, 237 PS_ARGUMENTS, 238 PS_TYPE 239 ) 240 }; 241 } 242 243 module.exports = powershell;