Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pygments/lexers/shell.py: 83%

205 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-01 06:54 +0000

1""" 

2 pygments.lexers.shell 

3 ~~~~~~~~~~~~~~~~~~~~~ 

4 

5 Lexers for various shells. 

6 

7 :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS. 

8 :license: BSD, see LICENSE for details. 

9""" 

10 

11import re 

12 

13from pygments.lexer import Lexer, RegexLexer, do_insertions, bygroups, \ 

14 include, default, this, using, words, line_re 

15from pygments.token import Punctuation, Whitespace, \ 

16 Text, Comment, Operator, Keyword, Name, String, Number, Generic 

17from pygments.util import shebang_matches 

18 

19__all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer', 

20 'SlurmBashLexer', 'MSDOSSessionLexer', 'PowerShellLexer', 

21 'PowerShellSessionLexer', 'TcshSessionLexer', 'FishShellLexer', 

22 'ExeclineLexer'] 

23 

24 

25class BashLexer(RegexLexer): 

26 """ 

27 Lexer for (ba|k|z|)sh shell scripts. 

28 

29 .. versionadded:: 0.6 

30 """ 

31 

32 name = 'Bash' 

33 aliases = ['bash', 'sh', 'ksh', 'zsh', 'shell'] 

34 filenames = ['*.sh', '*.ksh', '*.bash', '*.ebuild', '*.eclass', 

35 '*.exheres-0', '*.exlib', '*.zsh', 

36 '.bashrc', 'bashrc', '.bash_*', 'bash_*', 'zshrc', '.zshrc', 

37 '.kshrc', 'kshrc', 

38 'PKGBUILD'] 

39 mimetypes = ['application/x-sh', 'application/x-shellscript', 'text/x-shellscript'] 

40 

41 tokens = { 

42 'root': [ 

43 include('basic'), 

44 (r'`', String.Backtick, 'backticks'), 

45 include('data'), 

46 include('interp'), 

47 ], 

48 'interp': [ 

49 (r'\$\(\(', Keyword, 'math'), 

50 (r'\$\(', Keyword, 'paren'), 

51 (r'\$\{#?', String.Interpol, 'curly'), 

52 (r'\$[a-zA-Z_]\w*', Name.Variable), # user variable 

53 (r'\$(?:\d+|[#$?!_*@-])', Name.Variable), # builtin 

54 (r'\$', Text), 

55 ], 

56 'basic': [ 

57 (r'\b(if|fi|else|while|in|do|done|for|then|return|function|case|' 

58 r'select|break|continue|until|esac|elif)(\s*)\b', 

59 bygroups(Keyword, Whitespace)), 

60 (r'\b(alias|bg|bind|builtin|caller|cd|command|compgen|' 

61 r'complete|declare|dirs|disown|echo|enable|eval|exec|exit|' 

62 r'export|false|fc|fg|getopts|hash|help|history|jobs|kill|let|' 

63 r'local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|' 

64 r'shopt|source|suspend|test|time|times|trap|true|type|typeset|' 

65 r'ulimit|umask|unalias|unset|wait)(?=[\s)`])', 

66 Name.Builtin), 

67 (r'\A#!.+\n', Comment.Hashbang), 

68 (r'#.*\n', Comment.Single), 

69 (r'\\[\w\W]', String.Escape), 

70 (r'(\b\w+)(\s*)(\+?=)', bygroups(Name.Variable, Whitespace, Operator)), 

71 (r'[\[\]{}()=]', Operator), 

72 (r'<<<', Operator), # here-string 

73 (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String), 

74 (r'&&|\|\|', Operator), 

75 ], 

76 'data': [ 

77 (r'(?s)\$?"(\\.|[^"\\$])*"', String.Double), 

78 (r'"', String.Double, 'string'), 

79 (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single), 

80 (r"(?s)'.*?'", String.Single), 

81 (r';', Punctuation), 

82 (r'&', Punctuation), 

83 (r'\|', Punctuation), 

84 (r'\s+', Whitespace), 

85 (r'\d+\b', Number), 

86 (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text), 

87 (r'<', Text), 

88 ], 

89 'string': [ 

90 (r'"', String.Double, '#pop'), 

91 (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double), 

92 include('interp'), 

93 ], 

94 'curly': [ 

95 (r'\}', String.Interpol, '#pop'), 

96 (r':-', Keyword), 

97 (r'\w+', Name.Variable), 

98 (r'[^}:"\'`$\\]+', Punctuation), 

99 (r':', Punctuation), 

100 include('root'), 

101 ], 

102 'paren': [ 

103 (r'\)', Keyword, '#pop'), 

104 include('root'), 

105 ], 

106 'math': [ 

107 (r'\)\)', Keyword, '#pop'), 

108 (r'\*\*|\|\||<<|>>|[-+*/%^|&<>]', Operator), 

109 (r'\d+#[\da-zA-Z]+', Number), 

110 (r'\d+#(?! )', Number), 

111 (r'0[xX][\da-fA-F]+', Number), 

112 (r'\d+', Number), 

113 (r'[a-zA-Z_]\w*', Name.Variable), # user variable 

114 include('root'), 

115 ], 

116 'backticks': [ 

117 (r'`', String.Backtick, '#pop'), 

118 include('root'), 

119 ], 

120 } 

121 

122 def analyse_text(text): 

123 if shebang_matches(text, r'(ba|z|)sh'): 

124 return 1 

