16 Text, Comment, Operator, Keyword, Name, String, Number, Generic |
16 Text, Comment, Operator, Keyword, Name, String, Number, Generic |
17 from pygments.util import shebang_matches |
17 from pygments.util import shebang_matches |
18 |
18 |
19 |
19 |
20 __all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer', |
20 __all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer', |
21 'PowerShellLexer'] |
21 'PowerShellLexer', 'ShellSessionLexer'] |
22 |
22 |
23 line_re = re.compile('.*?\n') |
23 line_re = re.compile('.*?\n') |
24 |
24 |
25 |
25 |
26 class BashLexer(RegexLexer): |
26 class BashLexer(RegexLexer): |
58 Name.Builtin), |
58 Name.Builtin), |
59 (r'#.*\n', Comment), |
59 (r'#.*\n', Comment), |
60 (r'\\[\w\W]', String.Escape), |
60 (r'\\[\w\W]', String.Escape), |
61 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)), |
61 (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)), |
62 (r'[\[\]{}()=]', Operator), |
62 (r'[\[\]{}()=]', Operator), |
|
63 (r'<<<', Operator), # here-string |
63 (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String), |
64 (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String), |
64 (r'&&|\|\|', Operator), |
65 (r'&&|\|\|', Operator), |
65 ], |
66 ], |
66 'data': [ |
67 'data': [ |
67 (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double), |
68 (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double), |
136 curcode += m.group(2) |
137 curcode += m.group(2) |
137 elif line.startswith('>'): |
138 elif line.startswith('>'): |
138 insertions.append((len(curcode), |
139 insertions.append((len(curcode), |
139 [(0, Generic.Prompt, line[:1])])) |
140 [(0, Generic.Prompt, line[:1])])) |
140 curcode += line[1:] |
141 curcode += line[1:] |
|
142 else: |
|
143 if insertions: |
|
144 toks = bashlexer.get_tokens_unprocessed(curcode) |
|
145 for i, t, v in do_insertions(insertions, toks): |
|
146 yield pos+i, t, v |
|
147 yield match.start(), Generic.Output, line |
|
148 insertions = [] |
|
149 curcode = '' |
|
150 if insertions: |
|
151 for i, t, v in do_insertions(insertions, |
|
152 bashlexer.get_tokens_unprocessed(curcode)): |
|
153 yield pos+i, t, v |
|
154 |
|
155 |
|
156 class ShellSessionLexer(Lexer): |
|
157 """ |
|
158 Lexer for shell sessions that works with different command prompts |
|
159 |
|
160 *New in Pygments 1.6.* |
|
161 """ |
|
162 |
|
163 name = 'Shell Session' |
|
164 aliases = ['shell-session'] |
|
165 filenames = ['*.shell-session'] |
|
166 mimetypes = ['application/x-sh-session'] |
|
167 |
|
168 def get_tokens_unprocessed(self, text): |
|
169 bashlexer = BashLexer(**self.options) |
|
170 |
|
171 pos = 0 |
|
172 curcode = '' |
|
173 insertions = [] |
|
174 |
|
175 for match in line_re.finditer(text): |
|
176 line = match.group() |
|
177 m = re.match(r'^((?:\[?\S+@[^$#%]+)[$#%])(.*\n?)', line) |
|
178 if m: |
|
179 # To support output lexers (say diff output), the output |
|
180 # needs to be broken by prompts whenever the output lexer |
|
181 # changes. |
|
182 if not insertions: |
|
183 pos = match.start() |
|
184 |
|
185 insertions.append((len(curcode), |
|
186 [(0, Generic.Prompt, m.group(1))])) |
|
187 curcode += m.group(2) |
141 else: |
188 else: |
142 if insertions: |
189 if insertions: |
143 toks = bashlexer.get_tokens_unprocessed(curcode) |
190 toks = bashlexer.get_tokens_unprocessed(curcode) |
144 for i, t, v in do_insertions(insertions, toks): |
191 for i, t, v in do_insertions(insertions, toks): |
145 yield pos+i, t, v |
192 yield pos+i, t, v |
326 bygroups(Comment, String.Doc, Comment)), |
373 bygroups(Comment, String.Doc, Comment)), |
327 (r'#[^\n]*?$', Comment), |
374 (r'#[^\n]*?$', Comment), |
328 (r'(<|<)#', Comment.Multiline, 'multline'), |
375 (r'(<|<)#', Comment.Multiline, 'multline'), |
329 (r'@"\n.*?\n"@', String.Heredoc), |
376 (r'@"\n.*?\n"@', String.Heredoc), |
330 (r"@'\n.*?\n'@", String.Heredoc), |
377 (r"@'\n.*?\n'@", String.Heredoc), |
|
378 # escaped syntax |
|
379 (r'`[\'"$@-]', Punctuation), |
331 (r'"', String.Double, 'string'), |
380 (r'"', String.Double, 'string'), |
332 (r"'([^']|'')*'", String.Single), |
381 (r"'([^']|'')*'", String.Single), |
333 (r'(\$|@@|@)((global|script|private|env):)?[a-z0-9_]+', |
382 (r'(\$|@@|@)((global|script|private|env):)?[a-z0-9_]+', |
334 Name.Variable), |
383 Name.Variable), |
335 (r'(%s)\b' % '|'.join(keywords), Keyword), |
384 (r'(%s)\b' % '|'.join(keywords), Keyword), |