diff options
Diffstat (limited to 'pygments/lexers/shell.py')
-rw-r--r-- | pygments/lexers/shell.py | 119 |
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'(<|<)#', 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), ] } |