clike.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. (function(mod) {
  2. if (typeof exports == "object" && typeof module == "object") // CommonJS
  3. mod(require("../../lib/codemirror"));
  4. else if (typeof define == "function" && define.amd) // AMD
  5. define(["../../lib/codemirror"], mod);
  6. else // Plain browser env
  7. mod(CodeMirror);
  8. })(function(CodeMirror) {
  9. "use strict";
  10. CodeMirror.defineMode("clike", function(config, parserConfig) {
  11. var indentUnit = config.indentUnit,
  12. statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
  13. dontAlignCalls = parserConfig.dontAlignCalls,
  14. keywords = parserConfig.keywords || {},
  15. builtin = parserConfig.builtin || {},
  16. blockKeywords = parserConfig.blockKeywords || {},
  17. atoms = parserConfig.atoms || {},
  18. hooks = parserConfig.hooks || {},
  19. multiLineStrings = parserConfig.multiLineStrings;
  20. var isOperatorChar = /[+\-*&%=<>!?|\/]/;
  21. var curPunc;
  22. function tokenBase(stream, state) {
  23. var ch = stream.next();
  24. if (hooks[ch]) {
  25. var result = hooks[ch](stream, state);
  26. if (result !== false) return result;
  27. }
  28. if (ch == '"' || ch == "'") {
  29. state.tokenize = tokenString(ch);
  30. return state.tokenize(stream, state);
  31. }
  32. if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
  33. curPunc = ch;
  34. return null;
  35. }
  36. if (/\d/.test(ch)) {
  37. stream.eatWhile(/[\w\.]/);
  38. return "number";
  39. }
  40. if (ch == "/") {
  41. if (stream.eat("*")) {
  42. state.tokenize = tokenComment;
  43. return tokenComment(stream, state);
  44. }
  45. if (stream.eat("/")) {
  46. stream.skipToEnd();
  47. return "comment";
  48. }
  49. }
  50. if (isOperatorChar.test(ch)) {
  51. stream.eatWhile(isOperatorChar);
  52. return "operator";
  53. }
  54. stream.eatWhile(/[\w\$_]/);
  55. var cur = stream.current();
  56. if (keywords.propertyIsEnumerable(cur)) {
  57. if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
  58. return "keyword";
  59. }
  60. if (builtin.propertyIsEnumerable(cur)) {
  61. if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
  62. return "builtin";
  63. }
  64. if (atoms.propertyIsEnumerable(cur)) return "atom";
  65. return "variable";
  66. }
  67. function tokenString(quote) {
  68. return function(stream, state) {
  69. var escaped = false, next, end = false;
  70. while ((next = stream.next()) != null) {
  71. if (next == quote && !escaped) {end = true; break;}
  72. escaped = !escaped && next == "\\";
  73. }
  74. if (end || !(escaped || multiLineStrings))
  75. state.tokenize = null;
  76. return "string";
  77. };
  78. }
  79. function tokenComment(stream, state) {
  80. var maybeEnd = false, ch;
  81. while (ch = stream.next()) {
  82. if (ch == "/" && maybeEnd) {
  83. state.tokenize = null;
  84. break;
  85. }
  86. maybeEnd = (ch == "*");
  87. }
  88. return "comment";
  89. }
  90. function Context(indented, column, type, align, prev) {
  91. this.indented = indented;
  92. this.column = column;
  93. this.type = type;
  94. this.align = align;
  95. this.prev = prev;
  96. }
  97. function pushContext(state, col, type) {
  98. var indent = state.indented;
  99. if (state.context && state.context.type == "statement")
  100. indent = state.context.indented;
  101. return state.context = new Context(indent, col, type, null, state.context);
  102. }
  103. function popContext(state) {
  104. var t = state.context.type;
  105. if (t == ")" || t == "]" || t == "}")
  106. state.indented = state.context.indented;
  107. return state.context = state.context.prev;
  108. }
  109. // Interface
  110. return {
  111. startState: function(basecolumn) {
  112. return {
  113. tokenize: null,
  114. context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
  115. indented: 0,
  116. startOfLine: true
  117. };
  118. },
  119. token: function(stream, state) {
  120. var ctx = state.context;
  121. if (stream.sol()) {
  122. if (ctx.align == null) ctx.align = false;
  123. state.indented = stream.indentation();
  124. state.startOfLine = true;
  125. }
  126. if (stream.eatSpace()) return null;
  127. curPunc = null;
  128. var style = (state.tokenize || tokenBase)(stream, state);
  129. if (style == "comment" || style == "meta") return style;
  130. if (ctx.align == null) ctx.align = true;
  131. if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
  132. else if (curPunc == "{") pushContext(state, stream.column(), "}");
  133. else if (curPunc == "[") pushContext(state, stream.column(), "]");
  134. else if (curPunc == "(") pushContext(state, stream.column(), ")");
  135. else if (curPunc == "}") {
  136. while (ctx.type == "statement") ctx = popContext(state);
  137. if (ctx.type == "}") ctx = popContext(state);
  138. while (ctx.type == "statement") ctx = popContext(state);
  139. }
  140. else if (curPunc == ctx.type) popContext(state);
  141. else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
  142. pushContext(state, stream.column(), "statement");
  143. state.startOfLine = false;
  144. return style;
  145. },
  146. indent: function(state, textAfter) {
  147. if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
  148. var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
  149. if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
  150. var closing = firstChar == ctx.type;
  151. if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
  152. else if (ctx.align && (!dontAlignCalls || ctx.type != ")")) return ctx.column + (closing ? 0 : 1);
  153. else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
  154. else return ctx.indented + (closing ? 0 : indentUnit);
  155. },
  156. electricChars: "{}",
  157. blockCommentStart: "/*",
  158. blockCommentEnd: "*/",
  159. lineComment: "//",
  160. fold: "brace"
  161. };
  162. });
  163. (function() {
  164. function words(str) {
  165. var obj = {}, words = str.split(" ");
  166. for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
  167. return obj;
  168. }
  169. var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
  170. "double static else struct entry switch extern typedef float union for unsigned " +
  171. "goto while enum void const signed volatile";
  172. function cppHook(stream, state) {
  173. if (!state.startOfLine) return false;
  174. for (;;) {
  175. if (stream.skipTo("\\")) {
  176. stream.next();
  177. if (stream.eol()) {
  178. state.tokenize = cppHook;
  179. break;
  180. }
  181. } else {
  182. stream.skipToEnd();
  183. state.tokenize = null;
  184. break;
  185. }
  186. }
  187. return "meta";
  188. }
  189. function cpp11StringHook(stream, state) {
  190. stream.backUp(1);
  191. // Raw strings.
  192. if (stream.match(/(R|u8R|uR|UR|LR)/)) {
  193. var match = stream.match(/"(.{0,16})\(/);
  194. if (!match) {
  195. return false;
  196. }
  197. state.cpp11RawStringDelim = match[1];
  198. state.tokenize = tokenRawString;
  199. return tokenRawString(stream, state);
  200. }
  201. // Unicode strings/chars.
  202. if (stream.match(/(u8|u|U|L)/)) {
  203. if (stream.match(/["']/, /* eat */ false)) {
  204. return "string";
  205. }
  206. return false;
  207. }
  208. // Ignore this hook.
  209. stream.next();
  210. return false;
  211. }
  212. // C#-style strings where "" escapes a quote.
  213. function tokenAtString(stream, state) {
  214. var next;
  215. while ((next = stream.next()) != null) {
  216. if (next == '"' && !stream.eat('"')) {
  217. state.tokenize = null;
  218. break;
  219. }
  220. }
  221. return "string";
  222. }
  223. // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
  224. // <delim> can be a string up to 16 characters long.
  225. function tokenRawString(stream, state) {
  226. var closingSequence = new RegExp(".*?\\)" + state.cpp11RawStringDelim + '"');
  227. var match = stream.match(closingSequence);
  228. if (match) {
  229. state.tokenize = null;
  230. } else {
  231. stream.skipToEnd();
  232. }
  233. return "string";
  234. }
  235. function def(mimes, mode) {
  236. var words = [];
  237. function add(obj) {
  238. if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
  239. words.push(prop);
  240. }
  241. add(mode.keywords);
  242. add(mode.builtin);
  243. add(mode.atoms);
  244. if (words.length) {
  245. mode.helperType = mimes[0];
  246. CodeMirror.registerHelper("hintWords", mimes[0], words);
  247. }
  248. for (var i = 0; i < mimes.length; ++i)
  249. CodeMirror.defineMIME(mimes[i], mode);
  250. }
  251. def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
  252. name: "clike",
  253. keywords: words(cKeywords),
  254. blockKeywords: words("case do else for if switch while struct"),
  255. atoms: words("null"),
  256. hooks: {"#": cppHook},
  257. modeProps: {fold: ["brace", "include"]}
  258. });
  259. def(["text/x-c++src", "text/x-c++hdr"], {
  260. name: "clike",
  261. keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
  262. "static_cast typeid catch operator template typename class friend private " +
  263. "this using const_cast inline public throw virtual delete mutable protected " +
  264. "wchar_t alignas alignof constexpr decltype nullptr noexcept thread_local final " +
  265. "static_assert override"),
  266. blockKeywords: words("catch class do else finally for if struct switch try while"),
  267. atoms: words("true false null"),
  268. hooks: {
  269. "#": cppHook,
  270. "u": cpp11StringHook,
  271. "U": cpp11StringHook,
  272. "L": cpp11StringHook,
  273. "R": cpp11StringHook
  274. },
  275. modeProps: {fold: ["brace", "include"]}
  276. });
  277. CodeMirror.defineMIME("text/x-java", {
  278. name: "clike",
  279. keywords: words("abstract assert boolean break byte case catch char class const continue default " +
  280. "do double else enum extends final finally float for goto if implements import " +
  281. "instanceof int interface long native new package private protected public " +
  282. "return short static strictfp super switch synchronized this throw throws transient " +
  283. "try void volatile while"),
  284. blockKeywords: words("catch class do else finally for if switch try while"),
  285. atoms: words("true false null"),
  286. hooks: {
  287. "@": function(stream) {
  288. stream.eatWhile(/[\w\$_]/);
  289. return "meta";
  290. }
  291. },
  292. modeProps: {fold: ["brace", "import"]}
  293. });
  294. CodeMirror.defineMIME("text/x-csharp", {
  295. name: "clike",
  296. keywords: words("abstract as base break case catch checked class const continue" +
  297. " default delegate do else enum event explicit extern finally fixed for" +
  298. " foreach goto if implicit in interface internal is lock namespace new" +
  299. " operator out override params private protected public readonly ref return sealed" +
  300. " sizeof stackalloc static struct switch this throw try typeof unchecked" +
  301. " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
  302. " global group into join let orderby partial remove select set value var yield"),
  303. blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
  304. builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
  305. " Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
  306. " UInt64 bool byte char decimal double short int long object" +
  307. " sbyte float string ushort uint ulong"),
  308. atoms: words("true false null"),
  309. hooks: {
  310. "@": function(stream, state) {
  311. if (stream.eat('"')) {
  312. state.tokenize = tokenAtString;
  313. return tokenAtString(stream, state);
  314. }
  315. stream.eatWhile(/[\w\$_]/);
  316. return "meta";
  317. }
  318. }
  319. });
  320. CodeMirror.defineMIME("text/x-scala", {
  321. name: "clike",
  322. keywords: words(
  323. /* scala */
  324. "abstract case catch class def do else extends false final finally for forSome if " +
  325. "implicit import lazy match new null object override package private protected return " +
  326. "sealed super this throw trait try trye type val var while with yield _ : = => <- <: " +
  327. "<% >: # @ " +
  328. /* package scala */
  329. "assert assume require print println printf readLine readBoolean readByte readShort " +
  330. "readChar readInt readLong readFloat readDouble " +
  331. "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
  332. "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
  333. "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
  334. "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
  335. "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: " +
  336. /* package java.lang */
  337. "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
  338. "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
  339. "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
  340. "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
  341. ),
  342. blockKeywords: words("catch class do else finally for forSome if match switch try while"),
  343. atoms: words("true false null"),
  344. hooks: {
  345. "@": function(stream) {
  346. stream.eatWhile(/[\w\$_]/);
  347. return "meta";
  348. }
  349. }
  350. });
  351. def(["x-shader/x-vertex", "x-shader/x-fragment"], {
  352. name: "clike",
  353. keywords: words("float int bool void " +
  354. "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
  355. "mat2 mat3 mat4 " +
  356. "sampler1D sampler2D sampler3D samplerCube " +
  357. "sampler1DShadow sampler2DShadow" +
  358. "const attribute uniform varying " +
  359. "break continue discard return " +
  360. "for while do if else struct " +
  361. "in out inout"),
  362. blockKeywords: words("for while do if else struct"),
  363. builtin: words("radians degrees sin cos tan asin acos atan " +
  364. "pow exp log exp2 sqrt inversesqrt " +
  365. "abs sign floor ceil fract mod min max clamp mix step smootstep " +
  366. "length distance dot cross normalize ftransform faceforward " +
  367. "reflect refract matrixCompMult " +
  368. "lessThan lessThanEqual greaterThan greaterThanEqual " +
  369. "equal notEqual any all not " +
  370. "texture1D texture1DProj texture1DLod texture1DProjLod " +
  371. "texture2D texture2DProj texture2DLod texture2DProjLod " +
  372. "texture3D texture3DProj texture3DLod texture3DProjLod " +
  373. "textureCube textureCubeLod " +
  374. "shadow1D shadow2D shadow1DProj shadow2DProj " +
  375. "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
  376. "dFdx dFdy fwidth " +
  377. "noise1 noise2 noise3 noise4"),
  378. atoms: words("true false " +
  379. "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
  380. "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
  381. "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
  382. "gl_FogCoord " +
  383. "gl_Position gl_PointSize gl_ClipVertex " +
  384. "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
  385. "gl_TexCoord gl_FogFragCoord " +
  386. "gl_FragCoord gl_FrontFacing " +
  387. "gl_FragColor gl_FragData gl_FragDepth " +
  388. "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
  389. "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
  390. "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
  391. "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
  392. "gl_ProjectionMatrixInverseTranspose " +
  393. "gl_ModelViewProjectionMatrixInverseTranspose " +
  394. "gl_TextureMatrixInverseTranspose " +
  395. "gl_NormalScale gl_DepthRange gl_ClipPlane " +
  396. "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
  397. "gl_FrontLightModelProduct gl_BackLightModelProduct " +
  398. "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
  399. "gl_FogParameters " +
  400. "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
  401. "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
  402. "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
  403. "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
  404. "gl_MaxDrawBuffers"),
  405. hooks: {"#": cppHook},
  406. modeProps: {fold: ["brace", "include"]}
  407. });
  408. }());
  409. });