125 if text.startswith('$ '): 

126 return 0.2 

127 

128 

129class SlurmBashLexer(BashLexer): 

130 """ 

131 Lexer for (ba|k|z|)sh Slurm scripts. 

132 

133 .. versionadded:: 2.4 

134 """ 

135 

136 name = 'Slurm' 

137 aliases = ['slurm', 'sbatch'] 

138 filenames = ['*.sl'] 

139 mimetypes = [] 

140 EXTRA_KEYWORDS = {'srun'} 

141 

142 def get_tokens_unprocessed(self, text): 

143 for index, token, value in BashLexer.get_tokens_unprocessed(self, text): 

144 if token is Text and value in self.EXTRA_KEYWORDS: 

145 yield index, Name.Builtin, value 

146 elif token is Comment.Single and 'SBATCH' in value: 

147 yield index, Keyword.Pseudo, value 

148 else: 

149 yield index, token, value 

150 

151 

152class ShellSessionBaseLexer(Lexer): 

153 """ 

154 Base lexer for shell sessions. 

155 

156 .. versionadded:: 2.1 

157 """ 

158 

159 _bare_continuation = False 

160 _venv = re.compile(r'^(\([^)]*\))(\s*)') 

161 

162 def get_tokens_unprocessed(self, text): 

163 innerlexer = self._innerLexerCls(**self.options) 

164 

165 pos = 0 

166 curcode = '' 

167 insertions = [] 

168 backslash_continuation = False 

169 

170 for match in line_re.finditer(text): 

171 line = match.group() 

172 

173 venv_match = self._venv.match(line) 

174 if venv_match: 

175 venv = venv_match.group(1) 

176 venv_whitespace = venv_match.group(2) 

177 insertions.append((len(curcode), 

178 [(0, Generic.Prompt.VirtualEnv, venv)])) 

179 if venv_whitespace: 

180 insertions.append((len(curcode), 

181 [(0, Text, venv_whitespace)])) 

182 line = line[venv_match.end():] 

183 

184 m = self._ps1rgx.match(line) 

185 if m: 

186 # To support output lexers (say diff output), the output 

187 # needs to be broken by prompts whenever the output lexer 

188 # changes. 

189 if not insertions: 

190 pos = match.start() 

191 

192 insertions.append((len(curcode), 

193 [(0, Generic.Prompt, m.group(1))])) 

194 curcode += m.group(2) 

195 backslash_continuation = curcode.endswith('\\\n') 

196 elif backslash_continuation: 

197 if line.startswith(self._ps2): 

198 insertions.append((len(curcode), 

199 [(0, Generic.Prompt, 

200 line[:len(self._ps2)])])) 

201 curcode += line[len(self._ps2):] 

202 else: 

203 curcode += line 

204 backslash_continuation = curcode.endswith('\\\n') 

205 elif self._bare_continuation and line.startswith(self._ps2): 

206 insertions.append((len(curcode), 

207 [(0, Generic.Prompt, 

208 line[:len(self._ps2)])])) 

209 curcode += line[len(self._ps2):] 

210 else: 

211 if insertions: 

212 toks = innerlexer.get_tokens_unprocessed(curcode) 

213 for i, t, v in do_insertions(insertions, toks): 

214 yield pos+i, t, v 

215 yield match.start(), Generic.Output, line 

216 insertions = [] 

217 curcode = '' 

218 if insertions: 

219 for i, t, v in do_insertions(insertions, 

220 innerlexer.get_tokens_unprocessed(curcode)): 

221 yield pos+i, t, v 

222 

223 

224class BashSessionLexer(ShellSessionBaseLexer): 

225 """ 

226 Lexer for Bash shell sessions, i.e. command lines, including a 

227 prompt, interspersed with output. 

228 

229 .. versionadded:: 1.1 

230 """ 

231 

232 name = 'Bash Session' 

233 aliases = ['console', 'shell-session'] 

234 filenames = ['*.sh-session', '*.shell-session'] 

235 mimetypes = ['application/x-shell-session', 'application/x-sh-session'] 

236 

237 _innerLexerCls = BashLexer 

238 _ps1rgx = re.compile( 

239 r'^((?:(?:\[.*?\])|(?:\(\S+\))?(?:| |sh\S*?|\w+\S+[@:]\S+(?:\s+\S+)' \ 

240 r'?|\[\S+[@:][^\n]+\].+))\s*[$#%]\s*)(.*\n?)') 

241 _ps2 = '> ' 

242 

243 

244class BatchLexer(RegexLexer): 

245 """ 

246 Lexer for the DOS/Windows Batch file format. 

247 

248 .. versionadded:: 0.7 

249 """ 

250 name = 'Batchfile' 

251 aliases = ['batch', 'bat', 'dosbatch', 'winbatch'] 

252 filenames = ['*.bat', '*.cmd'] 

253 mimetypes = ['application/x-dos-batch'] 

254 

255 flags = re.MULTILINE | re.IGNORECASE 

256 

257 _nl = r'\n\x1a' 

258 _punct = r'&<>|' 

259 _ws = r'\t\v\f\r ,;=\xa0' 

260 _nlws = r'\s\x1a\xa0,;=' 

261 _space = r'(?:(?:(?:\^[%s])?[%s])+)' % (_nl, _ws) 

262 _keyword_terminator = (r'(?=(?:\^[%s]?)?[%s+./:[\\\]]|[%s%s(])' % 

263 (_nl, _ws, _nl, _punct)) 

