eric6/ThirdParty/Pygments/pygments/lexers/shell.py

changeset 6942
2602857055c5
parent 6651
e8f3b5568b21
child 7547
21b0534faebc
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2 """
3 pygments.lexers.shell
4 ~~~~~~~~~~~~~~~~~~~~~
5
6 Lexers for various shells.
7
8 :copyright: Copyright 2006-2017 by the Pygments team, see AUTHORS.
9 :license: BSD, see LICENSE for details.
10 """
11
12 import re
13
14 from pygments.lexer import Lexer, RegexLexer, do_insertions, bygroups, \
15 include, default, this, using, words
16 from pygments.token import Punctuation, \
17 Text, Comment, Operator, Keyword, Name, String, Number, Generic
18 from pygments.util import shebang_matches
19
20
21 __all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer',
22 'MSDOSSessionLexer', 'PowerShellLexer',
23 'PowerShellSessionLexer', 'TcshSessionLexer', 'FishShellLexer']
24
25 line_re = re.compile('.*?\n')
26
27
28 class BashLexer(RegexLexer):
29 """
30 Lexer for (ba|k|z|)sh shell scripts.
31
32 .. versionadded:: 0.6
33 """
34
35 name = 'Bash'
36 aliases = ['bash', 'sh', 'ksh', 'zsh', 'shell']
37 filenames = ['*.sh', '*.ksh', '*.bash', '*.ebuild', '*.eclass',
38 '*.exheres-0', '*.exlib', '*.zsh',
39 '.bashrc', 'bashrc', '.bash_*', 'bash_*', 'zshrc', '.zshrc',
40 'PKGBUILD']
41 mimetypes = ['application/x-sh', 'application/x-shellscript']
42
43 tokens = {
44 'root': [
45 include('basic'),
46 (r'`', String.Backtick, 'backticks'),
47 include('data'),
48 include('interp'),
49 ],
50 'interp': [
51 (r'\$\(\(', Keyword, 'math'),
52 (r'\$\(', Keyword, 'paren'),
53 (r'\$\{#?', String.Interpol, 'curly'),
54 (r'\$[a-zA-Z_]\w*', Name.Variable), # user variable
55 (r'\$(?:\d+|[#$?!_*@-])', Name.Variable), # builtin
56 (r'\$', Text),
57 ],
58 'basic': [
59 (r'\b(if|fi|else|while|do|done|for|then|return|function|case|'
60 r'select|continue|until|esac|elif)(\s*)\b',
61 bygroups(Keyword, Text)),
62 (r'\b(alias|bg|bind|break|builtin|caller|cd|command|compgen|'
63 r'complete|declare|dirs|disown|echo|enable|eval|exec|exit|'
64 r'export|false|fc|fg|getopts|hash|help|history|jobs|kill|let|'
65 r'local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|'
66 r'shopt|source|suspend|test|time|times|trap|true|type|typeset|'
67 r'ulimit|umask|unalias|unset|wait)(?=[\s)`])',
68 Name.Builtin),
69 (r'\A#!.+\n', Comment.Hashbang),
70 (r'#.*\n', Comment.Single),
71 (r'\\[\w\W]', String.Escape),
72 (r'(\b\w+)(\s*)(\+?=)', bygroups(Name.Variable, Text, Operator)),
73 (r'[\[\]{}()=]', Operator),
74 (r'<<<', Operator), # here-string
75 (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
76 (r'&&|\|\|', Operator),
77 ],
78 'data': [
79 (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\$])*"', String.Double),
80 (r'"', String.Double, 'string'),
81 (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
82 (r"(?s)'.*?'", String.Single),
83 (r';', Punctuation),
84 (r'&', Punctuation),
85 (r'\|', Punctuation),
86 (r'\s+', Text),
87 (r'\d+\b', Number),
88 (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text),
89 (r'<', Text),
90 ],
91 'string': [
92 (r'"', String.Double, '#pop'),
93 (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double),
94 include('interp'),
95 ],
96 'curly': [
97 (r'\}', String.Interpol, '#pop'),
98 (r':-', Keyword),
99 (r'\w+', Name.Variable),
100 (r'[^}:"\'`$\\]+', Punctuation),
101 (r':', Punctuation),
102 include('root'),
103 ],
104 'paren': [
105 (r'\)', Keyword, '#pop'),
106 include('root'),
107 ],
108 'math': [
109 (r'\)\)', Keyword, '#pop'),
110 (r'[-+*/%^|&]|\*\*|\|\|', Operator),
111 (r'\d+#\d+', Number),
112 (r'\d+#(?! )', Number),
113 (r'\d+', Number),
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
129 class ShellSessionBaseLexer(Lexer):
130 """
131 Base lexer for simplistic shell sessions.
132
133 .. versionadded:: 2.1
134 """
135 def get_tokens_unprocessed(self, text):
136 innerlexer = self._innerLexerCls(**self.options)
137
138 pos = 0
139 curcode = ''
140 insertions = []
141 backslash_continuation = False
142
143 for match in line_re.finditer(text):
144 line = match.group()
145 m = re.match(self._ps1rgx, line)
146 if backslash_continuation:
147 curcode += line
148 backslash_continuation = curcode.endswith('\\\n')
149 elif m:
150 # To support output lexers (say diff output), the output
151 # needs to be broken by prompts whenever the output lexer
152 # changes.
153 if not insertions:
154 pos = match.start()
155
156 insertions.append((len(curcode),
157 [(0, Generic.Prompt, m.group(1))]))
158 curcode += m.group(2)
159 backslash_continuation = curcode.endswith('\\\n')
160 elif line.startswith(self._ps2):
161 insertions.append((len(curcode),
162 [(0, Generic.Prompt, line[:len(self._ps2)])]))
163 curcode += line[len(self._ps2):]
164 backslash_continuation = curcode.endswith('\\\n')
165 else:
166 if insertions:
167 toks = innerlexer.get_tokens_unprocessed(curcode)
168 for i, t, v in do_insertions(insertions, toks):
169 yield pos+i, t, v
170 yield match.start(), Generic.Output, line
171 insertions = []
172 curcode = ''
173 if insertions:
174 for i, t, v in do_insertions(insertions,
175 innerlexer.get_tokens_unprocessed(curcode)):
176 yield pos+i, t, v
177
178
179 class BashSessionLexer(ShellSessionBaseLexer):
180 """
181 Lexer for simplistic shell sessions.
182
183 .. versionadded:: 1.1
184 """
185
186 name = 'Bash Session'
187 aliases = ['console', 'shell-session']
188 filenames = ['*.sh-session', '*.shell-session']
189 mimetypes = ['application/x-shell-session', 'application/x-sh-session']
190
191 _innerLexerCls = BashLexer
192 _ps1rgx = \
193 r'^((?:(?:\[.*?\])|(?:\(\S+\))?(?:| |sh\S*?|\w+\S+[@:]\S+(?:\s+\S+)' \
194 r'?|\[\S+[@:][^\n]+\].+))\s*[$#%])(.*\n?)'
195 _ps2 = '>'
196
197
198 class BatchLexer(RegexLexer):
199 """
200 Lexer for the DOS/Windows Batch file format.
201
202 .. versionadded:: 0.7
203 """
204 name = 'Batchfile'
205 aliases = ['bat', 'batch', 'dosbatch', 'winbatch']
206 filenames = ['*.bat', '*.cmd']
207 mimetypes = ['application/x-dos-batch']
208
209 flags = re.MULTILINE | re.IGNORECASE
210
211 _nl = r'\n\x1a'
212 _punct = r'&<>|'
213 _ws = r'\t\v\f\r ,;=\xa0'
214 _space = r'(?:(?:(?:\^[%s])?[%s])+)' % (_nl, _ws)
215 _keyword_terminator = (r'(?=(?:\^[%s]?)?[%s+./:[\\\]]|[%s%s(])' %
216 (_nl, _ws, _nl, _punct))
217 _token_terminator = r'(?=\^?[%s]|[%s%s])' % (_ws, _punct, _nl)
218 _start_label = r'((?:(?<=^[^:])|^[^:]?)[%s]*)(:)' % _ws
219 _label = r'(?:(?:[^%s%s%s+:^]|\^[%s]?[\w\W])*)' % (_nl, _punct, _ws, _nl)
220 _label_compound = (r'(?:(?:[^%s%s%s+:^)]|\^[%s]?[^)])*)' %
221 (_nl, _punct, _ws, _nl))
222 _number = r'(?:-?(?:0[0-7]+|0x[\da-f]+|\d+)%s)' % _token_terminator
223 _opword = r'(?:equ|geq|gtr|leq|lss|neq)'
224 _string = r'(?:"[^%s"]*(?:"|(?=[%s])))' % (_nl, _nl)
225 _variable = (r'(?:(?:%%(?:\*|(?:~[a-z]*(?:\$[^:]+:)?)?\d|'
226 r'[^%%:%s]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:[^%%%s^]|'
227 r'\^[^%%%s])[^=%s]*=(?:[^%%%s^]|\^[^%%%s])*)?)?%%))|'
228 r'(?:\^?![^!:%s]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:'
229 r'[^!%s^]|\^[^!%s])[^=%s]*=(?:[^!%s^]|\^[^!%s])*)?)?\^?!))' %
230 (_nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl, _nl))
231 _core_token = r'(?:(?:(?:\^[%s]?)?[^"%s%s%s])+)' % (_nl, _nl, _punct, _ws)
232 _core_token_compound = r'(?:(?:(?:\^[%s]?)?[^"%s%s%s)])+)' % (_nl, _nl,
233 _punct, _ws)
234 _token = r'(?:[%s]+|%s)' % (_punct, _core_token)
235 _token_compound = r'(?:[%s]+|%s)' % (_punct, _core_token_compound)
236 _stoken = (r'(?:[%s]+|(?:%s|%s|%s)+)' %
237 (_punct, _string, _variable, _core_token))
238
239 def _make_begin_state(compound, _core_token=_core_token,
240 _core_token_compound=_core_token_compound,
241 _keyword_terminator=_keyword_terminator,
242 _nl=_nl, _punct=_punct, _string=_string,
243 _space=_space, _start_label=_start_label,
244 _stoken=_stoken, _token_terminator=_token_terminator,
245 _variable=_variable, _ws=_ws):
246 rest = '(?:%s|%s|[^"%%%s%s%s])*' % (_string, _variable, _nl, _punct,
247 ')' if compound else '')
248 rest_of_line = r'(?:(?:[^%s^]|\^[%s]?[\w\W])*)' % (_nl, _nl)
249 rest_of_line_compound = r'(?:(?:[^%s^)]|\^[%s]?[^)])*)' % (_nl, _nl)
250 set_space = r'((?:(?:\^[%s]?)?[^\S\n])*)' % _nl
251 suffix = ''
252 if compound:
253 _keyword_terminator = r'(?:(?=\))|%s)' % _keyword_terminator
254 _token_terminator = r'(?:(?=\))|%s)' % _token_terminator
255 suffix = '/compound'
256 return [
257 ((r'\)', Punctuation, '#pop') if compound else
258 (r'\)((?=\()|%s)%s' % (_token_terminator, rest_of_line),
259 Comment.Single)),
260 (r'(?=%s)' % _start_label, Text, 'follow%s' % suffix),
261 (_space, using(this, state='text')),
262 include('redirect%s' % suffix),
263 (r'[%s]+' % _nl, Text),
264 (r'\(', Punctuation, 'root/compound'),
265 (r'@+', Punctuation),
266 (r'((?:for|if|rem)(?:(?=(?:\^[%s]?)?/)|(?:(?!\^)|'
267 r'(?<=m))(?:(?=\()|%s)))(%s?%s?(?:\^[%s]?)?/(?:\^[%s]?)?\?)' %
268 (_nl, _token_terminator, _space,
269 _core_token_compound if compound else _core_token, _nl, _nl),
270 bygroups(Keyword, using(this, state='text')),
271 'follow%s' % suffix),
272 (r'(goto%s)(%s(?:\^[%s]?)?/(?:\^[%s]?)?\?%s)' %
273 (_keyword_terminator, rest, _nl, _nl, rest),
274 bygroups(Keyword, using(this, state='text')),
275 'follow%s' % suffix),
276 (words(('assoc', 'break', 'cd', 'chdir', 'cls', 'color', 'copy',
277 'date', 'del', 'dir', 'dpath', 'echo', 'endlocal', 'erase',
278 'exit', 'ftype', 'keys', 'md', 'mkdir', 'mklink', 'move',
279 'path', 'pause', 'popd', 'prompt', 'pushd', 'rd', 'ren',
280 'rename', 'rmdir', 'setlocal', 'shift', 'start', 'time',
281 'title', 'type', 'ver', 'verify', 'vol'),
282 suffix=_keyword_terminator), Keyword, 'follow%s' % suffix),
283 (r'(call)(%s?)(:)' % _space,
284 bygroups(Keyword, using(this, state='text'), Punctuation),
285 'call%s' % suffix),
286 (r'call%s' % _keyword_terminator, Keyword),
287 (r'(for%s(?!\^))(%s)(/f%s)' %
288 (_token_terminator, _space, _token_terminator),
289 bygroups(Keyword, using(this, state='text'), Keyword),
290 ('for/f', 'for')),
291 (r'(for%s(?!\^))(%s)(/l%s)' %
292 (_token_terminator, _space, _token_terminator),
293 bygroups(Keyword, using(this, state='text'), Keyword),
294 ('for/l', 'for')),
295 (r'for%s(?!\^)' % _token_terminator, Keyword, ('for2', 'for')),
296 (r'(goto%s)(%s?)(:?)' % (_keyword_terminator, _space),
297 bygroups(Keyword, using(this, state='text'), Punctuation),
298 'label%s' % suffix),
299 (r'(if(?:(?=\()|%s)(?!\^))(%s?)((?:/i%s)?)(%s?)((?:not%s)?)(%s?)' %
300 (_token_terminator, _space, _token_terminator, _space,
301 _token_terminator, _space),
302 bygroups(Keyword, using(this, state='text'), Keyword,
303 using(this, state='text'), Keyword,
304 using(this, state='text')), ('(?', 'if')),
305 (r'rem(((?=\()|%s)%s?%s?.*|%s%s)' %
306 (_token_terminator, _space, _stoken, _keyword_terminator,
307 rest_of_line_compound if compound else rest_of_line),
308 Comment.Single, 'follow%s' % suffix),
309 (r'(set%s)%s(/a)' % (_keyword_terminator, set_space),
310 bygroups(Keyword, using(this, state='text'), Keyword),
311 'arithmetic%s' % suffix),
312 (r'(set%s)%s((?:/p)?)%s((?:(?:(?:\^[%s]?)?[^"%s%s^=%s]|'
313 r'\^[%s]?[^"=])+)?)((?:(?:\^[%s]?)?=)?)' %
314 (_keyword_terminator, set_space, set_space, _nl, _nl, _punct,
315 ')' if compound else '', _nl, _nl),
316 bygroups(Keyword, using(this, state='text'), Keyword,
317 using(this, state='text'), using(this, state='variable'),
318 Punctuation),
319 'follow%s' % suffix),
320 default('follow%s' % suffix)
321 ]
322
323 def _make_follow_state(compound, _label=_label,
324 _label_compound=_label_compound, _nl=_nl,
325 _space=_space, _start_label=_start_label,
326 _token=_token, _token_compound=_token_compound,
327 _ws=_ws):
328 suffix = '/compound' if compound else ''
329 state = []
330 if compound:
331 state.append((r'(?=\))', Text, '#pop'))
332 state += [
333 (r'%s([%s]*)(%s)(.*)' %
334 (_start_label, _ws, _label_compound if compound else _label),
335 bygroups(Text, Punctuation, Text, Name.Label, Comment.Single)),
336 include('redirect%s' % suffix),
337 (r'(?=[%s])' % _nl, Text, '#pop'),
338 (r'\|\|?|&&?', Punctuation, '#pop'),
339 include('text')
340 ]
341 return state
342
343 def _make_arithmetic_state(compound, _nl=_nl, _punct=_punct,
344 _string=_string, _variable=_variable, _ws=_ws):
345 op = r'=+\-*/!~'
346 state = []
347 if compound:
348 state.append((r'(?=\))', Text, '#pop'))
349 state += [
350 (r'0[0-7]+', Number.Oct),
351 (r'0x[\da-f]+', Number.Hex),
352 (r'\d+', Number.Integer),
353 (r'[(),]+', Punctuation),
354 (r'([%s]|%%|\^\^)+' % op, Operator),
355 (r'(%s|%s|(\^[%s]?)?[^()%s%%^"%s%s%s]|\^[%s%s]?%s)+' %
356 (_string, _variable, _nl, op, _nl, _punct, _ws, _nl, _ws,
357 r'[^)]' if compound else r'[\w\W]'),
358 using(this, state='variable')),
359 (r'(?=[\x00|&])', Text, '#pop'),
360 include('follow')
361 ]
362 return state
363
364 def _make_call_state(compound, _label=_label,
365 _label_compound=_label_compound):
366 state = []
367 if compound:
368 state.append((r'(?=\))', Text, '#pop'))
369 state.append((r'(:?)(%s)' % (_label_compound if compound else _label),
370 bygroups(Punctuation, Name.Label), '#pop'))
371 return state
372
373 def _make_label_state(compound, _label=_label,
374 _label_compound=_label_compound, _nl=_nl,
375 _punct=_punct, _string=_string, _variable=_variable):
376 state = []
377 if compound:
378 state.append((r'(?=\))', Text, '#pop'))
379 state.append((r'(%s?)((?:%s|%s|\^[%s]?%s|[^"%%^%s%s%s])*)' %
380 (_label_compound if compound else _label, _string,
381 _variable, _nl, r'[^)]' if compound else r'[\w\W]', _nl,
382 _punct, r')' if compound else ''),
383 bygroups(Name.Label, Comment.Single), '#pop'))
384 return state
385
386 def _make_redirect_state(compound,
387 _core_token_compound=_core_token_compound,
388 _nl=_nl, _punct=_punct, _stoken=_stoken,
389 _string=_string, _space=_space,
390 _variable=_variable, _ws=_ws):
391 stoken_compound = (r'(?:[%s]+|(?:%s|%s|%s)+)' %
392 (_punct, _string, _variable, _core_token_compound))
393 return [
394 (r'((?:(?<=[%s%s])\d)?)(>>?&|<&)([%s%s]*)(\d)' %
395 (_nl, _ws, _nl, _ws),
396 bygroups(Number.Integer, Punctuation, Text, Number.Integer)),
397 (r'((?:(?<=[%s%s])(?<!\^[%s])\d)?)(>>?|<)(%s?%s)' %
398 (_nl, _ws, _nl, _space, stoken_compound if compound else _stoken),
399 bygroups(Number.Integer, Punctuation, using(this, state='text')))
400 ]
401
402 tokens = {
403 'root': _make_begin_state(False),
404 'follow': _make_follow_state(False),
405 'arithmetic': _make_arithmetic_state(False),
406 'call': _make_call_state(False),
407 'label': _make_label_state(False),
408 'redirect': _make_redirect_state(False),
409 'root/compound': _make_begin_state(True),
410 'follow/compound': _make_follow_state(True),
411 'arithmetic/compound': _make_arithmetic_state(True),
412 'call/compound': _make_call_state(True),
413 'label/compound': _make_label_state(True),
414 'redirect/compound': _make_redirect_state(True),
415 'variable-or-escape': [
416 (_variable, Name.Variable),
417 (r'%%%%|\^[%s]?(\^!|[\w\W])' % _nl, String.Escape)
418 ],
419 'string': [
420 (r'"', String.Double, '#pop'),
421 (_variable, Name.Variable),
422 (r'\^!|%%', String.Escape),
423 (r'[^"%%^%s]+|[%%^]' % _nl, String.Double),
424 default('#pop')
425 ],
426 'sqstring': [
427 include('variable-or-escape'),
428 (r'[^%]+|%', String.Single)
429 ],
430 'bqstring': [
431 include('variable-or-escape'),
432 (r'[^%]+|%', String.Backtick)
433 ],
434 'text': [
435 (r'"', String.Double, 'string'),
436 include('variable-or-escape'),
437 (r'[^"%%^%s%s%s\d)]+|.' % (_nl, _punct, _ws), Text)
438 ],
439 'variable': [
440 (r'"', String.Double, 'string'),
441 include('variable-or-escape'),
442 (r'[^"%%^%s]+|.' % _nl, Name.Variable)
443 ],
444 'for': [
445 (r'(%s)(in)(%s)(\()' % (_space, _space),
446 bygroups(using(this, state='text'), Keyword,
447 using(this, state='text'), Punctuation), '#pop'),
448 include('follow')
449 ],
450 'for2': [
451 (r'\)', Punctuation),
452 (r'(%s)(do%s)' % (_space, _token_terminator),
453 bygroups(using(this, state='text'), Keyword), '#pop'),
454 (r'[%s]+' % _nl, Text),
455 include('follow')
456 ],
457 'for/f': [
458 (r'(")((?:%s|[^"])*?")([%s%s]*)(\))' % (_variable, _nl, _ws),
459 bygroups(String.Double, using(this, state='string'), Text,
460 Punctuation)),
461 (r'"', String.Double, ('#pop', 'for2', 'string')),
462 (r"('(?:%%%%|%s|[\w\W])*?')([%s%s]*)(\))" % (_variable, _nl, _ws),
463 bygroups(using(this, state='sqstring'), Text, Punctuation)),
464 (r'(`(?:%%%%|%s|[\w\W])*?`)([%s%s]*)(\))' % (_variable, _nl, _ws),
465 bygroups(using(this, state='bqstring'), Text, Punctuation)),
466 include('for2')
467 ],
468 'for/l': [
469 (r'-?\d+', Number.Integer),
470 include('for2')
471 ],
472 'if': [
473 (r'((?:cmdextversion|errorlevel)%s)(%s)(\d+)' %
474 (_token_terminator, _space),
475 bygroups(Keyword, using(this, state='text'),
476 Number.Integer), '#pop'),
477 (r'(defined%s)(%s)(%s)' % (_token_terminator, _space, _stoken),
478 bygroups(Keyword, using(this, state='text'),
479 using(this, state='variable')), '#pop'),
480 (r'(exist%s)(%s%s)' % (_token_terminator, _space, _stoken),
481 bygroups(Keyword, using(this, state='text')), '#pop'),
482 (r'(%s%s)(%s)(%s%s)' % (_number, _space, _opword, _space, _number),
483 bygroups(using(this, state='arithmetic'), Operator.Word,
484 using(this, state='arithmetic')), '#pop'),
485 (_stoken, using(this, state='text'), ('#pop', 'if2')),
486 ],
487 'if2': [
488 (r'(%s?)(==)(%s?%s)' % (_space, _space, _stoken),
489 bygroups(using(this, state='text'), Operator,
490 using(this, state='text')), '#pop'),
491 (r'(%s)(%s)(%s%s)' % (_space, _opword, _space, _stoken),
492 bygroups(using(this, state='text'), Operator.Word,
493 using(this, state='text')), '#pop')
494 ],
495 '(?': [
496 (_space, using(this, state='text')),
497 (r'\(', Punctuation, ('#pop', 'else?', 'root/compound')),
498 default('#pop')
499 ],
500 'else?': [
501 (_space, using(this, state='text')),
502 (r'else%s' % _token_terminator, Keyword, '#pop'),
503 default('#pop')
504 ]
505 }
506
507
508 class MSDOSSessionLexer(ShellSessionBaseLexer):
509 """
510 Lexer for simplistic MSDOS sessions.
511
512 .. versionadded:: 2.1
513 """
514
515 name = 'MSDOS Session'
516 aliases = ['doscon']
517 filenames = []
518 mimetypes = []
519
520 _innerLexerCls = BatchLexer
521 _ps1rgx = r'^([^>]+>)(.*\n?)'
522 _ps2 = 'More? '
523
524
525 class TcshLexer(RegexLexer):
526 """
527 Lexer for tcsh scripts.
528
529 .. versionadded:: 0.10
530 """
531
532 name = 'Tcsh'
533 aliases = ['tcsh', 'csh']
534 filenames = ['*.tcsh', '*.csh']
535 mimetypes = ['application/x-csh']
536
537 tokens = {
538 'root': [
539 include('basic'),
540 (r'\$\(', Keyword, 'paren'),
541 (r'\$\{#?', Keyword, 'curly'),
542 (r'`', String.Backtick, 'backticks'),
543 include('data'),
544 ],
545 'basic': [
546 (r'\b(if|endif|else|while|then|foreach|case|default|'
547 r'continue|goto|breaksw|end|switch|endsw)\s*\b',
548 Keyword),
549 (r'\b(alias|alloc|bg|bindkey|break|builtins|bye|caller|cd|chdir|'
550 r'complete|dirs|echo|echotc|eval|exec|exit|fg|filetest|getxvers|'
551 r'glob|getspath|hashstat|history|hup|inlib|jobs|kill|'
552 r'limit|log|login|logout|ls-F|migrate|newgrp|nice|nohup|notify|'
553 r'onintr|popd|printenv|pushd|rehash|repeat|rootnode|popd|pushd|'
554 r'set|shift|sched|setenv|setpath|settc|setty|setxvers|shift|'
555 r'source|stop|suspend|source|suspend|telltc|time|'
556 r'umask|unalias|uncomplete|unhash|universe|unlimit|unset|unsetenv|'
557 r'ver|wait|warp|watchlog|where|which)\s*\b',
558 Name.Builtin),
559 (r'#.*', Comment),
560 (r'\\[\w\W]', String.Escape),
561 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
562 (r'[\[\]{}()=]+', Operator),
563 (r'<<\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
564 (r';', Punctuation),
565 ],
566 'data': [
567 (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
568 (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
569 (r'\s+', Text),
570 (r'[^=\s\[\]{}()$"\'`\\;#]+', Text),
571 (r'\d+(?= |\Z)', Number),
572 (r'\$#?(\w+|.)', Name.Variable),
573 ],
574 'curly': [
575 (r'\}', Keyword, '#pop'),
576 (r':-', Keyword),
577 (r'\w+', Name.Variable),
578 (r'[^}:"\'`$]+', Punctuation),
579 (r':', Punctuation),
580 include('root'),
581 ],
582 'paren': [
583 (r'\)', Keyword, '#pop'),
584 include('root'),
585 ],
586 'backticks': [
587 (r'`', String.Backtick, '#pop'),
588 include('root'),
589 ],
590 }
591
592
593 class TcshSessionLexer(ShellSessionBaseLexer):
594 """
595 Lexer for Tcsh sessions.
596
597 .. versionadded:: 2.1
598 """
599
600 name = 'Tcsh Session'
601 aliases = ['tcshcon']
602 filenames = []
603 mimetypes = []
604
605 _innerLexerCls = TcshLexer
606 _ps1rgx = r'^([^>]+>)(.*\n?)'
607 _ps2 = '? '
608
609
610 class PowerShellLexer(RegexLexer):
611 """
612 For Windows PowerShell code.
613
614 .. versionadded:: 1.5
615 """
616 name = 'PowerShell'
617 aliases = ['powershell', 'posh', 'ps1', 'psm1']
618 filenames = ['*.ps1', '*.psm1']
619 mimetypes = ['text/x-powershell']
620
621 flags = re.DOTALL | re.IGNORECASE | re.MULTILINE
622
623 keywords = (
624 'while validateset validaterange validatepattern validatelength '
625 'validatecount until trap switch return ref process param parameter in '
626 'if global: function foreach for finally filter end elseif else '
627 'dynamicparam do default continue cmdletbinding break begin alias \\? '
628 '% #script #private #local #global mandatory parametersetname position '
629 'valuefrompipeline valuefrompipelinebypropertyname '
630 'valuefromremainingarguments helpmessage try catch throw').split()
631
632 operators = (
633 'and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle '
634 'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains '
635 'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt '
636 'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like '
637 'lt match ne not notcontains notlike notmatch or regex replace '
638 'wildcard').split()
639
640 verbs = (
641 'write where watch wait use update unregister unpublish unprotect '
642 'unlock uninstall undo unblock trace test tee take sync switch '
643 'suspend submit stop step start split sort skip show set send select '
644 'search scroll save revoke resume restore restart resolve resize '
645 'reset request repair rename remove register redo receive read push '
646 'publish protect pop ping out optimize open new move mount merge '
647 'measure lock limit join invoke install initialize import hide group '
648 'grant get format foreach find export expand exit enter enable edit '
649 'dismount disconnect disable deny debug cxnew copy convertto '
650 'convertfrom convert connect confirm compress complete compare close '
651 'clear checkpoint block backup assert approve aggregate add').split()
652
653 aliases = (
654 'ac asnp cat cd cfs chdir clc clear clhy cli clp cls clv cnsn '
655 'compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo epal '
656 'epcsv epsn erase etsn exsn fc fhx fl foreach ft fw gal gbp gc gci gcm '
657 'gcs gdr ghy gi gjb gl gm gmo gp gps gpv group gsn gsnp gsv gu gv gwmi '
658 'h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp '
659 'ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv '
660 'oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo '
661 'rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc select '
662 'set shcm si sl sleep sls sort sp spjb spps spsv start sujb sv swmi tee '
663 'trcm type wget where wjb write').split()
664
665 commenthelp = (
666 'component description example externalhelp forwardhelpcategory '
667 'forwardhelptargetname functionality inputs link '
668 'notes outputs parameter remotehelprunspace role synopsis').split()
669
670 tokens = {
671 'root': [
672 # we need to count pairs of parentheses for correct highlight
673 # of '$(...)' blocks in strings
674 (r'\(', Punctuation, 'child'),
675 (r'\s+', Text),
676 (r'^(\s*#[#\s]*)(\.(?:%s))([^\n]*$)' % '|'.join(commenthelp),
677 bygroups(Comment, String.Doc, Comment)),
678 (r'#[^\n]*?$', Comment),
679 (r'(&lt;|<)#', Comment.Multiline, 'multline'),
680 (r'@"\n', String.Heredoc, 'heredoc-double'),
681 (r"@'\n.*?\n'@", String.Heredoc),
682 # escaped syntax
683 (r'`[\'"$@-]', Punctuation),
684 (r'"', String.Double, 'string'),
685 (r"'([^']|'')*'", String.Single),
686 (r'(\$|@@|@)((global|script|private|env):)?\w+',
687 Name.Variable),
688 (r'(%s)\b' % '|'.join(keywords), Keyword),
689 (r'-(%s)\b' % '|'.join(operators), Operator),
690 (r'(%s)-[a-z_]\w*\b' % '|'.join(verbs), Name.Builtin),
691 (r'(%s)\s' % '|'.join(aliases), Name.Builtin),
692 (r'\[[a-z_\[][\w. `,\[\]]*\]', Name.Constant), # .net [type]s
693 (r'-[a-z_]\w*', Name),
694 (r'\w+', Name),
695 (r'[.,;@{}\[\]$()=+*/\\&%!~?^`|<>-]|::', Punctuation),
696 ],
697 'child': [
698 (r'\)', Punctuation, '#pop'),
699 include('root'),
700 ],
701 'multline': [
702 (r'[^#&.]+', Comment.Multiline),
703 (r'#(>|&gt;)', Comment.Multiline, '#pop'),
704 (r'\.(%s)' % '|'.join(commenthelp), String.Doc),
705 (r'[#&.]', Comment.Multiline),
706 ],
707 'string': [
708 (r"`[0abfnrtv'\"$`]", String.Escape),
709 (r'[^$`"]+', String.Double),
710 (r'\$\(', Punctuation, 'child'),
711 (r'""', String.Double),
712 (r'[`$]', String.Double),
713 (r'"', String.Double, '#pop'),
714 ],
715 'heredoc-double': [
716 (r'\n"@', String.Heredoc, '#pop'),
717 (r'\$\(', Punctuation, 'child'),
718 (r'[^@\n]+"]', String.Heredoc),
719 (r".", String.Heredoc),
720 ]
721 }
722
723
724 class PowerShellSessionLexer(ShellSessionBaseLexer):
725 """
726 Lexer for simplistic Windows PowerShell sessions.
727
728 .. versionadded:: 2.1
729 """
730
731 name = 'PowerShell Session'
732 aliases = ['ps1con']
733 filenames = []
734 mimetypes = []
735
736 _innerLexerCls = PowerShellLexer
737 _ps1rgx = r'^(PS [^>]+> )(.*\n?)'
738 _ps2 = '>> '
739
740
741 class FishShellLexer(RegexLexer):
742 """
743 Lexer for Fish shell scripts.
744
745 .. versionadded:: 2.1
746 """
747
748 name = 'Fish'
749 aliases = ['fish', 'fishshell']
750 filenames = ['*.fish', '*.load']
751 mimetypes = ['application/x-fish']
752
753 tokens = {
754 'root': [
755 include('basic'),
756 include('data'),
757 include('interp'),
758 ],
759 'interp': [
760 (r'\$\(\(', Keyword, 'math'),
761 (r'\(', Keyword, 'paren'),
762 (r'\$#?(\w+|.)', Name.Variable),
763 ],
764 'basic': [
765 (r'\b(begin|end|if|else|while|break|for|in|return|function|block|'
766 r'case|continue|switch|not|and|or|set|echo|exit|pwd|true|false|'
767 r'cd|count|test)(\s*)\b',
768 bygroups(Keyword, Text)),
769 (r'\b(alias|bg|bind|breakpoint|builtin|command|commandline|'
770 r'complete|contains|dirh|dirs|emit|eval|exec|fg|fish|fish_config|'
771 r'fish_indent|fish_pager|fish_prompt|fish_right_prompt|'
772 r'fish_update_completions|fishd|funced|funcsave|functions|help|'
773 r'history|isatty|jobs|math|mimedb|nextd|open|popd|prevd|psub|'
774 r'pushd|random|read|set_color|source|status|trap|type|ulimit|'
775 r'umask|vared|fc|getopts|hash|kill|printf|time|wait)\s*\b(?!\.)',
776 Name.Builtin),
777 (r'#.*\n', Comment),
778 (r'\\[\w\W]', String.Escape),
779 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
780 (r'[\[\]()=]', Operator),
781 (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
782 ],
783 'data': [
784 (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\$])*"', String.Double),
785 (r'"', String.Double, 'string'),
786 (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
787 (r"(?s)'.*?'", String.Single),
788 (r';', Punctuation),
789 (r'&|\||\^|<|>', Operator),
790 (r'\s+', Text),
791 (r'\d+(?= |\Z)', Number),
792 (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text),
793 ],
794 'string': [
795 (r'"', String.Double, '#pop'),
796 (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double),
797 include('interp'),
798 ],
799 'paren': [
800 (r'\)', Keyword, '#pop'),
801 include('root'),
802 ],
803 'math': [
804 (r'\)\)', Keyword, '#pop'),
805 (r'[-+*/%^|&]|\*\*|\|\|', Operator),
806 (r'\d+#\d+', Number),
807 (r'\d+#(?! )', Number),
808 (r'\d+', Number),
809 include('root'),
810 ],
811 }

eric ide

mercurial