{ "scopeName": "source.shell", "name": "Shell Script", "fileTypes": [ "sh", "bash", "ksh", "zsh", "zsh-theme", "zshenv", "zlogin", "zlogout", "zprofile", "zshrc", "bashrc", "bash_aliases", "bash_profile", "bash_login", "profile", "bash_logout", ".textmate_init", "npmrc", "PKGBUILD", "install", "cygport", "bats", "ebuild" ], "firstLineMatch": "(?x)\n# Hashbang\n^\\#!.*(?:\\s|\\/)\n (?:bash|zsh|sh|tcsh|ksh|dash|ash|csh|rc)\n(?:$|\\s)\n|\n# Modeline\n(?i:\n # Emacs\n -\\*-(?:\\s*(?=[^:;\\s]+\\s*-\\*-)|(?:.*?[;\\s]|(?<=-\\*-))mode\\s*:\\s*)\n (?:shell-script|sh)\n (?=[\\s;]|(?]?\\d+|m)?|\\sex)(?=:(?=\\s*set?\\s[^\\n:]+:)|:(?!\\s* set?\\s))(?:(?:\\s|\\s*:\\s*)\\w*(?:\\s*=(?:[^\\n\\\\\\s]|\\\\.)*)?)*[\\s:](?:filetype|ft|syntax)\\s*=\n sh\n (?=\\s|:|$)\n)", "patterns": [ { "include": "#comment" }, { "include": "#pipeline" }, { "include": "#list" }, { "include": "#compound-command" }, { "include": "#loop" }, { "include": "#function-definition" }, { "include": "#string" }, { "include": "#variable" }, { "include": "#interpolation" }, { "include": "#heredoc" }, { "include": "#herestring" }, { "include": "#redirection" }, { "include": "#pathname" }, { "include": "#keyword" }, { "include": "#support" } ], "repository": { "case-clause": { "patterns": [ { "begin": "(?=\\S)", "end": ";;", "endCaptures": { "0": { "name": "punctuation.terminator.case-clause.shell" } }, "name": "meta.scope.case-clause.shell", "patterns": [ { "begin": "\\(|(?=\\S)", "beginCaptures": { "0": { "name": "punctuation.definition.case-pattern.shell" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.case-pattern.shell" } }, "name": "meta.scope.case-pattern.shell", "patterns": [ { "match": "\\|", "name": "punctuation.separator.pipe-sign.shell" }, { "include": "#string" }, { "include": "#variable" }, { "include": "#interpolation" }, { "include": "#pathname" } ] }, { "begin": "(?<=\\))", "end": "(?=;;)", "name": "meta.scope.case-clause-body.shell", "patterns": [ { "include": "$self" } ] } ] } ] }, "comment": { "begin": "(^\\s+)?(?<=^|\\W)(?=#)(?!#{)", "beginCaptures": { "1": { "name": "punctuation.whitespace.comment.leading.shell" } }, "end": "(?!\\G)", "patterns": [ { "begin": "#!", "beginCaptures": { "0": { "name": "punctuation.definition.comment.shebang.shell" } }, "end": "$", "name": "comment.line.number-sign.shebang.shell" }, { "begin": "#", "beginCaptures": { "0": { "name": "punctuation.definition.comment.shell" } }, "end": "$", "name": "comment.line.number-sign.shell" } ] }, "compound-command": { "patterns": [ { "begin": "\\[{1,2}", "beginCaptures": { "0": { "name": "punctuation.definition.logical-expression.shell" } }, "end": "\\]{1,2}", "endCaptures": { "0": { "name": "punctuation.definition.logical-expression.shell" } }, "name": "meta.scope.logical-expression.shell", "patterns": [ { "include": "#logical-expression" }, { "include": "$self" } ] }, { "begin": "\\({2}", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.shell" } }, "end": "\\){2}", "endCaptures": { "0": { "name": "punctuation.definition.string.end.shell" } }, "name": "string.other.math.shell", "patterns": [ { "include": "#math" } ] }, { "begin": "\\(", "beginCaptures": { "0": { "name": "punctuation.definition.subshell.shell" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.subshell.shell" } }, "name": "meta.scope.subshell.shell", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=\\s|^){(?=\\s|$)", "beginCaptures": { "0": { "name": "punctuation.definition.group.shell" } }, "end": "(?<=^|;)\\s*(})", "endCaptures": { "1": { "name": "punctuation.definition.group.shell" } }, "name": "meta.scope.group.shell", "patterns": [ { "include": "$self" } ] } ] }, "function-definition": { "patterns": [ { "begin": "(?<=^|;|&|\\s)(function)\\s+([^\\s\\\\]+)(?:\\s*(\\(\\)))?", "beginCaptures": { "1": { "name": "storage.type.function.shell" }, "2": { "name": "entity.name.function.shell" }, "3": { "name": "punctuation.definition.arguments.shell" } }, "end": ";|&|$", "endCaptures": { "0": { "name": "punctuation.definition.function.shell" } }, "name": "meta.function.shell", "patterns": [ { "include": "$self" } ] }, { "begin": "(?<=^|;|&|\\s)([^\\s\\\\=]+)\\s*(\\(\\))", "beginCaptures": { "1": { "name": "entity.name.function.shell" }, "2": { "name": "punctuation.definition.arguments.shell" } }, "end": ";|&|$", "endCaptures": { "0": { "name": "punctuation.definition.function.shell" } }, "name": "meta.function.shell", "patterns": [ { "include": "$self" } ] } ] }, "heredoc": { "patterns": [ { "begin": "(<<)-(\"|'|)(RUBY)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^\\t*(RUBY)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.no-indent.ruby.shell", "contentName": "source.ruby.embedded.shell", "patterns": [ { "include": "source.ruby" } ] }, { "begin": "(<<)(\"|'|)(RUBY)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^(RUBY)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.ruby.shell", "contentName": "source.ruby.embedded.shell", "patterns": [ { "include": "source.ruby" } ] }, { "begin": "(<<)-(\"|'|)(PYTHON)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^\\t*(PYTHON)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.no-indent.python.shell", "contentName": "source.python.embedded.shell", "patterns": [ { "include": "source.python" } ] }, { "begin": "(<<)(\"|'|)(PYTHON)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^(PYTHON)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.python.shell", "contentName": "source.python.embedded.shell", "patterns": [ { "include": "source.python" } ] }, { "begin": "(<<)-(\"|'|)(APPLESCRIPT)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^\\t*(APPLESCRIPT)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.no-indent.applescript.shell", "contentName": "source.applescript.embedded.shell", "patterns": [ { "include": "source.applescript" } ] }, { "begin": "(<<)(\"|'|)(APPLESCRIPT)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^(APPLESCRIPT)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.applescript.shell", "contentName": "source.applescript.embedded.shell", "patterns": [ { "include": "source.applescript" } ] }, { "begin": "(<<)-(\"|'|)(HTML)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^\\t*(HTML)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.no-indent.html.shell", "contentName": "text.html.embedded.shell", "patterns": [ { "include": "text.html.basic" } ] }, { "begin": "(<<)(\"|'|)(HTML)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^(HTML)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.html.shell", "contentName": "text.html.embedded.shell", "patterns": [ { "include": "text.html.basic" } ] }, { "begin": "(<<)-(\"|'|)(MARKDOWN)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^\\t*(MARKDOWN)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.no-indent.markdown.shell", "contentName": "text.html.markdown.embedded.shell", "patterns": [ { "include": "text.html.markdown" } ] }, { "begin": "(<<)(\"|'|)(MARKDOWN)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^(MARKDOWN)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.markdown.shell", "contentName": "text.html.markdown.embedded.shell", "patterns": [ { "include": "text.html.markdown" } ] }, { "begin": "(<<)-(\"|'|)(TEXTILE)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^\\t*(TEXTILE)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.no-indent.textile.shell", "contentName": "text.html.textile.embedded.shell", "patterns": [ { "include": "text.html.textile" } ] }, { "begin": "(<<)(\"|'|)(TEXTILE)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^(TEXTILE)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.textile.shell", "contentName": "text.html.textile.embedded.shell", "patterns": [ { "include": "text.html.textile" } ] }, { "begin": "(<<)-(\"|'|)(SHELL)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^\\t*(\\3)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "contentName": "source.shell.embedded.shell", "name": "string.unquoted.heredoc.no-indent.shell.shell", "patterns": [ { "include": "source.shell" } ] }, { "begin": "(<<)(\"|'|)(SHELL)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^(\\3)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.shell.shell", "contentName": "source.shell.embedded.shell", "patterns": [ { "include": "source.shell" } ] }, { "begin": "(<<)-(\"|'|)\\\\?(\\w+)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^\\t*(\\3)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.no-indent.shell" }, { "begin": "(<<)(\"|'|)\\\\?(\\w+)\\2", "beginCaptures": { "1": { "name": "keyword.operator.heredoc.shell" }, "3": { "name": "keyword.control.heredoc-token.shell" } }, "end": "^(\\3)(?=\\s|;|&|$)", "endCaptures": { "1": { "name": "keyword.control.heredoc-token.shell" } }, "name": "string.unquoted.heredoc.shell" } ] }, "herestring": { "patterns": [ { "begin": "(<<<)\\s*(('))", "beginCaptures": { "1": { "name": "keyword.operator.herestring.shell" }, "2": { "name": "string.quoted.single.shell" }, "3": { "name": "punctuation.definition.string.begin.shell" } }, "end": "(')", "endCaptures": { "0": { "name": "string.quoted.single.shell" }, "1": { "name": "punctuation.definition.string.end.shell" } }, "name": "meta.herestring.shell", "contentName": "string.quoted.single.shell" }, { "begin": "(<<<)\\s*((\"))", "beginCaptures": { "1": { "name": "keyword.operator.herestring.shell" }, "2": { "name": "string.quoted.double.shell" }, "3": { "name": "punctuation.definition.string.begin.shell" } }, "end": "(\")", "endCaptures": { "0": { "name": "string.quoted.double.shell" }, "1": { "name": "punctuation.definition.string.end.shell" } }, "name": "meta.herestring.shell", "contentName": "string.quoted.double.shell" }, { "captures": { "1": { "name": "keyword.operator.herestring.shell" }, "2": { "name": "string.unquoted.herestring.shell" } }, "match": "(<<<)(([^\\s\\\\]|\\\\.)+)", "name": "meta.herestring.shell" } ] }, "interpolation": { "patterns": [ { "begin": "\\$\\({2}", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.shell" } }, "end": "\\){2}", "endCaptures": { "0": { "name": "punctuation.definition.string.end.shell" } }, "name": "string.other.math.shell", "patterns": [ { "include": "#math" } ] }, { "begin": "`", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.shell" } }, "end": "`", "endCaptures": { "0": { "name": "punctuation.definition.string.end.shell" } }, "name": "string.interpolated.backtick.shell", "patterns": [ { "match": "\\\\[`\\\\$]", "name": "constant.character.escape.shell" }, { "begin": "(?<=\\W)(?=#)(?!#{)", "beginCaptures": { "1": { "name": "punctuation.whitespace.comment.leading.shell" } }, "end": "(?!\\G)", "patterns": [ { "begin": "#", "beginCaptures": { "0": { "name": "punctuation.definition.comment.shell" } }, "end": "(?=`)", "name": "comment.line.number-sign.shell" } ] }, { "include": "$self" } ] }, { "begin": "\\$\\(", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.shell" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.string.end.shell" } }, "name": "string.interpolated.dollar.shell", "patterns": [ { "include": "$self" } ] } ] }, "keyword": { "patterns": [ { "match": "(?<=^|;|&|\\s)(then|else|elif|fi|for|in|do|done|select|case|continue|esac|while|until|return)(?=\\s|;|&|$)", "name": "keyword.control.shell" }, { "match": "(?<=^|;|&|\\s)(?:export|declare|typeset|local|readonly)(?=\\s|;|&|$)", "name": "storage.modifier.shell" } ] }, "list": { "patterns": [ { "match": ";|&&|&|\\|\\|", "name": "keyword.operator.list.shell" } ] }, "logical-expression": { "patterns": [ { "comment": "do we want a special rule for ( expr )?", "match": "=[=~]?|!=?|<|>|&&|\\|\\|", "name": "keyword.operator.logical.shell" }, { "match": "(?[>=]?|==|!=|^|\\|{1,2}|&{1,2}|\\?|\\:|,|=|[*/%+\\-&^|]=|<<=|>>=", "name": "keyword.operator.arithmetic.shell" }, { "match": "0[xX]\\h+", "name": "constant.numeric.hex.shell" }, { "match": "0\\d+", "name": "constant.numeric.octal.shell" }, { "match": "\\d{1,2}#[0-9a-zA-Z@_]+", "name": "constant.numeric.other.shell" }, { "match": "\\d+", "name": "constant.numeric.integer.shell" } ] }, "pathname": { "patterns": [ { "match": "(?<=\\s|:|=|^)~", "name": "keyword.operator.tilde.shell" }, { "match": "\\*|\\?", "name": "keyword.operator.glob.shell" }, { "begin": "([?*+@!])(\\()", "beginCaptures": { "1": { "name": "keyword.operator.extglob.shell" }, "2": { "name": "punctuation.definition.extglob.shell" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.extglob.shell" } }, "name": "meta.structure.extglob.shell", "patterns": [ { "include": "$self" } ] } ] }, "pipeline": { "patterns": [ { "match": "(?<=^|;|&|\\s)(time)(?=\\s|;|&|$)", "name": "keyword.other.shell" }, { "match": "[|!]", "name": "keyword.operator.pipe.shell" } ] }, "redirection": { "patterns": [ { "begin": "[><]\\(", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.shell" } }, "end": "\\)", "endCaptures": { "0": { "name": "punctuation.definition.string.end.shell" } }, "name": "string.interpolated.process-substitution.shell", "patterns": [ { "include": "$self" } ] }, { "match": "&>|\\d*>&\\d*|\\d*(>>|>|<)|\\d*<&|\\d*<>", "name": "keyword.operator.redirect.shell" } ] }, "string": { "patterns": [ { "match": "\\\\.", "name": "constant.character.escape.shell" }, { "begin": "'", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.shell" } }, "end": "'", "endCaptures": { "0": { "name": "punctuation.definition.string.end.shell" } }, "name": "string.quoted.single.shell" }, { "begin": "\\$?\"", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.shell" } }, "end": "\"", "endCaptures": { "0": { "name": "punctuation.definition.string.end.shell" } }, "name": "string.quoted.double.shell", "patterns": [ { "match": "\\\\[\\$`\"\\\\\\n]", "name": "constant.character.escape.shell" }, { "include": "#variable" }, { "include": "#interpolation" } ] }, { "begin": "\\$'", "beginCaptures": { "0": { "name": "punctuation.definition.string.begin.shell" } }, "end": "'", "endCaptures": { "0": { "name": "punctuation.definition.string.end.shell" } }, "name": "string.quoted.single.dollar.shell", "patterns": [ { "match": "\\\\(a|b|e|f|n|r|t|v|\\\\|')", "name": "constant.character.escape.ansi-c.shell" }, { "match": "\\\\[0-9]{3}", "name": "constant.character.escape.octal.shell" }, { "match": "\\\\x[0-9a-fA-F]{2}", "name": "constant.character.escape.hex.shell" }, { "match": "\\\\c.", "name": "constant.character.escape.control-char.shell" } ] } ] }, "support": { "patterns": [ { "match": "(?<=^|;|&|\\s)(?::|\\.)(?=\\s|;|&|$)", "name": "support.function.builtin.shell" }, { "match": "(?<=^|;|&|\\s)(?:alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|times|trap|true|type|ulimit|umask|unalias|unset|wait)(?=\\s|;|&|$)", "name": "support.function.builtin.shell" } ] }, "variable": { "patterns": [ { "captures": { "1": { "name": "punctuation.definition.variable.shell" } }, "match": "(\\$)[a-zA-Z_][a-zA-Z0-9_]*", "name": "variable.other.normal.shell" }, { "captures": { "1": { "name": "punctuation.definition.variable.shell" } }, "match": "(\\$)[-*@#?$!0_]", "name": "variable.other.special.shell" }, { "captures": { "1": { "name": "punctuation.definition.variable.shell" } }, "match": "(\\$)[1-9]", "name": "variable.other.positional.shell" }, { "begin": "\\${", "beginCaptures": { "0": { "name": "punctuation.definition.variable.shell" } }, "end": "}", "endCaptures": { "0": { "name": "punctuation.definition.variable.shell" } }, "name": "variable.other.bracket.shell", "patterns": [ { "match": "!|:[-=?]?|\\*|@|#{1,2}|%{1,2}|/", "name": "keyword.operator.expansion.shell" }, { "captures": { "1": { "name": "punctuation.section.array.shell" }, "3": { "name": "punctuation.section.array.shell" } }, "match": "(\\[)([^\\]]+)(\\])" }, { "include": "#variable" }, { "include": "#string" } ] } ] } } }