|
1 | 1 | (function(Prism) { |
| 2 | + // $ set | grep '^[A-Z][^[:space:]]*=' | cut -d= -f1 | tr '\n' '|' |
| 3 | + // + LC_ALL, RANDOM, REPLY, SECONDS. |
| 4 | + // + make sure PS1..4 are here as they are not always set, |
| 5 | + // - some useless things. |
| 6 | + var envVars = '\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b'; |
2 | 7 | var insideString = { |
3 | | - variable: [ |
4 | | - // Arithmetic Environment |
| 8 | + 'environment': { |
| 9 | + pattern: RegExp("\\$" + envVars), |
| 10 | + alias: 'constant' |
| 11 | + }, |
| 12 | + 'variable': [ |
| 13 | + // [0]: Arithmetic Environment |
5 | 14 | { |
6 | 15 | pattern: /\$?\(\([\s\S]+?\)\)/, |
| 16 | + greedy: true, |
7 | 17 | inside: { |
8 | 18 | // If there is a $ sign at the beginning highlight $(( and )) as variable |
9 | | - variable: [{ |
| 19 | + 'variable': [ |
| 20 | + { |
10 | 21 | pattern: /(^\$\(\([\s\S]+)\)\)/, |
11 | 22 | lookbehind: true |
12 | 23 | }, |
13 | 24 | /^\$\(\(/ |
14 | 25 | ], |
15 | | - number: /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/, |
| 26 | + 'number': /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/, |
16 | 27 | // Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic |
17 | | - operator: /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/, |
| 28 | + 'operator': /--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/, |
18 | 29 | // If there is no $ sign at the beginning highlight (( and )) as punctuation |
19 | | - punctuation: /\(\(?|\)\)?|,|;/ |
| 30 | + 'punctuation': /\(\(?|\)\)?|,|;/ |
| 31 | + } |
| 32 | + }, |
| 33 | + // [1]: Command Substitution |
| 34 | + { |
| 35 | + pattern: /\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/, |
| 36 | + greedy: true, |
| 37 | + inside: { |
| 38 | + 'variable': /^\$\(|^`|\)$|`$/ |
20 | 39 | } |
21 | 40 | }, |
22 | | - // Command Substitution |
| 41 | + // [2]: Brace expansion |
23 | 42 | { |
24 | | - pattern: /\$\([^)]+\)|`[^`]+`/, |
| 43 | + pattern: /\$\{[^}]+\}/, |
25 | 44 | greedy: true, |
26 | 45 | inside: { |
27 | | - variable: /^\$\(|^`|\)$|`$/ |
| 46 | + 'operator': /:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/, |
| 47 | + 'punctuation': /[\[\]]/, |
| 48 | + 'environment': { |
| 49 | + pattern: RegExp("(\\{)" + envVars), |
| 50 | + lookbehind: true, |
| 51 | + alias: 'constant' |
| 52 | + } |
28 | 53 | } |
29 | 54 | }, |
30 | | - /\$(?:[\w#?*!@]+|\{[^}]+\})/i |
31 | | - ] |
| 55 | + /\$(?:\w+|[#?*!@$])/ |
| 56 | + ], |
| 57 | + // Escape sequences from echo and printf's manuals, and escaped quotes. |
| 58 | + 'entity': /\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/ |
32 | 59 | }; |
33 | 60 |
|
34 | 61 | Prism.languages.bash = { |
35 | 62 | 'shebang': { |
36 | | - pattern: /^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/, |
| 63 | + pattern: /^#!\s*\/.*/, |
37 | 64 | alias: 'important' |
38 | 65 | }, |
39 | 66 | 'comment': { |
40 | | - pattern: /(^|[^"{\\])#.*/, |
| 67 | + pattern: /(^|[^"{\\$])#.*/, |
| 68 | + lookbehind: true |
| 69 | + }, |
| 70 | + 'function-name': [ |
| 71 | + // a) function foo { |
| 72 | + // b) foo() { |
| 73 | + // c) function foo() { |
| 74 | + // but not “foo {” |
| 75 | + { |
| 76 | + // a) and c) |
| 77 | + pattern: /(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/, |
| 78 | + lookbehind: true, |
| 79 | + alias: 'function' |
| 80 | + }, |
| 81 | + { |
| 82 | + // b) |
| 83 | + pattern: /\b\w+(?=\s*\(\s*\)\s*\{)/, |
| 84 | + alias: 'function' |
| 85 | + } |
| 86 | + ], |
| 87 | + // Highlight variable names as variables in for and select beginnings. |
| 88 | + 'for-or-select': { |
| 89 | + pattern: /(\b(?:for|select)\s+)\w+(?=\s+in\s)/, |
| 90 | + alias: 'variable', |
| 91 | + lookbehind: true |
| 92 | + }, |
| 93 | + // Highlight variable names as variables in the left-hand part |
| 94 | + // of assignments (“=” and “+=”). |
| 95 | + 'assign-left': { |
| 96 | + pattern: /(^|[\s;|&]|[<>]\()\w+(?=\+?=)/, |
| 97 | + inside: { |
| 98 | + 'environment': { |
| 99 | + pattern: RegExp("(^|[\\s;|&]|[<>]\\()" + envVars), |
| 100 | + lookbehind: true, |
| 101 | + alias: 'constant' |
| 102 | + } |
| 103 | + }, |
| 104 | + alias: 'variable', |
41 | 105 | lookbehind: true |
42 | 106 | }, |
43 | 107 | 'string': [ |
44 | | - //Support for Here-Documents https://en.wikipedia.org/wiki/Here_document |
| 108 | + // Support for Here-documents https://en.wikipedia.org/wiki/Here_document |
45 | 109 | { |
46 | | - pattern: /((?:^|[^<])<<\s*)["']?(\w+?)["']?\s*\r?\n(?:[\s\S])*?\r?\n\2/, |
| 110 | + pattern: /((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)(?:[\s\S])*?(?:\r?\n|\r)\2/, |
47 | 111 | lookbehind: true, |
48 | 112 | greedy: true, |
49 | 113 | inside: insideString |
50 | 114 | }, |
| 115 | + // Here-document with quotes around the tag |
| 116 | + // → No expansion (so no “inside”). |
| 117 | + { |
| 118 | + pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)(?:[\s\S])*?(?:\r?\n|\r)\3/, |
| 119 | + lookbehind: true, |
| 120 | + greedy: true |
| 121 | + }, |
| 122 | + // “Normal” string |
51 | 123 | { |
52 | 124 | pattern: /(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\1)[^\\])*\1/, |
53 | 125 | greedy: true, |
54 | 126 | inside: insideString |
55 | 127 | } |
56 | 128 | ], |
| 129 | + 'environment': { |
| 130 | + pattern: RegExp("\\$?" + envVars), |
| 131 | + alias: 'constant' |
| 132 | + }, |
57 | 133 | 'variable': insideString.variable, |
58 | | - // Originally based on http://ss64.com/bash/ |
59 | 134 | 'function': { |
60 | | - pattern: /(^|[\s;|&])(?:add|alias|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|hash|head|help|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logout|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tail|tar|tee|test|time|timeout|times|top|touch|tr|traceroute|trap|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zip|zypper)(?=$|[\s;|&])/, |
| 135 | + pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/, |
61 | 136 | lookbehind: true |
62 | 137 | }, |
63 | 138 | 'keyword': { |
64 | | - pattern: /(^|[\s;|&])(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|[\s;|&])/, |
| 139 | + pattern: /(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/, |
65 | 140 | lookbehind: true |
66 | 141 | }, |
| 142 | + // https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html |
| 143 | + 'builtin': { |
| 144 | + pattern: /(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/, |
| 145 | + lookbehind: true, |
| 146 | + // Alias added to make those easier to distinguish from strings. |
| 147 | + alias: 'class-name' |
| 148 | + }, |
67 | 149 | 'boolean': { |
68 | | - pattern: /(^|[\s;|&])(?:true|false)(?=$|[\s;|&])/, |
| 150 | + pattern: /(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/, |
69 | 151 | lookbehind: true |
70 | 152 | }, |
71 | | - 'operator': /&&?|\|\|?|==?|!=?|<<<?|>>|<=?|>=?|=~/, |
72 | | - 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];]/ |
| 153 | + 'file-descriptor': { |
| 154 | + pattern: /\B&\d\b/, |
| 155 | + alias: 'important' |
| 156 | + }, |
| 157 | + 'operator': { |
| 158 | + // Lots of redirections here, but not just that. |
| 159 | + pattern: /\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/, |
| 160 | + inside: { |
| 161 | + 'file-descriptor': { |
| 162 | + pattern: /^\d/, |
| 163 | + alias: 'important' |
| 164 | + } |
| 165 | + } |
| 166 | + }, |
| 167 | + 'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/, |
| 168 | + 'number': { |
| 169 | + pattern: /(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/, |
| 170 | + lookbehind: true |
| 171 | + } |
73 | 172 | }; |
74 | 173 |
|
| 174 | + /* Patterns in command substitution. */ |
| 175 | + var toBeCopied = [ |
| 176 | + 'comment', |
| 177 | + 'function-name', |
| 178 | + 'for-or-select', |
| 179 | + 'assign-left', |
| 180 | + 'string', |
| 181 | + 'environment', |
| 182 | + 'function', |
| 183 | + 'keyword', |
| 184 | + 'builtin', |
| 185 | + 'boolean', |
| 186 | + 'file-descriptor', |
| 187 | + 'operator', |
| 188 | + 'punctuation', |
| 189 | + 'number' |
| 190 | + ]; |
75 | 191 | var inside = insideString.variable[1].inside; |
76 | | - inside.string = Prism.languages.bash.string; |
77 | | - inside['function'] = Prism.languages.bash['function']; |
78 | | - inside.keyword = Prism.languages.bash.keyword; |
79 | | - inside['boolean'] = Prism.languages.bash['boolean']; |
80 | | - inside.operator = Prism.languages.bash.operator; |
81 | | - inside.punctuation = Prism.languages.bash.punctuation; |
82 | | - |
| 192 | + for(var i = 0; i < toBeCopied.length; i++) { |
| 193 | + inside[toBeCopied[i]] = Prism.languages.bash[toBeCopied[i]]; |
| 194 | + } |
| 195 | + |
83 | 196 | Prism.languages.shell = Prism.languages.bash; |
84 | 197 | })(Prism); |
0 commit comments