From c5f58503fea090230a113ad069d29dd358aaa2a0 Mon Sep 17 00:00:00 2001 From: Patrick Nevels Date: Sat, 25 Jan 2014 19:19:57 -0600 Subject: [PATCH 1/6] added Gherkin highlighting support --- demo/kitchen-sink/docs/gherkin.feature | 10 +++ lib/ace/ext/modelist.js | 1 + lib/ace/mode/gherkin.js | 58 +++++++++++++++++ lib/ace/mode/gherkin_highlight_rules.js | 83 +++++++++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 demo/kitchen-sink/docs/gherkin.feature create mode 100644 lib/ace/mode/gherkin.js create mode 100644 lib/ace/mode/gherkin_highlight_rules.js diff --git a/demo/kitchen-sink/docs/gherkin.feature b/demo/kitchen-sink/docs/gherkin.feature new file mode 100644 index 00000000..ab31cdf1 --- /dev/null +++ b/demo/kitchen-sink/docs/gherkin.feature @@ -0,0 +1,10 @@ +Feature: Serve coffee + Coffee should not be served until paid for + Coffee should not be served until the button has been pressed + If there is no coffee left then money should be refunded + + Scenario: Buy last coffee + Given there are 1 coffees left in the machine + And I have deposited 1$ + When I press the coffee button + Then I should be served a coffee \ No newline at end of file diff --git a/lib/ace/ext/modelist.js b/lib/ace/ext/modelist.js index e3b8862a..67c80ef0 100644 --- a/lib/ace/ext/modelist.js +++ b/lib/ace/ext/modelist.js @@ -67,6 +67,7 @@ var supportedModes = { EJS: ["ejs"], Forth: ["frt|fs|ldr"], FTL: ["ftl"], + Gherkin: ["feature"], Glsl: ["glsl|frag|vert"], golang: ["go"], Groovy: ["groovy"], diff --git a/lib/ace/mode/gherkin.js b/lib/ace/mode/gherkin.js new file mode 100644 index 00000000..8b9b58a5 --- /dev/null +++ b/lib/ace/mode/gherkin.js @@ -0,0 +1,58 @@ +define(function(require, exports, module) { + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var Tokenizer = require("../tokenizer").Tokenizer; +var GherkinHighlightRules = require("./gherkin_highlight_rules").GherkinHighlightRules; + +var Mode = function() { + this.$tokenizer = new Tokenizer(new GherkinHighlightRules().getRules()); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "#"; + this.$id = "ace/mode/gherkin"; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + + var tokenizedLine = this.getTokenizer().getLineTokens(line, state); + var tokens = tokenizedLine.tokens; + + console.log(state) + + if(line.match("[ ]*\\|")) { + console.log(line.match("\|")); + indent += "| "; + } + + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + + if (state == "start") { + if (line.match("Scenario:|Feature:")) { + indent = tab; + } else if(line.match("Given.+(:)$|Examples:")) { + indent += tab; + } else if(line.match("\\*.+")) { + indent += "* "; + } + } + + + return indent; + }; + + this.checkOutdent = function(state, line, input) { + if(line.match("Feature:")) { + + } + } + // Extra logic goes here. (see below) +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/gherkin_highlight_rules.js b/lib/ace/mode/gherkin_highlight_rules.js new file mode 100644 index 00000000..a902703d --- /dev/null +++ b/lib/ace/mode/gherkin_highlight_rules.js @@ -0,0 +1,83 @@ +define(function(require, exports, module) { + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var stringEscape = "\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})"; + +var GherkinHighlightRules = function() { + + // need to include constant ints + this.$rules = { + start : [{ + token: 'constant.numeric', + regex: "(?:(?:[1-9]\\d*)|(?:0))" + }, { + token : "comment", + regex : "#.*$" + }, { + token : "keyword", + regex : "Feature:|Background:|Scenario:|Scenario Outline:|Examples:|Given|When|Then|And|But|\\*|Scenario\ Outline", + }, { + token : "string", // multi line """ string start + regex : '"{3}', + next : "qqstring3" + }, { + token : "string", // " string + regex : '"', + next : "qqstring" + }, { + token : "comment", + regex : "@[A-Za-z0-9]+", + next : "start" + }, { + token : "comment", + regex : "<.+>" + }, { + token : "comment", + regex : "\\| ", + next : "table-item" + }, { + token : "comment", + regex : "\\|$", + next : "start" + }], + "qqstring3" : [ { + token : "constant.language.escape", + regex : stringEscape + }, { + token : "string", // multi line """ string end + regex : '"{3}', + next : "start" + }, { + defaultToken : "string" + }], + "qqstring" : [{ + token : "constant.language.escape", + regex : stringEscape + }, { + token : "string", + regex : "\\\\$", + next : "qqstring" + }, { + token : "string", + regex : '"|$', + next : "start" + }, { + defaultToken: "string" + }], + "table-item" : [{ + token : "string", + regex : "[A-Za-z0-9 ]*", + next : "start" + }], + }; + + + //new TextHighlightRules().getRules(); + +} + +oop.inherits(GherkinHighlightRules, TextHighlightRules); + +exports.GherkinHighlightRules = GherkinHighlightRules; +}); \ No newline at end of file From 2428de10edb19ca8dfbe2ad8eed935773923c5a1 Mon Sep 17 00:00:00 2001 From: Patrick Nevels Date: Sat, 25 Jan 2014 19:32:40 -0600 Subject: [PATCH 2/6] add Gherkin highlighting --- lib/ace/mode/gherkin.js | 19 ++++++------------- lib/ace/mode/gherkin_highlight_rules.js | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/lib/ace/mode/gherkin.js b/lib/ace/mode/gherkin.js index 8b9b58a5..4a29f971 100644 --- a/lib/ace/mode/gherkin.js +++ b/lib/ace/mode/gherkin.js @@ -16,14 +16,14 @@ oop.inherits(Mode, TextMode); this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); + var space2 = " "; var tokenizedLine = this.getTokenizer().getLineTokens(line, state); var tokens = tokenizedLine.tokens; console.log(state) - if(line.match("[ ]*\\|")) { - console.log(line.match("\|")); + if(line.match("[ ]*\\|")) { indent += "| "; } @@ -33,10 +33,10 @@ oop.inherits(Mode, TextMode); if (state == "start") { - if (line.match("Scenario:|Feature:")) { - indent = tab; - } else if(line.match("Given.+(:)$|Examples:")) { - indent += tab; + if (line.match("Scenario:|Feature:|Scenario\ Outline:")) { + indent += space2; + } else if(line.match("(Given|Then).+(:)$|Examples:")) { + indent += space2; } else if(line.match("\\*.+")) { indent += "* "; } @@ -45,13 +45,6 @@ oop.inherits(Mode, TextMode); return indent; }; - - this.checkOutdent = function(state, line, input) { - if(line.match("Feature:")) { - - } - } - // Extra logic goes here. (see below) }).call(Mode.prototype); exports.Mode = Mode; diff --git a/lib/ace/mode/gherkin_highlight_rules.js b/lib/ace/mode/gherkin_highlight_rules.js index a902703d..13416d5b 100644 --- a/lib/ace/mode/gherkin_highlight_rules.js +++ b/lib/ace/mode/gherkin_highlight_rules.js @@ -16,7 +16,7 @@ var GherkinHighlightRules = function() { regex : "#.*$" }, { token : "keyword", - regex : "Feature:|Background:|Scenario:|Scenario Outline:|Examples:|Given|When|Then|And|But|\\*|Scenario\ Outline", + regex : "Feature:|Background:|Scenario:|Scenario\ Outline:|Examples:|Given|When|Then|And|But|\\*", }, { token : "string", // multi line """ string start regex : '"{3}', From d44c8080bf4d82541f1cd46c319fcc288f9b5e47 Mon Sep 17 00:00:00 2001 From: Patrick Nevels Date: Sat, 25 Jan 2014 20:03:49 -0600 Subject: [PATCH 3/6] make demo more expressive --- demo/kitchen-sink/docs/gherkin.feature | 27 +++++++++++++++++++++----- lib/ace/mode/gherkin.js | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/demo/kitchen-sink/docs/gherkin.feature b/demo/kitchen-sink/docs/gherkin.feature index ab31cdf1..6f8d0df4 100644 --- a/demo/kitchen-sink/docs/gherkin.feature +++ b/demo/kitchen-sink/docs/gherkin.feature @@ -1,10 +1,27 @@ Feature: Serve coffee - Coffee should not be served until paid for - Coffee should not be served until the button has been pressed - If there is no coffee left then money should be refunded + Coffee should not be served until paid for + Coffee should not be served until the button has been pressed + If there is no coffee left then money should be refunded + + Scenario Outline: Eating + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + + Examples: + | start | eat | left | + | 12 | 5 | 7 | + | 20 | 5 | 15 | Scenario: Buy last coffee Given there are 1 coffees left in the machine - And I have deposited 1$ + And I have deposited 1$ When I press the coffee button - Then I should be served a coffee \ No newline at end of file + Then I should be served a "coffee" + + # this a comment + + """ + this is a + pystring + """ \ No newline at end of file diff --git a/lib/ace/mode/gherkin.js b/lib/ace/mode/gherkin.js index 4a29f971..94dba209 100644 --- a/lib/ace/mode/gherkin.js +++ b/lib/ace/mode/gherkin.js @@ -33,7 +33,7 @@ oop.inherits(Mode, TextMode); if (state == "start") { - if (line.match("Scenario:|Feature:|Scenario\ Outline:")) { + if (line.match("Scenario:|Feature:|Scenario\ Outline:|Background:")) { indent += space2; } else if(line.match("(Given|Then).+(:)$|Examples:")) { indent += space2; From 68f46ff7efa8088095a66d81214a056b43a87320 Mon Sep 17 00:00:00 2001 From: Patrick Nevels Date: Sat, 25 Jan 2014 20:06:40 -0600 Subject: [PATCH 4/6] add tags to the demo --- demo/kitchen-sink/docs/gherkin.feature | 1 + 1 file changed, 1 insertion(+) diff --git a/demo/kitchen-sink/docs/gherkin.feature b/demo/kitchen-sink/docs/gherkin.feature index 6f8d0df4..52cd811e 100644 --- a/demo/kitchen-sink/docs/gherkin.feature +++ b/demo/kitchen-sink/docs/gherkin.feature @@ -1,3 +1,4 @@ +@these @are @tags Feature: Serve coffee Coffee should not be served until paid for Coffee should not be served until the button has been pressed From 7d3fdc00b074eaf08aba677c6a5e84cb89a629a4 Mon Sep 17 00:00:00 2001 From: Patrick Nevels Date: Tue, 28 Jan 2014 21:27:26 -0600 Subject: [PATCH 5/6] replaced tokenizer with highlightrules --- lib/ace/mode/gherkin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mode/gherkin.js b/lib/ace/mode/gherkin.js index 94dba209..78ee8a08 100644 --- a/lib/ace/mode/gherkin.js +++ b/lib/ace/mode/gherkin.js @@ -6,7 +6,7 @@ var Tokenizer = require("../tokenizer").Tokenizer; var GherkinHighlightRules = require("./gherkin_highlight_rules").GherkinHighlightRules; var Mode = function() { - this.$tokenizer = new Tokenizer(new GherkinHighlightRules().getRules()); + this.HighlightRules = GherkinHighlightRules; }; oop.inherits(Mode, TextMode); From 5223d19e3f0ebc6afa07dc7994db5e6c4b8c076e Mon Sep 17 00:00:00 2001 From: Patrick Nevels Date: Tue, 28 Jan 2014 21:45:28 -0600 Subject: [PATCH 6/6] added license to files --- lib/ace/mode/gherkin.js | 30 +++++++++++++++++++++++++ lib/ace/mode/gherkin_highlight_rules.js | 30 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/lib/ace/mode/gherkin.js b/lib/ace/mode/gherkin.js index 78ee8a08..557ce9fc 100644 --- a/lib/ace/mode/gherkin.js +++ b/lib/ace/mode/gherkin.js @@ -1,3 +1,33 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2014, 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 ***** */ + define(function(require, exports, module) { var oop = require("../lib/oop"); diff --git a/lib/ace/mode/gherkin_highlight_rules.js b/lib/ace/mode/gherkin_highlight_rules.js index 13416d5b..d54db204 100644 --- a/lib/ace/mode/gherkin_highlight_rules.js +++ b/lib/ace/mode/gherkin_highlight_rules.js @@ -1,3 +1,33 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2014, 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 ***** */ + define(function(require, exports, module) { var oop = require("../lib/oop");