summaryrefslogtreecommitdiff
path: root/pygments/lexers/shell.py
diff options
context:
space:
mode:
Diffstat (limited to 'pygments/lexers/shell.py')
-rw-r--r--pygments/lexers/shell.py119
1 files changed, 91 insertions, 28 deletions
diff --git a/pygments/lexers/shell.py b/pygments/lexers/shell.py
index b6afa353..b069b375 100644
--- a/pygments/lexers/shell.py
+++ b/pygments/lexers/shell.py
@@ -5,7 +5,7 @@
Lexers for various shells.
- :copyright: Copyright 2006-2012 by the Pygments team, see AUTHORS.
+ :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@@ -18,7 +18,7 @@ from pygments.util import shebang_matches
__all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer',
- 'PowerShellLexer']
+ 'PowerShellLexer', 'ShellSessionLexer']
line_re = re.compile('.*?\n')
@@ -27,13 +27,13 @@ class BashLexer(RegexLexer):
"""
Lexer for (ba|k|)sh shell scripts.
- *New in Pygments 0.6.*
+ .. versionadded:: 0.6
"""
name = 'Bash'
aliases = ['bash', 'sh', 'ksh']
filenames = ['*.sh', '*.ksh', '*.bash', '*.ebuild', '*.eclass',
- '.bashrc', 'bashrc', '.bash_*', 'bash_*']
+ '.bashrc', 'bashrc', '.bash_*', 'bash_*', 'PKGBUILD']
mimetypes = ['application/x-sh', 'application/x-shellscript']
tokens = {
@@ -47,8 +47,8 @@ class BashLexer(RegexLexer):
],
'basic': [
(r'\b(if|fi|else|while|do|done|for|then|return|function|case|'
- r'select|continue|until|esac|elif)\s*\b',
- Keyword),
+ r'select|continue|until|esac|elif)(\s*)\b',
+ bygroups(Keyword, Text)),
(r'\b(alias|bg|bind|break|builtin|caller|cd|command|compgen|'
r'complete|declare|dirs|disown|echo|enable|eval|exec|exit|'
r'export|false|fc|fg|getopts|hash|help|history|jobs|kill|let|'
@@ -60,15 +60,18 @@ class BashLexer(RegexLexer):
(r'\\[\w\W]', String.Escape),
(r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
(r'[\[\]{}()=]', Operator),
+ (r'<<<', Operator), # here-string
(r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
(r'&&|\|\|', Operator),
],
'data': [
(r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
(r"(?s)\$?'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
- (r';', Text),
+ (r';', Punctuation),
+ (r'&', Punctuation),
+ (r'\|', Punctuation),
(r'\s+', Text),
- (r'[^=\s\[\]{}()$"\'`\\<]+', Text),
+ (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text),
(r'\d+(?= |\Z)', Number),
(r'\$#?(\w+|.)', Name.Variable),
(r'<', Text),
@@ -98,14 +101,17 @@ class BashLexer(RegexLexer):
}
def analyse_text(text):
- return shebang_matches(text, r'(ba|z|)sh')
+ if shebang_matches(text, r'(ba|z|)sh'):
+ return 1
+ if text.startswith('$ '):
+ return 0.2
class BashSessionLexer(Lexer):
"""
Lexer for simplistic shell sessions.
- *New in Pygments 1.1.*
+ .. versionadded:: 1.1
"""
name = 'Bash Session'
@@ -152,14 +158,60 @@ class BashSessionLexer(Lexer):
yield pos+i, t, v
+class ShellSessionLexer(Lexer):
+ """
+ Lexer for shell sessions that works with different command prompts
+
+ .. versionadded:: 1.6
+ """
+
+ name = 'Shell Session'
+ aliases = ['shell-session']
+ filenames = ['*.shell-session']
+ mimetypes = ['application/x-sh-session']
+
+ def get_tokens_unprocessed(self, text):
+ bashlexer = BashLexer(**self.options)
+
+ pos = 0
+ curcode = ''
+ insertions = []
+
+ for match in line_re.finditer(text):
+ line = match.group()
+ m = re.match(r'^((?:\[?\S+@[^$#%]+\]?\s*)[$#%])(.*\n?)', line)
+ if m:
+ # To support output lexers (say diff output), the output
+ # needs to be broken by prompts whenever the output lexer
+ # changes.
+ if not insertions:
+ pos = match.start()
+
+ insertions.append((len(curcode),
+ [(0, Generic.Prompt, m.group(1))]))
+ curcode += m.group(2)
+ else:
+ if insertions:
+ toks = bashlexer.get_tokens_unprocessed(curcode)
+ for i, t, v in do_insertions(insertions, toks):
+ yield pos+i, t, v
+ yield match.start(), Generic.Output, line
+ insertions = []
+ curcode = ''
+ if insertions:
+ for i, t, v in do_insertions(insertions,
+ bashlexer.get_tokens_unprocessed(curcode)):
+ yield pos+i, t, v
+
+
class BatchLexer(RegexLexer):
"""
Lexer for the DOS/Windows Batch file format.
- *New in Pygments 0.7.*
+ .. versionadded:: 0.7
"""
name = 'Batchfile'
- aliases = ['bat']
+ aliases = ['bat', 'batch', 'dosbatch', 'winbatch']
filenames = ['*.bat', '*.cmd']
mimetypes = ['application/x-dos-batch']
@@ -176,9 +228,9 @@ class BatchLexer(RegexLexer):
# like %~$VAR:zlt
(r'%%?[~$:\w]+%?', Name.Variable),
(r'::.*', Comment), # Technically :: only works at BOL
- (r'(set)(\s+)(\w+)', bygroups(Keyword, Text, Name.Variable)),
- (r'(call)(\s+)(:\w+)', bygroups(Keyword, Text, Name.Label)),
- (r'(goto)(\s+)(\w+)', bygroups(Keyword, Text, Name.Label)),
+ (r'\b(set)(\s+)(\w+)', bygroups(Keyword, Text, Name.Variable)),
+ (r'\b(call)(\s+)(:\w+)', bygroups(Keyword, Text, Name.Label)),
+ (r'\b(goto)(\s+)(\w+)', bygroups(Keyword, Text, Name.Label)),
(r'\b(set|call|echo|on|off|endlocal|for|do|goto|if|pause|'
r'setlocal|shift|errorlevel|exist|defined|cmdextversion|'
r'errorlevel|else|cd|md|del|deltree|cls|choice)\b', Keyword),
@@ -212,7 +264,7 @@ class TcshLexer(RegexLexer):
"""
Lexer for tcsh scripts.
- *New in Pygments 0.10.*
+ .. versionadded:: 0.10
"""
name = 'Tcsh'
@@ -279,11 +331,11 @@ class PowerShellLexer(RegexLexer):
"""
For Windows PowerShell code.
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'PowerShell'
- aliases = ['powershell', 'posh', 'ps1']
- filenames = ['*.ps1']
+ aliases = ['powershell', 'posh', 'ps1', 'psm1']
+ filenames = ['*.ps1','*.psm1']
mimetypes = ['text/x-powershell']
flags = re.DOTALL | re.IGNORECASE | re.MULTILINE
@@ -295,7 +347,7 @@ class PowerShellLexer(RegexLexer):
'dynamicparam do default continue cmdletbinding break begin alias \\? '
'% #script #private #local #global mandatory parametersetname position '
'valuefrompipeline valuefrompipelinebypropertyname '
- 'valuefromremainingarguments helpmessage try catch').split()
+ 'valuefromremainingarguments helpmessage try catch throw').split()
operators = (
'and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle '
@@ -321,13 +373,18 @@ class PowerShellLexer(RegexLexer):
tokens = {
'root': [
+ # we need to count pairs of parentheses for correct highlight
+ # of '$(...)' blocks in strings
+ (r'\(', Punctuation, 'child'),
(r'\s+', Text),
(r'^(\s*#[#\s]*)(\.(?:%s))([^\n]*$)' % '|'.join(commenthelp),
bygroups(Comment, String.Doc, Comment)),
(r'#[^\n]*?$', Comment),
(r'(&lt;|<)#', Comment.Multiline, 'multline'),
- (r'@"\n.*?\n"@', String.Heredoc),
+ (r'@"\n', String.Heredoc, 'heredoc-double'),
(r"@'\n.*?\n'@", String.Heredoc),
+ # escaped syntax
+ (r'`[\'"$@-]', Punctuation),
(r'"', String.Double, 'string'),
(r"'([^']|'')*'", String.Single),
(r'(\$|@@|@)((global|script|private|env):)?[a-z0-9_]+',
@@ -338,7 +395,11 @@ class PowerShellLexer(RegexLexer):
(r'\[[a-z_\[][a-z0-9_. `,\[\]]*\]', Name.Constant), # .net [type]s
(r'-[a-z_][a-z0-9_]*', Name),
(r'\w+', Name),
- (r'[.,{}\[\]$()=+*/\\&%!~?^`|<>-]', Punctuation),
+ (r'[.,;@{}\[\]$()=+*/\\&%!~?^`|<>-]|::', Punctuation),
+ ],
+ 'child': [
+ (r'\)', Punctuation, '#pop'),
+ include('root'),
],
'multline': [
(r'[^#&.]+', Comment.Multiline),
@@ -347,15 +408,17 @@ class PowerShellLexer(RegexLexer):
(r'[#&.]', Comment.Multiline),
],
'string': [
+ (r"`[0abfnrtv'\"\$`]", String.Escape),
(r'[^$`"]+', String.Double),
- (r'\$\(', String.Interpol, 'interpol'),
- (r'`"|""', String.Double),
+ (r'\$\(', Punctuation, 'child'),
+ (r'""', String.Double),
(r'[`$]', String.Double),
(r'"', String.Double, '#pop'),
],
- 'interpol': [
- (r'[^$)]+', String.Interpol),
- (r'\$\(', String.Interpol, '#push'),
- (r'\)', String.Interpol, '#pop'),
+ 'heredoc-double': [
+ (r'\n"@', String.Heredoc, '#pop'),
+ (r'\$\(', Punctuation, 'child'),
+ (r'[^@\n]+"]', String.Heredoc),
+ (r".", String.Heredoc),
]
}