powershell.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. ;(function (mod) {
  4. 'use strict'
  5. if (typeof exports == 'object' && typeof module == 'object')
  6. // CommonJS
  7. mod(require('../../lib/codemirror'))
  8. else if (typeof define == 'function' && define.amd)
  9. // AMD
  10. define(['../../lib/codemirror'], mod)
  11. // Plain browser env
  12. else mod(window.CodeMirror)
  13. })(function (CodeMirror) {
  14. 'use strict'
  15. CodeMirror.defineMode('powershell', function () {
  16. function buildRegexp(patterns, options) {
  17. options = options || {}
  18. var prefix = options.prefix !== undefined ? options.prefix : '^'
  19. var suffix = options.suffix !== undefined ? options.suffix : '\\b'
  20. for (var i = 0; i < patterns.length; i++) {
  21. if (patterns[i] instanceof RegExp) {
  22. patterns[i] = patterns[i].source
  23. } else {
  24. patterns[i] = patterns[i].replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
  25. }
  26. }
  27. return new RegExp(prefix + '(' + patterns.join('|') + ')' + suffix, 'i')
  28. }
  29. var notCharacterOrDash = '(?=[^A-Za-z\\d\\-_]|$)'
  30. var varNames = /[\w\-:]/
  31. var keywords = buildRegexp(
  32. [
  33. /begin|break|catch|continue|data|default|do|dynamicparam/,
  34. /else|elseif|end|exit|filter|finally|for|foreach|from|function|if|in/,
  35. /param|process|return|switch|throw|trap|try|until|where|while/,
  36. ],
  37. { suffix: notCharacterOrDash }
  38. )
  39. var punctuation = /[\[\]{},;`\\\.]|@[({]/
  40. var wordOperators = buildRegexp(['f', /b?not/, /[ic]?split/, 'join', /is(not)?/, 'as', /[ic]?(eq|ne|[gl][te])/, /[ic]?(not)?(like|match|contains)/, /[ic]?replace/, /b?(and|or|xor)/], {
  41. prefix: '-',
  42. })
  43. var symbolOperators = /[+\-*\/%]=|\+\+|--|\.\.|[+\-*&^%:=!|\/]|<(?!#)|(?!#)>/
  44. var operators = buildRegexp([wordOperators, symbolOperators], { suffix: '' })
  45. var numbers = /^((0x[\da-f]+)|((\d+\.\d+|\d\.|\.\d+|\d+)(e[\+\-]?\d+)?))[ld]?([kmgtp]b)?/i
  46. var identifiers = /^[A-Za-z\_][A-Za-z\-\_\d]*\b/
  47. var symbolBuiltins = /[A-Z]:|%|\?/i
  48. var namedBuiltins = buildRegexp(
  49. [
  50. /Add-(Computer|Content|History|Member|PSSnapin|Type)/,
  51. /Checkpoint-Computer/,
  52. /Clear-(Content|EventLog|History|Host|Item(Property)?|Variable)/,
  53. /Compare-Object/,
  54. /Complete-Transaction/,
  55. /Connect-PSSession/,
  56. /ConvertFrom-(Csv|Json|SecureString|StringData)/,
  57. /Convert-Path/,
  58. /ConvertTo-(Csv|Html|Json|SecureString|Xml)/,
  59. /Copy-Item(Property)?/,
  60. /Debug-Process/,
  61. /Disable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)/,
  62. /Disconnect-PSSession/,
  63. /Enable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)/,
  64. /(Enter|Exit)-PSSession/,
  65. /Export-(Alias|Clixml|Console|Counter|Csv|FormatData|ModuleMember|PSSession)/,
  66. /ForEach-Object/,
  67. /Format-(Custom|List|Table|Wide)/,
  68. new RegExp(
  69. 'Get-(Acl|Alias|AuthenticodeSignature|ChildItem|Command|ComputerRestorePoint|Content|ControlPanelItem|Counter|Credential' +
  70. '|Culture|Date|Event|EventLog|EventSubscriber|ExecutionPolicy|FormatData|Help|History|Host|HotFix|Item|ItemProperty|Job' +
  71. '|Location|Member|Module|PfxCertificate|Process|PSBreakpoint|PSCallStack|PSDrive|PSProvider|PSSession|PSSessionConfiguration' +
  72. '|PSSnapin|Random|Service|TraceSource|Transaction|TypeData|UICulture|Unique|Variable|Verb|WinEvent|WmiObject)'
  73. ),
  74. /Group-Object/,
  75. /Import-(Alias|Clixml|Counter|Csv|LocalizedData|Module|PSSession)/,
  76. /ImportSystemModules/,
  77. /Invoke-(Command|Expression|History|Item|RestMethod|WebRequest|WmiMethod)/,
  78. /Join-Path/,
  79. /Limit-EventLog/,
  80. /Measure-(Command|Object)/,
  81. /Move-Item(Property)?/,
  82. new RegExp(
  83. 'New-(Alias|Event|EventLog|Item(Property)?|Module|ModuleManifest|Object|PSDrive|PSSession|PSSessionConfigurationFile' +
  84. '|PSSessionOption|PSTransportOption|Service|TimeSpan|Variable|WebServiceProxy|WinEvent)'
  85. ),
  86. /Out-(Default|File|GridView|Host|Null|Printer|String)/,
  87. /Pause/,
  88. /(Pop|Push)-Location/,
  89. /Read-Host/,
  90. /Receive-(Job|PSSession)/,
  91. /Register-(EngineEvent|ObjectEvent|PSSessionConfiguration|WmiEvent)/,
  92. /Remove-(Computer|Event|EventLog|Item(Property)?|Job|Module|PSBreakpoint|PSDrive|PSSession|PSSnapin|TypeData|Variable|WmiObject)/,
  93. /Rename-(Computer|Item(Property)?)/,
  94. /Reset-ComputerMachinePassword/,
  95. /Resolve-Path/,
  96. /Restart-(Computer|Service)/,
  97. /Restore-Computer/,
  98. /Resume-(Job|Service)/,
  99. /Save-Help/,
  100. /Select-(Object|String|Xml)/,
  101. /Send-MailMessage/,
  102. new RegExp(
  103. 'Set-(Acl|Alias|AuthenticodeSignature|Content|Date|ExecutionPolicy|Item(Property)?|Location|PSBreakpoint|PSDebug' +
  104. '|PSSessionConfiguration|Service|StrictMode|TraceSource|Variable|WmiInstance)'
  105. ),
  106. /Show-(Command|ControlPanelItem|EventLog)/,
  107. /Sort-Object/,
  108. /Split-Path/,
  109. /Start-(Job|Process|Service|Sleep|Transaction|Transcript)/,
  110. /Stop-(Computer|Job|Process|Service|Transcript)/,
  111. /Suspend-(Job|Service)/,
  112. /TabExpansion2/,
  113. /Tee-Object/,
  114. /Test-(ComputerSecureChannel|Connection|ModuleManifest|Path|PSSessionConfigurationFile)/,
  115. /Trace-Command/,
  116. /Unblock-File/,
  117. /Undo-Transaction/,
  118. /Unregister-(Event|PSSessionConfiguration)/,
  119. /Update-(FormatData|Help|List|TypeData)/,
  120. /Use-Transaction/,
  121. /Wait-(Event|Job|Process)/,
  122. /Where-Object/,
  123. /Write-(Debug|Error|EventLog|Host|Output|Progress|Verbose|Warning)/,
  124. /cd|help|mkdir|more|oss|prompt/,
  125. /ac|asnp|cat|cd|chdir|clc|clear|clhy|cli|clp|cls|clv|cnsn|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|dnsn|ebp/,
  126. /echo|epal|epcsv|epsn|erase|etsn|exsn|fc|fl|foreach|ft|fw|gal|gbp|gc|gci|gcm|gcs|gdr|ghy|gi|gjb|gl|gm|gmo|gp|gps/,
  127. /group|gsn|gsnp|gsv|gu|gv|gwmi|h|history|icm|iex|ihy|ii|ipal|ipcsv|ipmo|ipsn|irm|ise|iwmi|iwr|kill|lp|ls|man|md/,
  128. /measure|mi|mount|move|mp|mv|nal|ndr|ni|nmo|npssc|nsn|nv|ogv|oh|popd|ps|pushd|pwd|r|rbp|rcjb|rcsn|rd|rdr|ren|ri/,
  129. /rjb|rm|rmdir|rmo|rni|rnp|rp|rsn|rsnp|rujb|rv|rvpa|rwmi|sajb|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls/,
  130. /sort|sp|spjb|spps|spsv|start|sujb|sv|swmi|tee|trcm|type|where|wjb|write/,
  131. ],
  132. { prefix: '', suffix: '' }
  133. )
  134. var variableBuiltins = buildRegexp(
  135. [
  136. /[$?^_]|Args|ConfirmPreference|ConsoleFileName|DebugPreference|Error|ErrorActionPreference|ErrorView|ExecutionContext/,
  137. /FormatEnumerationLimit|Home|Host|Input|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount/,
  138. /MaximumHistoryCount|MaximumVariableCount|MyInvocation|NestedPromptLevel|OutputEncoding|Pid|Profile|ProgressPreference/,
  139. /PSBoundParameters|PSCommandPath|PSCulture|PSDefaultParameterValues|PSEmailServer|PSHome|PSScriptRoot|PSSessionApplicationName/,
  140. /PSSessionConfigurationName|PSSessionOption|PSUICulture|PSVersionTable|Pwd|ShellId|StackTrace|VerbosePreference/,
  141. /WarningPreference|WhatIfPreference/,
  142. /Event|EventArgs|EventSubscriber|Sender/,
  143. /Matches|Ofs|ForEach|LastExitCode|PSCmdlet|PSItem|PSSenderInfo|This/,
  144. /true|false|null/,
  145. ],
  146. { prefix: '\\$', suffix: '' }
  147. )
  148. var builtins = buildRegexp([symbolBuiltins, namedBuiltins, variableBuiltins], { suffix: notCharacterOrDash })
  149. var grammar = {
  150. keyword: keywords,
  151. number: numbers,
  152. operator: operators,
  153. builtin: builtins,
  154. punctuation: punctuation,
  155. identifier: identifiers,
  156. }
  157. // tokenizers
  158. function tokenBase(stream, state) {
  159. // Handle Comments
  160. //var ch = stream.peek();
  161. var parent = state.returnStack[state.returnStack.length - 1]
  162. if (parent && parent.shouldReturnFrom(state)) {
  163. state.tokenize = parent.tokenize
  164. state.returnStack.pop()
  165. return state.tokenize(stream, state)
  166. }
  167. if (stream.eatSpace()) {
  168. return null
  169. }
  170. if (stream.eat('(')) {
  171. state.bracketNesting += 1
  172. return 'punctuation'
  173. }
  174. if (stream.eat(')')) {
  175. state.bracketNesting -= 1
  176. return 'punctuation'
  177. }
  178. for (var key in grammar) {
  179. if (stream.match(grammar[key])) {
  180. return key
  181. }
  182. }
  183. var ch = stream.next()
  184. // single-quote string
  185. if (ch === "'") {
  186. return tokenSingleQuoteString(stream, state)
  187. }
  188. if (ch === '$') {
  189. return tokenVariable(stream, state)
  190. }
  191. // double-quote string
  192. if (ch === '"') {
  193. return tokenDoubleQuoteString(stream, state)
  194. }
  195. if (ch === '<' && stream.eat('#')) {
  196. state.tokenize = tokenComment
  197. return tokenComment(stream, state)
  198. }
  199. if (ch === '#') {
  200. stream.skipToEnd()
  201. return 'comment'
  202. }
  203. if (ch === '@') {
  204. var quoteMatch = stream.eat(/["']/)
  205. if (quoteMatch && stream.eol()) {
  206. state.tokenize = tokenMultiString
  207. state.startQuote = quoteMatch[0]
  208. return tokenMultiString(stream, state)
  209. } else if (stream.eol()) {
  210. return 'error'
  211. } else if (stream.peek().match(/[({]/)) {
  212. return 'punctuation'
  213. } else if (stream.peek().match(varNames)) {
  214. // splatted variable
  215. return tokenVariable(stream, state)
  216. }
  217. }
  218. return 'error'
  219. }
  220. function tokenSingleQuoteString(stream, state) {
  221. var ch
  222. while ((ch = stream.peek()) != null) {
  223. stream.next()
  224. if (ch === "'" && !stream.eat("'")) {
  225. state.tokenize = tokenBase
  226. return 'string'
  227. }
  228. }
  229. return 'error'
  230. }
  231. function tokenDoubleQuoteString(stream, state) {
  232. var ch
  233. while ((ch = stream.peek()) != null) {
  234. if (ch === '$') {
  235. state.tokenize = tokenStringInterpolation
  236. return 'string'
  237. }
  238. stream.next()
  239. if (ch === '`') {
  240. stream.next()
  241. continue
  242. }
  243. if (ch === '"' && !stream.eat('"')) {
  244. state.tokenize = tokenBase
  245. return 'string'
  246. }
  247. }
  248. return 'error'
  249. }
  250. function tokenStringInterpolation(stream, state) {
  251. return tokenInterpolation(stream, state, tokenDoubleQuoteString)
  252. }
  253. function tokenMultiStringReturn(stream, state) {
  254. state.tokenize = tokenMultiString
  255. state.startQuote = '"'
  256. return tokenMultiString(stream, state)
  257. }
  258. function tokenHereStringInterpolation(stream, state) {
  259. return tokenInterpolation(stream, state, tokenMultiStringReturn)
  260. }
  261. function tokenInterpolation(stream, state, parentTokenize) {
  262. if (stream.match('$(')) {
  263. var savedBracketNesting = state.bracketNesting
  264. state.returnStack.push({
  265. /*jshint loopfunc:true */
  266. shouldReturnFrom: function (state) {
  267. return state.bracketNesting === savedBracketNesting
  268. },
  269. tokenize: parentTokenize,
  270. })
  271. state.tokenize = tokenBase
  272. state.bracketNesting += 1
  273. return 'punctuation'
  274. } else {
  275. stream.next()
  276. state.returnStack.push({
  277. shouldReturnFrom: function () {
  278. return true
  279. },
  280. tokenize: parentTokenize,
  281. })
  282. state.tokenize = tokenVariable
  283. return state.tokenize(stream, state)
  284. }
  285. }
  286. function tokenComment(stream, state) {
  287. var maybeEnd = false,
  288. ch
  289. while ((ch = stream.next()) != null) {
  290. if (maybeEnd && ch == '>') {
  291. state.tokenize = tokenBase
  292. break
  293. }
  294. maybeEnd = ch === '#'
  295. }
  296. return 'comment'
  297. }
  298. function tokenVariable(stream, state) {
  299. var ch = stream.peek()
  300. if (stream.eat('{')) {
  301. state.tokenize = tokenVariableWithBraces
  302. return tokenVariableWithBraces(stream, state)
  303. } else if (ch != undefined && ch.match(varNames)) {
  304. stream.eatWhile(varNames)
  305. state.tokenize = tokenBase
  306. return 'variable-2'
  307. } else {
  308. state.tokenize = tokenBase
  309. return 'error'
  310. }
  311. }
  312. function tokenVariableWithBraces(stream, state) {
  313. var ch
  314. while ((ch = stream.next()) != null) {
  315. if (ch === '}') {
  316. state.tokenize = tokenBase
  317. break
  318. }
  319. }
  320. return 'variable-2'
  321. }
  322. function tokenMultiString(stream, state) {
  323. var quote = state.startQuote
  324. if (stream.sol() && stream.match(new RegExp(quote + '@'))) {
  325. state.tokenize = tokenBase
  326. } else if (quote === '"') {
  327. while (!stream.eol()) {
  328. var ch = stream.peek()
  329. if (ch === '$') {
  330. state.tokenize = tokenHereStringInterpolation
  331. return 'string'
  332. }
  333. stream.next()
  334. if (ch === '`') {
  335. stream.next()
  336. }
  337. }
  338. } else {
  339. stream.skipToEnd()
  340. }
  341. return 'string'
  342. }
  343. var external = {
  344. startState: function () {
  345. return {
  346. returnStack: [],
  347. bracketNesting: 0,
  348. tokenize: tokenBase,
  349. }
  350. },
  351. token: function (stream, state) {
  352. return state.tokenize(stream, state)
  353. },
  354. blockCommentStart: '<#',
  355. blockCommentEnd: '#>',
  356. lineComment: '#',
  357. fold: 'brace',
  358. }
  359. return external
  360. })
  361. CodeMirror.defineMIME('application/x-powershell', 'powershell')
  362. })