You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			903 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			903 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Python
		
	
"""
 | 
						|
    pygments.lexers.shell
 | 
						|
    ~~~~~~~~~~~~~~~~~~~~~
 | 
						|
 | 
						|
    Lexers for various shells.
 | 
						|
 | 
						|
    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
 | 
						|
    :license: BSD, see LICENSE for details.
 | 
						|
"""
 | 
						|
 | 
						|
import re
 | 
						|
 | 
						|
from pygments.lexer import Lexer, RegexLexer, do_insertions, bygroups, \
 | 
						|
    include, default, this, using, words, line_re
 | 
						|
from pygments.token import Punctuation, Whitespace, \
 | 
						|
    Text, Comment, Operator, Keyword, Name, String, Number, Generic
 | 
						|
from pygments.util import shebang_matches
 | 
						|
 | 
						|
__all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer',
 | 
						|
           'SlurmBashLexer', 'MSDOSSessionLexer', 'PowerShellLexer',
 | 
						|
           'PowerShellSessionLexer', 'TcshSessionLexer', 'FishShellLexer',
 | 
						|
           'ExeclineLexer']
 | 
						|
 | 
						|
 | 
						|
class BashLexer(RegexLexer):
 | 
						|
    """
 | 
						|
    Lexer for (ba|k|z|)sh shell scripts.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'Bash'
 | 
						|
    aliases = ['bash', 'sh', 'ksh', 'zsh', 'shell', 'openrc']
 | 
						|
    filenames = ['*.sh', '*.ksh', '*.bash', '*.ebuild', '*.eclass',
 | 
						|
                 '*.exheres-0', '*.exlib', '*.zsh',
 | 
						|
                 '.bashrc', 'bashrc', '.bash_*', 'bash_*', 'zshrc', '.zshrc',
 | 
						|
                 '.kshrc', 'kshrc',
 | 
						|
                 'PKGBUILD']
 | 
						|
    mimetypes = ['application/x-sh', 'application/x-shellscript', 'text/x-shellscript']
 | 
						|
    url = 'https://en.wikipedia.org/wiki/Unix_shell'
 | 
						|
    version_added = '0.6'
 | 
						|
 | 
						|
    tokens = {
 | 
						|
        'root': [
 | 
						|
            include('basic'),
 | 
						|
            (r'`', String.Backtick, 'backticks'),
 | 
						|
            include('data'),
 | 
						|
            include('interp'),
 | 
						|
        ],
 | 
						|
        'interp': [
 | 
						|
            (r'\$\(\(', Keyword, 'math'),
 | 
						|
            (r'\$\(', Keyword, 'paren'),
 | 
						|
            (r'\$\{#?', String.Interpol, 'curly'),
 | 
						|
            (r'\$[a-zA-Z_]\w*', Name.Variable),  # user variable
 | 
						|
            (r'\$(?:\d+|[#$?!_*@-])', Name.Variable),      # builtin
 | 
						|
            (r'\$', Text),
 | 
						|
        ],
 | 
						|
        'basic': [
 | 
						|
            (r'\b(if|fi|else|while|in|do|done|for|then|return|function|case|'
 | 
						|
             r'select|break|continue|until|esac|elif)(\s*)\b',
 | 
						|
             bygroups(Keyword, Whitespace)),
 | 
						|
            (r'\b(alias|bg|bind|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|'
 | 
						|
             r'local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|'
 | 
						|
             r'shopt|source|suspend|test|time|times|trap|true|type|typeset|'
 | 
						|
             r'ulimit|umask|unalias|unset|wait)(?=[\s)`])',
 | 
						|
             Name.Builtin),
 | 
						|
            (r'\A#!.+\n', Comment.Hashbang),
 | 
						|
            (r'#.*\n', Comment.Single),
 | 
						|
            (r'\\[\w\W]', String.Escape),
 | 
						|
            (r'(\b\w+)(\s*)(\+?=)', bygroups(Name.Variable, Whitespace, Operator)),
 | 
						|
            (r'[\[\]{}()=]', Operator),
 | 
						|
            (r'<<<', Operator),  # here-string
 | 
						|
            (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
 | 
						|
            (r'&&|\|\|', Operator),
 | 
						|
        ],
 | 
						|
        'data': [
 | 
						|
            (r'(?s)\$?"(\\.|[^"\\$])*"', String.Double),
 | 
						|
            (r'"', String.Double, 'string'),
 | 
						|
            (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
 | 
						|
            (r"(?s)'.*?'", String.Single),
 | 
						|
            (r';', Punctuation),
 | 
						|
            (r'&', Punctuation),
 | 
						|
            (r'\|', Punctuation),
 | 
						|
            (r'\s+', Whitespace),
 | 
						|
            (r'\d+\b', Number),
 | 
						|
            (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text),
 | 
						|
            (r'<', Text),
 | 
						|
        ],
 | 
						|
        'string': [
 | 
						|
            (r'"', String.Double, '#pop'),
 | 
						|
            (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double),
 | 
						|
            include('interp'),
 | 
						|
        ],
 | 
						|
        'curly': [
 | 
						|
            (r'\}', String.Interpol, '#pop'),
 | 
						|
            (r':-', Keyword),
 | 
						|
            (r'\w+', Name.Variable),
 | 
						|
            (r'[^}:"\'`$\\]+', Punctuation),
 | 
						|
            (r':', Punctuation),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
        'paren': [
 | 
						|
            (r'\)', Keyword, '#pop'),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
        'math': [
 | 
						|
            (r'\)\)', Keyword, '#pop'),
 | 
						|
            (r'\*\*|\|\||<<|>>|[-+*/%^|&<>]', Operator),
 | 
						|
            (r'\d+#[\da-zA-Z]+', Number),
 | 
						|
            (r'\d+#(?! )', Number),
 | 
						|
            (r'0[xX][\da-fA-F]+', Number),
 | 
						|
            (r'\d+', Number),
 | 
						|
            (r'[a-zA-Z_]\w*', Name.Variable),  # user variable
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
        'backticks': [
 | 
						|
            (r'`', String.Backtick, '#pop'),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
    }
 | 
						|
 | 
						|
    def analyse_text(text):
 | 
						|
        if shebang_matches(text, r'(ba|z|)sh'):
 | 
						|
            return 1
 | 
						|
        if text.startswith('$ '):
 | 
						|
            return 0.2
 | 
						|
 | 
						|
 | 
						|
class SlurmBashLexer(BashLexer):
 | 
						|
    """
 | 
						|
    Lexer for (ba|k|z|)sh Slurm scripts.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'Slurm'
 | 
						|
    aliases = ['slurm', 'sbatch']
 | 
						|
    filenames = ['*.sl']
 | 
						|
    mimetypes = []
 | 
						|
    version_added = '2.4'
 | 
						|
    EXTRA_KEYWORDS = {'srun'}
 | 
						|
 | 
						|
    def get_tokens_unprocessed(self, text):
 | 
						|
        for index, token, value in BashLexer.get_tokens_unprocessed(self, text):
 | 
						|
            if token is Text and value in self.EXTRA_KEYWORDS:
 | 
						|
                yield index, Name.Builtin, value
 | 
						|
            elif token is Comment.Single and 'SBATCH' in value:
 | 
						|
                yield index, Keyword.Pseudo, value
 | 
						|
            else:
 | 
						|
                yield index, token, value
 | 
						|
 | 
						|
 | 
						|
