From 671a8d654363b4249c0b1b5d3ffc27f345b9f562 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 1 Nov 2014 18:15:00 +0400 Subject: [PATCH 01/11] support nested comments in rust mode --- lib/ace/mode/rust_highlight_rules.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/ace/mode/rust_highlight_rules.js b/lib/ace/mode/rust_highlight_rules.js index 1a7d38a6..422e8e80 100644 --- a/lib/ace/mode/rust_highlight_rules.js +++ b/lib/ace/mode/rust_highlight_rules.js @@ -127,10 +127,14 @@ var RustHighlightRules = function() { regex: '$', next: 'pop' }, { defaultToken: 'comment.line.double-dash.source.rust' } ] }, - { token: 'comment.block.source.rust', + { token: 'comment.start.block.source.rust', regex: '/\\*', + stateName: 'comment', push: - [ { token: 'comment.block.source.rust', + [ { token: 'comment.start.block.source.rust', + regex: '/\\*', + push: 'comment' }, + { token: 'comment.end.block.source.rust', regex: '\\*/', next: 'pop' }, { defaultToken: 'comment.block.source.rust' } ] } ], From 5b3bbba54e07a4c14b6bb8f34c1ce55eea0e58b2 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 1 Nov 2014 19:27:40 +0400 Subject: [PATCH 02/11] fix xquery mode breaking autocompletion and add tests --- lib/ace/ext/language_tools.js | 3 + lib/ace/mode/_test/highlight_rules_test.js | 9 +- lib/ace/mode/_test/tokens_eiffel.json | 141 ++++++++++ lib/ace/mode/_test/tokens_elm.json | 198 ++++++++++++++ lib/ace/mode/_test/tokens_gcode.json | 296 +++++++++++++++++++++ lib/ace/mode/_test/tokens_io.json | 49 ++++ lib/ace/mode/_test/tokens_jsoniq.json | 4 + lib/ace/mode/_test/tokens_matlab.json | 88 +++++- lib/ace/mode/_test/tokens_xquery.json | 44 +++ lib/ace/mode/jsoniq.js | 7 +- lib/ace/mode/xquery.js | 7 +- lib/ace/snippets/dockerfile.js | 7 + lib/ace/snippets/dockerfile.snippets | 0 lib/ace/snippets/dummy.js | 7 + lib/ace/snippets/dummy_syntax.js | 7 + lib/ace/snippets/eiffel.js | 7 + lib/ace/snippets/eiffel.snippets | 0 lib/ace/snippets/elm.js | 7 + lib/ace/snippets/elm.snippets | 0 lib/ace/snippets/io.snippets | 0 lib/ace/snippets/vala.snippets | 0 21 files changed, 871 insertions(+), 10 deletions(-) create mode 100644 lib/ace/mode/_test/tokens_eiffel.json create mode 100644 lib/ace/mode/_test/tokens_elm.json create mode 100644 lib/ace/mode/_test/tokens_gcode.json create mode 100644 lib/ace/mode/_test/tokens_io.json create mode 100644 lib/ace/mode/_test/tokens_jsoniq.json create mode 100644 lib/ace/mode/_test/tokens_xquery.json create mode 100644 lib/ace/snippets/dockerfile.js create mode 100644 lib/ace/snippets/dockerfile.snippets create mode 100644 lib/ace/snippets/dummy.js create mode 100644 lib/ace/snippets/dummy_syntax.js create mode 100644 lib/ace/snippets/eiffel.js create mode 100644 lib/ace/snippets/eiffel.snippets create mode 100644 lib/ace/snippets/elm.js create mode 100644 lib/ace/snippets/elm.snippets create mode 100644 lib/ace/snippets/io.snippets create mode 100644 lib/ace/snippets/vala.snippets diff --git a/lib/ace/ext/language_tools.js b/lib/ace/ext/language_tools.js index 4687efd5..12fcf5b2 100644 --- a/lib/ace/ext/language_tools.js +++ b/lib/ace/ext/language_tools.js @@ -40,6 +40,9 @@ var util = require("../autocomplete/util"); var textCompleter = require("../autocomplete/text_completer"); var keyWordCompleter = { getCompletions: function(editor, session, pos, prefix, callback) { + if (session.$mode.completer) { + return session.$mode.completer.getCompletions(editor, session, pos, prefix, callback); + } var state = editor.session.getState(pos.row); var completions = session.$mode.getCompletions(state, session, pos, prefix); callback(null, completions); diff --git a/lib/ace/mode/_test/highlight_rules_test.js b/lib/ace/mode/_test/highlight_rules_test.js index 647ca3c3..e0244abc 100644 --- a/lib/ace/mode/_test/highlight_rules_test.js +++ b/lib/ace/mode/_test/highlight_rules_test.js @@ -58,7 +58,8 @@ function checkModes() { } function generateTestData() { - var docs = jsFileList(cwd + root); + var docRoot = root + "/demo/kitchen-sink/docs"; + var docs = fs.readdirSync(docRoot); var specialDocs = fs.readdirSync(cwd); var modes = modeList(); @@ -79,10 +80,12 @@ function generateTestData() { var filePath = "text_" + modeName + ".txt"; if (specialDocs.indexOf(filePath) == -1) { - filePath = root + "/" + docName; + filePath = docRoot + "/" + docName; + } else { + filePath = cwd + filePath; } - var text = fs.readFileSync(cwd + filePath, "utf8"); + var text = fs.readFileSync(filePath, "utf8"); try { var Mode = require("../" + modeName).Mode; } catch(e) { diff --git a/lib/ace/mode/_test/tokens_eiffel.json b/lib/ace/mode/_test/tokens_eiffel.json new file mode 100644 index 00000000..344dbc62 --- /dev/null +++ b/lib/ace/mode/_test/tokens_eiffel.json @@ -0,0 +1,141 @@ +[[ + "start", + ["keyword","note"] +],[ + "start", + ["text","\t"], + ["identifier","description"], + ["keyword.operator",":"], + ["text"," "], + ["string.quoted.double","\"Represents a person.\""] +],[ + "start" +],[ + "start", + ["keyword","class"] +],[ + "start", + ["text","\t"], + ["entity.name.type","PERSON"] +],[ + "start" +],[ + "start", + ["keyword","create"] +],[ + "start", + ["text","\t"], + ["identifier","make"], + ["keyword.operator",","], + ["text"," "], + ["identifier","make_unknown"] +],[ + "start" +],[ + "start", + ["keyword","feature"], + ["text"," "], + ["paren.lparen","{"], + ["entity.name.type","NONE"], + ["paren.rparen","}"], + ["text"," "], + ["comment.line.double-dash","-- Creation"] +],[ + "start" +],[ + "start", + ["text","\t"], + ["identifier","make"], + ["text"," "], + ["paren.lparen","("], + ["identifier","a_name"], + ["keyword.operator",":"], + ["text"," "], + ["keyword","like"], + ["text"," "], + ["identifier","name"], + ["paren.rparen",")"] +],[ + "start", + ["text","\t\t\t"], + ["comment.line.double-dash","-- Create a person with `a_name' as `name'."] +],[ + "start", + ["text","\t\t"], + ["keyword","do"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","name"], + ["text"," "], + ["keyword.operator",":="], + ["text"," "], + ["identifier","a_name"] +],[ + "start", + ["text","\t\t"], + ["keyword","ensure"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","name"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["identifier","a_name"] +],[ + "start", + ["text","\t\t"], + ["keyword","end"] +],[ + "start" +],[ + "start", + ["text","\t"], + ["identifier","make_unknown"] +],[ + "start", + ["text","\t\t"], + ["keyword","do"], + ["text"," "], + ["keyword","ensure"] +],[ + "start", + ["text","\t\t\t"], + ["identifier","name"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["constant.language","Void"] +],[ + "start", + ["text","\t\t"], + ["keyword","end"] +],[ + "start" +],[ + "start", + ["keyword","feature"], + ["text"," "], + ["comment.line.double-dash","-- Access"] +],[ + "start" +],[ + "start", + ["text","\t"], + ["identifier","name"], + ["keyword.operator",":"], + ["text"," "], + ["keyword","detachable"], + ["text"," "], + ["entity.name.type","STRING"] +],[ + "start", + ["text","\t\t\t"], + ["comment.line.double-dash","-- Full name or Void if unknown."] +],[ + "start" +],[ + "start", + ["keyword","end"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_elm.json b/lib/ace/mode/_test/tokens_elm.json new file mode 100644 index 00000000..b39de92f --- /dev/null +++ b/lib/ace/mode/_test/tokens_elm.json @@ -0,0 +1,198 @@ +[[ + "start", + ["comment.start","{-"], + ["comment"," Ace "], + ["comment.start","{-"], + ["comment"," 4 "], + ["comment.end","-}"], + ["comment"," Elm "], + ["comment.end","-}"] +],[ + "start", + ["constant.language","main"], + ["text"," "], + ["keyword","="], + ["text"," "], + ["identifier","lift"], + ["text"," "], + ["identifier","clock"], + ["text"," "], + ["paren.lparen","("], + ["identifier","every"], + ["text"," "], + ["identifier","second"], + ["paren.rparen",")"] +],[ + "start" +],[ + "start", + ["constant.language","clock"], + ["text"," "], + ["identifier","t"], + ["text"," "], + ["keyword","="], + ["text"," "], + ["identifier","collage"], + ["text"," "], + ["constant.numeric","400"], + ["text"," "], + ["constant.numeric","400"], + ["text"," "], + ["paren.lparen","["], + ["text"," "], + ["identifier","filled"], + ["text"," "], + ["identifier","lightGrey"], + ["text"," "], + ["paren.lparen","("], + ["identifier","ngon"], + ["text"," "], + ["constant.numeric","12"], + ["text"," "], + ["constant.numeric","110"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["operator.punctuation",","], + ["text"," "], + ["identifier","outlined"], + ["text"," "], + ["paren.lparen","("], + ["identifier","solid"], + ["text"," "], + ["identifier","grey"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","("], + ["identifier","ngon"], + ["text"," "], + ["constant.numeric","12"], + ["text"," "], + ["constant.numeric","110"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["operator.punctuation",","], + ["text"," "], + ["identifier","hand"], + ["text"," "], + ["identifier","orange"], + ["text"," "], + ["constant.numeric","100"], + ["text"," "], + ["identifier","t"] +],[ + "start", + ["text"," "], + ["operator.punctuation",","], + ["text"," "], + ["identifier","hand"], + ["text"," "], + ["identifier","charcoal"], + ["text"," "], + ["constant.numeric","100"], + ["text"," "], + ["paren.lparen","("], + ["identifier","t"], + ["keyword.operator","/"], + ["constant.numeric","60"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["operator.punctuation",","], + ["text"," "], + ["identifier","hand"], + ["text"," "], + ["identifier","charcoal"], + ["text"," "], + ["constant.numeric","60"], + ["text"," "], + ["paren.lparen","("], + ["identifier","t"], + ["keyword.operator","/"], + ["constant.numeric","720"], + ["paren.rparen",")"], + ["text"," "], + ["paren.rparen","]"] +],[ + "start" +],[ + "start", + ["constant.language","hand"], + ["text"," "], + ["identifier","clr"], + ["text"," "], + ["identifier","len"], + ["text"," "], + ["identifier","time"], + ["text"," "], + ["keyword","="] +],[ + "start", + ["text"," "], + ["keyword","let"], + ["text"," "], + ["identifier","angle"], + ["text"," "], + ["keyword","="], + ["text"," "], + ["identifier","degrees"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","90"], + ["text"," "], + ["keyword.operator","-"], + ["text"," "], + ["constant.numeric","6"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["identifier","inSeconds"], + ["text"," "], + ["identifier","time"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["keyword","in"], + ["text"," "], + ["identifier","traced"], + ["text"," "], + ["paren.lparen","("], + ["identifier","solid"], + ["text"," "], + ["identifier","clr"], + ["paren.rparen",")"], + ["text"," "], + ["keyword.operator","<|"], + ["text"," "], + ["identifier","segment"], + ["text"," "], + ["paren.lparen","("], + ["constant.numeric","0"], + ["operator.punctuation",","], + ["constant.numeric","0"], + ["paren.rparen",")"], + ["text"," "], + ["paren.lparen","("], + ["identifier","len"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["identifier","cos"], + ["text"," "], + ["identifier","angle"], + ["operator.punctuation",","], + ["text"," "], + ["identifier","len"], + ["text"," "], + ["keyword.operator","*"], + ["text"," "], + ["identifier","sin"], + ["text"," "], + ["identifier","angle"], + ["paren.rparen",")"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_gcode.json b/lib/ace/mode/_test/tokens_gcode.json new file mode 100644 index 00000000..d6227473 --- /dev/null +++ b/lib/ace/mode/_test/tokens_gcode.json @@ -0,0 +1,296 @@ +[[ + "start", + ["identifier","O"], + ["constant.numeric","003"], + ["text"," "], + ["comment","(DIAMOND SQUARE)"] +],[ + "start", + ["comment","N2"], + ["text"," "], + ["string","G54"], + ["text"," "], + ["string","G90"], + ["text"," "], + ["string","G49"], + ["text"," "], + ["string","G80"] +],[ + "start", + ["comment","N3"], + ["text"," "], + ["string","M6"], + ["text"," "], + ["identifier","T"], + ["constant.numeric","1"], + ["text"," "], + ["comment","(1.ENDMILL)"] +],[ + "start", + ["comment","N4"], + ["text"," "], + ["string","M3"], + ["text"," "], + ["identifier","S"], + ["constant.numeric","1800"] +],[ + "start", + ["comment","N5"], + ["text"," "], + ["string","G0"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","-.6"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","2.050"] +],[ + "start", + ["comment","N6"], + ["text"," "], + ["string","G43"], + ["text"," "], + ["identifier","H"], + ["constant.numeric","1"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric",".1"] +],[ + "start", + ["comment","N7"], + ["text"," "], + ["string","G1"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric","-.3"], + ["text"," "], + ["identifier","F"], + ["constant.numeric","50."] +],[ + "start", + ["comment","N8"], + ["text"," "], + ["string","G41"], + ["text"," "], + ["identifier","D"], + ["constant.numeric","1"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","1.45"] +],[ + "start", + ["comment","N9"], + ["text"," "], + ["string","G1"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","0"], + ["text"," "], + ["identifier","F"], + ["constant.numeric","20."] +],[ + "start", + ["comment","N10"], + ["text"," "], + ["string","G2"], + ["text"," "], + ["identifier","J"], + ["constant.numeric","-1.45"] +],[ + "start", + ["comment","(CUTTER COMP CANCEL)"] +],[ + "start", + ["comment","N11"], + ["text"," "], + ["string","G1"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric","-.2"], + ["text"," "], + ["identifier","F"], + ["constant.numeric","50."] +],[ + "start", + ["comment","N12"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","-.990"] +],[ + "start", + ["comment","N13"], + ["text"," "], + ["string","G40"] +],[ + "start", + ["comment","N14"], + ["text"," "], + ["string","G0"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","-.6"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","1.590"] +],[ + "start", + ["comment","N15"], + ["text"," "], + ["string","G0"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric",".1"] +],[ + "start", + ["comment","N16"], + ["text"," "], + ["string","M5"], + ["text"," "], + ["string","G49"], + ["text"," "], + ["string","G28"], + ["text"," "], + ["string","G91"], + ["text"," "], + ["identifier","Z"], + ["constant.numeric","0"] +],[ + "start", + ["comment","N17"], + ["text"," "], + ["identifier","CALL"], + ["text"," "], + ["identifier","O"], + ["constant.numeric","9456"] +],[ + "start", + ["comment","N18"], + ["text"," #"], + ["constant.numeric","500"], + ["text","="], + ["constant.numeric","0.004"] +],[ + "start", + ["comment","N19"], + ["text"," #"], + ["constant.numeric","503"], + ["text","="], + ["paren.lparen","["], + ["text","#"], + ["constant.numeric","500"], + ["text","+#"], + ["constant.numeric","501"], + ["paren.rparen","]"] +],[ + "start", + ["comment","N20"], + ["text"," "], + ["identifier","VC"], + ["constant.numeric","45"], + ["text","="], + ["constant.numeric","0.0006"] +],[ + "start", + ["identifier","VS"], + ["constant.numeric","4"], + ["text","="], + ["constant.numeric","0.0007"] +],[ + "start", + ["comment","N21"], + ["text"," "], + ["string","G90"], + ["text"," "], + ["string","G10"], + ["text"," "], + ["identifier","L"], + ["constant.numeric","20"], + ["text"," "], + ["identifier","P"], + ["constant.numeric","3"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","5."], + ["identifier","Y"], + ["constant.numeric","4."], + ["text"," "], + ["identifier","Z"], + ["constant.numeric","6.567"] +],[ + "start", + ["comment","N22"], + ["text"," "], + ["string","G0"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","5000"] +],[ + "start", + ["comment","N23"], + ["text"," "], + ["identifier","IF"], + ["text"," "], + ["paren.lparen","["], + ["text","#"], + ["constant.numeric","1"], + ["text"," "], + ["identifier","LT"], + ["text"," "], + ["constant.numeric","0.370"], + ["paren.rparen","]"], + ["text"," "], + ["identifier","GOTO"], + ["text"," "], + ["constant.numeric","49"] +],[ + "start", + ["comment","N24"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","-0.678"], + ["text"," "], + ["identifier","Y"], + ["constant.numeric","+.990"] +],[ + "start", + ["comment","N25"], + ["text"," "], + ["string","G84.3"], + ["text"," "], + ["identifier","X"], + ["constant.numeric","-0.1"] +],[ + "start", + ["comment","N26"], + ["text"," #"], + ["constant.numeric","4"], + ["text","=#"], + ["constant.numeric","5"], + ["text","*"], + ["identifier","COS"], + ["paren.lparen","["], + ["constant.numeric","45"], + ["paren.rparen","]"] +],[ + "start", + ["comment","N27"], + ["text"," #"], + ["constant.numeric","4"], + ["text","=#"], + ["constant.numeric","5"], + ["text","*"], + ["identifier","SIN"], + ["paren.lparen","["], + ["constant.numeric","45"], + ["paren.rparen","]"] +],[ + "start", + ["comment","N28"], + ["text"," "], + ["identifier","VZOFZ"], + ["text","="], + ["constant.numeric","652.9658"] +],[ + "start", + ["text","%"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_io.json b/lib/ace/mode/_test/tokens_io.json new file mode 100644 index 00000000..b83a675a --- /dev/null +++ b/lib/ace/mode/_test/tokens_io.json @@ -0,0 +1,49 @@ +[[ + "start", + ["punctuation.definition.comment.io","//"], + ["comment.line.double-slash.io"," computes factorial of a number"] +],[ + "start", + ["text","factorial "], + ["keyword.operator.io",":="], + ["text"," "], + ["support.function.io","method"], + ["text","(n,"] +],[ + "start", + ["text"," "], + ["keyword.control.io","if"], + ["text","(n "], + ["keyword.operator.io","=="], + ["text"," "], + ["constant.numeric.io","0"], + ["text",", "], + ["keyword.control.io","return"], + ["text"," "], + ["constant.numeric.io","1"], + ["text",")"] +],[ + "start", + ["text"," res "], + ["keyword.operator.io",":="], + ["text"," "], + ["constant.numeric.io","1"] +],[ + "start", + ["text"," "], + ["support.class.io","Range"], + ["text"," "], + ["constant.numeric.io","1"], + ["text"," "], + ["support.function.io","to"], + ["text","(n) "], + ["keyword.control.io","foreach"], + ["text","(i, res "], + ["keyword.operator.io","="], + ["text"," res "], + ["keyword.operator.io","*"], + ["text"," i)"] +],[ + "start", + ["text",")"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_jsoniq.json b/lib/ace/mode/_test/tokens_jsoniq.json new file mode 100644 index 00000000..0f4ee6e9 --- /dev/null +++ b/lib/ace/mode/_test/tokens_jsoniq.json @@ -0,0 +1,4 @@ +[[ + "[\"start\"]", + ["support.function","TODO"] +]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_matlab.json b/lib/ace/mode/_test/tokens_matlab.json index 9909eadd..6b4a8567 100644 --- a/lib/ace/mode/_test/tokens_matlab.json +++ b/lib/ace/mode/_test/tokens_matlab.json @@ -1,4 +1,90 @@ [[ + ["blockComment","noQstring"], + ["comment.start","%{"] +],[ + ["blockComment","blockComment","blockComment","noQstring"], + ["comment.start"," %{"] +],[ + ["blockComment","blockComment","blockComment","noQstring"], + ["comment"," Ace Matlab demo"] +],[ + ["blockComment","noQstring"], + ["comment.end"," %}"] +],[ + "noQstring", + ["comment.end","%}"] +],[ + "start" +],[ "start", - ["identifier","TODO"] + ["keyword","classdef"], + ["text"," "], + ["identifier","hello"] +],[ + "start", + ["text"," "], + ["support.function","methods"] +],[ + "start", + ["text"," "], + ["keyword","function"], + ["text"," "], + ["identifier","greet"], + ["paren.lparen","("], + ["identifier","this"], + ["paren.rparen",")"] +],[ + "start", + ["text"," "], + ["support.function","disp"], + ["paren.lparen","("], + ["string","'Hello!'"], + ["paren.rparen",")"], + ["text"," "], + ["comment","% say hi"] +],[ + "start", + ["text"," "], + ["keyword","end"] +],[ + "start", + ["text"," "], + ["keyword","end"] +],[ + "start", + ["keyword","end"] +],[ + "noQstring" +],[ + "start", + ["comment","% transpose "] +],[ + "qqstring", + ["identifier","a"], + ["text"," "], + ["keyword.operator","="], + ["text"," "], + ["paren.lparen","["], + ["text"," "], + ["string","'x"], + ["constant.language.escape","''"], + ["string","y'"], + ["punctuation.operator",","], + ["text"," "], + ["string","\"x"], + ["constant.language.escape","\\n"], + ["string","\\"] +],[ + "start", + ["string"," y\""], + ["punctuation.operator",","], + ["text"," "], + ["constant.numeric","1"], + ["text","' "], + ["paren.rparen","]"], + ["text","' "], + ["keyword.operator","+"], + ["text"," "], + ["constant.numeric","2"], + ["text","'"] ]] \ No newline at end of file diff --git a/lib/ace/mode/_test/tokens_xquery.json b/lib/ace/mode/_test/tokens_xquery.json new file mode 100644 index 00000000..aaf9ab9b --- /dev/null +++ b/lib/ace/mode/_test/tokens_xquery.json @@ -0,0 +1,44 @@ +[[ + "[\"start\"]", + ["keyword","xquery"], + ["text"," "], + ["keyword","version"], + ["text"," "], + ["string","\""], + ["string","1.0"], + ["string","\""], + ["text",";"] +],[ + "[\"start\"]" +],[ + "[\"start\"]", + ["keyword","let"], + ["text"," "], + ["variable","$message"], + ["text"," "], + ["keyword.operator",":="], + ["text"," "], + ["string","\""], + ["string","Hello World!"], + ["string","\""] +],[ + "[\"start\",\"StartTag\",\"TagContent\"]", + ["keyword","return"], + ["text"," "], + ["meta.tag",""] +],[ + "[\"start\",\"StartTag\",\"TagContent\"]", + ["text"," "], + ["meta.tag",""], + ["text","{"], + ["variable","$message"], + ["text","}"], + ["meta.tag",""] +],[ + "[\"start\"]", + ["meta.tag",""] +],[ + "[\"start\"]" +]] \ No newline at end of file diff --git a/lib/ace/mode/jsoniq.js b/lib/ace/mode/jsoniq.js index 6f10d2d3..64dc9541 100644 --- a/lib/ace/mode/jsoniq.js +++ b/lib/ace/mode/jsoniq.js @@ -39,7 +39,6 @@ var Range = require("../range").Range; var XQueryBehaviour = require("./behaviour/xquery").XQueryBehaviour; var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Anchor = require("../anchor").Anchor; -var LanguageTools = require("../ext/language_tools"); var Mode = function() { this.$tokenizer = new JSONiqLexer(); @@ -52,14 +51,16 @@ oop.inherits(Mode, TextMode); (function() { - LanguageTools.addCompleter({ + this.completer = { getCompletions: function(editor, session, pos, prefix, callback) { + if (!session.$worker) + return callback(); session.$worker.emit("complete", { data: { pos: pos, prefix: prefix } }); session.$worker.on("complete", function(e){ callback(null, e.data); }); } - }); + }; this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); diff --git a/lib/ace/mode/xquery.js b/lib/ace/mode/xquery.js index b93d61d2..024a5c6a 100644 --- a/lib/ace/mode/xquery.js +++ b/lib/ace/mode/xquery.js @@ -39,7 +39,6 @@ var Range = require("../range").Range; var XQueryBehaviour = require("./behaviour/xquery").XQueryBehaviour; var CStyleFoldMode = require("./folding/cstyle").FoldMode; var Anchor = require("../anchor").Anchor; -var LanguageTools = require("../ext/language_tools"); var Mode = function() { this.$tokenizer = new XQueryLexer(); @@ -51,14 +50,16 @@ oop.inherits(Mode, TextMode); (function() { - LanguageTools.addCompleter({ + this.completer = { getCompletions: function(editor, session, pos, prefix, callback) { + if (!session.$worker) + return callback(); session.$worker.emit("complete", { data: { pos: pos, prefix: prefix } }); session.$worker.on("complete", function(e){ callback(null, e.data); }); } - }); + }; this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); diff --git a/lib/ace/snippets/dockerfile.js b/lib/ace/snippets/dockerfile.js new file mode 100644 index 00000000..057347fb --- /dev/null +++ b/lib/ace/snippets/dockerfile.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./dockerfile.snippets"); +exports.scope = "dockerfile"; + +}); diff --git a/lib/ace/snippets/dockerfile.snippets b/lib/ace/snippets/dockerfile.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/dummy.js b/lib/ace/snippets/dummy.js new file mode 100644 index 00000000..359d9103 --- /dev/null +++ b/lib/ace/snippets/dummy.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./.snippets"); +exports.scope = ""; + +}); diff --git a/lib/ace/snippets/dummy_syntax.js b/lib/ace/snippets/dummy_syntax.js new file mode 100644 index 00000000..359d9103 --- /dev/null +++ b/lib/ace/snippets/dummy_syntax.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./.snippets"); +exports.scope = ""; + +}); diff --git a/lib/ace/snippets/eiffel.js b/lib/ace/snippets/eiffel.js new file mode 100644 index 00000000..04f4c5a9 --- /dev/null +++ b/lib/ace/snippets/eiffel.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./eiffel.snippets"); +exports.scope = "eiffel"; + +}); diff --git a/lib/ace/snippets/eiffel.snippets b/lib/ace/snippets/eiffel.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/elm.js b/lib/ace/snippets/elm.js new file mode 100644 index 00000000..44f18c11 --- /dev/null +++ b/lib/ace/snippets/elm.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./elm.snippets"); +exports.scope = "elm"; + +}); diff --git a/lib/ace/snippets/elm.snippets b/lib/ace/snippets/elm.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/io.snippets b/lib/ace/snippets/io.snippets new file mode 100644 index 00000000..e69de29b diff --git a/lib/ace/snippets/vala.snippets b/lib/ace/snippets/vala.snippets new file mode 100644 index 00000000..e69de29b From ca9bc7a97a00f15b421a08d2abe3c87e5eac9df3 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 1 Nov 2014 21:44:53 +0400 Subject: [PATCH 03/11] improve highlighting of ruby strings --- lib/ace/mode/ruby_highlight_rules.js | 68 ++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/lib/ace/mode/ruby_highlight_rules.js b/lib/ace/mode/ruby_highlight_rules.js index 13dcd1b2..a1cb12f9 100644 --- a/lib/ace/mode/ruby_highlight_rules.js +++ b/lib/ace/mode/ruby_highlight_rules.js @@ -141,9 +141,71 @@ var RubyHighlightRules = function() { regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)" }, - qString, - qqString, - tString, + [{ + regex: "[{}]", onMatch: function(val, state, stack) { + this.next = val == "{" ? this.nextState : ""; + if (val == "{" && stack.length) { + stack.unshift("start", state); + return "paren.lparen"; + } + if (val == "}" && stack.length) { + stack.shift(); + this.next = stack.shift(); + if (this.next.indexOf("string") != -1) + return "paren.end"; + } + return val == "{" ? "paren.lparen" : "paren.rparen"; + }, + nextState: "start" + }, { + token : "string.start", + regex : /"/, + push : [{ + token : "constant.language.escape", + regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + }, { + token : "paren.start", + regex : /\#{/, + push : "start" + }, { + token : "string.end", + regex : /"/, + next : "pop" + }, { + defaultToken: "string" + }] + }, { + token : "string.start", + regex : /`/, + push : [{ + token : "constant.language.escape", + regex : /\\(?:[nsrtvfbae'"\\]|c.|C-.|M-.(?:\\C-.)?|[0-7]{3}|x[\da-fA-F]{2}|u[\da-fA-F]{4})/ + }, { + token : "paren.start", + regex : /\#{/, + push : "start" + }, { + token : "string.end", + regex : /`/, + next : "pop" + }, { + defaultToken: "string" + }] + }, { + token : "string.start", + regex : /'/, + push : [{ + token : "constant.language.escape", + regex : /\\['\\]/ + }, { + token : "string.end", + regex : /'/, + next : "pop" + }, { + defaultToken: "string" + }] + }], + // TODO: add support for %[QqxWwrs][{[(] { token : "text", // namespaces aren't symbols From 4da689e71b52825332fd115909fa0bcbc76ca438 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 2 Nov 2014 15:06:12 +0400 Subject: [PATCH 04/11] add elixir mode --- demo/kitchen-sink/docs/elixir.ex | 1 + lib/ace/ext/modelist.js | 1 + lib/ace/mode/elixir.js | 58 ++++ lib/ace/mode/elixir_highlight_rules.js | 435 +++++++++++++++++++++++++ 4 files changed, 495 insertions(+) create mode 100644 demo/kitchen-sink/docs/elixir.ex create mode 100644 lib/ace/mode/elixir.js create mode 100644 lib/ace/mode/elixir_highlight_rules.js diff --git a/demo/kitchen-sink/docs/elixir.ex b/demo/kitchen-sink/docs/elixir.ex new file mode 100644 index 00000000..ec0cfb59 --- /dev/null +++ b/demo/kitchen-sink/docs/elixir.ex @@ -0,0 +1 @@ +TODO add a nice demo! \ No newline at end of file diff --git a/lib/ace/ext/modelist.js b/lib/ace/ext/modelist.js index 3f85c5b3..9e012f51 100644 --- a/lib/ace/ext/modelist.js +++ b/lib/ace/ext/modelist.js @@ -69,6 +69,7 @@ var supportedModes = { DummySyntax: ["dummy"], Eiffel: ["e"], EJS: ["ejs"], + Elixir: ["ex|exs"], Elm: ["elm"], Erlang: ["erl|hrl"], Forth: ["frt|fs|ldr"], diff --git a/lib/ace/mode/elixir.js b/lib/ace/mode/elixir.js new file mode 100644 index 00000000..c64f5cce --- /dev/null +++ b/lib/ace/mode/elixir.js @@ -0,0 +1,58 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var ElixirHighlightRules = require("./elixir_highlight_rules").ElixirHighlightRules; +// TODO: pick appropriate fold mode +var FoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = ElixirHighlightRules; + this.foldingRules = new FoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + // this.lineCommentStart = ""@(?:module|type)?doc \"""; + // this.blockComment = {start: ""/*"", end: ""*/""}; + // Extra logic goes here. + this.$id = "ace/mode/elixir" +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/elixir_highlight_rules.js b/lib/ace/mode/elixir_highlight_rules.js new file mode 100644 index 00000000..a52bdf4f --- /dev/null +++ b/lib/ace/mode/elixir_highlight_rules.js @@ -0,0 +1,435 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ***** END LICENSE BLOCK ***** */ + +/* This file was autogenerated from https://raw.githubusercontent.com/elixir-lang/elixir-tmbundle/master/Syntaxes/Elixir.tmLanguage (uuid: ) */ +/**************************************************************************************** + * IT MIGHT NOT BE PERFECT ...But it's a good start from an existing *.tmlanguage file. * + * fileTypes * + ****************************************************************************************/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var ElixirHighlightRules = function() { + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = { start: + [ { token: + [ 'meta.module.elixir', + 'keyword.control.module.elixir', + 'meta.module.elixir', + 'entity.name.type.module.elixir' ], + regex: '^(\\s*)(defmodule)(\\s+)((?:[A-Z]\\w*\\s*\\.\\s*)*[A-Z]\\w*)' }, + { token: 'comment.documentation.heredoc', + regex: '@(?:module|type)?doc (?:~[a-z])?"""', + push: + [ { token: 'comment.documentation.heredoc', + regex: '\\s*"""', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'comment.documentation.heredoc' } ], + comment: '@doc with heredocs is treated as documentation' }, + { token: 'comment.documentation.heredoc', + regex: '@(?:module|type)?doc ~[A-Z]"""', + push: + [ { token: 'comment.documentation.heredoc', + regex: '\\s*"""', + next: 'pop' }, + { defaultToken: 'comment.documentation.heredoc' } ], + comment: '@doc with heredocs is treated as documentation' }, + { token: 'comment.documentation.heredoc', + regex: '@(?:module|type)?doc (?:~[a-z])?\'\'\'', + push: + [ { token: 'comment.documentation.heredoc', + regex: '\\s*\'\'\'', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'comment.documentation.heredoc' } ], + comment: '@doc with heredocs is treated as documentation' }, + { token: 'comment.documentation.heredoc', + regex: '@(?:module|type)?doc ~[A-Z]\'\'\'', + push: + [ { token: 'comment.documentation.heredoc', + regex: '\\s*\'\'\'', + next: 'pop' }, + { defaultToken: 'comment.documentation.heredoc' } ], + comment: '@doc with heredocs is treated as documentation' }, + { token: 'comment.documentation.false', + regex: '@(?:module|type)?doc false', + comment: '@doc false is treated as documentation' }, + { token: 'comment.documentation.string', + regex: '@(?:module|type)?doc "', + push: + [ { token: 'comment.documentation.string', + regex: '"', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'comment.documentation.string' } ], + comment: '@doc with string is treated as documentation' }, + { token: 'keyword.control.elixir', + regex: '(?_?[\\da-fA-F])*|\\d(?>_?\\d)*(?:\\.(?![^[:space:][:digit:]])(?>_?\\d)*)?(?:[eE][-+]?\\d(?>_?\\d)*)?|0b[01]+|0o[0-7]+)\\b', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '\\b(0x\\h(?>_?\\h)*|\\d(?>_?\\d)*(\\.(?![^[:space:][:digit:]])(?>_?\\d)*)?([eE][-+]?\\d(?>_?\\d)*)?|0b[01]+|0o[0-7]+)\\b' }, + { token: 'punctuation.definition.constant.elixir', + regex: ':\'', + push: + [ { token: 'punctuation.definition.constant.elixir', + regex: '\'', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'constant.other.symbol.single-quoted.elixir' } ] }, + { token: 'punctuation.definition.constant.elixir', + regex: ':"', + push: + [ { token: 'punctuation.definition.constant.elixir', + regex: '"', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'constant.other.symbol.double-quoted.elixir' } ] }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '(?>\'\'\')', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '(?>\'\'\')', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '^\\s*\'\'\'', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'support.function.variable.quoted.single.heredoc.elixir' } ], + comment: 'Single-quoted heredocs' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '\'', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\'', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'support.function.variable.quoted.single.elixir' } ], + comment: 'single quoted string (allows for interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '(?>""")', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '(?>""")', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '^\\s*"""', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'string.quoted.double.heredoc.elixir' } ], + comment: 'Double-quoted heredocs' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '"', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '"', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'string.quoted.double.elixir' } ], + comment: 'double quoted string (allows for interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[a-z](?>""")', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '~[a-z](?>""")', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '^\\s*"""', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'string.quoted.double.heredoc.elixir' } ], + comment: 'Double-quoted heredocs sigils' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[a-z]\\{', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\\}[a-z]*', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'string.interpolated.elixir' } ], + comment: 'sigil (allow for interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[a-z]\\[', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\\][a-z]*', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'string.interpolated.elixir' } ], + comment: 'sigil (allow for interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[a-z]\\<', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\\>[a-z]*', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'string.interpolated.elixir' } ], + comment: 'sigil (allow for interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[a-z]\\(', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\\)[a-z]*', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { defaultToken: 'string.interpolated.elixir' } ], + comment: 'sigil (allow for interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[a-z][^\\w]', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '[^\\w][a-z]*', + next: 'pop' }, + { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { include: '#escaped_char' }, + { defaultToken: 'string.interpolated.elixir' } ], + comment: 'sigil (allow for interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[A-Z](?>""")', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '~[A-Z](?>""")', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '^\\s*"""', + next: 'pop' }, + { defaultToken: 'string.quoted.other.literal.upper.elixir' } ], + comment: 'Double-quoted heredocs sigils' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[A-Z]\\{', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\\}[a-z]*', + next: 'pop' }, + { defaultToken: 'string.quoted.other.literal.upper.elixir' } ], + comment: 'sigil (without interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[A-Z]\\[', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\\][a-z]*', + next: 'pop' }, + { defaultToken: 'string.quoted.other.literal.upper.elixir' } ], + comment: 'sigil (without interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[A-Z]\\<', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\\>[a-z]*', + next: 'pop' }, + { defaultToken: 'string.quoted.other.literal.upper.elixir' } ], + comment: 'sigil (without interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[A-Z]\\(', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '\\)[a-z]*', + next: 'pop' }, + { defaultToken: 'string.quoted.other.literal.upper.elixir' } ], + comment: 'sigil (without interpolation)' }, + { token: 'punctuation.definition.string.begin.elixir', + regex: '~[A-Z][^\\w]', + push: + [ { token: 'punctuation.definition.string.end.elixir', + regex: '[^\\w][a-z]*', + next: 'pop' }, + { defaultToken: 'string.quoted.other.literal.upper.elixir' } ], + comment: 'sigil (without interpolation)' }, + { token: 'punctuation.definition.constant.elixir', + regex: '(?[a-zA-Z_][\\w@]*(?>[?!]|=(?![>=]))?|\\<\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\-|\\|>|=>|~|~=|=|/|\\\\\\\\|\\*\\*?|\\.\\.?\\.?|>=?|<=?|&&?&?|\\+\\+?|\\-\\-?|\\|\\|?\\|?|\\!|@|\\%?\\{\\}|%|\\[\\]|\\^(?:\\^\\^)?)', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '(?[a-zA-Z_][\\w@]*(?>[?!]|=(?![>=]))?|\\<\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\-|\\|>|=>|~|~=|=|/|\\\\\\\\|\\*\\*?|\\.\\.?\\.?|>=?|<=?|&&?&?|\\+\\+?|\\-\\-?|\\|\\|?\\|?|\\!|@|\\%?\\{\\}|%|\\[\\]|\\^(\\^\\^)?)', + comment: 'symbols' }, + { token: 'punctuation.definition.constant.elixir', + regex: '(?>[a-zA-Z_][\\w@]*(?>[?!])?):(?!:)', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '(?>[a-zA-Z_][\\w@]*(?>[?!])?)(:)(?!:)', + comment: 'symbols' }, + { token: + [ 'punctuation.definition.comment.elixir', + 'comment.line.number-sign.elixir' ], + regex: '(?:^[ \\t]+)?(#)(.*$)' }, + { token: 'constant.numeric.elixir', + regex: '(?=?' }, + { token: 'keyword.operator.bitwise.elixir', + regex: '\\|\\|\\||&&&|^^^|<<<|>>>|~~~' }, + { token: 'keyword.operator.logical.elixir', + regex: '(?<=[ \\t])!+|\\bnot\\b|&&|\\band\\b|\\|\\||\\bor\\b|\\bxor\\b', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '(?<=[ \\t])!+|\\bnot\\b|&&|\\band\\b|\\|\\||\\bor\\b|\\bxor\\b' }, + { token: 'keyword.operator.arithmetic.elixir', + regex: '\\*|\\+|\\-|/' }, + { token: 'keyword.operator.other.elixir', + regex: '\\||\\+\\+|\\-\\-|\\*\\*|\\\\\\\\|\\<\\-|\\<\\>|\\<\\<|\\>\\>|\\:\\:|\\.\\.|\\|>|~|=>' }, + { token: 'keyword.operator.assignment.elixir', regex: '=' }, + { token: 'punctuation.separator.other.elixir', regex: ':' }, + { token: 'punctuation.separator.statement.elixir', + regex: '\\;' }, + { token: 'punctuation.separator.object.elixir', regex: ',' }, + { token: 'punctuation.separator.method.elixir', regex: '\\.' }, + { token: 'punctuation.section.scope.elixir', regex: '\\{|\\}' }, + { token: 'punctuation.section.array.elixir', regex: '\\[|\\]' }, + { token: 'punctuation.section.function.elixir', + regex: '\\(|\\)' } ], + '#escaped_char': + [ { token: 'constant.character.escape.elixir', + regex: '\\\\(?:x[\\da-fA-F]{1,2}|.)' } ], + '#interpolated_elixir': + [ { token: + [ 'source.elixir.embedded.source', + 'source.elixir.embedded.source.empty' ], + regex: '(#\\{)(\\})' }, + { todo: + { token: 'punctuation.section.embedded.elixir', + regex: '#\\{', + push: + [ { token: 'punctuation.section.embedded.elixir', + regex: '\\}', + next: 'pop' }, + { include: '#nest_curly_and_self' }, + { include: '$self' }, + { defaultToken: 'source.elixir.embedded.source' } ] } } ], + '#nest_curly_and_self': + [ { token: 'punctuation.section.scope.elixir', + regex: '\\{', + push: + [ { token: 'punctuation.section.scope.elixir', + regex: '\\}', + next: 'pop' }, + { include: '#nest_curly_and_self' } ] }, + { include: '$self' } ], + '#regex_sub': + [ { include: '#interpolated_elixir' }, + { include: '#escaped_char' }, + { token: + [ 'punctuation.definition.arbitrary-repitition.elixir', + 'string.regexp.arbitrary-repitition.elixir', + 'string.regexp.arbitrary-repitition.elixir', + 'punctuation.definition.arbitrary-repitition.elixir' ], + regex: '(\\{)(\\d+)((?:,\\d+)?)(\\})' }, + { token: 'punctuation.definition.character-class.elixir', + regex: '\\[(?:\\^?\\])?', + push: + [ { token: 'punctuation.definition.character-class.elixir', + regex: '\\]', + next: 'pop' }, + { include: '#escaped_char' }, + { defaultToken: 'string.regexp.character-class.elixir' } ] }, + { token: 'punctuation.definition.group.elixir', + regex: '\\(', + push: + [ { token: 'punctuation.definition.group.elixir', + regex: '\\)', + next: 'pop' }, + { include: '#regex_sub' }, + { defaultToken: 'string.regexp.group.elixir' } ] }, + { token: + [ 'punctuation.definition.comment.elixir', + 'comment.line.number-sign.elixir' ], + regex: '(?<=^|\\s)(#)(\\s[[a-zA-Z0-9,. \\t?!-][^\\x00-\\x7F]]*$)', + TODO: 'FIXME: regexp doesn\'t have js equivalent', + originalRegex: '(?<=^|\\s)(#)\\s[[a-zA-Z0-9,. \\t?!-][^\\x{00}-\\x{7F}]]*$', + comment: 'We are restrictive in what we allow to go after the comment character to avoid false positives, since the availability of comments depend on regexp flags.' } ] } + + this.normalizeRules(); +}; + +ElixirHighlightRules.metaData = { comment: 'Textmate bundle for Elixir Programming Language.', + fileTypes: [ 'ex', 'exs' ], + firstLineMatch: '^#!/.*\\belixir', + foldingStartMarker: '(after|else|catch|rescue|\\-\\>|\\{|\\[|do)\\s*$', + foldingStopMarker: '^\\s*((\\}|\\]|after|else|catch|rescue)\\s*$|end\\b)', + keyEquivalent: '^~E', + name: 'Elixir', + scopeName: 'source.elixir' } + + +oop.inherits(ElixirHighlightRules, TextHighlightRules); + +exports.ElixirHighlightRules = ElixirHighlightRules; +}); \ No newline at end of file From 399e25ceaf58c7c3d1505715f41535ef0406947a Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 2 Nov 2014 15:04:55 +0400 Subject: [PATCH 05/11] fix errors in imported elixir mode --- demo/kitchen-sink/docs/elixir.ex | 25 +++++++++++++++++- lib/ace/mode/elixir.js | 4 +-- lib/ace/mode/elixir_highlight_rules.js | 36 ++++++++++++-------------- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/demo/kitchen-sink/docs/elixir.ex b/demo/kitchen-sink/docs/elixir.ex index ec0cfb59..693a4bb1 100644 --- a/demo/kitchen-sink/docs/elixir.ex +++ b/demo/kitchen-sink/docs/elixir.ex @@ -1 +1,24 @@ -TODO add a nice demo! \ No newline at end of file +defmodule HelloModule do + # A "Hello world" function + def some_fun do + IO.puts "Juhu Kinners!" + end + # A private function + defp priv do + is_regex ~r""" + This is a regex + spanning several + lines. + """ + x = elem({ :a, :b, :c }, 0) #=> :a + end +end + +test_fun = fn(x) -> + cond do + x > 10 -> + :greater_than_ten + true -> + :maybe_ten + end +end \ No newline at end of file diff --git a/lib/ace/mode/elixir.js b/lib/ace/mode/elixir.js index c64f5cce..c55ea366 100644 --- a/lib/ace/mode/elixir.js +++ b/lib/ace/mode/elixir.js @@ -39,7 +39,7 @@ var oop = require("../lib/oop"); var TextMode = require("./text").Mode; var ElixirHighlightRules = require("./elixir_highlight_rules").ElixirHighlightRules; // TODO: pick appropriate fold mode -var FoldMode = require("./folding/cstyle").FoldMode; +var FoldMode = require("./folding/coffee").FoldMode; var Mode = function() { this.HighlightRules = ElixirHighlightRules; @@ -48,7 +48,7 @@ var Mode = function() { oop.inherits(Mode, TextMode); (function() { - // this.lineCommentStart = ""@(?:module|type)?doc \"""; + this.lineCommentStart = "#"; // this.blockComment = {start: ""/*"", end: ""*/""}; // Extra logic goes here. this.$id = "ace/mode/elixir" diff --git a/lib/ace/mode/elixir_highlight_rules.js b/lib/ace/mode/elixir_highlight_rules.js index a52bdf4f..a13492be 100644 --- a/lib/ace/mode/elixir_highlight_rules.js +++ b/lib/ace/mode/elixir_highlight_rules.js @@ -101,11 +101,11 @@ var ElixirHighlightRules = function() { { defaultToken: 'comment.documentation.string' } ], comment: '@doc with string is treated as documentation' }, { token: 'keyword.control.elixir', - regex: '(?_?[\\da-fA-F])*|\\d(?>_?\\d)*(?:\\.(?![^[:space:][:digit:]])(?>_?\\d)*)?(?:[eE][-+]?\\d(?>_?\\d)*)?|0b[01]+|0o[0-7]+)\\b', + regex: '\\b(?:0x[\\da-fA-F](?:_?[\\da-fA-F])*|\\d(?:_?\\d)*(?:\\.(?![^[:space:][:digit:]])(?:_?\\d)*)?(?:[eE][-+]?\\d(?:_?\\d)*)?|0b[01]+|0o[0-7]+)\\b', TODO: 'FIXME: regexp doesn\'t have js equivalent', originalRegex: '\\b(0x\\h(?>_?\\h)*|\\d(?>_?\\d)*(\\.(?![^[:space:][:digit:]])(?>_?\\d)*)?([eE][-+]?\\d(?>_?\\d)*)?|0b[01]+|0o[0-7]+)\\b' }, { token: 'punctuation.definition.constant.elixir', @@ -146,7 +146,7 @@ var ElixirHighlightRules = function() { { include: '#escaped_char' }, { defaultToken: 'constant.other.symbol.double-quoted.elixir' } ] }, { token: 'punctuation.definition.string.begin.elixir', - regex: '(?>\'\'\')', + regex: '(?:\'\'\')', TODO: 'FIXME: regexp doesn\'t have js equivalent', originalRegex: '(?>\'\'\')', push: @@ -168,7 +168,7 @@ var ElixirHighlightRules = function() { { defaultToken: 'support.function.variable.quoted.single.elixir' } ], comment: 'single quoted string (allows for interpolation)' }, { token: 'punctuation.definition.string.begin.elixir', - regex: '(?>""")', + regex: '(?:""")', TODO: 'FIXME: regexp doesn\'t have js equivalent', originalRegex: '(?>""")', push: @@ -190,7 +190,7 @@ var ElixirHighlightRules = function() { { defaultToken: 'string.quoted.double.elixir' } ], comment: 'double quoted string (allows for interpolation)' }, { token: 'punctuation.definition.string.begin.elixir', - regex: '~[a-z](?>""")', + regex: '~[a-z](?:""")', TODO: 'FIXME: regexp doesn\'t have js equivalent', originalRegex: '~[a-z](?>""")', push: @@ -253,7 +253,7 @@ var ElixirHighlightRules = function() { { defaultToken: 'string.interpolated.elixir' } ], comment: 'sigil (allow for interpolation)' }, { token: 'punctuation.definition.string.begin.elixir', - regex: '~[A-Z](?>""")', + regex: '~[A-Z](?:""")', TODO: 'FIXME: regexp doesn\'t have js equivalent', originalRegex: '~[A-Z](?>""")', push: @@ -302,26 +302,26 @@ var ElixirHighlightRules = function() { next: 'pop' }, { defaultToken: 'string.quoted.other.literal.upper.elixir' } ], comment: 'sigil (without interpolation)' }, - { token: 'punctuation.definition.constant.elixir', - regex: '(?[a-zA-Z_][\\w@]*(?>[?!]|=(?![>=]))?|\\<\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\-|\\|>|=>|~|~=|=|/|\\\\\\\\|\\*\\*?|\\.\\.?\\.?|>=?|<=?|&&?&?|\\+\\+?|\\-\\-?|\\|\\|?\\|?|\\!|@|\\%?\\{\\}|%|\\[\\]|\\^(?:\\^\\^)?)', + { token: ['punctuation.definition.constant.elixir', 'constant.other.symbol.elixir'], + regex: '(:)([a-zA-Z_][\\w@]*(?:[?!]|=(?![>=]))?|\\<\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\-|\\|>|=>|~|~=|=|/|\\\\\\\\|\\*\\*?|\\.\\.?\\.?|>=?|<=?|&&?&?|\\+\\+?|\\-\\-?|\\|\\|?\\|?|\\!|@|\\%?\\{\\}|%|\\[\\]|\\^(?:\\^\\^)?)', TODO: 'FIXME: regexp doesn\'t have js equivalent', originalRegex: '(?[a-zA-Z_][\\w@]*(?>[?!]|=(?![>=]))?|\\<\\>|===?|!==?|<<>>|<<<|>>>|~~~|::|<\\-|\\|>|=>|~|~=|=|/|\\\\\\\\|\\*\\*?|\\.\\.?\\.?|>=?|<=?|&&?&?|\\+\\+?|\\-\\-?|\\|\\|?\\|?|\\!|@|\\%?\\{\\}|%|\\[\\]|\\^(\\^\\^)?)', comment: 'symbols' }, { token: 'punctuation.definition.constant.elixir', - regex: '(?>[a-zA-Z_][\\w@]*(?>[?!])?):(?!:)', + regex: '(?:[a-zA-Z_][\\w@]*(?:[?!])?):(?!:)', TODO: 'FIXME: regexp doesn\'t have js equivalent', originalRegex: '(?>[a-zA-Z_][\\w@]*(?>[?!])?)(:)(?!:)', comment: 'symbols' }, { token: [ 'punctuation.definition.comment.elixir', 'comment.line.number-sign.elixir' ], - regex: '(?:^[ \\t]+)?(#)(.*$)' }, + regex: '(#)(.*)' }, { token: 'constant.numeric.elixir', - regex: '(?=?' }, { token: 'keyword.operator.bitwise.elixir', - regex: '\\|\\|\\||&&&|^^^|<<<|>>>|~~~' }, + regex: '\\|{3}|&{3}|\\^{3}|<{3}|>{3}|~{3}' }, { token: 'keyword.operator.logical.elixir', - regex: '(?<=[ \\t])!+|\\bnot\\b|&&|\\band\\b|\\|\\||\\bor\\b|\\bxor\\b', - TODO: 'FIXME: regexp doesn\'t have js equivalent', + regex: '!+|\\bnot\\b|&&|\\band\\b|\\|\\||\\bor\\b|\\bxor\\b', originalRegex: '(?<=[ \\t])!+|\\bnot\\b|&&|\\band\\b|\\|\\||\\bor\\b|\\bxor\\b' }, { token: 'keyword.operator.arithmetic.elixir', regex: '\\*|\\+|\\-|/' }, @@ -411,8 +410,7 @@ var ElixirHighlightRules = function() { { token: [ 'punctuation.definition.comment.elixir', 'comment.line.number-sign.elixir' ], - regex: '(?<=^|\\s)(#)(\\s[[a-zA-Z0-9,. \\t?!-][^\\x00-\\x7F]]*$)', - TODO: 'FIXME: regexp doesn\'t have js equivalent', + regex: '(?:^|\\s)(#)(\\s[[a-zA-Z0-9,. \\t?!-][^\\x00-\\x7F]]*$)', originalRegex: '(?<=^|\\s)(#)\\s[[a-zA-Z0-9,. \\t?!-][^\\x{00}-\\x{7F}]]*$', comment: 'We are restrictive in what we allow to go after the comment character to avoid false positives, since the availability of comments depend on regexp flags.' } ] } From c83f39e4a9f9f7529cb064f2252c3dbb6a1f2752 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 2 Nov 2014 15:33:10 +0400 Subject: [PATCH 06/11] update tests for ruby mode --- lib/ace/mode/_test/tokens_html_ruby.json | 20 +++++++++++++++----- lib/ace/mode/_test/tokens_ruby.json | 4 +++- lib/ace/mode/_test/tokens_sh.json | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/ace/mode/_test/tokens_html_ruby.json b/lib/ace/mode/_test/tokens_html_ruby.json index 2c74ba56..8ff5f6ea 100644 --- a/lib/ace/mode/_test/tokens_html_ruby.json +++ b/lib/ace/mode/_test/tokens_html_ruby.json @@ -144,7 +144,9 @@ ["text"," "], ["support.function","link_to"], ["text"," "], - ["string","'Show'"], + ["string.start","'"], + ["string","Show"], + ["string.end","'"], ["text",", "], ["identifier","book"], ["text"," "], @@ -162,7 +164,9 @@ ["text"," "], ["support.function","link_to"], ["text"," "], - ["string","'Edit'"], + ["string.start","'"], + ["string","Edit"], + ["string.end","'"], ["text",", "], ["identifier","edit_book_path"], ["paren.lparen","("], @@ -183,7 +187,9 @@ ["text"," "], ["support.function","link_to"], ["text"," "], - ["string","'Remove'"], + ["string.start","'"], + ["string","Remove"], + ["string.end","'"], ["text",", "], ["identifier","book"], ["text",", "], @@ -191,7 +197,9 @@ ["text"," "], ["punctuation.separator.key-value","=>"], ["text"," "], - ["string","'Are you sure?'"], + ["string.start","'"], + ["string","Are you sure?"], + ["string.end","'"], ["text",", "], ["constant.other.symbol.ruby",":method"], ["text"," "], @@ -239,7 +247,9 @@ ["text"," "], ["support.function","link_to"], ["text"," "], - ["string","'New book'"], + ["string.start","'"], + ["string","New book"], + ["string.end","'"], ["text",", "], ["identifier","new_book_path"], ["text"," "], diff --git a/lib/ace/mode/_test/tokens_ruby.json b/lib/ace/mode/_test/tokens_ruby.json index 19b98b70..1809f5ee 100644 --- a/lib/ace/mode/_test/tokens_ruby.json +++ b/lib/ace/mode/_test/tokens_ruby.json @@ -145,7 +145,9 @@ ["text"," "], ["punctuation.separator.key-value","=>"], ["text"," "], - ["string","\"value\""], + ["string.start","\""], + ["string","value"], + ["string.end","\""], ["paren.rparen","}"] ],[ "start" diff --git a/lib/ace/mode/_test/tokens_sh.json b/lib/ace/mode/_test/tokens_sh.json index 53411906..f2c6b276 100644 --- a/lib/ace/mode/_test/tokens_sh.json +++ b/lib/ace/mode/_test/tokens_sh.json @@ -331,4 +331,4 @@ ["keyword","fi"] ],[ "start" -]] +]] \ No newline at end of file From 78cda6bc3a55a4973018ec242fe7acee6027825c Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 2 Nov 2014 15:33:23 +0400 Subject: [PATCH 07/11] update architect-build --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9734fc52..e7a166dc 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "jsdom": "0.2.x", "amd-loader": "~0.0.4", "dryice": "0.4.11", - "architect-build": "https://github.com/c9/architect-build/tarball/42723e152bb" + "architect-build": "https://github.com/c9/architect-build/tarball/a3bad51808" }, "mappings": { "ace": "." From 70337ea5bae6f1a5eb07a81beea8020d7f969b95 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 5 Nov 2014 16:42:39 +0400 Subject: [PATCH 08/11] fix infinite loop in soy mode and make tokenizer more robust --- lib/ace/mode/soy_template_highlight_rules.js | 2 +- lib/ace/tokenizer.js | 32 +++++++++++++++----- lib/ace/tokenizer_test.js | 32 ++++++++++++++++++-- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/lib/ace/mode/soy_template_highlight_rules.js b/lib/ace/mode/soy_template_highlight_rules.js index 50e3ae48..aa913fac 100644 --- a/lib/ace/mode/soy_template_highlight_rules.js +++ b/lib/ace/mode/soy_template_highlight_rules.js @@ -188,7 +188,7 @@ var SoyTemplateHighlightRules = function() { [ 'entity.other.attribute-name.soy', 'text', 'keyword.operator.soy' ], - regex: '\\b([\\w]*)(\\s*)((?::)?)' }, + regex: '\\b([\\w]+)(\\s*)((?::)?)' }, { defaultToken: 'meta.tag.param.soy' } ] } ], '#primitive': [ { token: 'constant.language.soy', diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index e947a130..a0756157 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -32,7 +32,7 @@ define(function(require, exports, module) { "use strict"; // tokenizing lines longer than this makes editor very slow -var MAX_TOKEN_COUNT = 1000; +var MAX_TOKEN_COUNT = 2000; /** * This class takes a set of highlighting rules, and creates a tokenizer out of them. For more information, see [the wiki on extending highlighters](https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#wiki-extendingTheHighlighter). * @class Tokenizer @@ -77,9 +77,11 @@ var Tokenizer = function(rules) { if (rule.token.length == 1 || matchcount == 1) { rule.token = rule.token[0]; } else if (matchcount - 1 != rule.token.length) { - throw new Error("number of classes and regexp groups in '" + - rule.token + "'\n'" + rule.regex + "' doesn't match\n" - + (matchcount - 1) + "!=" + rule.token.length); + this.reportError("number of classes and regexp groups doesn't match", { + rule: rule, + groupCount: matchcount - 1 + }); + rule.token = rule.token[0]; } else { rule.tokenArray = rule.token; rule.token = null; @@ -240,6 +242,7 @@ var Tokenizer = function(rules) { var match, tokens = []; var lastIndex = 0; + var matchAttempts = 0; var token = {type: null, value: ""}; @@ -280,7 +283,7 @@ var Tokenizer = function(rules) { state = this.states[currentState]; if (!state) { - window.console && console.error && console.error(currentState, "doesn't exist"); + this.reportError("state doesn't exist", currentState); currentState = "start"; state = this.states[currentState]; } @@ -293,7 +296,7 @@ var Tokenizer = function(rules) { } if (value) { - if (typeof type == "string") { + if (typeof type === "string") { if ((!rule || rule.merge !== false) && token.type === type) { token.value += value; } else { @@ -315,7 +318,13 @@ var Tokenizer = function(rules) { lastIndex = index; - if (tokens.length > MAX_TOKEN_COUNT) { + if (matchAttempts++ > MAX_TOKEN_COUNT) { + if (matchAttempts > 2 * line.length) { + this.reportError("infinite loop with in ace tokenizer", { + startState: startState, + line: line + }); + } // chrome doens't show contents of text nodes with very long text while (lastIndex < line.length) { if (token.type) @@ -343,7 +352,14 @@ var Tokenizer = function(rules) { state : stack.length ? stack : currentState }; }; - + + this.reportError = function(msg, data) { + var e = new Error(msg); + e.data = data; + if (typeof console == "object" && console.error) + console.error(e); + setTimeout(function() { throw e; }); + }; }).call(Tokenizer.prototype); exports.Tokenizer = Tokenizer; diff --git a/lib/ace/tokenizer_test.js b/lib/ace/tokenizer_test.js index 281f58b3..41bf01c8 100644 --- a/lib/ace/tokenizer_test.js +++ b/lib/ace/tokenizer_test.js @@ -29,7 +29,7 @@ * ***** END LICENSE BLOCK ***** */ if (typeof process !== "undefined") { - require("amd-loader"); + require("amd-loader"); } define(function(require, exports, module) { @@ -59,7 +59,35 @@ module.exports = { var t = new Tokenizer({}); var re = t.removeCapturingGroups("(ax(by))[()]"); assert.equal(re, "(?:ax(?:by))[()]"); - } + }, + + "test: broken highlight rules": function() { + var t = new Tokenizer({ + start: [{ + token: 's', + regex: '&&&|^^^' + }, { + defaultToken: "def" + }], + state1: [{ + token: 'x', + regex: /\b([\w]*)(\s*)((?::)?)/ + }] + }); + var errorReports = 0; + t.reportError = function() { errorReports++; }; + var tokens = t.getLineTokens("x|", "start"); + assert.deepEqual(tokens, { + tokens: [{value: 'x|', type: 'overflow'}], + state: 'start' + }); + var tokens = t.getLineTokens("x|", "state1"); + assert.deepEqual(tokens, { + tokens: [{value: 'x', type: 'x'}, {value: '|', type: 'overflow'}], + state: 'start' + }); + assert.equal(errorReports, 2); + }, }; }); From 96061f72aef6f63843642b84b11518ddb3768870 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 5 Nov 2014 16:51:34 +0400 Subject: [PATCH 09/11] update ChangeLog --- ChangeLog.txt | 11 +++++++++-- tool/tmlanguage.js | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 7c3db96d..86399b5e 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,8 +1,15 @@ - + + * API Changes - `editor.commands.commandKeyBinding` now contains direct map from keys to commands instead of grouping them by hashid - - +* New Features + - Improved autoindent for html and php modes (Adam Jimenez) + - Find All from searchbox (Colton Voege) + +* new language modes + - Elixir, Elm + 2014.09.21 Version 1.1.7 * Bugfixes diff --git a/tool/tmlanguage.js b/tool/tmlanguage.js index d3e42141..9261a2f1 100644 --- a/tool/tmlanguage.js +++ b/tool/tmlanguage.js @@ -107,7 +107,7 @@ function convertToNonCapturingGroups(str) { function simplifyNonCapturingGroups(str) { var tokens = tokenize(str); - var t = tokens[0]; + var t = tokens[0] || {}; if (t.type == "group.start" && t.value == "(?:" && t.end == last(tokens)) { t.value = t.end.value = ""; From f362d2e84abbfd76ccf189bb0cf8ac21976f84f7 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 5 Nov 2014 16:56:51 +0400 Subject: [PATCH 10/11] add markdown comment to elixir demo --- demo/kitchen-sink/docs/elixir.ex | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/demo/kitchen-sink/docs/elixir.ex b/demo/kitchen-sink/docs/elixir.ex index 693a4bb1..bb6a45f1 100644 --- a/demo/kitchen-sink/docs/elixir.ex +++ b/demo/kitchen-sink/docs/elixir.ex @@ -1,4 +1,22 @@ defmodule HelloModule do + @moduledoc """ + This is supposed to be `markdown`. + __Yes__ this is [mark](http://down.format) + + # Truly + + ## marked + + * with lists + * more + * and more + + Even.with(code) + blocks |> with |> samples + + _Docs are first class citizens in Elixir_ (Jose Valim) + """ + # A "Hello world" function def some_fun do IO.puts "Juhu Kinners!" From e26c70ad53a375a99b6844df1833f764023bf0b8 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 5 Nov 2014 17:36:14 +0400 Subject: [PATCH 11/11] update soy_template test --- lib/ace/mode/_test/highlight_rules_test.js | 5 +++-- lib/ace/mode/_test/tokens_soy_template.json | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ace/mode/_test/highlight_rules_test.js b/lib/ace/mode/_test/highlight_rules_test.js index e0244abc..c3b877ec 100644 --- a/lib/ace/mode/_test/highlight_rules_test.js +++ b/lib/ace/mode/_test/highlight_rules_test.js @@ -63,8 +63,8 @@ function generateTestData() { var specialDocs = fs.readdirSync(cwd); var modes = modeList(); - console.log("Docs:", docs); - console.log("Modes:", modes); + // console.log("Docs:", docs); + // console.log("Modes:", modes); docs.forEach(function(docName) { var p = docName.toLowerCase().split("."); @@ -92,6 +92,7 @@ function generateTestData() { console.warn("Can't load mode :" + modeName, p, e); return; } + console.log(modeName); var tokenizer = new Mode().getTokenizer(); var state = "start"; diff --git a/lib/ace/mode/_test/tokens_soy_template.json b/lib/ace/mode/_test/tokens_soy_template.json index 46ea77fa..9ae7c4ed 100644 --- a/lib/ace/mode/_test/tokens_soy_template.json +++ b/lib/ace/mode/_test/tokens_soy_template.json @@ -157,13 +157,12 @@ ["text.xml"," "], ["punctuation.definition.tag.begin.soy","{"], ["entity.name.tag.soy","param"], - ["text"," "], + ["meta.tag.param.soy"," "], ["entity.other.attribute-name.soy","name"], ["keyword.operator.soy",":"], ["meta.tag.param.soy"," "], ["variable.other.soy","$additionalName"], - ["text"," "], - ["meta.tag.param.soy","/"], + ["meta.tag.param.soy"," /"], ["punctuation.definition.tag.end.soy","}"] ],[ "start",