1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
5 if (typeof exports
== "object" && typeof module
== "object") // CommonJS
6 mod(require("../../lib/codemirror"));
7 else if (typeof define
== "function" && define
.amd
) // AMD
8 define(["../../lib/codemirror"], mod
);
9 else // Plain browser env
11 })(function(CodeMirror
) {
14 CodeMirror
.defineMode('shell', function() {
17 function define(style
, string
) {
18 var split
= string
.split(' ');
19 for(var i
= 0; i
< split
.length
; i
++) {
20 words
[split
[i
]] = style
;
25 define('atom', 'true false');
28 define('keyword', 'if then do else elif while until for in esac fi fin ' +
29 'fil done exit set unset export function');
32 define('builtin', 'ab awk bash beep cat cc cd chown chmod chroot clear cp ' +
33 'curl cut diff echo find gawk gcc get git grep kill killall ln ls make ' +
34 'mkdir openssl mv nc node npm ping ps restart rm rmdir sed service sh ' +
35 'shopt shred source sort sleep ssh start stop su sudo tee telnet top ' +
36 'touch vi vim wall wc wget who write yes zsh');
38 function tokenBase(stream
, state
) {
39 if (stream
.eatSpace()) return null;
41 var sol
= stream
.sol();
42 var ch
= stream
.next();
48 if (ch
=== '\'' || ch
=== '"' || ch
=== '`') {
49 state
.tokens
.unshift(tokenString(ch
));
50 return tokenize(stream
, state
);
53 if (sol
&& stream
.eat('!')) {
55 return 'meta'; // 'comment'?
61 state
.tokens
.unshift(tokenDollar
);
62 return tokenize(stream
, state
);
64 if (ch
=== '+' || ch
=== '=') {
69 stream
.eatWhile(/\w/);
73 stream
.eatWhile(/\d/);
74 if(stream
.eol() || !/\w/.test(stream
.peek())) {
78 stream
.eatWhile(/[\w-]/);
79 var cur
= stream
.current();
80 if (stream
.peek() === '=' && /\w+/.test(cur
)) return 'def';
81 return words
.hasOwnProperty(cur
) ? words
[cur
] : null;
84 function tokenString(quote
) {
85 return function(stream
, state
) {
86 var next
, end
= false, escaped
= false;
87 while ((next
= stream
.next()) != null) {
88 if (next
=== quote
&& !escaped
) {
92 if (next
=== '$' && !escaped
&& quote
!== '\'') {
95 state
.tokens
.unshift(tokenDollar
);
98 escaped
= !escaped
&& next
=== '\\';
100 if (end
|| !escaped
) {
101 state
.tokens
.shift();
103 return (quote
=== '`' || quote
=== ')' ? 'quote' : 'string');
107 var tokenDollar = function(stream
, state
) {
108 if (state
.tokens
.length
> 1) stream
.eat('$');
109 var ch
= stream
.next(), hungry
= /\w/;
110 if (ch
=== '{') hungry
= /[^}]/;
112 state
.tokens
[0] = tokenString(')');
113 return tokenize(stream
, state
);
115 if (!/\d/.test(ch
)) {
116 stream
.eatWhile(hungry
);
119 state
.tokens
.shift();
123 function tokenize(stream
, state
) {
124 return (state
.tokens
[0] || tokenBase
) (stream
, state
);
128 startState: function() {return {tokens
:[]};},
129 token: function(stream
, state
) {
130 return tokenize(stream
, state
);
135 CodeMirror
.defineMIME('text/x-sh', 'shell');