class ShellSessionBaseLexer(Lexer):
 | 
						|
    """
 | 
						|
    Base lexer for shell sessions.
 | 
						|
 | 
						|
    .. versionadded:: 2.1
 | 
						|
    """
 | 
						|
 | 
						|
    _bare_continuation = False
 | 
						|
    _venv = re.compile(r'^(\([^)]*\))(\s*)')
 | 
						|
 | 
						|
    def get_tokens_unprocessed(self, text):
 | 
						|
        innerlexer = self._innerLexerCls(**self.options)
 | 
						|
 | 
						|
        pos = 0
 | 
						|
        curcode = ''
 | 
						|
        insertions = []
 | 
						|
        backslash_continuation = False
 | 
						|
 | 
						|
        for match in line_re.finditer(text):
 | 
						|
            line = match.group()
 | 
						|
 | 
						|
            venv_match = self._venv.match(line)
 | 
						|
            if venv_match:
 | 
						|
                venv = venv_match.group(1)
 | 
						|
                venv_whitespace = venv_match.group(2)
 | 
						|
                insertions.append((len(curcode),
 | 
						|
                                   [(0, Generic.Prompt.VirtualEnv, venv)]))
 | 
						|
                if venv_whitespace:
 | 
						|
                    insertions.append((len(curcode),
 | 
						|
                                       [(0, Text, venv_whitespace)]))
 | 
						|
                line = line[venv_match.end():]
 | 
						|
 | 
						|
            m = self._ps1rgx.match(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)
 | 
						|
                backslash_continuation = curcode.endswith('\\\n')
 | 
						|
            elif backslash_continuation:
 | 
						|
                if line.startswith(self._ps2):
 | 
						|
                    insertions.append((len(curcode),
 | 
						|
                                       [(0, Generic.Prompt,
 | 
						|
                                         line[:len(self._ps2)])]))
 | 
						|
                    curcode += line[len(self._ps2):]
 | 
						|
                else:
 | 
						|
                    curcode += line
 | 
						|
                backslash_continuation = curcode.endswith('\\\n')
 | 
						|
            elif self._bare_continuation and line.startswith(self._ps2):
 | 
						|
                insertions.append((len(curcode),
 | 
						|
                                   [(0, Generic.Prompt,
 | 
						|
                                     line[:len(self._ps2)])]))
 | 
						|
                curcode += line[len(self._ps2):]
 | 
						|
            else:
 | 
						|
                if insertions:
 | 
						|
                    toks = innerlexer.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,
 | 
						|
                                         innerlexer.get_tokens_unprocessed(curcode)):
 | 
						|
                yield pos+i, t, v
 | 
						|
 | 
						|
 | 
						|
