shell-unix-bash.cson 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. 'scopeName': 'source.shell'
  2. 'name': 'Shell Script'
  3. 'fileTypes': [
  4. 'sh'
  5. 'bash'
  6. 'ksh'
  7. 'zsh'
  8. 'zsh-theme'
  9. 'zshenv'
  10. 'zlogin'
  11. 'zlogout'
  12. 'zprofile'
  13. 'zshrc'
  14. 'bashrc'
  15. 'bash_aliases'
  16. 'bash_profile'
  17. 'bash_login'
  18. 'profile'
  19. 'bash_logout'
  20. '.textmate_init'
  21. 'npmrc'
  22. 'PKGBUILD'
  23. 'install'
  24. 'cygport'
  25. 'bats'
  26. 'ebuild'
  27. ]
  28. 'firstLineMatch': '''(?x)
  29. # Hashbang
  30. ^\\#!.*(?:\\s|\\/)
  31. (?:bash|zsh|sh|tcsh|ksh|dash|ash|csh|rc)
  32. (?:$|\\s)
  33. |
  34. # Modeline
  35. (?i:
  36. # Emacs
  37. -\\*-(?:\\s*(?=[^:;\\s]+\\s*-\\*-)|(?:.*?[;\\s]|(?<=-\\*-))mode\\s*:\\s*)
  38. (?:shell-script|sh)
  39. (?=[\\s;]|(?<![-*])-\\*-).*?-\\*-
  40. |
  41. # Vim
  42. (?:(?:\\s|^)vi(?:m[<=>]?\\d+|m)?|\\sex)(?=:(?=\\s*set?\\s[^\\n:]+:)|:(?!\\s* set?\\s))(?:(?:\\s|\\s*:\\s*)\\w*(?:\\s*=(?:[^\\n\\\\\\s]|\\\\.)*)?)*[\\s:](?:filetype|ft|syntax)\\s*=
  43. sh
  44. (?=\\s|:|$)
  45. )
  46. '''
  47. 'patterns': [
  48. {
  49. 'include': '#comment'
  50. }
  51. {
  52. 'include': '#pipeline'
  53. }
  54. {
  55. 'include': '#list'
  56. }
  57. {
  58. 'include': '#compound-command'
  59. }
  60. {
  61. 'include': '#loop'
  62. }
  63. {
  64. 'include': '#string'
  65. }
  66. {
  67. 'include': '#function-definition'
  68. }
  69. {
  70. 'include': '#variable'
  71. }
  72. {
  73. 'include': '#interpolation'
  74. }
  75. {
  76. 'include': '#heredoc'
  77. }
  78. {
  79. 'include': '#herestring'
  80. }
  81. {
  82. 'include': '#redirection'
  83. }
  84. {
  85. 'include': '#pathname'
  86. }
  87. {
  88. 'include': '#keyword'
  89. }
  90. {
  91. 'include': '#support'
  92. }
  93. ]
  94. 'repository':
  95. 'case-clause':
  96. 'patterns': [
  97. {
  98. 'begin': '(?=\\S)'
  99. 'end': ';;'
  100. 'endCaptures':
  101. '0':
  102. 'name': 'punctuation.terminator.case-clause.shell'
  103. 'name': 'meta.scope.case-clause.shell'
  104. 'patterns': [
  105. {
  106. 'begin': '\\(|(?=\\S)'
  107. 'beginCaptures':
  108. '0':
  109. 'name': 'punctuation.definition.case-pattern.shell'
  110. 'end': '\\)'
  111. 'endCaptures':
  112. '0':
  113. 'name': 'punctuation.definition.case-pattern.shell'
  114. 'name': 'meta.scope.case-pattern.shell'
  115. 'patterns': [
  116. {
  117. 'match': '\\|'
  118. 'name': 'punctuation.separator.pipe-sign.shell'
  119. }
  120. {
  121. 'include': '#string'
  122. }
  123. {
  124. 'include': '#variable'
  125. }
  126. {
  127. 'include': '#interpolation'
  128. }
  129. {
  130. 'include': '#pathname'
  131. }
  132. ]
  133. }
  134. {
  135. 'begin': '(?<=\\))'
  136. 'end': '(?=;;)'
  137. 'name': 'meta.scope.case-clause-body.shell'
  138. 'patterns': [
  139. {
  140. 'include': '$self'
  141. }
  142. ]
  143. }
  144. ]
  145. }
  146. ]
  147. 'comment':
  148. 'begin': '(^\\s+)?(?<=^|\\W)(?<!-)(?=#)(?!#{)'
  149. 'beginCaptures':
  150. '1':
  151. 'name': 'punctuation.whitespace.comment.leading.shell'
  152. 'end': '(?!\\G)'
  153. 'patterns': [
  154. {
  155. 'begin': '#!'
  156. 'beginCaptures':
  157. '0':
  158. 'name': 'punctuation.definition.comment.shebang.shell'
  159. 'end': '$'
  160. 'name': 'comment.line.number-sign.shebang.shell'
  161. }
  162. {
  163. 'begin': '#'
  164. 'beginCaptures':
  165. '0':
  166. 'name': 'punctuation.definition.comment.shell'
  167. 'end': '$'
  168. 'name': 'comment.line.number-sign.shell'
  169. }
  170. ]
  171. 'compound-command':
  172. 'patterns': [
  173. {
  174. 'begin': '\\[{1,2}'
  175. 'beginCaptures':
  176. '0':
  177. 'name': 'punctuation.definition.logical-expression.shell'
  178. 'end': '\\]{1,2}'
  179. 'endCaptures':
  180. '0':
  181. 'name': 'punctuation.definition.logical-expression.shell'
  182. 'name': 'meta.scope.logical-expression.shell'
  183. 'patterns': [
  184. {
  185. 'include': '#logical-expression'
  186. }
  187. {
  188. 'include': '$self'
  189. }
  190. ]
  191. }
  192. {
  193. 'begin': '\\({2}'
  194. 'beginCaptures':
  195. '0':
  196. 'name': 'punctuation.definition.string.begin.shell'
  197. 'end': '\\){2}'
  198. 'endCaptures':
  199. '0':
  200. 'name': 'punctuation.definition.string.end.shell'
  201. 'name': 'string.other.math.shell'
  202. 'patterns': [
  203. {
  204. 'include': '#math'
  205. }
  206. ]
  207. }
  208. {
  209. 'begin': '\\('
  210. 'beginCaptures':
  211. '0':
  212. 'name': 'punctuation.definition.subshell.shell'
  213. 'end': '\\)'
  214. 'endCaptures':
  215. '0':
  216. 'name': 'punctuation.definition.subshell.shell'
  217. 'name': 'meta.scope.subshell.shell'
  218. 'patterns': [
  219. {
  220. 'include': '$self'
  221. }
  222. ]
  223. }
  224. {
  225. 'begin': '(?<=\\s|^){(?=\\s|$)'
  226. 'beginCaptures':
  227. '0':
  228. 'name': 'punctuation.definition.group.shell'
  229. 'end': '(?<=^|;)\\s*(})'
  230. 'endCaptures':
  231. '1':
  232. 'name': 'punctuation.definition.group.shell'
  233. 'name': 'meta.scope.group.shell'
  234. 'patterns': [
  235. {
  236. 'include': '$self'
  237. }
  238. ]
  239. }
  240. ]
  241. 'function-definition':
  242. 'patterns': [
  243. {
  244. 'begin': '(?<=^|;|&|\\s)(function)\\s+([^\\s\\\\]+)(?:\\s*(\\(\\)))?'
  245. 'beginCaptures':
  246. '1':
  247. 'name': 'storage.type.function.shell'
  248. '2':
  249. 'name': 'entity.name.function.shell'
  250. '3':
  251. 'name': 'punctuation.definition.arguments.shell'
  252. 'end': ';|&|$'
  253. 'endCaptures':
  254. '0':
  255. 'name': 'punctuation.definition.function.shell'
  256. 'name': 'meta.function.shell'
  257. 'patterns': [
  258. {
  259. 'include': '$self'
  260. }
  261. ]
  262. }
  263. {
  264. 'begin': '(?<=^|;|&|\\s)([^\\s\\\\=]+)\\s*(\\(\\))'
  265. 'beginCaptures':
  266. '1':
  267. 'name': 'entity.name.function.shell'
  268. '2':
  269. 'name': 'punctuation.definition.arguments.shell'
  270. 'end': ';|&|$'
  271. 'endCaptures':
  272. '0':
  273. 'name': 'punctuation.definition.function.shell'
  274. 'name': 'meta.function.shell'
  275. 'patterns': [
  276. {
  277. 'include': '$self'
  278. }
  279. ]
  280. }
  281. ]
  282. 'heredoc':
  283. 'patterns': [
  284. {
  285. 'begin': '(<<)-\\s*("|\'|)\\s*(RUBY)(?=\\s|;|&|<|"|\')\\2'
  286. 'beginCaptures':
  287. '1':
  288. 'name': 'keyword.operator.heredoc.shell'
  289. '3':
  290. 'name': 'keyword.control.heredoc-token.shell'
  291. 'end': '^\\t*(RUBY)(?=\\s|;|&|$)'
  292. 'endCaptures':
  293. '1':
  294. 'name': 'keyword.control.heredoc-token.shell'
  295. 'name': 'string.unquoted.heredoc.no-indent.ruby.shell'
  296. 'contentName': 'source.ruby.embedded.shell'
  297. 'patterns': [
  298. {
  299. 'include': 'source.ruby'
  300. }
  301. ]
  302. }
  303. {
  304. 'begin': '(<<)\\s*("|\'|)\\s*(RUBY)(?=\\s|;|&|<|"|\')\\2'
  305. 'beginCaptures':
  306. '1':
  307. 'name': 'keyword.operator.heredoc.shell'
  308. '3':
  309. 'name': 'keyword.control.heredoc-token.shell'
  310. 'end': '^(RUBY)(?=\\s|;|&|$)'
  311. 'endCaptures':
  312. '1':
  313. 'name': 'keyword.control.heredoc-token.shell'
  314. 'name': 'string.unquoted.heredoc.ruby.shell'
  315. 'contentName': 'source.ruby.embedded.shell'
  316. 'patterns': [
  317. {
  318. 'include': 'source.ruby'
  319. }
  320. ]
  321. }
  322. {
  323. 'begin': '(<<)-\\s*("|\'|)\\s*(PYTHON)(?=\\s|;|&|<|"|\')\\2'
  324. 'beginCaptures':
  325. '1':
  326. 'name': 'keyword.operator.heredoc.shell'
  327. '3':
  328. 'name': 'keyword.control.heredoc-token.shell'
  329. 'end': '^\\t*(PYTHON)(?=\\s|;|&|$)'
  330. 'endCaptures':
  331. '1':
  332. 'name': 'keyword.control.heredoc-token.shell'
  333. 'name': 'string.unquoted.heredoc.no-indent.python.shell'
  334. 'contentName': 'source.python.embedded.shell'
  335. 'patterns': [
  336. {
  337. 'include': 'source.python'
  338. }
  339. ]
  340. }
  341. {
  342. 'begin': '(<<)\\s*("|\'|)\\s*(PYTHON)(?=\\s|;|&|<|"|\')\\2'
  343. 'beginCaptures':
  344. '1':
  345. 'name': 'keyword.operator.heredoc.shell'
  346. '3':
  347. 'name': 'keyword.control.heredoc-token.shell'
  348. 'end': '^(PYTHON)(?=\\s|;|&|$)'
  349. 'endCaptures':
  350. '1':
  351. 'name': 'keyword.control.heredoc-token.shell'
  352. 'name': 'string.unquoted.heredoc.python.shell'
  353. 'contentName': 'source.python.embedded.shell'
  354. 'patterns': [
  355. {
  356. 'include': 'source.python'
  357. }
  358. ]
  359. }
  360. {
  361. 'begin': '(<<)-\\s*("|\'|)\\s*(APPLESCRIPT)(?=\\s|;|&|<|"|\')\\2'
  362. 'beginCaptures':
  363. '1':
  364. 'name': 'keyword.operator.heredoc.shell'
  365. '3':
  366. 'name': 'keyword.control.heredoc-token.shell'
  367. 'end': '^\\t*(APPLESCRIPT)(?=\\s|;|&|$)'
  368. 'endCaptures':
  369. '1':
  370. 'name': 'keyword.control.heredoc-token.shell'
  371. 'name': 'string.unquoted.heredoc.no-indent.applescript.shell'
  372. 'contentName': 'source.applescript.embedded.shell'
  373. 'patterns': [
  374. {
  375. 'include': 'source.applescript'
  376. }
  377. ]
  378. }
  379. {
  380. 'begin': '(<<)\\s*("|\'|)\\s*(APPLESCRIPT)(?=\\s|;|&|<|"|\')\\2'
  381. 'beginCaptures':
  382. '1':
  383. 'name': 'keyword.operator.heredoc.shell'
  384. '3':
  385. 'name': 'keyword.control.heredoc-token.shell'
  386. 'end': '^(APPLESCRIPT)(?=\\s|;|&|$)'
  387. 'endCaptures':
  388. '1':
  389. 'name': 'keyword.control.heredoc-token.shell'
  390. 'name': 'string.unquoted.heredoc.applescript.shell'
  391. 'contentName': 'source.applescript.embedded.shell'
  392. 'patterns': [
  393. {
  394. 'include': 'source.applescript'
  395. }
  396. ]
  397. }
  398. {
  399. 'begin': '(<<)-\\s*("|\'|)\\s*(HTML)(?=\\s|;|&|<|"|\')\\2'
  400. 'beginCaptures':
  401. '1':
  402. 'name': 'keyword.operator.heredoc.shell'
  403. '3':
  404. 'name': 'keyword.control.heredoc-token.shell'
  405. 'end': '^\\t*(HTML)(?=\\s|;|&|$)'
  406. 'endCaptures':
  407. '1':
  408. 'name': 'keyword.control.heredoc-token.shell'
  409. 'name': 'string.unquoted.heredoc.no-indent.html.shell'
  410. 'contentName': 'text.html.embedded.shell'
  411. 'patterns': [
  412. {
  413. 'include': 'text.html.basic'
  414. }
  415. ]
  416. }
  417. {
  418. 'begin': '(<<)\\s*("|\'|)\\s*(HTML)(?=\\s|;|&|<|"|\')\\2'
  419. 'beginCaptures':
  420. '1':
  421. 'name': 'keyword.operator.heredoc.shell'
  422. '3':
  423. 'name': 'keyword.control.heredoc-token.shell'
  424. 'end': '^(HTML)(?=\\s|;|&|$)'
  425. 'endCaptures':
  426. '1':
  427. 'name': 'keyword.control.heredoc-token.shell'
  428. 'name': 'string.unquoted.heredoc.html.shell'
  429. 'contentName': 'text.html.embedded.shell'
  430. 'patterns': [
  431. {
  432. 'include': 'text.html.basic'
  433. }
  434. ]
  435. }
  436. {
  437. 'begin': '(<<)-\\s*("|\'|)\\s*(MARKDOWN)(?=\\s|;|&|<|"|\')\\2'
  438. 'beginCaptures':
  439. '1':
  440. 'name': 'keyword.operator.heredoc.shell'
  441. '3':
  442. 'name': 'keyword.control.heredoc-token.shell'
  443. 'end': '^\\t*(MARKDOWN)(?=\\s|;|&|$)'
  444. 'endCaptures':
  445. '1':
  446. 'name': 'keyword.control.heredoc-token.shell'
  447. 'name': 'string.unquoted.heredoc.no-indent.markdown.shell'
  448. 'contentName': 'text.html.markdown.embedded.shell'
  449. 'patterns': [
  450. {
  451. 'include': 'text.html.markdown'
  452. }
  453. ]
  454. }
  455. {
  456. 'begin': '(<<)\\s*("|\'|)\\s*(MARKDOWN)(?=\\s|;|&|<|"|\')\\2'
  457. 'beginCaptures':
  458. '1':
  459. 'name': 'keyword.operator.heredoc.shell'
  460. '3':
  461. 'name': 'keyword.control.heredoc-token.shell'
  462. 'end': '^(MARKDOWN)(?=\\s|;|&|$)'
  463. 'endCaptures':
  464. '1':
  465. 'name': 'keyword.control.heredoc-token.shell'
  466. 'name': 'string.unquoted.heredoc.markdown.shell'
  467. 'contentName': 'text.html.markdown.embedded.shell'
  468. 'patterns': [
  469. {
  470. 'include': 'text.html.markdown'
  471. }
  472. ]
  473. }
  474. {
  475. 'begin': '(<<)-\\s*("|\'|)\\s*(TEXTILE)(?=\\s|;|&|<|"|\')\\2'
  476. 'beginCaptures':
  477. '1':
  478. 'name': 'keyword.operator.heredoc.shell'
  479. '3':
  480. 'name': 'keyword.control.heredoc-token.shell'
  481. 'end': '^\\t*(TEXTILE)(?=\\s|;|&|$)'
  482. 'endCaptures':
  483. '1':
  484. 'name': 'keyword.control.heredoc-token.shell'
  485. 'name': 'string.unquoted.heredoc.no-indent.textile.shell'
  486. 'contentName': 'text.html.textile.embedded.shell'
  487. 'patterns': [
  488. {
  489. 'include': 'text.html.textile'
  490. }
  491. ]
  492. }
  493. {
  494. 'begin': '(<<)\\s*("|\'|)\\s*(TEXTILE)(?=\\s|;|&|<|"|\')\\2'
  495. 'beginCaptures':
  496. '1':
  497. 'name': 'keyword.operator.heredoc.shell'
  498. '3':
  499. 'name': 'keyword.control.heredoc-token.shell'
  500. 'end': '^(TEXTILE)(?=\\s|;|&|$)'
  501. 'endCaptures':
  502. '1':
  503. 'name': 'keyword.control.heredoc-token.shell'
  504. 'name': 'string.unquoted.heredoc.textile.shell'
  505. 'contentName': 'text.html.textile.embedded.shell'
  506. 'patterns': [
  507. {
  508. 'include': 'text.html.textile'
  509. }
  510. ]
  511. }
  512. {
  513. 'begin': '(<<)-\\s*("|\'|)\\s*(SHELL)(?=\\s|;|&|<|"|\')\\2'
  514. 'beginCaptures':
  515. '1':
  516. 'name': 'keyword.operator.heredoc.shell'
  517. '3':
  518. 'name': 'keyword.control.heredoc-token.shell'
  519. 'end': '^\\t*(\\3)(?=\\s|;|&|$)'
  520. 'endCaptures':
  521. '1':
  522. 'name': 'keyword.control.heredoc-token.shell'
  523. 'contentName': 'source.shell.embedded.shell'
  524. 'name': 'string.unquoted.heredoc.no-indent.shell.shell'
  525. 'patterns': [
  526. {
  527. 'include': 'source.shell'
  528. }
  529. ]
  530. }
  531. {
  532. 'begin': '(<<)\\s*("|\'|)\\s*(SHELL)(?=\\s|;|&|<|"|\')\\2'
  533. 'beginCaptures':
  534. '1':
  535. 'name': 'keyword.operator.heredoc.shell'
  536. '3':
  537. 'name': 'keyword.control.heredoc-token.shell'
  538. 'end': '^(\\3)(?=\\s|;|&|$)'
  539. 'endCaptures':
  540. '1':
  541. 'name': 'keyword.control.heredoc-token.shell'
  542. 'name': 'string.unquoted.heredoc.shell.shell'
  543. 'contentName': 'source.shell.embedded.shell'
  544. 'patterns': [
  545. {
  546. 'include': 'source.shell'
  547. }
  548. ]
  549. }
  550. {
  551. 'begin': '(<<)-\\s*("|\')\\s*\\\\?([^;&<\\s]+)\\2'
  552. 'beginCaptures':
  553. '1':
  554. 'name': 'keyword.operator.heredoc.shell'
  555. '3':
  556. 'name': 'keyword.control.heredoc-token.shell'
  557. 'end': '^\\t*(\\3)(?=\\s|;|&|$)'
  558. 'endCaptures':
  559. '1':
  560. 'name': 'keyword.control.heredoc-token.shell'
  561. 'name': 'string.unquoted.heredoc.no-indent.shell'
  562. }
  563. {
  564. 'begin': '(<<)\\s*("|\')\\s*\\\\?([^;&<\\s]+)\\2'
  565. 'beginCaptures':
  566. '1':
  567. 'name': 'keyword.operator.heredoc.shell'
  568. '3':
  569. 'name': 'keyword.control.heredoc-token.shell'
  570. 'end': '^(\\3)(?=\\s|;|&|$)'
  571. 'endCaptures':
  572. '1':
  573. 'name': 'keyword.control.heredoc-token.shell'
  574. 'name': 'string.unquoted.heredoc.shell'
  575. }
  576. {
  577. 'begin': '(<<)-\\s*\\\\?([^;&<\\s]+)'
  578. 'beginCaptures':
  579. '1':
  580. 'name': 'keyword.operator.heredoc.shell'
  581. '2':
  582. 'name': 'keyword.control.heredoc-token.shell'
  583. 'end': '^\\t*(\\2)(?=\\s|;|&|$)'
  584. 'endCaptures':
  585. '1':
  586. 'name': 'keyword.control.heredoc-token.shell'
  587. 'name': 'string.unquoted.heredoc.expanded.no-indent.shell'
  588. 'patterns': [
  589. {
  590. 'match': '\\\\[\\$`\\\\\\n]'
  591. 'name': 'constant.character.escape.shell'
  592. }
  593. {
  594. 'include': '#variable'
  595. }
  596. {
  597. 'include': '#interpolation'
  598. }
  599. ]
  600. }
  601. {
  602. 'begin': '(<<)\\s*\\\\?([^;&<\\s]+)'
  603. 'beginCaptures':
  604. '1':
  605. 'name': 'keyword.operator.heredoc.shell'
  606. '2':
  607. 'name': 'keyword.control.heredoc-token.shell'
  608. 'end': '^(\\2)(?=\\s|;|&|$)'
  609. 'endCaptures':
  610. '1':
  611. 'name': 'keyword.control.heredoc-token.shell'
  612. 'name': 'string.unquoted.heredoc.expanded.shell'
  613. 'patterns': [
  614. {
  615. 'match': '\\\\[\\$`\\\\\\n]'
  616. 'name': 'constant.character.escape.shell'
  617. }
  618. {
  619. 'include': '#variable'
  620. }
  621. {
  622. 'include': '#interpolation'
  623. }
  624. ]
  625. }
  626. ]
  627. 'herestring':
  628. 'patterns': [
  629. {
  630. 'begin': '(<<<)\\s*((\'))'
  631. 'beginCaptures':
  632. '1':
  633. 'name': 'keyword.operator.herestring.shell'
  634. '2':
  635. 'name': 'string.quoted.single.shell'
  636. '3':
  637. 'name': 'punctuation.definition.string.begin.shell'
  638. 'end': '(\')'
  639. 'endCaptures':
  640. '0':
  641. 'name': 'string.quoted.single.shell'
  642. '1':
  643. 'name': 'punctuation.definition.string.end.shell'
  644. 'name': 'meta.herestring.shell'
  645. 'contentName': 'string.quoted.single.shell'
  646. }
  647. {
  648. 'begin': '(<<<)\\s*(("))'
  649. 'beginCaptures':
  650. '1':
  651. 'name': 'keyword.operator.herestring.shell'
  652. '2':
  653. 'name': 'string.quoted.double.shell'
  654. '3':
  655. 'name': 'punctuation.definition.string.begin.shell'
  656. 'end': '(")'
  657. 'endCaptures':
  658. '0':
  659. 'name': 'string.quoted.double.shell'
  660. '1':
  661. 'name': 'punctuation.definition.string.end.shell'
  662. 'name': 'meta.herestring.shell'
  663. 'contentName': 'string.quoted.double.shell'
  664. }
  665. {
  666. 'captures':
  667. '1':
  668. 'name': 'keyword.operator.herestring.shell'
  669. '2':
  670. 'name': 'string.unquoted.herestring.shell'
  671. 'patterns': [
  672. {
  673. 'include': '$self'
  674. }
  675. ]
  676. 'match': '(<<<)\\s*(([^\\s)\\\\]|\\\\.)+)'
  677. 'name': 'meta.herestring.shell'
  678. }
  679. ]
  680. 'interpolation':
  681. 'patterns': [
  682. {
  683. 'begin': '\\$\\({2}'
  684. 'beginCaptures':
  685. '0':
  686. 'name': 'punctuation.definition.string.begin.shell'
  687. 'end': '\\){2}'
  688. 'endCaptures':
  689. '0':
  690. 'name': 'punctuation.definition.string.end.shell'
  691. 'name': 'string.other.math.shell'
  692. 'patterns': [
  693. {
  694. 'include': '#math'
  695. }
  696. ]
  697. }
  698. {
  699. 'begin': '`'
  700. 'beginCaptures':
  701. '0':
  702. 'name': 'punctuation.definition.string.begin.shell'
  703. 'end': '`'
  704. 'endCaptures':
  705. '0':
  706. 'name': 'punctuation.definition.string.end.shell'
  707. 'name': 'string.interpolated.backtick.shell'
  708. 'patterns': [
  709. {
  710. 'match': '\\\\[`\\\\$]'
  711. 'name': 'constant.character.escape.shell'
  712. }
  713. {
  714. # Lifted from the #comment section to handle ending on ` instead of $
  715. 'begin': '(?<=\\W)(?=#)(?!#{)'
  716. 'beginCaptures':
  717. '1':
  718. 'name': 'punctuation.whitespace.comment.leading.shell'
  719. 'end': '(?!\\G)'
  720. 'patterns': [
  721. {
  722. 'begin': '#'
  723. 'beginCaptures':
  724. '0':
  725. 'name': 'punctuation.definition.comment.shell'
  726. 'end': '(?=`)'
  727. 'name': 'comment.line.number-sign.shell'
  728. }
  729. ]
  730. }
  731. {
  732. 'include': '$self'
  733. }
  734. ]
  735. }
  736. {
  737. 'begin': '\\$\\('
  738. 'beginCaptures':
  739. '0':
  740. 'name': 'punctuation.definition.string.begin.shell'
  741. 'end': '\\)'
  742. 'endCaptures':
  743. '0':
  744. 'name': 'punctuation.definition.string.end.shell'
  745. 'name': 'string.interpolated.dollar.shell'
  746. 'patterns': [
  747. {
  748. 'include': '$self'
  749. }
  750. ]
  751. }
  752. ]
  753. 'keyword':
  754. 'patterns': [
  755. {
  756. 'match': '(?<=^|;|&|\\s)(then|else|elif|fi|for|in|do|done|select|case|continue|esac|while|until|return)(?=\\s|;|&|$)'
  757. 'name': 'keyword.control.shell'
  758. }
  759. {
  760. 'match': '(?<=^|;|&|\\s)(?:export|declare|typeset|local|readonly)(?=\\s|;|&|$)'
  761. 'name': 'storage.modifier.shell'
  762. }
  763. ]
  764. 'list':
  765. 'patterns': [
  766. {
  767. 'match': ';|&&|&|\\|\\|'
  768. 'name': 'keyword.operator.list.shell'
  769. }
  770. ]
  771. 'logical-expression':
  772. 'patterns': [
  773. {
  774. 'comment': 'do we want a special rule for ( expr )?'
  775. 'match': '=[=~]?|!=?|<|>|&&|\\|\\|'
  776. 'name': 'keyword.operator.logical.shell'
  777. }
  778. {
  779. 'match': '(?<!\\S)-(nt|ot|ef|eq|ne|l[te]|g[te]|[a-hknoprstuwxzOGLSN])'
  780. 'name': 'keyword.operator.logical.shell'
  781. }
  782. ]
  783. 'loop':
  784. 'patterns': [
  785. {
  786. 'begin': '(?<=^|;|&|\\s)(for)\\s+(?=\\({2})'
  787. 'beginCaptures':
  788. '1':
  789. 'name': 'keyword.control.shell'
  790. 'end': '(?<=^|;|&|\\s)done(?=\\s|;|&|$)'
  791. 'endCaptures':
  792. '0':
  793. 'name': 'keyword.control.shell'
  794. 'name': 'meta.scope.for-loop.shell'
  795. 'patterns': [
  796. {
  797. 'include': '$self'
  798. }
  799. ]
  800. }
  801. {
  802. 'begin': '(?<=^|;|&|\\s)(for)\\s+(.+?)\\s+(in)(?=\\s|;|&|$)'
  803. 'beginCaptures':
  804. '1':
  805. 'name': 'keyword.control.shell'
  806. '2':
  807. 'name': 'variable.other.loop.shell'
  808. 'patterns': [
  809. {
  810. 'include': '#string'
  811. }
  812. ]
  813. '3':
  814. 'name': 'keyword.control.shell'
  815. 'end': '(?<=^|;|&|\\s)done(?=\\s|;|&|$)'
  816. 'endCaptures':
  817. '0':
  818. 'name': 'keyword.control.shell'
  819. 'name': 'meta.scope.for-in-loop.shell'
  820. 'patterns': [
  821. {
  822. 'include': '$self'
  823. }
  824. ]
  825. }
  826. {
  827. 'begin': '(?<=^|;|&|\\s)(while|until)(?=\\s|;|&|$)'
  828. 'beginCaptures':
  829. '1':
  830. 'name': 'keyword.control.shell'
  831. 'end': '(?<=^|;|&|\\s)done(?=\\s|;|&|$)'
  832. 'endCaptures':
  833. '0':
  834. 'name': 'keyword.control.shell'
  835. 'name': 'meta.scope.while-loop.shell'
  836. 'patterns': [
  837. {
  838. 'include': '$self'
  839. }
  840. ]
  841. }
  842. {
  843. 'begin': '(?<=^|;|&|\\s)(select)\\s+((?:[^\\s\\\\]|\\\\.)+)(?=\\s|;|&|$)'
  844. 'beginCaptures':
  845. '1':
  846. 'name': 'keyword.control.shell'
  847. '2':
  848. 'name': 'variable.other.loop.shell'
  849. 'end': '(?<=^|;|&|\\s)(done)(?=\\s|;|&|$)'
  850. 'endCaptures':
  851. '1':
  852. 'name': 'keyword.control.shell'
  853. 'name': 'meta.scope.select-block.shell'
  854. 'patterns': [
  855. {
  856. 'include': '$self'
  857. }
  858. ]
  859. }
  860. {
  861. 'begin': '(?<=^|;|&|\\s)case(?=\\s|;|&|$)'
  862. 'beginCaptures':
  863. '0':
  864. 'name': 'keyword.control.shell'
  865. 'end': '(?<=^|;|&|\\s)esac(?=\\s|;|&|$)'
  866. 'endCaptures':
  867. '0':
  868. 'name': 'keyword.control.shell'
  869. 'name': 'meta.scope.case-block.shell'
  870. 'patterns': [
  871. {
  872. 'begin': '(?<=^|;|&|\\s)in(?=\\s|;|&|$)'
  873. 'beginCaptures':
  874. '0':
  875. 'name': 'keyword.control.shell'
  876. 'end': '(?<=^|;|&|\\s)(?=esac(\\s|;|&|$))'
  877. 'name': 'meta.scope.case-body.shell'
  878. 'patterns': [
  879. {
  880. 'include': '#comment'
  881. }
  882. {
  883. 'include': '#case-clause'
  884. }
  885. {
  886. 'include': '$self'
  887. }
  888. ]
  889. }
  890. {
  891. 'include': '$self'
  892. }
  893. ]
  894. }
  895. {
  896. 'begin': '(?<=^|;|&|\\s)if(?=\\s|;|&|$)'
  897. 'beginCaptures':
  898. '0':
  899. 'name': 'keyword.control.shell'
  900. 'end': '(?<=^|;|&|\\s)fi(?=\\s|;|&|$)'
  901. 'endCaptures':
  902. '0':
  903. 'name': 'keyword.control.shell'
  904. 'name': 'meta.scope.if-block.shell'
  905. 'patterns': [
  906. {
  907. 'include': '$self'
  908. }
  909. ]
  910. }
  911. ]
  912. 'math':
  913. 'patterns': [
  914. {
  915. 'include': '#variable'
  916. }
  917. {
  918. 'match': '\\+{1,2}|-{1,2}|!|~|\\*{1,2}|/|%|<[<=]?|>[>=]?|==|!=|^|\\|{1,2}|&{1,2}|\\?|\\:|,|=|[*/%+\\-&^|]=|<<=|>>='
  919. 'name': 'keyword.operator.arithmetic.shell'
  920. }
  921. {
  922. 'match': '0[xX][0-9A-Fa-f]+'
  923. 'name': 'constant.numeric.hex.shell'
  924. }
  925. {
  926. 'match': '0\\d+'
  927. 'name': 'constant.numeric.octal.shell'
  928. }
  929. {
  930. 'match': '\\d{1,2}#[0-9a-zA-Z@_]+'
  931. 'name': 'constant.numeric.other.shell'
  932. }
  933. {
  934. 'match': '\\d+'
  935. 'name': 'constant.numeric.integer.shell'
  936. }
  937. ]
  938. 'pathname':
  939. 'patterns': [
  940. {
  941. 'match': '(?<=\\s|:|=|^)~'
  942. 'name': 'keyword.operator.tilde.shell'
  943. }
  944. {
  945. 'match': '\\*|\\?'
  946. 'name': 'keyword.operator.glob.shell'
  947. }
  948. {
  949. 'begin': '([?*+@!])(\\()'
  950. 'beginCaptures':
  951. '1':
  952. 'name': 'keyword.operator.extglob.shell'
  953. '2':
  954. 'name': 'punctuation.definition.extglob.shell'
  955. 'end': '\\)'
  956. 'endCaptures':
  957. '0':
  958. 'name': 'punctuation.definition.extglob.shell'
  959. 'name': 'meta.structure.extglob.shell'
  960. 'patterns': [
  961. {
  962. 'include': '$self'
  963. }
  964. ]
  965. }
  966. ]
  967. 'pipeline':
  968. 'patterns': [
  969. {
  970. 'match': '(?<=^|;|&|\\s)(time)(?=\\s|;|&|$)'
  971. 'name': 'keyword.other.shell'
  972. }
  973. {
  974. 'match': '[|!]'
  975. 'name': 'keyword.operator.pipe.shell'
  976. }
  977. ]
  978. 'redirection':
  979. 'patterns': [
  980. {
  981. 'begin': '[><]\\('
  982. 'beginCaptures':
  983. '0':
  984. 'name': 'punctuation.definition.string.begin.shell'
  985. 'end': '\\)'
  986. 'endCaptures':
  987. '0':
  988. 'name': 'punctuation.definition.string.end.shell'
  989. 'name': 'string.interpolated.process-substitution.shell'
  990. 'patterns': [
  991. {
  992. 'include': '$self'
  993. }
  994. ]
  995. }
  996. {
  997. # valid: &>word >&word >word [n]>&[n] [n]<word [n]>word [n]>>word [n]<&word (last one is duplicate)
  998. 'match': '(?<![<>])(&>|\\d*>&\\d*|\\d*(>>|>|<)|\\d*<&|\\d*<>)(?![<>])'
  999. 'name': 'keyword.operator.redirect.shell'
  1000. }
  1001. ]
  1002. 'string':
  1003. 'patterns': [
  1004. {
  1005. 'match': '\\\\.'
  1006. 'name': 'constant.character.escape.shell'
  1007. }
  1008. {
  1009. 'begin': '\''
  1010. 'beginCaptures':
  1011. '0':
  1012. 'name': 'punctuation.definition.string.begin.shell'
  1013. 'end': '\''
  1014. 'endCaptures':
  1015. '0':
  1016. 'name': 'punctuation.definition.string.end.shell'
  1017. 'name': 'string.quoted.single.shell'
  1018. }
  1019. {
  1020. 'begin': '\\$?"'
  1021. 'beginCaptures':
  1022. '0':
  1023. 'name': 'punctuation.definition.string.begin.shell'
  1024. 'end': '"'
  1025. 'endCaptures':
  1026. '0':
  1027. 'name': 'punctuation.definition.string.end.shell'
  1028. 'name': 'string.quoted.double.shell'
  1029. 'patterns': [
  1030. {
  1031. 'match': '\\\\[\\$`"\\\\\\n]'
  1032. 'name': 'constant.character.escape.shell'
  1033. }
  1034. {
  1035. 'include': '#variable'
  1036. }
  1037. {
  1038. 'include': '#interpolation'
  1039. }
  1040. ]
  1041. }
  1042. {
  1043. 'begin': '\\$\''
  1044. 'beginCaptures':
  1045. '0':
  1046. 'name': 'punctuation.definition.string.begin.shell'
  1047. 'end': '\''
  1048. 'endCaptures':
  1049. '0':
  1050. 'name': 'punctuation.definition.string.end.shell'
  1051. 'name': 'string.quoted.single.dollar.shell'
  1052. 'patterns': [
  1053. {
  1054. 'match': '\\\\(a|b|e|f|n|r|t|v|\\\\|\')'
  1055. 'name': 'constant.character.escape.ansi-c.shell'
  1056. }
  1057. {
  1058. 'match': '\\\\[0-9]{3}'
  1059. 'name': 'constant.character.escape.octal.shell'
  1060. }
  1061. {
  1062. 'match': '\\\\x[0-9a-fA-F]{2}'
  1063. 'name': 'constant.character.escape.hex.shell'
  1064. }
  1065. {
  1066. 'match': '\\\\c.'
  1067. 'name': 'constant.character.escape.control-char.shell'
  1068. }
  1069. ]
  1070. }
  1071. ]
  1072. 'support':
  1073. 'patterns': [
  1074. {
  1075. 'match': '(?<=^|;|&|\\s)(?::|\\.)(?=\\s|;|&|$)'
  1076. 'name': 'support.function.builtin.shell'
  1077. }
  1078. {
  1079. 'match': '(?<=^|;|&|\\s)(?:alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|times|trap|true|type|ulimit|umask|unalias|unset|wait)(?=\\s|;|&|$)'
  1080. 'name': 'support.function.builtin.shell'
  1081. }
  1082. ]
  1083. 'variable':
  1084. 'patterns': [
  1085. {
  1086. 'captures':
  1087. '1':
  1088. 'name': 'punctuation.definition.variable.shell'
  1089. 'match': '(\\$)[a-zA-Z_][a-zA-Z0-9_]*'
  1090. 'name': 'variable.other.normal.shell'
  1091. }
  1092. {
  1093. 'captures':
  1094. '1':
  1095. 'name': 'punctuation.definition.variable.shell'
  1096. 'match': '(\\$)[-*@#?$!0_]'
  1097. 'name': 'variable.other.special.shell'
  1098. }
  1099. {
  1100. 'captures':
  1101. '1':
  1102. 'name': 'punctuation.definition.variable.shell'
  1103. 'match': '(\\$)[1-9]'
  1104. 'name': 'variable.other.positional.shell'
  1105. }
  1106. {
  1107. 'begin': '\\${'
  1108. 'beginCaptures':
  1109. '0':
  1110. 'name': 'punctuation.definition.variable.shell'
  1111. 'end': '}'
  1112. 'endCaptures':
  1113. '0':
  1114. 'name': 'punctuation.definition.variable.shell'
  1115. 'name': 'variable.other.bracket.shell'
  1116. 'patterns': [
  1117. {
  1118. 'match': '!|:[-=?]?|\\*|@|\#\{1,2}|%{1,2}|/' # #{ is escaped to prevent coffeelint complaining about interpolation
  1119. 'name': 'keyword.operator.expansion.shell'
  1120. }
  1121. {
  1122. 'captures':
  1123. '1':
  1124. 'name': 'punctuation.section.array.shell'
  1125. '3':
  1126. 'name': 'punctuation.section.array.shell'
  1127. 'match': '(\\[)([^\\]]+)(\\])'
  1128. }
  1129. {
  1130. 'include': '#variable'
  1131. }
  1132. {
  1133. 'include': '#string'
  1134. }
  1135. ]
  1136. }
  1137. ]