From a44b053eabb5015ec7119d27883c55b6978200d9 Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Tue, 3 Sep 2013 17:21:47 +0200 Subject: [PATCH 1/3] Initial Nix mode --- lib/ace/ext/modelist.js | 1 + lib/ace/mode/nix.js | 66 +++++++++++++++++ lib/ace/mode/nix_highlight_rules.js | 105 ++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 lib/ace/mode/nix.js create mode 100644 lib/ace/mode/nix_highlight_rules.js diff --git a/lib/ace/ext/modelist.js b/lib/ace/ext/modelist.js index 2cc550bb..5e6551ba 100644 --- a/lib/ace/ext/modelist.js +++ b/lib/ace/ext/modelist.js @@ -98,6 +98,7 @@ var supportedModes = { Markdown: ["md|markdown"], MySQL: ["mysql"], MUSHCode: ["mc|mush"], + Nix: ["nix"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], diff --git a/lib/ace/mode/nix.js b/lib/ace/mode/nix.js new file mode 100644 index 00000000..44e55822 --- /dev/null +++ b/lib/ace/mode/nix.js @@ -0,0 +1,66 @@ +/* ***** 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. + * + * + * Contributor(s): + * + * + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var CMode = require("./c_cpp").Mode; +var Tokenizer = require("../tokenizer").Tokenizer; +var NixHighlightRules = require("./nix_highlight_rules").NixHighlightRules; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + CMode.call(this); + var highlighter = new NixHighlightRules(); + this.foldingRules = new CStyleFoldMode(); + + this.$tokenizer = new Tokenizer(highlighter.getRules()); + this.$keywordList = highlighter.$keywordList; +}; +oop.inherits(Mode, CMode); + +(function() { + // Extra logic goes here. + this.lineCommentStart = "#"; + this.blockComment = {start: "/*", end: "*/"}; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/nix_highlight_rules.js b/lib/ace/mode/nix_highlight_rules.js new file mode 100644 index 00000000..30143eec --- /dev/null +++ b/lib/ace/mode/nix_highlight_rules.js @@ -0,0 +1,105 @@ +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var NixHighlightRules = function() { + + var constantLanguage = "true|false"; + var keywordControl = "with|import|if|else|then"; + var keywordDeclaration = "let|in|rec"; + + var keywordMapper = this.createKeywordMapper({ + "constant.language.nix": constantLanguage, + "keyword.control.nix": keywordControl, + "keyword.declaration.nix": keywordDeclaration + }, "identifier"); + + this.$rules = { + "start": [{ + token: "comment", + regex: /#.*$/ + }, { + token: "comment", + regex: /\/\*/, + next: "comment" + }, { + regex: "(==|!=|<=?|>=?)", + token: ["keyword.operator.comparison.nix"] + }, { + regex: "((?:[+*/%-]|\\~)=)", + token: ["keyword.operator.assignment.arithmetic.nix"] + }, { + regex: "=", + token: "keyword.operator.assignment.nix" + }, { + token: "string", + regex: "''", + next: "qqdoc" + }, { + token: "string", + regex: "'", + next: "qstring" + }, { + token: "string", + regex: '"', + next: "qqstring" + }, { + token: "constant.numeric", // hex + regex: "0[xX][0-9a-fA-F]+\\b" + }, { + token: "constant.numeric", // float + regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token: keywordMapper, + regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }], + "comment": [{ + token: "comment", // closing comment + regex: ".*?\\*\\/", + next: "start" + }, { + token: "comment", // comment spanning whole line + regex: ".+" + }], + "qqdoc": [{ + token: "constant.language.escape", + regex: /\$\{[^}]+\}/ + }, { + token: "string", + regex: "''", + next: "start" + }, { + defaultToken: "string" + }], + + "qqstring": [{ + token: "constant.language.escape", + regex: /\$\{[^}]+\}/ + }, { + token: "string", + regex: '"', + next: "start" + }, { + defaultToken: "string" + }], + + "qstring": [{ + token: "constant.language.escape", + regex: /\$\{[^}]+\}/ + }, { + token: "string", + regex: "'", + next: "start" + }, { + defaultToken: "string" + }] + }; + +}; + +oop.inherits(NixHighlightRules, TextHighlightRules); + +exports.NixHighlightRules = NixHighlightRules; +}); \ No newline at end of file From 3812b205462759c198cd4ce7ed1ed44020aacc0b Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Tue, 3 Sep 2013 20:46:27 +0200 Subject: [PATCH 2/3] Nix mode --- demo/kitchen-sink/doclist.js | 3 +- demo/kitchen-sink/docs/Nix.nix | 57 ++++++++ lib/ace/mode/nix.js | 2 +- lib/ace/mode/nix_highlight_rules.js | 202 +++++++++++++++------------- lib/ace/snippets/nix.js | 7 + lib/ace/snippets/nix.snippets | 0 6 files changed, 175 insertions(+), 96 deletions(-) create mode 100644 demo/kitchen-sink/docs/Nix.nix create mode 100644 lib/ace/snippets/nix.js create mode 100644 lib/ace/snippets/nix.snippets diff --git a/demo/kitchen-sink/doclist.js b/demo/kitchen-sink/doclist.js index c650d554..a5f92fd4 100644 --- a/demo/kitchen-sink/doclist.js +++ b/demo/kitchen-sink/doclist.js @@ -151,7 +151,8 @@ var docs = { "docs/julia.js": "Julia", "docs/prolog.plg": "Prolog", "docs/rust.rs": "Rust", - "docs/twig.twig": "Twig" + "docs/twig.twig": "Twig", + "docs/Nix.nix": "Nix" }; var ownSource = { diff --git a/demo/kitchen-sink/docs/Nix.nix b/demo/kitchen-sink/docs/Nix.nix new file mode 100644 index 00000000..9476db3b --- /dev/null +++ b/demo/kitchen-sink/docs/Nix.nix @@ -0,0 +1,57 @@ +{ + # Name of our deployment + network.description = "HelloWorld"; + # Enable rolling back to previous versions of our infrastructure + network.enableRollback = true; + + # It consists of a single server named 'helloserver' + helloserver = + # Every server gets passed a few arguments, including a reference + # to nixpkgs (pkgs) + { config, pkgs, ... }: + let + # We import our custom packages from ./default passing pkgs as argument + packages = import ./default.nix { pkgs = pkgs; }; + # This is the nodejs version specified in default.nix + nodejs = packages.nodejs; + # And this is the application we'd like to deploy + app = packages.app; + in + { + # We'll be running our application on port 8080, because a regular + # user cannot bind to port 80 + # Then, using some iptables magic we'll forward traffic designated to port 80 to 8080 + networking.firewall.enable = true; + # We will open up port 22 (SSH) as well otherwise we're locking ourselves out + networking.firewall.allowedTCPPorts = [ 80 8080 22 ]; + networking.firewall.allowPing = true; + + # Port forwarding using iptables + networking.firewall.extraCommands = '' + iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 + ''; + + # To run our node.js program we're going to use a systemd service + # We can configure the service to automatically start on boot and to restart + # the process in case it crashes + systemd.services.helloserver = { + description = "Hello world application"; + # Start the service after the network is available + after = [ "network.target" ]; + # We're going to run it on port 8080 in production + environment = { PORT = "8080"; }; + serviceConfig = { + # The actual command to run + ExecStart = "${nodejs}/bin/node ${app}/server.js"; + # For security reasons we'll run this process as a special 'nodejs' user + User = "nodejs"; + Restart = "always"; + }; + }; + + # And lastly we ensure the user we run our application as is created + users.extraUsers = { + nodejs = { }; + }; + }; +} \ No newline at end of file diff --git a/lib/ace/mode/nix.js b/lib/ace/mode/nix.js index 44e55822..b864fc49 100644 --- a/lib/ace/mode/nix.js +++ b/lib/ace/mode/nix.js @@ -29,7 +29,7 @@ * * Contributor(s): * - * + * Zef Hemel * * ***** END LICENSE BLOCK ***** */ diff --git a/lib/ace/mode/nix_highlight_rules.js b/lib/ace/mode/nix_highlight_rules.js index 30143eec..4a8e5ebd 100644 --- a/lib/ace/mode/nix_highlight_rules.js +++ b/lib/ace/mode/nix_highlight_rules.js @@ -1,105 +1,119 @@ define(function(require, exports, module) { -"use strict"; + "use strict"; -var oop = require("../lib/oop"); -var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + var oop = require("../lib/oop"); + var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; -var NixHighlightRules = function() { + var NixHighlightRules = function() { - var constantLanguage = "true|false"; - var keywordControl = "with|import|if|else|then"; - var keywordDeclaration = "let|in|rec"; + var constantLanguage = "true|false"; + var keywordControl = "with|import|if|else|then"; + var keywordDeclaration = "let|in|rec"; - var keywordMapper = this.createKeywordMapper({ - "constant.language.nix": constantLanguage, - "keyword.control.nix": keywordControl, - "keyword.declaration.nix": keywordDeclaration - }, "identifier"); + var keywordMapper = this.createKeywordMapper({ + "constant.language.nix": constantLanguage, + "keyword.control.nix": keywordControl, + "keyword.declaration.nix": keywordDeclaration + }, "identifier"); - this.$rules = { - "start": [{ - token: "comment", - regex: /#.*$/ - }, { - token: "comment", - regex: /\/\*/, - next: "comment" - }, { - regex: "(==|!=|<=?|>=?)", - token: ["keyword.operator.comparison.nix"] - }, { - regex: "((?:[+*/%-]|\\~)=)", - token: ["keyword.operator.assignment.arithmetic.nix"] - }, { - regex: "=", - token: "keyword.operator.assignment.nix" - }, { - token: "string", - regex: "''", - next: "qqdoc" - }, { - token: "string", - regex: "'", - next: "qstring" - }, { - token: "string", - regex: '"', - next: "qqstring" - }, { - token: "constant.numeric", // hex - regex: "0[xX][0-9a-fA-F]+\\b" - }, { - token: "constant.numeric", // float - regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, { - token: keywordMapper, - regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" - }], - "comment": [{ - token: "comment", // closing comment - regex: ".*?\\*\\/", - next: "start" - }, { - token: "comment", // comment spanning whole line - regex: ".+" - }], - "qqdoc": [{ - token: "constant.language.escape", - regex: /\$\{[^}]+\}/ - }, { - token: "string", - regex: "''", - next: "start" - }, { - defaultToken: "string" - }], + this.$rules = { + "start": [{ + token: "comment", + regex: /#.*$/ + }, { + token: "comment", + regex: /\/\*/, + next: "comment" + }, { + token: "constant", + regex: "<[^>]+>" + }, { + regex: "(==|!=|<=?|>=?)", + token: ["keyword.operator.comparison.nix"] + }, { + regex: "((?:[+*/%-]|\\~)=)", + token: ["keyword.operator.assignment.arithmetic.nix"] + }, { + regex: "=", + token: "keyword.operator.assignment.nix" + }, { + token: "string", + regex: "''", + next: "qqdoc" + }, { + token: "string", + regex: "'", + next: "qstring" + }, { + token: "string", + regex: '"', + push: "qqstring" + }, { + token: "constant.numeric", // hex + regex: "0[xX][0-9a-fA-F]+\\b" + }, { + token: "constant.numeric", // float + regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token: keywordMapper, + regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + }, { + regex: "}", + token: function(val, start, stack) { + return stack[1] == "qqstring" ? "constant.language.escape" : "text" + }, + next: "pop" + }], + "comment": [{ + token: "comment", // closing comment + regex: ".*?\\*\\/", + next: "start" + }, { + token: "comment", // comment spanning whole line + regex: ".+" + }], + "qqdoc": [ + { + token: "constant.language.escape", + regex: /\$\{/, + push: "start" + }, { + token: "string", + regex: "''", + next: "pop" + }, { + defaultToken: "string" + }], + "qqstring": [ + { + token: "constant.language.escape", + regex: /\$\{/, + push: "start" + }, { + token: "string", + regex: '"', + next: "pop" + }, { + defaultToken: "string" + }], + "qstring": [ + { + token: "constant.language.escape", + regex: /\$\{/, + push: "start" + }, { + token: "string", + regex: "'", + next: "pop" + }, { + defaultToken: "string" + }] + }; - "qqstring": [{ - token: "constant.language.escape", - regex: /\$\{[^}]+\}/ - }, { - token: "string", - regex: '"', - next: "start" - }, { - defaultToken: "string" - }], - - "qstring": [{ - token: "constant.language.escape", - regex: /\$\{[^}]+\}/ - }, { - token: "string", - regex: "'", - next: "start" - }, { - defaultToken: "string" - }] + this.normalizeRules(); }; -}; + oop.inherits(NixHighlightRules, TextHighlightRules); -oop.inherits(NixHighlightRules, TextHighlightRules); - -exports.NixHighlightRules = NixHighlightRules; + exports.NixHighlightRules = NixHighlightRules; }); \ No newline at end of file diff --git a/lib/ace/snippets/nix.js b/lib/ace/snippets/nix.js new file mode 100644 index 00000000..583abf85 --- /dev/null +++ b/lib/ace/snippets/nix.js @@ -0,0 +1,7 @@ +define(function(require, exports, module) { +"use strict"; + +exports.snippetText = require("../requirejs/text!./nix.snippets"); +exports.scope = "nix"; + +}); diff --git a/lib/ace/snippets/nix.snippets b/lib/ace/snippets/nix.snippets new file mode 100644 index 00000000..e69de29b From 00a640e4733e8ce21d10a38f7e428a2b9418daac Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 4 Sep 2013 13:19:23 +0400 Subject: [PATCH 3/3] fix highlighting of closing brace --- lib/ace/mode/nix_highlight_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mode/nix_highlight_rules.js b/lib/ace/mode/nix_highlight_rules.js index 4a8e5ebd..5cee8675 100644 --- a/lib/ace/mode/nix_highlight_rules.js +++ b/lib/ace/mode/nix_highlight_rules.js @@ -60,7 +60,7 @@ define(function(require, exports, module) { }, { regex: "}", token: function(val, start, stack) { - return stack[1] == "qqstring" ? "constant.language.escape" : "text" + return stack[1] && stack[1].charAt(0) == "q" ? "constant.language.escape" : "text"; }, next: "pop" }],