264 _token_terminator = r'(?=\^?[%s]|[%s%s])' % (_ws, _punct, _nl) 

265 _start_label = r'((?:(?<=^[^:])|^[^:]?)[%s]*)(:)' % _ws 

266 _label = r'(?:(?:[^%s%s+:^]|\^[%s]?[\w\W])*)' % (_nlws, _punct, _nl) 

267 _label_compound = r'(?:(?:[^%s%s+:^)]|\^[%s]?[^)])*)' % (_nlws, _punct, _nl) 

268 _number = r'(?:-?(?:0[0-7]+|0x[\da-f]+|\d+)%s)' % _token_terminator 

269 _opword = r'(?:equ|geq|gtr|leq|lss|neq)' 

270 _string = r'(?:"[^%s"]*(?:"|(?=[%s])))' % (_nl, _nl) 

271 _variable = (r'(?:(?:%%(?:\*|(?:~[a-z]*(?:\$[^:]+:)?)?\d|' 

272 r'[^%%:%s]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:[^%%%s^]|' 

273 r'\^[^%%%s])[^=%s]*=(?:[^%%%s^]|\^[^%%%s])*)?)?%%))|' 

274 r'(?:\^?![^!:%s]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:' 

275 r'[^!%s^]|\^[^!%s])[^=%s]*=(?:[^!%s^]|\^[^!%s])*)?)?\^?!))' % 

276 (_nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl)) 

277 _core_token = r'(?:(?:(?:\^[%s]?)?[^"%s%s])+)' % (_nl, _nlws, _punct) 

278 _core_token_compound = r'(?:(?:(?:\^[%s]?)?[^"%s%s)])+)' % (_nl, _nlws, _punct) 

279 _token = r'(?:[%s]+|%s)' % (_punct, _core_token) 

280 _token_compound = r'(?:[%s]+|%s)' % (_punct, _core_token_compound) 

281 _stoken = (r'(?:[%s]+|(?:%s|%s|%s)+)' % 

282 (_punct, _string, _variable, _core_token)) 

283 

284 def _make_begin_state(compound, _core_token=_core_token, 

285 _core_token_compound=_core_token_compound, 

286 _keyword_terminator=_keyword_terminator, 

287 _nl=_nl, _punct=_punct, _string=_string, 

288 _space=_space, _start_label=_start_label, 

289 _stoken=_stoken, _token_terminator=_token_terminator, 

290 _variable=_variable, _ws=_ws): 

291 rest = '(?:%s|%s|[^"%%%s%s%s])*' % (_string, _variable, _nl, _punct, 

292 ')' if compound else '') 

293 rest_of_line = r'(?:(?:[^%s^]|\^[%s]?[\w\W])*)' % (_nl, _nl) 

294 rest_of_line_compound = r'(?:(?:[^%s^)]|\^[%s]?[^)])*)' % (_nl, _nl) 

295 set_space = r'((?:(?:\^[%s]?)?[^\S\n])*)' % _nl 

296 suffix = '' 

297 if compound: 

298 _keyword_terminator = r'(?:(?=\))|%s)' % _keyword_terminator 

299 _token_terminator = r'(?:(?=\))|%s)' % _token_terminator 

300 suffix = '/compound' 

