ThirdParty/Pygments/pygments/lexers/shell.py

changeset 1705
b0fbc9300f2b
child 2426
da76c71624de
equal deleted inserted replaced
1704:02ae6c55b35b 1705:b0fbc9300f2b
1 # -*- coding: utf-8 -*-
2 """
3 pygments.lexers.shell
4 ~~~~~~~~~~~~~~~~~~~~~
5
6 Lexers for various shells.
7
8 :copyright: Copyright 2006-2012 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, include
15 from pygments.token import Punctuation, \
16 Text, Comment, Operator, Keyword, Name, String, Number, Generic
17 from pygments.util import shebang_matches
18
19
20 __all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer',
21 'PowerShellLexer']
22
23 line_re = re.compile('.*?\n')
24
25
26 class BashLexer(RegexLexer):
27 """
28 Lexer for (ba|k|)sh shell scripts.
29
30 *New in Pygments 0.6.*
31 """
32
33 name = 'Bash'
34 aliases = ['bash', 'sh', 'ksh']
35 filenames = ['*.sh', '*.ksh', '*.bash', '*.ebuild', '*.eclass',
36 '.bashrc', 'bashrc', '.bash_*', 'bash_*']
37 mimetypes = ['application/x-sh', 'application/x-shellscript']
38
39 tokens = {
40 'root': [
41 include('basic'),
42 (r'\$\(\(', Keyword, 'math'),
43 (r'\$\(', Keyword, 'paren'),
44 (r'\${#?', Keyword, 'curly'),
45 (r'`', String.Backtick, 'backticks'),
46 include('data'),
47 ],
48 'basic': [
49 (r'\b(if|fi|else|while|do|done|for|then|return|function|case|'
50 r'select|continue|until|esac|elif)\s*\b',
51 Keyword),
52 (r'\b(alias|bg|bind|break|builtin|caller|cd|command|compgen|'
53 r'complete|declare|dirs|disown|echo|enable|eval|exec|exit|'
54 r'export|false|fc|fg|getopts|hash|help|history|jobs|kill|let|'
55 r'local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|'
56 r'shopt|source|suspend|test|time|times|trap|true|type|typeset|'
57 r'ulimit|umask|unalias|unset|wait)\s*\b(?!\.)',
58 Name.Builtin),
59 (r'#.*\n', Comment),
60 (r'\\[\w\W]', String.Escape),
61 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
62 (r'[\[\]{}()=]', Operator),
63 (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
64 (r'&&|\|\|', Operator),
65 ],
66 'data': [
67 (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
68 (r"(?s)\$?'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
69 (r';', Text),
70 (r'\s+', Text),
71 (r'[^=\s\[\]{}()$"\'`\\<]+', Text),
72 (r'\d+(?= |\Z)', Number),
73 (r'\$#?(\w+|.)', Name.Variable),
74 (r'<', Text),
75 ],
76 'curly': [
77 (r'}', Keyword, '#pop'),
78 (r':-', Keyword),
79 (r'[a-zA-Z0-9_]+', Name.Variable),
80 (r'[^}:"\'`$]+', Punctuation),
81 (r':', Punctuation),
82 include('root'),
83 ],
84 'paren': [
85 (r'\)', Keyword, '#pop'),
86 include('root'),
87 ],
88 'math': [
89 (r'\)\)', Keyword, '#pop'),
90 (r'[-+*/%^|&]|\*\*|\|\|', Operator),
91 (r'\d+', Number),
92 include('root'),
93 ],
94 'backticks': [
95 (r'`', String.Backtick, '#pop'),
96 include('root'),
97 ],
98 }
99
100 def analyse_text(text):
101 return shebang_matches(text, r'(ba|z|)sh')
102
103
104 class BashSessionLexer(Lexer):
105 """
106 Lexer for simplistic shell sessions.
107
108 *New in Pygments 1.1.*
109 """
110
111 name = 'Bash Session'
112 aliases = ['console']
113 filenames = ['*.sh-session']
114 mimetypes = ['application/x-shell-session']
115
116 def get_tokens_unprocessed(self, text):
117 bashlexer = BashLexer(**self.options)
118
119 pos = 0
120 curcode = ''
121 insertions = []
122
123 for match in line_re.finditer(text):
124 line = match.group()
125 m = re.match(r'^((?:\(\S+\))?(?:|sh\S*?|\w+\S+[@:]\S+(?:\s+\S+)'
126 r'?|\[\S+[@:][^\n]+\].+)[$#%])(.*\n?)' , line)
127 if m:
128 # To support output lexers (say diff output), the output
129 # needs to be broken by prompts whenever the output lexer
130 # changes.
131 if not insertions:
132 pos = match.start()
133
134 insertions.append((len(curcode),
135 [(0, Generic.Prompt, m.group(1))]))
136 curcode += m.group(2)
137 elif line.startswith('>'):
138 insertions.append((len(curcode),
139 [(0, Generic.Prompt, line[:1])]))
140 curcode += line[1:]
141 else:
142 if insertions:
143 toks = bashlexer.get_tokens_unprocessed(curcode)
144 for i, t, v in do_insertions(insertions, toks):
145 yield pos+i, t, v
146 yield match.start(), Generic.Output, line
147 insertions = []
148 curcode = ''
149 if insertions:
150 for i, t, v in do_insertions(insertions,
151 bashlexer.get_tokens_unprocessed(curcode)):
152 yield pos+i, t, v
153
154
155 class BatchLexer(RegexLexer):
156 """
157 Lexer for the DOS/Windows Batch file format.
158
159 *New in Pygments 0.7.*
160 """
161 name = 'Batchfile'
162 aliases = ['bat']
163 filenames = ['*.bat', '*.cmd']
164 mimetypes = ['application/x-dos-batch']
165
166 flags = re.MULTILINE | re.IGNORECASE
167
168 tokens = {
169 'root': [
170 # Lines can start with @ to prevent echo
171 (r'^\s*@', Punctuation),
172 (r'^(\s*)(rem\s.*)$', bygroups(Text, Comment)),
173 (r'".*?"', String.Double),
174 (r"'.*?'", String.Single),
175 # If made more specific, make sure you still allow expansions
176 # like %~$VAR:zlt
177 (r'%%?[~$:\w]+%?', Name.Variable),
178 (r'::.*', Comment), # Technically :: only works at BOL
179 (r'(set)(\s+)(\w+)', bygroups(Keyword, Text, Name.Variable)),
180 (r'(call)(\s+)(:\w+)', bygroups(Keyword, Text, Name.Label)),
181 (r'(goto)(\s+)(\w+)', bygroups(Keyword, Text, Name.Label)),
182 (r'\b(set|call|echo|on|off|endlocal|for|do|goto|if|pause|'
183 r'setlocal|shift|errorlevel|exist|defined|cmdextversion|'
184 r'errorlevel|else|cd|md|del|deltree|cls|choice)\b', Keyword),
185 (r'\b(equ|neq|lss|leq|gtr|geq)\b', Operator),
186 include('basic'),
187 (r'.', Text),
188 ],
189 'echo': [
190 # Escapes only valid within echo args?
191 (r'\^\^|\^<|\^>|\^\|', String.Escape),
192 (r'\n', Text, '#pop'),
193 include('basic'),
194 (r'[^\'"^]+', Text),
195 ],
196 'basic': [
197 (r'".*?"', String.Double),
198 (r"'.*?'", String.Single),
199 (r'`.*?`', String.Backtick),
200 (r'-?\d+', Number),
201 (r',', Punctuation),
202 (r'=', Operator),
203 (r'/\S+', Name),
204 (r':\w+', Name.Label),
205 (r'\w:\w+', Text),
206 (r'([<>|])(\s*)(\w+)', bygroups(Punctuation, Text, Name)),
207 ],
208 }
209
210
211 class TcshLexer(RegexLexer):
212 """
213 Lexer for tcsh scripts.
214
215 *New in Pygments 0.10.*
216 """
217
218 name = 'Tcsh'
219 aliases = ['tcsh', 'csh']
220 filenames = ['*.tcsh', '*.csh']
221 mimetypes = ['application/x-csh']
222
223 tokens = {
224 'root': [
225 include('basic'),
226 (r'\$\(', Keyword, 'paren'),
227 (r'\${#?', Keyword, 'curly'),
228 (r'`', String.Backtick, 'backticks'),
229 include('data'),
230 ],
231 'basic': [
232 (r'\b(if|endif|else|while|then|foreach|case|default|'
233 r'continue|goto|breaksw|end|switch|endsw)\s*\b',
234 Keyword),
235 (r'\b(alias|alloc|bg|bindkey|break|builtins|bye|caller|cd|chdir|'
236 r'complete|dirs|echo|echotc|eval|exec|exit|fg|filetest|getxvers|'
237 r'glob|getspath|hashstat|history|hup|inlib|jobs|kill|'
238 r'limit|log|login|logout|ls-F|migrate|newgrp|nice|nohup|notify|'
239 r'onintr|popd|printenv|pushd|rehash|repeat|rootnode|popd|pushd|'
240 r'set|shift|sched|setenv|setpath|settc|setty|setxvers|shift|'
241 r'source|stop|suspend|source|suspend|telltc|time|'
242 r'umask|unalias|uncomplete|unhash|universe|unlimit|unset|unsetenv|'
243 r'ver|wait|warp|watchlog|where|which)\s*\b',
244 Name.Builtin),
245 (r'#.*\n', Comment),
246 (r'\\[\w\W]', String.Escape),
247 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
248 (r'[\[\]{}()=]+', Operator),
249 (r'<<\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
250 ],
251 'data': [
252 (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
253 (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
254 (r'\s+', Text),
255 (r'[^=\s\[\]{}()$"\'`\\]+', Text),
256 (r'\d+(?= |\Z)', Number),
257 (r'\$#?(\w+|.)', Name.Variable),
258 ],
259 'curly': [
260 (r'}', Keyword, '#pop'),
261 (r':-', Keyword),
262 (r'[a-zA-Z0-9_]+', Name.Variable),
263 (r'[^}:"\'`$]+', Punctuation),
264 (r':', Punctuation),
265 include('root'),
266 ],
267 'paren': [
268 (r'\)', Keyword, '#pop'),
269 include('root'),
270 ],
271 'backticks': [
272 (r'`', String.Backtick, '#pop'),
273 include('root'),
274 ],
275 }
276
277
278 class PowerShellLexer(RegexLexer):
279 """
280 For Windows PowerShell code.
281
282 *New in Pygments 1.5.*
283 """
284 name = 'PowerShell'
285 aliases = ['powershell', 'posh', 'ps1']
286 filenames = ['*.ps1']
287 mimetypes = ['text/x-powershell']
288
289 flags = re.DOTALL | re.IGNORECASE | re.MULTILINE
290
291 keywords = (
292 'while validateset validaterange validatepattern validatelength '
293 'validatecount until trap switch return ref process param parameter in '
294 'if global: function foreach for finally filter end elseif else '
295 'dynamicparam do default continue cmdletbinding break begin alias \\? '
296 '% #script #private #local #global mandatory parametersetname position '
297 'valuefrompipeline valuefrompipelinebypropertyname '
298 'valuefromremainingarguments helpmessage try catch').split()
299
300 operators = (
301 'and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle '
302 'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains '
303 'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt '
304 'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like '
305 'lt match ne not notcontains notlike notmatch or regex replace '
306 'wildcard').split()
307
308 verbs = (
309 'write where wait use update unregister undo trace test tee take '
310 'suspend stop start split sort skip show set send select scroll resume '
311 'restore restart resolve resize reset rename remove register receive '
312 'read push pop ping out new move measure limit join invoke import '
313 'group get format foreach export expand exit enter enable disconnect '
314 'disable debug cxnew copy convertto convertfrom convert connect '
315 'complete compare clear checkpoint aggregate add').split()
316
317 commenthelp = (
318 'component description example externalhelp forwardhelpcategory '
319 'forwardhelptargetname functionality inputs link '
320 'notes outputs parameter remotehelprunspace role synopsis').split()
321
322 tokens = {
323 'root': [
324 (r'\s+', Text),
325 (r'^(\s*#[#\s]*)(\.(?:%s))([^\n]*$)' % '|'.join(commenthelp),
326 bygroups(Comment, String.Doc, Comment)),
327 (r'#[^\n]*?$', Comment),
328 (r'(&lt;|<)#', Comment.Multiline, 'multline'),
329 (r'@"\n.*?\n"@', String.Heredoc),
330 (r"@'\n.*?\n'@", String.Heredoc),
331 (r'"', String.Double, 'string'),
332 (r"'([^']|'')*'", String.Single),
333 (r'(\$|@@|@)((global|script|private|env):)?[a-z0-9_]+',
334 Name.Variable),
335 (r'(%s)\b' % '|'.join(keywords), Keyword),
336 (r'-(%s)\b' % '|'.join(operators), Operator),
337 (r'(%s)-[a-z_][a-z0-9_]*\b' % '|'.join(verbs), Name.Builtin),
338 (r'\[[a-z_\[][a-z0-9_. `,\[\]]*\]', Name.Constant), # .net [type]s
339 (r'-[a-z_][a-z0-9_]*', Name),
340 (r'\w+', Name),
341 (r'[.,{}\[\]$()=+*/\\&%!~?^`|<>-]', Punctuation),
342 ],
343 'multline': [
344 (r'[^#&.]+', Comment.Multiline),
345 (r'#(>|&gt;)', Comment.Multiline, '#pop'),
346 (r'\.(%s)' % '|'.join(commenthelp), String.Doc),
347 (r'[#&.]', Comment.Multiline),
348 ],
349 'string': [
350 (r'[^$`"]+', String.Double),
351 (r'\$\(', String.Interpol, 'interpol'),
352 (r'`"|""', String.Double),
353 (r'[`$]', String.Double),
354 (r'"', String.Double, '#pop'),
355 ],
356 'interpol': [
357 (r'[^$)]+', String.Interpol),
358 (r'\$\(', String.Interpol, '#push'),
359 (r'\)', String.Interpol, '#pop'),
360 ]
361 }

eric ide

mercurial