| 776 |
lars |
1 |
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
|
2 |
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
|
|
3 |
|
|
|
4 |
(function(mod) {
|
|
|
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
|
|
|
10 |
mod(CodeMirror);
|
|
|
11 |
})(function(CodeMirror) {
|
|
|
12 |
"use strict";
|
|
|
13 |
|
|
|
14 |
CodeMirror.defineMode('shell', function() {
|
|
|
15 |
|
|
|
16 |
var words = {};
|
|
|
17 |
function define(style, string) {
|
|
|
18 |
var split = string.split(' ');
|
|
|
19 |
for(var i = 0; i < split.length; i++) {
|
|
|
20 |
words[split[i]] = style;
|
|
|
21 |
}
|
|
|
22 |
};
|
|
|
23 |
|
|
|
24 |
// Atoms
|
|
|
25 |
define('atom', 'true false');
|
|
|
26 |
|
|
|
27 |
// Keywords
|
|
|
28 |
define('keyword', 'if then do else elif while until for in esac fi fin ' +
|
|
|
29 |
'fil done exit set unset export function');
|
|
|
30 |
|
|
|
31 |
// Commands
|
|
|
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');
|
|
|
37 |
|
|
|
38 |
function tokenBase(stream, state) {
|
|
|
39 |
if (stream.eatSpace()) return null;
|
|
|
40 |
|
|
|
41 |
var sol = stream.sol();
|
|
|
42 |
var ch = stream.next();
|
|
|
43 |
|
|
|
44 |
if (ch === '\\') {
|
|
|
45 |
stream.next();
|
|
|
46 |
return null;
|
|
|
47 |
}
|
|
|
48 |
if (ch === '\'' || ch === '"' || ch === '`') {
|
|
|
49 |
state.tokens.unshift(tokenString(ch));
|
|
|
50 |
return tokenize(stream, state);
|
|
|
51 |
}
|
|
|
52 |
if (ch === '#') {
|
|
|
53 |
if (sol && stream.eat('!')) {
|
|
|
54 |
stream.skipToEnd();
|
|
|
55 |
return 'meta'; // 'comment'?
|
|
|
56 |
}
|
|
|
57 |
stream.skipToEnd();
|
|
|
58 |
return 'comment';
|
|
|
59 |
}
|
|
|
60 |
if (ch === '$') {
|
|
|
61 |
state.tokens.unshift(tokenDollar);
|
|
|
62 |
return tokenize(stream, state);
|
|
|
63 |
}
|
|
|
64 |
if (ch === '+' || ch === '=') {
|
|
|
65 |
return 'operator';
|
|
|
66 |
}
|
|
|
67 |
if (ch === '-') {
|
|
|
68 |
stream.eat('-');
|
|
|
69 |
stream.eatWhile(/\w/);
|
|
|
70 |
return 'attribute';
|
|
|
71 |
}
|
|
|
72 |
if (/\d/.test(ch)) {
|
|
|
73 |
stream.eatWhile(/\d/);
|
|
|
74 |
if(stream.eol() || !/\w/.test(stream.peek())) {
|
|
|
75 |
return 'number';
|
|
|
76 |
}
|
|
|
77 |
}
|
|
|
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;
|
|
|
82 |
}
|
|
|
83 |
|
|
|
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) {
|
|
|
89 |
end = true;
|
|
|
90 |
break;
|
|
|
91 |
}
|
|
|
92 |
if (next === '$' && !escaped && quote !== '\'') {
|
|
|
93 |
escaped = true;
|
|
|
94 |
stream.backUp(1);
|
|
|
95 |
state.tokens.unshift(tokenDollar);
|
|
|
96 |
break;
|
|
|
97 |
}
|
|
|
98 |
escaped = !escaped && next === '\\';
|
|
|
99 |
}
|
|
|
100 |
if (end || !escaped) {
|
|
|
101 |
state.tokens.shift();
|
|
|
102 |
}
|
|
|
103 |
return (quote === '`' || quote === ')' ? 'quote' : 'string');
|
|
|
104 |
};
|
|
|
105 |
};
|
|
|
106 |
|
|
|
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 = /[^}]/;
|
|
|
111 |
if (ch === '(') {
|
|
|
112 |
state.tokens[0] = tokenString(')');
|
|
|
113 |
return tokenize(stream, state);
|
|
|
114 |
}
|
|
|
115 |
if (!/\d/.test(ch)) {
|
|
|
116 |
stream.eatWhile(hungry);
|
|
|
117 |
stream.eat('}');
|
|
|
118 |
}
|
|
|
119 |
state.tokens.shift();
|
|
|
120 |
return 'def';
|
|
|
121 |
};
|
|
|
122 |
|
|
|
123 |
function tokenize(stream, state) {
|
|
|
124 |
return (state.tokens[0] || tokenBase) (stream, state);
|
|
|
125 |
};
|
|
|
126 |
|
|
|
127 |
return {
|
|
|
128 |
startState: function() {return {tokens:[]};},
|
|
|
129 |
token: function(stream, state) {
|
|
|
130 |
return tokenize(stream, state);
|
|
|
131 |
},
|
|
|
132 |
lineComment: '#',
|
|
|
133 |
fold: "brace"
|
|
|
134 |
};
|
|
|
135 |
});
|
|
|
136 |
|
|
|
137 |
CodeMirror.defineMIME('text/x-sh', 'shell');
|
|
|
138 |
|
|
|
139 |
});
|