301 return [ 

302 ((r'\)', Punctuation, '#pop') if compound else 

303 (r'\)((?=\()|%s)%s' % (_token_terminator, rest_of_line), 

304 Comment.Single)), 

305 (r'(?=%s)' % _start_label, Text, 'follow%s' % suffix), 

306 (_space, using(this, state='text')), 

307 include('redirect%s' % suffix), 

308 (r'[%s]+' % _nl, Text), 

309 (r'\(', Punctuation, 'root/compound'), 

310 (r'@+', Punctuation), 

311 (r'((?:for|if|rem)(?:(?=(?:\^[%s]?)?/)|(?:(?!\^)|' 

312 r'(?<=m))(?:(?=\()|%s)))(%s?%s?(?:\^[%s]?)?/(?:\^[%s]?)?\?)' % 

313 (_nl, _token_terminator, _space, 

314 _core_token_compound if compound else _core_token, _nl, _nl), 

315 bygroups(Keyword, using(this, state='text')), 

316 'follow%s' % suffix), 

317 (r'(goto%s)(%s(?:\^[%s]?)?/(?:\^[%s]?)?\?%s)' % 

318 (_keyword_terminator, rest, _nl, _nl, rest), 

319 bygroups(Keyword, using(this, state='text')), 

320 'follow%s' % suffix), 

321 (words(('assoc', 'break', 'cd', 'chdir', 'cls', 'color', 'copy', 

322 'date', 'del', 'dir', 'dpath', 'echo', 'endlocal', 'erase', 

323 'exit', 'ftype', 'keys', 'md', 'mkdir', 'mklink', 'move', 

324 'path', 'pause', 'popd', 'prompt', 'pushd', 'rd', 'ren', 

325 'rename', 'rmdir', 'setlocal', 'shift', 'start', 'time', 

326 'title', 'type', 'ver', 'verify', 'vol'), 

327 suffix=_keyword_terminator), Keyword, 'follow%s' % suffix), 

328 (r'(call)(%s?)(:)' % _space, 

329 bygroups(Keyword, using(this, state='text'), Punctuation), 

330 'call%s' % suffix), 

331 (r'call%s' % _keyword_terminator, Keyword), 

332 (r'(for%s(?!\^))(%s)(/f%s)' % 

333 (_token_terminator, _space, _token_terminator), 

334 bygroups(Keyword, using(this, state='text'), Keyword), 

335 ('for/f', 'for')), 

336 (r'(for%s(?!\^))(%s)(/l%s)' % 

337 (_token_terminator, _space, _token_terminator), 

338 bygroups(Keyword, using(this, state='text'), Keyword), 

339 ('for/l', 'for')), 

340 (r'for%s(?!\^)' % _token_terminator, Keyword, ('for2', 'for')), 

341 (r'(goto%s)(%s?)(:?)' % (_keyword_terminator, _space), 

342 bygroups(Keyword, using(this, state='text'), Punctuation), 

343 'label%s' % suffix), 

344 (r'(if(?:(?=\()|%s)(?!\^))(%s?)((?:/i%s)?)(%s?)((?:not%s)?)(%s?)' % 

345 (_token_terminator, _space, _token_terminator, _space, 

346 _token_terminator, _space), 

347 bygroups(Keyword, using(this, state='text'), Keyword, 

348 using(this, state='text'), Keyword, 

349 using(this, state='text')), ('(?', 'if')), 

350 (r'rem(((?=\()|%s)%s?%s?.*|%s%s)' % 

351 (_token_terminator, _space, _stoken, _keyword_terminator, 

352 rest_of_line_compound if compound else rest_of_line), 

353 Comment.Single, 'follow%s' % suffix), 

354 (r'(set%s)%s(/a)' % (_keyword_terminator, set_space), 

355 bygroups(Keyword, using(this, state='text'), Keyword), 

356 'arithmetic%s' % suffix), 

357 (r'(set%s)%s((?:/p)?)%s((?:(?:(?:\^[%s]?)?[^"%s%s^=%s]|' 

358 r'\^[%s]?[^"=])+)?)((?:(?:\^[%s]?)?=)?)' % 

359 (_keyword_terminator, set_space, set_space, _nl, _nl, _punct, 

360 ')' if compound else '', _nl, _nl), 

361 bygroups(Keyword, using(this, state='text'), Keyword, 

362 using(this, state='text'), using(this, state='variable'), 

363 Punctuation), 

364 'follow%s' % suffix), 

365 default('follow%s' % suffix) 

366 ] 

367 

368 def _make_follow_state(compound, _label=_label, 

369 _label_compound=_label_compound, _nl=_nl, 

370 _space=_space, _start_label=_start_label, 

371 _token=_token, _token_compound=_token_compound, 

372 _ws=_ws): 

373 suffix = '/compound' if compound else '' 

374 state = [] 

375 if compound: 

376 state.append((r'(?=\))', Text, '#pop')) 

377 state += [ 

378 (r'%s([%s]*)(%s)(.*)' % 

379 (_start_label, _ws, _label_compound if compound else _label), 

380 bygroups(Text, Punctuation, Text, Name.Label, Comment.Single)), 

381 include('redirect%s' % suffix), 

382 (r'(?=[%s])' % _nl, Text, '#pop'), 

383 (r'\|\|?|&&?', Punctuation, '#pop'), 

384 include('text') 

385 ] 

386 return state 

387 

388 def _make_arithmetic_state(compound, _nl=_nl, _punct=_punct, 

389 _string=_string, _variable=_variable, 

390 _ws=_ws, _nlws=_nlws): 

391 op = r'=+\-*/!~' 

392 state = [] 

393 if compound: 

394 state.append((r'(?=\))', Text, '#pop')) 

395 state += [ 

396 (r'0[0-7]+', Number.Oct), 

397 (r'0x[\da-f]+', Number.Hex), 

398 (r'\d+', Number.Integer), 

399 (r'[(),]+', Punctuation), 

400 (r'([%s]|%%|\^\^)+' % op, Operator), 

401 (r'(%s|%s|(\^[%s]?)?[^()%s%%\^"%s%s]|\^[%s]?%s)+' % 

402 (_string, _variable, _nl, op, _nlws, _punct, _nlws, 

403 r'[^)]' if compound else r'[\w\W]'), 

404 using(this, state='variable')), 

405 (r'(?=[\x00|&])', Text, '#pop'), 

406 include('follow') 

407 ] 

408 return state 

409 

410 def _make_call_state(compound, _label=_label, 

411 _label_compound=_label_compound): 

412 state = [] 

413 if compound: 

414 state.append((r'(?=\))', Text, '#pop')) 

415 state.append((r'(:?)(%s)' % (_label_compound if compound else _label), 

416 bygroups(Punctuation, Name.Label), '#pop')) 

417 return state 

418 

419 def _make_label_state(compound, _label=_label, 

420 _label_compound=_label_compound, _nl=_nl, 

421 _punct=_punct, _string=_string, _variable=_variable): 

422 state = [] 

423 if compound: 

424 state.append((r'(?=\))', Text, '#pop')) 

425 state.append((r'(%s?)((?:%s|%s|\^[%s]?%s|[^"%%^%s%s%s])*)' % 

426 (_label_compound if compound else _label, _string, 

427 _variable, _nl, r'[^)]' if compound else r'[\w\W]', _nl, 

428 _punct, r')' if compound else ''), 

429 bygroups(Name.Label, Comment.Single), '#pop')) 

430 return state 

431 