class BashSessionLexer(ShellSessionBaseLexer):
 | 
						|
    """
 | 
						|
    Lexer for Bash shell sessions, i.e. command lines, including a
 | 
						|
    prompt, interspersed with output.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'Bash Session'
 | 
						|
    aliases = ['console', 'shell-session']
 | 
						|
    filenames = ['*.sh-session', '*.shell-session']
 | 
						|
    mimetypes = ['application/x-shell-session', 'application/x-sh-session']
 | 
						|
    url = 'https://en.wikipedia.org/wiki/Unix_shell'
 | 
						|
    version_added = '1.1'
 | 
						|
    _example = "console/example.sh-session"
 | 
						|
 | 
						|
    _innerLexerCls = BashLexer
 | 
						|
    _ps1rgx = re.compile(
 | 
						|
        r'^((?:(?:\[.*?\])|(?:\(\S+\))?(?:| |sh\S*?|\w+\S+[@:]\S+(?:\s+\S+)' \
 | 
						|
        r'?|\[\S+[@:][^\n]+\].+))\s*[$#%]\s*)(.*\n?)')
 | 
						|
    _ps2 = '> '
 | 
						|
 | 
						|
 | 
						|
class BatchLexer(RegexLexer):
 | 
						|
    """
 | 
						|
    Lexer for the DOS/Windows Batch file format.
 | 
						|
    """
 | 
						|
    name = 'Batchfile'
 | 
						|
    aliases = ['batch', 'bat', 'dosbatch', 'winbatch']
 | 
						|
    filenames = ['*.bat', '*.cmd']
 | 
						|
    mimetypes = ['application/x-dos-batch']
 | 
						|
    url = 'https://en.wikipedia.org/wiki/Batch_file'
 | 
						|
    version_added = '0.7'
 | 
						|
 | 
						|
    flags = re.MULTILINE | re.IGNORECASE
 | 
						|
 | 
						|
    _nl = r'\n\x1a'
 | 
						|
    _punct = r'&<>|'
 | 
						|
    _ws = r'\t\v\f\r ,;=\xa0'
 | 
						|
    _nlws = r'\s\x1a\xa0,;='
 | 
						|
    _space = rf'(?:(?:(?:\^[{_nl}])?[{_ws}])+)'
 | 
						|
    _keyword_terminator = (rf'(?=(?:\^[{_nl}]?)?[{_ws}+./:[\\\]]|[{_nl}{_punct}(])')
 | 
						|
    _token_terminator = rf'(?=\^?[{_ws}]|[{_punct}{_nl}])'
 | 
						|
    _start_label = rf'((?:(?<=^[^:])|^[^:]?)[{_ws}]*)(:)'
 | 
						|
    _label = rf'(?:(?:[^{_nlws}{_punct}+:^]|\^[{_nl}]?[\w\W])*)'
 | 
						|
    _label_compound = rf'(?:(?:[^{_nlws}{_punct}+:^)]|\^[{_nl}]?[^)])*)'
 | 
						|
    _number = rf'(?:-?(?:0[0-7]+|0x[\da-f]+|\d+){_token_terminator})'
 | 
						|
    _opword = r'(?:equ|geq|gtr|leq|lss|neq)'
 | 
						|
    _string = rf'(?:"[^{_nl}"]*(?:"|(?=[{_nl}])))'
 | 
						|
    _variable = (r'(?:(?:%(?:\*|(?:~[a-z]*(?:\$[^:]+:)?)?\d|'
 | 
						|
                 rf'[^%:{_nl}]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:[^%{_nl}^]|'
 | 
						|
                 rf'\^[^%{_nl}])[^={_nl}]*=(?:[^%{_nl}^]|\^[^%{_nl}])*)?)?%))|'
 | 
						|
                 rf'(?:\^?![^!:{_nl}]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:'
 | 
						|
                 rf'[^!{_nl}^]|\^[^!{_nl}])[^={_nl}]*=(?:[^!{_nl}^]|\^[^!{_nl}])*)?)?\^?!))')
 | 
						|
    _core_token = rf'(?:(?:(?:\^[{_nl}]?)?[^"{_nlws}{_punct}])+)'
 | 
						|
    _core_token_compound = rf'(?:(?:(?:\^[{_nl}]?)?[^"{_nlws}{_punct})])+)'
 | 
						|
    _token = rf'(?:[{_punct}]+|{_core_token})'
 | 
						|
    _token_compound = rf'(?:[{_punct}]+|{_core_token_compound})'
 | 
						|
    _stoken = (rf'(?:[{_punct}]+|(?:{_string}|{_variable}|{_core_token})+)')
 | 
						|
 | 
						|
    def _make_begin_state(compound, _core_token=_core_token,
 | 
						|
                          _core_token_compound=_core_token_compound,
 | 
						|
                          _keyword_terminator=_keyword_terminator,
 | 
						|
                          _nl=_nl, _punct=_punct, _string=_string,
 | 
						|
                          _space=_space, _start_label=_start_label,
 | 
						|
                          _stoken=_stoken, _token_terminator=_token_terminator,
 | 
						|
                          _variable=_variable, _ws=_ws):
 | 
						|
        rest = '(?:{}|{}|[^"%{}{}{}])*'.format(_string, _variable, _nl, _punct,
 | 
						|
                                            ')' if compound else '')
 | 
						|
        rest_of_line = rf'(?:(?:[^{_nl}^]|\^[{_nl}]?[\w\W])*)'
 | 
						|
        rest_of_line_compound = rf'(?:(?:[^{_nl}^)]|\^[{_nl}]?[^)])*)'
 | 
						|
        set_space = rf'((?:(?:\^[{_nl}]?)?[^\S\n])*)'
 | 
						|
        suffix = ''
 | 
						|
        if compound:
 | 
						|
            _keyword_terminator = rf'(?:(?=\))|{_keyword_terminator})'
 | 
						|
            _token_terminator = rf'(?:(?=\))|{_token_terminator})'
 | 
						|
            suffix = '/compound'
 | 
						|
        return [
 | 
						|
            ((r'\)', Punctuation, '#pop') if compound else
 | 
						|
             (rf'\)((?=\()|{_token_terminator}){rest_of_line}',
 | 
						|
              Comment.Single)),
 | 
						|
            (rf'(?={_start_label})', Text, f'follow{suffix}'),
 | 
						|
            (_space, using(this, state='text')),
 | 
						|
            include(f'redirect{suffix}'),
 | 
						|
            (rf'[{_nl}]+', Text),
 | 
						|
            (r'\(', Punctuation, 'root/compound'),
 | 
						|
            (r'@+', Punctuation),
 | 
						|
            (rf'((?:for|if|rem)(?:(?=(?:\^[{_nl}]?)?/)|(?:(?!\^)|'
 | 
						|
             rf'(?<=m))(?:(?=\()|{_token_terminator})))({_space}?{_core_token_compound if compound else _core_token}?(?:\^[{_nl}]?)?/(?:\^[{_nl}]?)?\?)',
 | 
						|
             bygroups(Keyword, using(this, state='text')),
 | 
						|
             f'follow{suffix}'),
 | 
						|
            (rf'(goto{_keyword_terminator})({rest}(?:\^[{_nl}]?)?/(?:\^[{_nl}]?)?\?{rest})',
 | 
						|
             bygroups(Keyword, using(this, state='text')),
 | 
						|
             f'follow{suffix}'),
 | 
						|
            (words(('assoc', 'break', 'cd', 'chdir', 'cls', 'color', 'copy',
 | 
						|
                    'date', 'del', 'dir', 'dpath', 'echo', 'endlocal', 'erase',
 | 
						|
                    'exit', 'ftype', 'keys', 'md', 'mkdir', 'mklink', 'move',
 | 
						|
                    'path', 'pause', 'popd', 'prompt', 'pushd', 'rd', 'ren',
 | 
						|
                    'rename', 'rmdir', 'setlocal', 'shift', 'start', 'time',
 | 
						|
                    'title', 'type', 'ver', 'verify', 'vol'),
 | 
						|
                   suffix=_keyword_terminator), Keyword, f'follow{suffix}'),
 | 
						|
            (rf'(call)({_space}?)(:)',
 | 
						|
             bygroups(Keyword, using(this, state='text'), Punctuation),
 | 
						|
             f'call{suffix}'),
 | 
						|
            (rf'call{_keyword_terminator}', Keyword),
 | 
						|
            (rf'(for{_token_terminator}(?!\^))({_space})(/f{_token_terminator})',
 | 
						|
             bygroups(Keyword, using(this, state='text'), Keyword),
 | 
						|
             ('for/f', 'for')),
 | 
						|
            (rf'(for{_token_terminator}(?!\^))({_space})(/l{_token_terminator})',
 | 
						|
             bygroups(Keyword, using(this, state='text'), Keyword),
 | 
						|
             ('for/l', 'for')),
 | 
						|
            (rf'for{_token_terminator}(?!\^)', Keyword, ('for2', 'for')),
 | 
						|
            (rf'(goto{_keyword_terminator})({_space}?)(:?)',
 | 
						|
             bygroups(Keyword, using(this, state='text'), Punctuation),
 | 
						|
             f'label{suffix}'),
 | 
						|
            (rf'(if(?:(?=\()|{_token_terminator})(?!\^))({_space}?)((?:/i{_token_terminator})?)({_space}?)((?:not{_token_terminator})?)({_space}?)',
 | 
						|
             bygroups(Keyword, using(this, state='text'), Keyword,
 | 
						|
                      using(this, state='text'), Keyword,
 | 
						|
                      using(this, state='text')), ('(?', 'if')),
 | 
						|
            (rf'rem(((?=\()|{_token_terminator}){_space}?{_stoken}?.*|{_keyword_terminator}{rest_of_line_compound if compound else rest_of_line})',
 | 
						|
             Comment.Single, f'follow{suffix}'),
 | 
						|
            (rf'(set{_keyword_terminator}){set_space}(/a)',
 | 
						|
             bygroups(Keyword, using(this, state='text'), Keyword),
 | 
						|
             f'arithmetic{suffix}'),
 | 
						|
            (r'(set{}){}((?:/p)?){}((?:(?:(?:\^[{}]?)?[^"{}{}^={}]|'
 | 
						|
             r'\^[{}]?[^"=])+)?)((?:(?:\^[{}]?)?=)?)'.format(_keyword_terminator, set_space, set_space, _nl, _nl, _punct,
 | 
						|
              ')' if compound else '', _nl, _nl),
 | 
						|
             bygroups(Keyword, using(this, state='text'), Keyword,
 | 
						|
                      using(this, state='text'), using(this, state='variable'),
 | 
						|
                      Punctuation),
 | 
						|
             f'follow{suffix}'),
 | 
						|
            default(f'follow{suffix}')
 | 
						|
        ]
 | 
						|
 | 
						|
    def _make_follow_state(compound, _label=_label,
 | 
						|
                           _label_compound=_label_compound, _nl=_nl,
 | 
						|
                           _space=_space, _start_label=_start_label,
 | 
						|
                           _token=_token, _token_compound=_token_compound,
 | 
						|
                           _ws=_ws):
 | 
						|
        suffix = '/compound' if compound else ''
 | 
						|
        state = []
 | 
						|
        if compound:
 | 
						|
            state.append((r'(?=\))', Text, '#pop'))
 | 
						|
        state += [
 | 
						|
            (rf'{_start_label}([{_ws}]*)({_label_compound if compound else _label})(.*)',
 | 
						|
             bygroups(Text, Punctuation, Text, Name.Label, Comment.Single)),
 | 
						|
            include(f'redirect{suffix}'),
 | 
						|
            (rf'(?=[{_nl}])', Text, '#pop'),
 | 
						|
            (r'\|\|?|&&?', Punctuation, '#pop'),
 | 
						|
            include('text')
 | 
						|
        ]
 | 
						|
        return state
 | 
						|
 | 
						|
    def _make_arithmetic_state(compound, _nl=_nl, _punct=_punct,
 | 
						|
                               _string=_string, _variable=_variable,
 | 
						|
                               _ws=_ws, _nlws=_nlws):
 | 
						|
        op = r'=+\-*/!~'
 | 
						|
        state = []
 | 
						|
        if compound:
 | 
						|
            state.append((r'(?=\))', Text, '#pop'))
 | 
						|
        state += [
 | 
						|
            (r'0[0-7]+', Number.Oct),
 | 
						|
            (r'0x[\da-f]+', Number.Hex),
 | 
						|
            (r'\d+', Number.Integer),
 | 
						|
            (r'[(),]+', Punctuation),
 | 
						|
            (rf'([{op}]|%|\^\^)+', Operator),
 | 
						|
            (r'({}|{}|(\^[{}]?)?[^(){}%\^"{}{}]|\^[{}]?{})+'.format(_string, _variable, _nl, op, _nlws, _punct, _nlws,
 | 
						|
              r'[^)]' if compound else r'[\w\W]'),
 | 
						|
             using(this, state='variable')),
 | 
						|
            (r'(?=[\x00|&])', Text, '#pop'),
 | 
						|
            include('follow')
 | 
						|
        ]
 | 
						|
        return state
 | 
						|
 | 
						|
    def _make_call_state(compound, _label=_label,
 | 
						|
                         _label_compound=_label_compound):
 | 
						|
        state = []
 | 
						|
        if compound:
 | 
						|
            state.append((r'(?=\))', Text, '#pop'))
 | 
						|
        state.append((r'(:?)(%s)' % (_label_compound if compound else _label),
 | 
						|
                      bygroups(Punctuation, Name.Label), '#pop'))
 | 
						|
        return state
 | 
						|
 | 
						|
    def _make_label_state(compound, _label=_label,
 | 
						|
                          _label_compound=_label_compound, _nl=_nl,
 | 
						|
                          _punct=_punct, _string=_string, _variable=_variable):
 | 
						|
        state = []
 | 
						|
        if compound:
 | 
						|
            state.append((r'(?=\))', Text, '#pop'))
 | 
						|
        state.append((r'({}?)((?:{}|{}|\^[{}]?{}|[^"%^{}{}{}])*)'.format(_label_compound if compound else _label, _string,
 | 
						|
                       _variable, _nl, r'[^)]' if compound else r'[\w\W]', _nl,
 | 
						|
                       _punct, r')' if compound else ''),
 | 
						|
                      bygroups(Name.Label, Comment.Single), '#pop'))
 | 
						|
        return state
 | 
						|
 | 
						|
    def _make_redirect_state(compound,
 | 
						|
                             _core_token_compound=_core_token_compound,
 | 
						|
                             _nl=_nl, _punct=_punct, _stoken=_stoken,
 | 
						|
                             _string=_string, _space=_space,
 | 
						|
                             _variable=_variable, _nlws=_nlws):
 | 
						|
        stoken_compound = (rf'(?:[{_punct}]+|(?:{_string}|{_variable}|{_core_token_compound})+)')
 | 
						|
        return [
 | 
						|
            (rf'((?:(?<=[{_nlws}])\d)?)(>>?&|<&)([{_nlws}]*)(\d)',
 | 
						|
             bygroups(Number.Integer, Punctuation, Text, Number.Integer)),
 | 
						|
            (rf'((?:(?<=[{_nlws}])(?<!\^[{_nl}])\d)?)(>>?|<)({_space}?{stoken_compound if compound else _stoken})',
 | 
						|
             bygroups(Number.Integer, Punctuation, using(this, state='text')))
 | 
						|
        ]
 | 
						|
 | 
						|
    tokens = {
 | 
						|
        'root': _make_begin_state(False),
 | 
						|
        'follow': _make_follow_state(False),
 | 
						|
        'arithmetic': _make_arithmetic_state(False),
 | 
						|
        'call': _make_call_state(False),
 | 
						|
        'label': _make_label_state(False),
 | 
						|
        'redirect': _make_redirect_state(False),
 | 
						|
        'root/compound': _make_begin_state(True),
 | 
						|
        'follow/compound': _make_follow_state(True),
 | 
						|
        'arithmetic/compound': _make_arithmetic_state(True),
 | 
						|
        'call/compound': _make_call_state(True),
 | 
						|
        'label/compound': _make_label_state(True),
 | 
						|
        'redirect/compound': _make_redirect_state(True),
 | 
						|
        'variable-or-escape': [
 | 
						|
            (_variable, Name.Variable),
 | 
						|
            (rf'%%|\^[{_nl}]?(\^!|[\w\W])', String.Escape)
 | 
						|
        ],
 | 
						|
        'string': [
 | 
						|
            (r'"', String.Double, '#pop'),
 | 
						|
            (_variable, Name.Variable),
 | 
						|
            (r'\^!|%%', String.Escape),
 | 
						|
            (rf'[^"%^{_nl}]+|[%^]', String.Double),
 | 
						|
            default('#pop')
 | 
						|
        ],
 | 
						|
        'sqstring': [
 | 
						|
            include('variable-or-escape'),
 | 
						|
            (r'[^%]+|%', String.Single)
 | 
						|
        ],
 | 
						|
        'bqstring': [
 | 
						|
            include('variable-or-escape'),
 | 
						|
            (r'[^%]+|%', String.Backtick)
 | 
						|
        ],
 | 
						|
        'text': [
 | 
						|
            (r'"', String.Double, 'string'),
 | 
						|
            include('variable-or-escape'),
 | 
						|
            (rf'[^"%^{_nlws}{_punct}\d)]+|.', Text)
 | 
						|
        ],
 | 
						|
        'variable': [
 | 
						|
            (r'"', String.Double, 'string'),
 | 
						|
            include('variable-or-escape'),
 | 
						|
            (rf'[^"%^{_nl}]+|.', Name.Variable)
 | 
						|
        ],
 | 
						|
        'for': [
 | 
						|
            (rf'({_space})(in)({_space})(\()',
 | 
						|
             bygroups(using(this, state='text'), Keyword,
 | 
						|
                      using(this, state='text'), Punctuation), '#pop'),
 | 
						|
            include('follow')
 | 
						|
        ],
 | 
						|
        'for2': [
 | 
						|
            (r'\)', Punctuation),
 | 
						|
            (rf'({_space})(do{_token_terminator})',
 | 
						|
             bygroups(using(this, state='text'), Keyword), '#pop'),
 | 
						|
            (rf'[{_nl}]+', Text),
 | 
						|
            include('follow')
 | 
						|
        ],
 | 
						|
        'for/f': [
 | 
						|
            (rf'(")((?:{_variable}|[^"])*?")([{_nlws}]*)(\))',
 | 
						|
             bygroups(String.Double, using(this, state='string'), Text,
 | 
						|
                      Punctuation)),
 | 
						|
            (r'"', String.Double, ('#pop', 'for2', 'string')),
 | 
						|
            (rf"('(?:%%|{_variable}|[\w\W])*?')([{_nlws}]*)(\))",
 | 
						|
             bygroups(using(this, state='sqstring'), Text, Punctuation)),
 | 
						|
            (rf'(`(?:%%|{_variable}|[\w\W])*?`)([{_nlws}]*)(\))',
 | 
						|
             bygroups(using(this, state='bqstring'), Text, Punctuation)),
 | 
						|
            include('for2')
 | 
						|
        ],
 | 
						|
        'for/l': [
 | 
						|
            (r'-?\d+', Number.Integer),
 | 
						|
            include('for2')
 | 
						|
        ],
 | 
						|
        'if': [
 | 
						|
            (rf'((?:cmdextversion|errorlevel){_token_terminator})({_space})(\d+)',
 | 
						|
             bygroups(Keyword, using(this, state='text'),
 | 
						|
                      Number.Integer), '#pop'),
 | 
						|
            (rf'(defined{_token_terminator})({_space})({_stoken})',
 | 
						|
             bygroups(Keyword, using(this, state='text'),
 | 
						|
                      using(this, state='variable')), '#pop'),
 | 
						|
            (rf'(exist{_token_terminator})({_space}{_stoken})',
 | 
						|
             bygroups(Keyword, using(this, state='text')), '#pop'),
 | 
						|
            (rf'({_number}{_space})({_opword})({_space}{_number})',
 | 
						|
             bygroups(using(this, state='arithmetic'), Operator.Word,
 | 
						|
                      using(this, state='arithmetic')), '#pop'),
 | 
						|
            (_stoken, using(this, state='text'), ('#pop', 'if2')),
 | 
						|
        ],
 | 
						|
        'if2': [
 | 
						|
            (rf'({_space}?)(==)({_space}?{_stoken})',
 | 
						|
             bygroups(using(this, state='text'), Operator,
 | 
						|
                      using(this, state='text')), '#pop'),
 | 
						|
            (rf'({_space})({_opword})({_space}{_stoken})',
 | 
						|
             bygroups(using(this, state='text'), Operator.Word,
 | 
						|
                      using(this, state='text')), '#pop')
 | 
						|
        ],
 | 
						|
        '(?': [
 | 
						|
            (_space, using(this, state='text')),
 | 
						|
            (r'\(', Punctuation, ('#pop', 'else?', 'root/compound')),
 | 
						|
            default('#pop')
 | 
						|
        ],
 | 
						|
        'else?': [
 | 
						|
            (_space, using(this, state='text')),
 | 
						|
            (rf'else{_token_terminator}', Keyword, '#pop'),
 | 
						|
            default('#pop')
 | 
						|
        ]
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
class MSDOSSessionLexer(ShellSessionBaseLexer):
 | 
						|
    """
 | 
						|
    Lexer for MS DOS shell sessions, i.e. command lines, including a
 | 
						|
    prompt, interspersed with output.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'MSDOS Session'
 | 
						|
    aliases = ['doscon']
 | 
						|
    filenames = []
 | 
						|
    mimetypes = []
 | 
						|
    url = 'https://en.wikipedia.org/wiki/MS-DOS'
 | 
						|
    version_added = '2.1'
 | 
						|
    _example = "doscon/session"
 | 
						|
 | 
						|
    _innerLexerCls = BatchLexer
 | 
						|
    _ps1rgx = re.compile(r'^([^>]*>)(.*\n?)')
 | 
						|
    _ps2 = 'More? '
 | 
						|
 | 
						|
 | 
						|
