1 | /**
|
---|
2 | * @param {string} value
|
---|
3 | * @returns {RegExp}
|
---|
4 | * */
|
---|
5 |
|
---|
6 | /**
|
---|
7 | * @param {RegExp | string } re
|
---|
8 | * @returns {string}
|
---|
9 | */
|
---|
10 | function source(re) {
|
---|
11 | if (!re) return null;
|
---|
12 | if (typeof re === "string") return re;
|
---|
13 |
|
---|
14 | return re.source;
|
---|
15 | }
|
---|
16 |
|
---|
17 | /**
|
---|
18 | * @param {...(RegExp | string) } args
|
---|
19 | * @returns {string}
|
---|
20 | */
|
---|
21 | function concat(...args) {
|
---|
22 | const joined = args.map((x) => source(x)).join("");
|
---|
23 | return joined;
|
---|
24 | }
|
---|
25 |
|
---|
26 | /*
|
---|
27 | Language: Bash
|
---|
28 | Author: vah <vahtenberg@gmail.com>
|
---|
29 | Contributrors: Benjamin Pannell <contact@sierrasoftworks.com>
|
---|
30 | Website: https://www.gnu.org/software/bash/
|
---|
31 | Category: common
|
---|
32 | */
|
---|
33 |
|
---|
34 | /** @type LanguageFn */
|
---|
35 | function bash(hljs) {
|
---|
36 | const VAR = {};
|
---|
37 | const BRACED_VAR = {
|
---|
38 | begin: /\$\{/,
|
---|
39 | end:/\}/,
|
---|
40 | contains: [
|
---|
41 | "self",
|
---|
42 | {
|
---|
43 | begin: /:-/,
|
---|
44 | contains: [ VAR ]
|
---|
45 | } // default values
|
---|
46 | ]
|
---|
47 | };
|
---|
48 | Object.assign(VAR,{
|
---|
49 | className: 'variable',
|
---|
50 | variants: [
|
---|
51 | {begin: concat(/\$[\w\d#@][\w\d_]*/,
|
---|
52 | // negative look-ahead tries to avoid matching patterns that are not
|
---|
53 | // Perl at all like $ident$, @ident@, etc.
|
---|
54 | `(?![\\w\\d])(?![$])`) },
|
---|
55 | BRACED_VAR
|
---|
56 | ]
|
---|
57 | });
|
---|
58 |
|
---|
59 | const SUBST = {
|
---|
60 | className: 'subst',
|
---|
61 | begin: /\$\(/, end: /\)/,
|
---|
62 | contains: [hljs.BACKSLASH_ESCAPE]
|
---|
63 | };
|
---|
64 | const HERE_DOC = {
|
---|
65 | begin: /<<-?\s*(?=\w+)/,
|
---|
66 | starts: {
|
---|
67 | contains: [
|
---|
68 | hljs.END_SAME_AS_BEGIN({
|
---|
69 | begin: /(\w+)/,
|
---|
70 | end: /(\w+)/,
|
---|
71 | className: 'string'
|
---|
72 | })
|
---|
73 | ]
|
---|
74 | }
|
---|
75 | };
|
---|
76 | const QUOTE_STRING = {
|
---|
77 | className: 'string',
|
---|
78 | begin: /"/, end: /"/,
|
---|
79 | contains: [
|
---|
80 | hljs.BACKSLASH_ESCAPE,
|
---|
81 | VAR,
|
---|
82 | SUBST
|
---|
83 | ]
|
---|
84 | };
|
---|
85 | SUBST.contains.push(QUOTE_STRING);
|
---|
86 | const ESCAPED_QUOTE = {
|
---|
87 | className: '',
|
---|
88 | begin: /\\"/
|
---|
89 |
|
---|
90 | };
|
---|
91 | const APOS_STRING = {
|
---|
92 | className: 'string',
|
---|
93 | begin: /'/, end: /'/
|
---|
94 | };
|
---|
95 | const ARITHMETIC = {
|
---|
96 | begin: /\$\(\(/,
|
---|
97 | end: /\)\)/,
|
---|
98 | contains: [
|
---|
99 | { begin: /\d+#[0-9a-f]+/, className: "number" },
|
---|
100 | hljs.NUMBER_MODE,
|
---|
101 | VAR
|
---|
102 | ]
|
---|
103 | };
|
---|
104 | const SH_LIKE_SHELLS = [
|
---|
105 | "fish",
|
---|
106 | "bash",
|
---|
107 | "zsh",
|
---|
108 | "sh",
|
---|
109 | "csh",
|
---|
110 | "ksh",
|
---|
111 | "tcsh",
|
---|
112 | "dash",
|
---|
113 | "scsh",
|
---|
114 | ];
|
---|
115 | const KNOWN_SHEBANG = hljs.SHEBANG({
|
---|
116 | binary: `(${SH_LIKE_SHELLS.join("|")})`,
|
---|
117 | relevance: 10
|
---|
118 | });
|
---|
119 | const FUNCTION = {
|
---|
120 | className: 'function',
|
---|
121 | begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/,
|
---|
122 | returnBegin: true,
|
---|
123 | contains: [hljs.inherit(hljs.TITLE_MODE, {begin: /\w[\w\d_]*/})],
|
---|
124 | relevance: 0
|
---|
125 | };
|
---|
126 |
|
---|
127 | return {
|
---|
128 | name: 'Bash',
|
---|
129 | aliases: ['sh', 'zsh'],
|
---|
130 | keywords: {
|
---|
131 | $pattern: /\b[a-z._-]+\b/,
|
---|
132 | keyword:
|
---|
133 | 'if then else elif fi for while in do done case esac function',
|
---|
134 | literal:
|
---|
135 | 'true false',
|
---|
136 | built_in:
|
---|
137 | // Shell built-ins
|
---|
138 | // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html
|
---|
139 | 'break cd continue eval exec exit export getopts hash pwd readonly return shift test times ' +
|
---|
140 | 'trap umask unset ' +
|
---|
141 | // Bash built-ins
|
---|
142 | 'alias bind builtin caller command declare echo enable help let local logout mapfile printf ' +
|
---|
143 | 'read readarray source type typeset ulimit unalias ' +
|
---|
144 | // Shell modifiers
|
---|
145 | 'set shopt ' +
|
---|
146 | // Zsh built-ins
|
---|
147 | 'autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles ' +
|
---|
148 | 'compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate ' +
|
---|
149 | 'fc fg float functions getcap getln history integer jobs kill limit log noglob popd print ' +
|
---|
150 | 'pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit ' +
|
---|
151 | 'unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof ' +
|
---|
152 | 'zpty zregexparse zsocket zstyle ztcp'
|
---|
153 | },
|
---|
154 | contains: [
|
---|
155 | KNOWN_SHEBANG, // to catch known shells and boost relevancy
|
---|
156 | hljs.SHEBANG(), // to catch unknown shells but still highlight the shebang
|
---|
157 | FUNCTION,
|
---|
158 | ARITHMETIC,
|
---|
159 | hljs.HASH_COMMENT_MODE,
|
---|
160 | HERE_DOC,
|
---|
161 | QUOTE_STRING,
|
---|
162 | ESCAPED_QUOTE,
|
---|
163 | APOS_STRING,
|
---|
164 | VAR
|
---|
165 | ]
|
---|
166 | };
|
---|
167 | }
|
---|
168 |
|
---|
169 | module.exports = bash;
|
---|