432 def _make_redirect_state(compound, 

433 _core_token_compound=_core_token_compound, 

434 _nl=_nl, _punct=_punct, _stoken=_stoken, 

435 _string=_string, _space=_space, 

436 _variable=_variable, _nlws=_nlws): 

437 stoken_compound = (r'(?:[%s]+|(?:%s|%s|%s)+)' % 

438 (_punct, _string, _variable, _core_token_compound)) 

439 return [ 

440 (r'((?:(?<=[%s])\d)?)(>>?&|<&)([%s]*)(\d)' % 

441 (_nlws, _nlws), 

442 bygroups(Number.Integer, Punctuation, Text, Number.Integer)), 

443 (r'((?:(?<=[%s])(?<!\^[%s])\d)?)(>>?|<)(%s?%s)' % 

444 (_nlws, _nl, _space, stoken_compound if compound else _stoken), 

445 bygroups(Number.Integer, Punctuation, using(this, state='text'))) 

446 ] 

447 

448 tokens = { 

449 'root': _make_begin_state(False), 

450 'follow': _make_follow_state(False), 

451 'arithmetic': _make_arithmetic_state(False), 

452 'call': _make_call_state(False), 

453 'label': _make_label_state(False), 

454 'redirect': _make_redirect_state(False), 

455 'root/compound': _make_begin_state(True), 

456 'follow/compound': _make_follow_state(True), 

457 'arithmetic/compound': _make_arithmetic_state(True), 

458 'call/compound': _make_call_state(True), 

459 'label/compound': _make_label_state(True), 

460 'redirect/compound': _make_redirect_state(True), 

461 'variable-or-escape': [ 

462 (_variable, Name.Variable), 

463 (r'%%%%|\^[%s]?(\^!|[\w\W])' % _nl, String.Escape) 

464 ], 

465 'string': [ 

466 (r'"', String.Double, '#pop'), 

467 (_variable, Name.Variable), 

468 (r'\^!|%%', String.Escape), 

469 (r'[^"%%^%s]+|[%%^]' % _nl, String.Double), 

470 default('#pop') 

471 ], 

472 'sqstring': [ 

473 include('variable-or-escape'), 

474 (r'[^%]+|%', String.Single) 

475 ], 

476 'bqstring': [ 

477 include('variable-or-escape'), 

478 (r'[^%]+|%', String.Backtick) 

479 ], 

480 'text': [ 

481 (r'"', String.Double, 'string'), 

482 include('variable-or-escape'), 

483 (r'[^"%%^%s%s\d)]+|.' % (_nlws, _punct), Text) 

484 ], 

485 'variable': [ 

486 (r'"', String.Double, 'string'), 

487 include('variable-or-escape'), 

488 (r'[^"%%^%s]+|.' % _nl, Name.Variable) 

489 ], 

490 'for': [ 

491 (r'(%s)(in)(%s)(\()' % (_space, _space), 

492 bygroups(using(this, state='text'), Keyword, 

493 using(this, state='text'), Punctuation), '#pop'), 

494 include('follow') 

495 ], 

496 'for2': [ 

497 (r'\)', Punctuation), 

498 (r'(%s)(do%s)' % (_space, _token_terminator), 

499 bygroups(using(this, state='text'), Keyword), '#pop'), 

500 (r'[%s]+' % _nl, Text), 

501 include('follow') 

502 ], 

503 'for/f': [ 

504 (r'(")((?:%s|[^"])*?")([%s]*)(\))' % (_variable, _nlws), 

505 bygroups(String.Double, using(this, state='string'), Text, 

506 Punctuation)), 

507 (r'"', String.Double, ('#pop', 'for2', 'string')), 

508 (r"('(?:%%%%|%s|[\w\W])*?')([%s]*)(\))" % (_variable, _nlws), 

509 bygroups(using(this, state='sqstring'), Text, Punctuation)), 

510 (r'(`(?:%%%%|%s|[\w\W])*?`)([%s]*)(\))' % (_variable, _nlws), 

511 bygroups(using(this, state='bqstring'), Text, Punctuation)), 

512 include('for2') 

513 ], 

514 'for/l': [ 

515 (r'-?\d+', Number.Integer), 

516 include('for2') 

517 ], 

518 'if': [ 

519 (r'((?:cmdextversion|errorlevel)%s)(%s)(\d+)' % 

520 (_token_terminator, _space), 

521 bygroups(Keyword, using(this, state='text'), 

522 Number.Integer), '#pop'), 

523 (r'(defined%s)(%s)(%s)' % (_token_terminator, _space, _stoken), 

524 bygroups(Keyword, using(this, state='text'), 

525 using(this, state='variable')), '#pop'), 

526 (r'(exist%s)(%s%s)' % (_token_terminator, _space, _stoken), 

527 bygroups(Keyword, using(this, state='text')), '#pop'), 

528 (r'(%s%s)(%s)(%s%s)' % (_number, _space, _opword, _space, _number), 

529 bygroups(using(this, state='arithmetic'), Operator.Word, 

530 using(this, state='arithmetic')), '#pop'), 

531 (_stoken, using(this, state='text'), ('#pop', 'if2')), 

532 ], 

533 'if2': [ 

534 (r'(%s?)(==)(%s?%s)' % (_space, _space, _stoken), 

535 bygroups(using(this, state='text'), Operator, 

536 using(this, state='text')), '#pop'), 

537 (r'(%s)(%s)(%s%s)' % (_space, _opword, _space, _stoken), 

538 bygroups(using(this, state='text'), Operator.Word, 

539 using(this, state='text')), '#pop') 

540 ], 

541 '(?': [ 

542 (_space, using(this, state='text')), 

543 (r'\(', Punctuation, ('#pop', 'else?', 'root/compound')), 

544 default('#pop') 

545 ], 

546 'else?': [ 

547 (_space, using(this, state='text')), 

548 (r'else%s' % _token_terminator, Keyword, '#pop'), 

549 default('#pop') 

550 ] 

551 } 