class TcshLexer(RegexLexer):
 | 
						|
    """
 | 
						|
    Lexer for tcsh scripts.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'Tcsh'
 | 
						|
    aliases = ['tcsh', 'csh']
 | 
						|
    filenames = ['*.tcsh', '*.csh']
 | 
						|
    mimetypes = ['application/x-csh']
 | 
						|
    url = 'https://www.tcsh.org'
 | 
						|
    version_added = '0.10'
 | 
						|
 | 
						|
    tokens = {
 | 
						|
        'root': [
 | 
						|
            include('basic'),
 | 
						|
            (r'\$\(', Keyword, 'paren'),
 | 
						|
            (r'\$\{#?', Keyword, 'curly'),
 | 
						|
            (r'`', String.Backtick, 'backticks'),
 | 
						|
            include('data'),
 | 
						|
        ],
 | 
						|
        'basic': [
 | 
						|
            (r'\b(if|endif|else|while|then|foreach|case|default|'
 | 
						|
             r'break|continue|goto|breaksw|end|switch|endsw)\s*\b',
 | 
						|
             Keyword),
 | 
						|
            (r'\b(alias|alloc|bg|bindkey|builtins|bye|caller|cd|chdir|'
 | 
						|
             r'complete|dirs|echo|echotc|eval|exec|exit|fg|filetest|getxvers|'
 | 
						|
             r'glob|getspath|hashstat|history|hup|inlib|jobs|kill|'
 | 
						|
             r'limit|log|login|logout|ls-F|migrate|newgrp|nice|nohup|notify|'
 | 
						|
             r'onintr|popd|printenv|pushd|rehash|repeat|rootnode|popd|pushd|'
 | 
						|
             r'set|shift|sched|setenv|setpath|settc|setty|setxvers|shift|'
 | 
						|
             r'source|stop|suspend|source|suspend|telltc|time|'
 | 
						|
             r'umask|unalias|uncomplete|unhash|universe|unlimit|unset|unsetenv|'
 | 
						|
             r'ver|wait|warp|watchlog|where|which)\s*\b',
 | 
						|
             Name.Builtin),
 | 
						|
            (r'#.*', Comment),
 | 
						|
            (r'\\[\w\W]', String.Escape),
 | 
						|
            (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
 | 
						|
            (r'[\[\]{}()=]+', Operator),
 | 
						|
            (r'<<\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
 | 
						|
            (r';', Punctuation),
 | 
						|
        ],
 | 
						|
        'data': [
 | 
						|
            (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
 | 
						|
            (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
 | 
						|
            (r'\s+', Text),
 | 
						|
            (r'[^=\s\[\]{}()$"\'`\\;#]+', Text),
 | 
						|
            (r'\d+(?= |\Z)', Number),
 | 
						|
            (r'\$#?(\w+|.)', Name.Variable),
 | 
						|
        ],
 | 
						|
        'curly': [
 | 
						|
            (r'\}', Keyword, '#pop'),
 | 
						|
            (r':-', Keyword),
 | 
						|
            (r'\w+', Name.Variable),
 | 
						|
            (r'[^}:"\'`$]+', Punctuation),
 | 
						|
            (r':', Punctuation),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
        'paren': [
 | 
						|
            (r'\)', Keyword, '#pop'),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
        'backticks': [
 | 
						|
            (r'`', String.Backtick, '#pop'),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
class TcshSessionLexer(ShellSessionBaseLexer):
 | 
						|
    """
 | 
						|
    Lexer for Tcsh sessions, i.e. command lines, including a
 | 
						|
    prompt, interspersed with output.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'Tcsh Session'
 | 
						|
    aliases = ['tcshcon']
 | 
						|
    filenames = []
 | 
						|
    mimetypes = []
 | 
						|
    url = 'https://www.tcsh.org'
 | 
						|
    version_added = '2.1'
 | 
						|
    _example = "tcshcon/session"
 | 
						|
 | 
						|
    _innerLexerCls = TcshLexer
 | 
						|
    _ps1rgx = re.compile(r'^([^>]+>)(.*\n?)')
 | 
						|
    _ps2 = '? '
 | 
						|
 | 
						|
 | 
						|