552 

553 

554class MSDOSSessionLexer(ShellSessionBaseLexer): 

555 """ 

556 Lexer for MS DOS shell sessions, i.e. command lines, including a 

557 prompt, interspersed with output. 

558 

559 .. versionadded:: 2.1 

560 """ 

561 

562 name = 'MSDOS Session' 

563 aliases = ['doscon'] 

564 filenames = [] 

565 mimetypes = [] 

566 

567 _innerLexerCls = BatchLexer 

568 _ps1rgx = re.compile(r'^([^>]*>)(.*\n?)') 

569 _ps2 = 'More? ' 

570 

571 

572class TcshLexer(RegexLexer): 

573 """ 

574 Lexer for tcsh scripts. 

575 

576 .. versionadded:: 0.10 

577 """ 

578 

579 name = 'Tcsh' 

580 aliases = ['tcsh', 'csh'] 

581 filenames = ['*.tcsh', '*.csh'] 

582 mimetypes = ['application/x-csh'] 

583 

584 tokens = { 

585 'root': [ 

586 include('basic'), 

587 (r'\$\(', Keyword, 'paren'), 

588 (r'\$\{#?', Keyword, 'curly'), 

589 (r'`', String.Backtick, 'backticks'), 

590 include('data'), 

591 ], 

592 'basic': [ 

593 (r'\b(if|endif|else|while|then|foreach|case|default|' 

594 r'break|continue|goto|breaksw|end|switch|endsw)\s*\b', 

595 Keyword), 

596 (r'\b(alias|alloc|bg|bindkey|builtins|bye|caller|cd|chdir|' 

597 r'complete|dirs|echo|echotc|eval|exec|exit|fg|filetest|getxvers|' 

598 r'glob|getspath|hashstat|history|hup|inlib|jobs|kill|' 

599 r'limit|log|login|logout|ls-F|migrate|newgrp|nice|nohup|notify|' 

600 r'onintr|popd|printenv|pushd|rehash|repeat|rootnode|popd|pushd|' 

601 r'set|shift|sched|setenv|setpath|settc|setty|setxvers|shift|' 

602 r'source|stop|suspend|source|suspend|telltc|time|' 

603 r'umask|unalias|uncomplete|unhash|universe|unlimit|unset|unsetenv|' 

604 r'ver|wait|warp|watchlog|where|which)\s*\b', 

605 Name.Builtin), 

606 (r'#.*', Comment), 

607 (r'\\[\w\W]', String.Escape), 

608 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)), 

609 (r'[\[\]{}()=]+', Operator), 

610 (r'<<\s*(\'?)\\?(\w+)[\w\W]+?\2', String), 

611 (r';', Punctuation), 

612 ], 

613 'data': [ 

614 (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double), 

615 (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single), 

616 (r'\s+', Text), 

617 (r'[^=\s\[\]{}()$"\'`\\;#]+', Text), 

618 (r'\d+(?= |\Z)', Number), 

619 (r'\$#?(\w+|.)', Name.Variable), 

620 ], 

621 'curly': [ 

622 (r'\}', Keyword, '#pop'), 

623 (r':-', Keyword), 

624 (r'\w+', Name.Variable), 

625 (r'[^}:"\'`$]+', Punctuation), 

626 (r':', Punctuation), 

627 include('root'), 

628 ], 

629 'paren': [ 

630 (r'\)', Keyword, '#pop'), 

631 include('root'), 

632 ], 

633 'backticks': [ 

634 (r'`', String.Backtick, '#pop'), 

635 include('root'), 

636 ], 

637 } 

638 

639 

640class TcshSessionLexer(ShellSessionBaseLexer): 

641 """ 

642 Lexer for Tcsh sessions, i.e. command lines, including a 

643 prompt, interspersed with output. 

644 

645 .. versionadded:: 2.1 

646 """ 

647 

648 name = 'Tcsh Session' 

649 aliases = ['tcshcon'] 

650 filenames = [] 

651 mimetypes = [] 

652 

653 _innerLexerCls = TcshLexer 

654 _ps1rgx = re.compile(r'^([^>]+>)(.*\n?)') 

655 _ps2 = '? ' 

656 

657 

658class PowerShellLexer(RegexLexer): 

659 """ 

660 For Windows PowerShell code. 

661 

662 .. versionadded:: 1.5 

663 """ 

664 name = 'PowerShell' 

665 aliases = ['powershell', 'pwsh', 'posh', 'ps1', 'psm1'] 

666 filenames = ['*.ps1', '*.psm1'] 

667 mimetypes = ['text/x-powershell'] 

668 

669 flags = re.DOTALL | re.IGNORECASE | re.MULTILINE 

670 

671 keywords = ( 

672 'while validateset validaterange validatepattern validatelength ' 

673 'validatecount until trap switch return ref process param parameter in ' 

674 'if global: local: function foreach for finally filter end elseif else ' 

675 'dynamicparam do default continue cmdletbinding break begin alias \\? ' 

676 '% #script #private #local #global mandatory parametersetname position ' 

677 'valuefrompipeline valuefrompipelinebypropertyname ' 

678 'valuefromremainingarguments helpmessage try catch throw').split() 