class PowerShellLexer(RegexLexer):
 | 
						|
    """
 | 
						|
    For Windows PowerShell code.
 | 
						|
    """
 | 
						|
    name = 'PowerShell'
 | 
						|
    aliases = ['powershell', 'pwsh', 'posh', 'ps1', 'psm1']
 | 
						|
    filenames = ['*.ps1', '*.psm1']
 | 
						|
    mimetypes = ['text/x-powershell']
 | 
						|
    url = 'https://learn.microsoft.com/en-us/powershell'
 | 
						|
    version_added = '1.5'
 | 
						|
 | 
						|
    flags = re.DOTALL | re.IGNORECASE | re.MULTILINE
 | 
						|
 | 
						|
    keywords = (
 | 
						|
        'while validateset validaterange validatepattern validatelength '
 | 
						|
        'validatecount until trap switch return ref process param parameter in '
 | 
						|
        'if global: local: function foreach for finally filter end elseif else '
 | 
						|
        'dynamicparam do default continue cmdletbinding break begin alias \\? '
 | 
						|
        '% #script #private #local #global mandatory parametersetname position '
 | 
						|
        'valuefrompipeline valuefrompipelinebypropertyname '
 | 
						|
        'valuefromremainingarguments helpmessage try catch throw').split()
 | 
						|
 | 
						|
    operators = (
 | 
						|
        'and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle '
 | 
						|
        'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains '
 | 
						|
        'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt '
 | 
						|
        'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like '
 | 
						|
        'lt match ne not notcontains notlike notmatch or regex replace '
 | 
						|
        'wildcard').split()
 | 
						|
 | 
						|
    verbs = (
 | 
						|
        'write where watch wait use update unregister unpublish unprotect '
 | 
						|
        'unlock uninstall undo unblock trace test tee take sync switch '
 | 
						|
        'suspend submit stop step start split sort skip show set send select '
 | 
						|
        'search scroll save revoke resume restore restart resolve resize '
 | 
						|
        'reset request repair rename remove register redo receive read push '
 | 
						|
        'publish protect pop ping out optimize open new move mount merge '
 | 
						|
        'measure lock limit join invoke install initialize import hide group '
 | 
						|
        'grant get format foreach find export expand exit enter enable edit '
 | 
						|
        'dismount disconnect disable deny debug cxnew copy convertto '
 | 
						|
        'convertfrom convert connect confirm compress complete compare close '
 | 
						|
        'clear checkpoint block backup assert approve aggregate add').split()
 | 
						|
 | 
						|
    aliases_ = (
 | 
						|
        'ac asnp cat cd cfs chdir clc clear clhy cli clp cls clv cnsn '
 | 
						|
        'compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo epal '
 | 
						|
        'epcsv epsn erase etsn exsn fc fhx fl foreach ft fw gal gbp gc gci gcm '
 | 
						|
        'gcs gdr ghy gi gjb gl gm gmo gp gps gpv group gsn gsnp gsv gu gv gwmi '
 | 
						|
        'h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp '
 | 
						|
        'ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv '
 | 
						|
        'oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo '
 | 
						|
        'rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc select '
 | 
						|
        'set shcm si sl sleep sls sort sp spjb spps spsv start sujb sv swmi tee '
 | 
						|
        'trcm type wget where wjb write').split()
 | 
						|
 | 
						|
    commenthelp = (
 | 
						|
        'component description example externalhelp forwardhelpcategory '
 | 
						|
        'forwardhelptargetname functionality inputs link '
 | 
						|
        'notes outputs parameter remotehelprunspace role synopsis').split()
 | 
						|
 | 
						|
    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]*)(\.(?:{}))([^\n]*$)'.format('|'.join(commenthelp)),
 | 
						|
             bygroups(Comment, String.Doc, Comment)),
 | 
						|
            (r'#[^\n]*?$', Comment),
 | 
						|
            (r'(<|<)#', Comment.Multiline, 'multline'),
 | 
						|
            (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):)?\w+',
 | 
						|
             Name.Variable),
 | 
						|
            (r'({})\b'.format('|'.join(keywords)), Keyword),
 | 
						|
            (r'-({})\b'.format('|'.join(operators)), Operator),
 | 
						|
            (r'({})-[a-z_]\w*\b'.format('|'.join(verbs)), Name.Builtin),
 | 
						|
            (r'({})\s'.format('|'.join(aliases_)), Name.Builtin),
 | 
						|
            (r'\[[a-z_\[][\w. `,\[\]]*\]', Name.Constant),  # .net [type]s
 | 
						|
            (r'-[a-z_]\w*', Name),
 | 
						|
            (r'\w+', Name),
 | 
						|
            (r'[.,;:@{}\[\]$()=+*/\\&%!~?^`|<>-]', Punctuation),
 | 
						|
        ],
 | 
						|
        'child': [
 | 
						|
            (r'\)', Punctuation, '#pop'),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
        'multline': [
 | 
						|
            (r'[^#&.]+', Comment.Multiline),
 | 
						|
            (r'#(>|>)', Comment.Multiline, '#pop'),
 | 
						|
            (r'\.({})'.format('|'.join(commenthelp)), String.Doc),
 | 
						|
            (r'[#&.]', Comment.Multiline),
 | 
						|
        ],
 | 
						|
        'string': [
 | 
						|
            (r"`[0abfnrtv'\"$`]", String.Escape),
 | 
						|
            (r'[^$`"]+', String.Double),
 | 
						|
            (r'\$\(', Punctuation, 'child'),
 | 
						|
            (r'""', String.Double),
 | 
						|
            (r'[`$]', String.Double),
 | 
						|
            (r'"', String.Double, '#pop'),
 | 
						|
        ],
 | 
						|
        'heredoc-double': [
 | 
						|
            (r'\n"@', String.Heredoc, '#pop'),
 | 
						|
            (r'\$\(', Punctuation, 'child'),
 | 
						|
            (r'[^@\n]+"]', String.Heredoc),
 | 
						|
            (r".", String.Heredoc),
 | 
						|
        ]
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
class PowerShellSessionLexer(ShellSessionBaseLexer):
 | 
						|
    """
 | 
						|
    Lexer for PowerShell sessions, i.e. command lines, including a
 | 
						|
    prompt, interspersed with output.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'PowerShell Session'
 | 
						|
    aliases = ['pwsh-session', 'ps1con']
 | 
						|
    filenames = []
 | 
						|
    mimetypes = []
 | 
						|
    url = 'https://learn.microsoft.com/en-us/powershell'
 | 
						|
    version_added = '2.1'
 | 
						|
    _example = "pwsh-session/session"
 | 
						|
 | 
						|
    _innerLexerCls = PowerShellLexer
 | 
						|
    _bare_continuation = True
 | 
						|
    _ps1rgx = re.compile(r'^((?:\[[^]]+\]: )?PS[^>]*> ?)(.*\n?)')
 | 
						|
    _ps2 = '> '
 | 
						|
 | 
						|
 | 
						|
class FishShellLexer(RegexLexer):
 | 
						|
    """
 | 
						|
    Lexer for Fish shell scripts.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'Fish'
 | 
						|
    aliases = ['fish', 'fishshell']
 | 
						|
    filenames = ['*.fish', '*.load']
 | 
						|
    mimetypes = ['application/x-fish']
 | 
						|
    url = 'https://fishshell.com'
 | 
						|
    version_added = '2.1'
 | 
						|
 | 
						|
    tokens = {
 | 
						|
        'root': [
 | 
						|
            include('basic'),
 | 
						|
            include('data'),
 | 
						|
            include('interp'),
 | 
						|
        ],
 | 
						|
        'interp': [
 | 
						|
            (r'\$\(\(', Keyword, 'math'),
 | 
						|
            (r'\(', Keyword, 'paren'),
 | 
						|
            (r'\$#?(\w+|.)', Name.Variable),
 | 
						|
        ],
 | 
						|
        'basic': [
 | 
						|
            (r'\b(begin|end|if|else|while|break|for|in|return|function|block|'
 | 
						|
             r'case|continue|switch|not|and|or|set|echo|exit|pwd|true|false|'
 | 
						|
             r'cd|count|test)(\s*)\b',
 | 
						|
             bygroups(Keyword, Text)),
 | 
						|
            (r'\b(alias|bg|bind|breakpoint|builtin|command|commandline|'
 | 
						|
             r'complete|contains|dirh|dirs|emit|eval|exec|fg|fish|fish_config|'
 | 
						|
             r'fish_indent|fish_pager|fish_prompt|fish_right_prompt|'
 | 
						|
             r'fish_update_completions|fishd|funced|funcsave|functions|help|'
 | 
						|
             r'history|isatty|jobs|math|mimedb|nextd|open|popd|prevd|psub|'
 | 
						|
             r'pushd|random|read|set_color|source|status|trap|type|ulimit|'
 | 
						|
             r'umask|vared|fc|getopts|hash|kill|printf|time|wait)\s*\b(?!\.)',
 | 
						|
             Name.Builtin),
 | 
						|
            (r'#.*\n', Comment),
 | 
						|
            (r'\\[\w\W]', String.Escape),
 | 
						|
            (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Whitespace, Operator)),
 | 
						|
            (r'[\[\]()=]', Operator),
 | 
						|
            (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
 | 
						|
        ],
 | 
						|
        'data': [
 | 
						|
            (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\$])*"', String.Double),
 | 
						|
            (r'"', String.Double, 'string'),
 | 
						|
            (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
 | 
						|
            (r"(?s)'.*?'", String.Single),
 | 
						|
            (r';', Punctuation),
 | 
						|
            (r'&|\||\^|<|>', Operator),
 | 
						|
            (r'\s+', Text),
 | 
						|
            (r'\d+(?= |\Z)', Number),
 | 
						|
            (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text),
 | 
						|
        ],
 | 
						|
        'string': [
 | 
						|
            (r'"', String.Double, '#pop'),
 | 
						|
            (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double),
 | 
						|
            include('interp'),
 | 
						|
        ],
 | 
						|
        'paren': [
 | 
						|
            (r'\)', Keyword, '#pop'),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
        'math': [
 | 
						|
            (r'\)\)', Keyword, '#pop'),
 | 
						|
            (r'[-+*/%^|&]|\*\*|\|\|', Operator),
 | 
						|
            (r'\d+#\d+', Number),
 | 
						|
            (r'\d+#(?! )', Number),
 | 
						|
            (r'\d+', Number),
 | 
						|
            include('root'),
 | 
						|
        ],
 | 
						|
    }
 | 
						|
 | 
						|
class ExeclineLexer(RegexLexer):
 | 
						|
    """
 | 
						|
    Lexer for Laurent Bercot's execline language.
 | 
						|
    """
 | 
						|
 | 
						|
    name = 'execline'
 | 
						|
    aliases = ['execline']
 | 
						|
    filenames = ['*.exec']
 | 
						|
    url = 'https://skarnet.org/software/execline'
 | 
						|
    version_added = '2.7'
 | 
						|
 | 
						|
    tokens = {
 | 
						|
        'root': [
 | 
						|
            include('basic'),
 | 
						|
            include('data'),
 | 
						|
            include('interp')
 | 
						|
        ],
 | 
						|
        'interp': [
 | 
						|
            (r'\$\{', String.Interpol, 'curly'),
 | 
						|
            (r'\$[\w@#]+', Name.Variable),  # user variable
 | 
						|
            (r'\$', Text),
 | 
						|
        ],
 | 
						|
        'basic': [
 | 
						|
            (r'\b(background|backtick|cd|define|dollarat|elgetopt|'
 | 
						|
             r'elgetpositionals|elglob|emptyenv|envfile|exec|execlineb|'
 | 
						|
             r'exit|export|fdblock|fdclose|fdmove|fdreserve|fdswap|'
 | 
						|
             r'forbacktickx|foreground|forstdin|forx|getcwd|getpid|heredoc|'
 | 
						|
             r'homeof|if|ifelse|ifte|ifthenelse|importas|loopwhilex|'
 | 
						|
             r'multidefine|multisubstitute|pipeline|piperw|posix-cd|'
 | 
						|
             r'redirfd|runblock|shift|trap|tryexec|umask|unexport|wait|'
 | 
						|
             r'withstdinas)\b', Name.Builtin),
 | 
						|
            (r'\A#!.+\n', Comment.Hashbang),
 | 
						|
            (r'#.*\n', Comment.Single),
 | 
						|
            (r'[{}]', Operator)
 | 
						|
        ],
 | 
						|
        'data': [
 | 
						|
            (r'(?s)"(\\.|[^"\\$])*"', String.Double),
 | 
						|
            (r'"', String.Double, 'string'),
 | 
						|
            (r'\s+', Text),
 | 
						|
            (r'[^\s{}$"\\]+', Text)
 | 
						|
        ],
 | 
						|
        'string': [
 | 
						|
            (r'"', String.Double, '#pop'),
 | 
						|
            (r'(?s)(\\\\|\\.|[^"\\$])+', String.Double),
 | 
						|
            include('interp'),
 | 
						|
        ],
 | 
						|
        'curly': [
 | 
						|
            (r'\}', String.Interpol, '#pop'),
 | 
						|
            (r'[\w#@]+', Name.Variable),
 | 
						|
            include('root')
 | 
						|
        ]
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    def analyse_text(text):
 | 
						|
        if shebang_matches(text, r'execlineb'):
 | 
						|
            return 1
 |