679 

680 operators = ( 

681 'and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle ' 

682 'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains ' 

683 'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt ' 

684 'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like ' 

685 'lt match ne not notcontains notlike notmatch or regex replace ' 

686 'wildcard').split() 

687 

688 verbs = ( 

689 'write where watch wait use update unregister unpublish unprotect ' 

690 'unlock uninstall undo unblock trace test tee take sync switch ' 

691 'suspend submit stop step start split sort skip show set send select ' 

692 'search scroll save revoke resume restore restart resolve resize ' 

693 'reset request repair rename remove register redo receive read push ' 

694 'publish protect pop ping out optimize open new move mount merge ' 

695 'measure lock limit join invoke install initialize import hide group ' 

696 'grant get format foreach find export expand exit enter enable edit ' 

697 'dismount disconnect disable deny debug cxnew copy convertto ' 

698 'convertfrom convert connect confirm compress complete compare close ' 

699 'clear checkpoint block backup assert approve aggregate add').split() 

700 

701 aliases_ = ( 

702 'ac asnp cat cd cfs chdir clc clear clhy cli clp cls clv cnsn ' 

703 'compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo epal ' 

704 'epcsv epsn erase etsn exsn fc fhx fl foreach ft fw gal gbp gc gci gcm ' 

705 'gcs gdr ghy gi gjb gl gm gmo gp gps gpv group gsn gsnp gsv gu gv gwmi ' 

706 'h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ' 

707 'ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv ' 

708 'oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo ' 

709 'rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc select ' 

710 'set shcm si sl sleep sls sort sp spjb spps spsv start sujb sv swmi tee ' 

711 'trcm type wget where wjb write').split() 

712 

713 commenthelp = ( 

714 'component description example externalhelp forwardhelpcategory ' 

715 'forwardhelptargetname functionality inputs link ' 

716 'notes outputs parameter remotehelprunspace role synopsis').split() 

717 

718 tokens = { 

719 'root': [ 

720 # we need to count pairs of parentheses for correct highlight 

721 # of '$(...)' blocks in strings 

722 (r'\(', Punctuation, 'child'), 

723 (r'\s+', Text), 

724 (r'^(\s*#[#\s]*)(\.(?:%s))([^\n]*$)' % '|'.join(commenthelp), 

725 bygroups(Comment, String.Doc, Comment)), 

726 (r'#[^\n]*?$', Comment), 

727 (r'(&lt;|<)#', Comment.Multiline, 'multline'), 

728 (r'@"\n', String.Heredoc, 'heredoc-double'), 

729 (r"@'\n.*?\n'@", String.Heredoc), 

730 # escaped syntax 

731 (r'`[\'"$@-]', Punctuation), 

732 (r'"', String.Double, 'string'), 

733 (r"'([^']|'')*'", String.Single), 

734 (r'(\$|@@|@)((global|script|private|env):)?\w+', 

735 Name.Variable), 

736 (r'(%s)\b' % '|'.join(keywords), Keyword), 

737 (r'-(%s)\b' % '|'.join(operators), Operator), 

738 (r'(%s)-[a-z_]\w*\b' % '|'.join(verbs), Name.Builtin), 

739 (r'(%s)\s' % '|'.join(aliases_), Name.Builtin), 

740 (r'\[[a-z_\[][\w. `,\[\]]*\]', Name.Constant), # .net [type]s 

741 (r'-[a-z_]\w*', Name), 

742 (r'\w+', Name), 

743 (r'[.,;:@{}\[\]$()=+*/\\&%!~?^`|<>-]', Punctuation), 

744 ], 

745 'child': [ 

746 (r'\)', Punctuation, '#pop'), 

747 include('root'), 

748 ], 

749 'multline': [ 

750 (r'[^#&.]+', Comment.Multiline), 

751 (r'#(>|&gt;)', Comment.Multiline, '#pop'), 

752 (r'\.(%s)' % '|'.join(commenthelp), String.Doc), 

753 (r'[#&.]', Comment.Multiline), 

754 ], 

755 'string': [ 

756 (r"`[0abfnrtv'\"$`]", String.Escape), 

757 (r'[^$`"]+', String.Double), 

758 (r'\$\(', Punctuation, 'child'), 

759 (r'""', String.Double), 

760 (r'[`$]', String.Double), 

761 (r'"', String.Double, '#pop'), 

762 ], 

763 'heredoc-double': [ 

764 (r'\n"@', String.Heredoc, '#pop'), 

765 (r'\$\(', Punctuation, 'child'), 

766 (r'[^@\n]+"]', String.Heredoc), 

767 (r".", String.Heredoc), 

768 ] 

769 } 

770 

771 

772class PowerShellSessionLexer(ShellSessionBaseLexer): 

773 """ 

774 Lexer for PowerShell sessions, i.e. command lines, including a 

775 prompt, interspersed with output. 

776 

777 .. versionadded:: 2.1 

778 """ 

779 

780 name = 'PowerShell Session' 

781 aliases = ['pwsh-session', 'ps1con'] 

782 filenames = [] 

783 mimetypes = [] 

784 

785 _innerLexerCls = PowerShellLexer 

786 _bare_continuation = True 

787 _ps1rgx = re.compile(r'^((?:\[[^]]+\]: )?PS[^>]*> ?)(.*\n?)') 

788 _ps2 = '> ' 

789 

790 

791class FishShellLexer(RegexLexer): 

792 """ 

793 Lexer for Fish shell scripts. 

794 

795 .. versionadded:: 2.1 

796 """ 

797 

798 name = 'Fish' 

799 aliases = ['fish', 'fishshell'] 

800 filenames = ['*.fish', '*.load'] 

801 mimetypes = ['application/x-fish'] 

802 

803 tokens = { 

804 'root': [ 

805 include('basic'), 

806 include('data'), 

807 include('interp'), 

808 ], 

809 'interp': [ 

810 (r'\$\(\(', Keyword, 'math'), 

811 (r'\(', Keyword, 'paren'), 

812 (r'\$#?(\w+|.)', Name.Variable), 

813 ], 

814 'basic': [ 

815 (r'\b(begin|end|if|else|while|break|for|in|return|function|block|' 

816 r'case|continue|switch|not|and|or|set|echo|exit|pwd|true|false|' 

817 r'cd|count|test)(\s*)\b', 

818 bygroups(Keyword, Text)), 

819 (r'\b(alias|bg|bind|breakpoint|builtin|command|commandline|' 

820 r'complete|contains|dirh|dirs|emit|eval|exec|fg|fish|fish_config|' 

821 r'fish_indent|fish_pager|fish_prompt|fish_right_prompt|' 

822 r'fish_update_completions|fishd|funced|funcsave|functions|help|' 

823 r'history|isatty|jobs|math|mimedb|nextd|open|popd|prevd|psub|' 

824 r'pushd|random|read|set_color|source|status|trap|type|ulimit|' 

825 r'umask|vared|fc|getopts|hash|kill|printf|time|wait)\s*\b(?!\.)', 

826 Name.Builtin), 

827 (r'#.*\n', Comment), 

828 (r'\\[\w\W]', String.Escape), 

829 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Whitespace, Operator)), 

830 (r'[\[\]()=]', Operator), 

831 (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String), 

832 ], 

833 'data': [ 

834 (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\$])*"', String.Double), 

835 (r'"', String.Double, 'string'), 

836 (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single), 

837 (r"(?s)'.*?'", String.Single), 

838 (r';', Punctuation), 

839 (r'&|\||\^|<|>', Operator), 

840 (r'\s+', Text), 

841 (r'\d+(?= |\Z)', Number), 

842 (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text), 

843 ], 

844 'string': [ 

845 (r'"', String.Double, '#pop'), 

846 (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double), 

847 include('interp'), 

848 ], 

849 'paren': [ 

850 (r'\)', Keyword, '#pop'), 

851 include('root'), 

852 ], 

853 'math': [ 

854 (r'\)\)', Keyword, '#pop'), 

855 (r'[-+*/%^|&]|\*\*|\|\|', Operator), 

856 (r'\d+#\d+', Number), 

857 (r'\d+#(?! )', Number), 

858 (r'\d+', Number), 

859 include('root'), 

860 ], 

861 } 

862 

863class ExeclineLexer(RegexLexer): 

864 """ 

865 Lexer for Laurent Bercot's execline language 

866 (https://skarnet.org/software/execline). 

867 

868 .. versionadded:: 2.7 

869 """ 

870 

871 name = 'execline' 

872 aliases = ['execline'] 

873 filenames = ['*.exec'] 

874 

875 tokens = { 

876 'root': [ 

877 include('basic'), 

878 include('data'), 

879 include('interp') 

880 ], 

881 'interp': [ 

882 (r'\$\{', String.Interpol, 'curly'), 

883 (r'\$[\w@#]+', Name.Variable), # user variable 

884 (r'\$', Text), 

885 ], 

886 'basic': [ 

887 (r'\b(background|backtick|cd|define|dollarat|elgetopt|' 

888 r'elgetpositionals|elglob|emptyenv|envfile|exec|execlineb|' 

889 r'exit|export|fdblock|fdclose|fdmove|fdreserve|fdswap|' 

890 r'forbacktickx|foreground|forstdin|forx|getcwd|getpid|heredoc|' 

891 r'homeof|if|ifelse|ifte|ifthenelse|importas|loopwhilex|' 

892 r'multidefine|multisubstitute|pipeline|piperw|posix-cd|' 

893 r'redirfd|runblock|shift|trap|tryexec|umask|unexport|wait|' 

894 r'withstdinas)\b', Name.Builtin), 

895 (r'\A#!.+\n', Comment.Hashbang), 

896 (r'#.*\n', Comment.Single), 

897 (r'[{}]', Operator) 

898 ], 

899 'data': [ 

900 (r'(?s)"(\\.|[^"\\$])*"', String.Double), 

901 (r'"', String.Double, 'string'), 

902 (r'\s+', Text), 

903 (r'[^\s{}$"\\]+', Text) 

904 ], 

905 'string': [ 

906 (r'"', String.Double, '#pop'), 

907 (r'(?s)(\\\\|\\.|[^"\\$])+', String.Double), 

908 include('interp'), 

909 ], 

910 'curly': [ 

911 (r'\}', String.Interpol, '#pop'), 

912 (r'[\w#@]+', Name.Variable), 

913 include('root') 

914 ] 

915 

916 } 

917 

918 def analyse_text(text): 

919 if shebang_matches(text, r'execlineb'): 

920 return 1