ferronconf 0.4.0

A Rust library for parsing `ferron.conf` configuration files — a domain-specific language for Ferron web server configurations.
{
  "name": "ferron",
  "scopeName": "source.ferron",
  "patterns": [
    { "include": "#comment" },
    { "include": "#line-continuation" },
    { "include": "#match-block" },
    { "include": "#snippet-block" },
    { "include": "#host-block" },
    { "include": "#global-block" },
    { "include": "#directive" },
    { "include": "#semicolon" }
  ],
  "repository": {
    "comment": {
      "name": "comment.line.number-sign.ferron",
      "match": "#.*$"
    },

    "boolean": {
      "name": "constant.language.boolean.ferron",
      "match": "\\b(true|false)\\b"
    },

    "number": {
      "name": "constant.numeric.ferron",
      "match": "\\b-?\\d+(?:\\.\\d+)?\\b"
    },

    "operator": {
      "name": "keyword.operator.ferron",
      "match": "==|!=|!~|~|\\bin\\b"
    },

    "string": {
      "patterns": [
        { "include": "#raw-string" },
        { "include": "#quoted-string" },
        { "include": "#bare-string" }
      ]
    },

    "raw-string": {
      "name": "string.quoted.raw.ferron",
      "begin": "r\"",
      "end": "\""
    },

    "quoted-string": {
      "name": "string.quoted.double.ferron",
      "begin": "\"",
      "end": "\"",
      "patterns": [
        {
          "name": "constant.character.escape.ferron",
          "match": "\\\\."
        },
        {
          "include": "#interpolation"
        }
      ]
    },

    "bare-string": {
      "name": "string.unquoted.ferron",
      "match": "[^\\s{}#\",;]+"
    },

    "interpolation": {
      "name": "meta.interpolation.ferron",
      "begin": "\\{\\{",
      "end": "\\}\\}",
      "patterns": [
        {
          "name": "variable.other.ferron",
          "match": "[A-Za-z][A-Za-z0-9_\\-]*(?:\\.[A-Za-z][A-Za-z0-9_\\-]*)*"
        }
      ]
    },

    "identifier": {
      "name": "entity.name.directive.ferron",
      "match": "\\b[A-Za-z][A-Za-z0-9_-]*\\b"
    },

    "directive": {
      "begin": "\\b([A-Za-z][A-Za-z0-9_-]*)\\b",
      "beginCaptures": {
        "1": { "name": "entity.name.directive.ferron" }
      },
      "end": "(?=\\{(?!\\{)|$|;)",
      "patterns": [
        { "include": "#comment" },
        { "include": "#line-continuation" },
        { "include": "#number" },
        { "include": "#boolean" },
        { "include": "#string" },
        { "include": "#interpolation" },
        { "include": "#semicolon" }
      ]
    },

    "block": {
      "name": "meta.block.ferron",
      "begin": "\\{",
      "beginCaptures": {
        "0": { "name": "punctuation.section.block.begin.ferron" }
      },
      "end": "\\}",
      "endCaptures": {
        "0": { "name": "punctuation.section.block.end.ferron" }
      },
      "patterns": [
        { "include": "#comment" },
        { "include": "#line-continuation" },
        { "include": "#directive" },
        { "include": "#match-block" },
        { "include": "#snippet-block" },
        { "include": "#block" },
        { "include": "#semicolon" }
      ]
    },

    "host-block": {
      "begin": "^(\\s*)(?!match\\s+|snippet\\s+)((?:[^\\s{}#\"\\[\\],]+\\s+)*(?:[^\\s{}#\"\\[\\],]+|\\[[^\\]]*\\](?::\\d+)?))(?:\\s*,\\s*[^\\s{}#\"\\[\\],]+)*\\s*(?=\\{)",
      "beginCaptures": {
        "2": { "name": "entity.name.host.ferron" }
      },
      "end": "(?<=\\})",
      "patterns": [{ "include": "#block" }]
    },

    "global-block": {
      "name": "meta.global.ferron",
      "begin": "^\\s*\\{",
      "beginCaptures": {
        "0": { "name": "punctuation.section.block.begin.ferron" }
      },
      "end": "^\\s*\\}",
      "endCaptures": {
        "0": { "name": "punctuation.section.block.end.ferron" }
      },
      "patterns": [
        { "include": "#directive" },
        { "include": "#block" },
        { "include": "#comment" }
      ]
    },

    "snippet-block": {
      "begin": "\\b(snippet)\\s+([A-Za-z][A-Za-z0-9_-]*)\\s*(?=\\{)",
      "beginCaptures": {
        "1": { "name": "keyword.control.snippet.ferron" },
        "2": { "name": "entity.name.snippet.ferron" }
      },
      "end": "(?<=\\})",
      "patterns": [{ "include": "#block" }]
    },

    "match-block": {
      "begin": "\\b(match)\\s+([A-Za-z][A-Za-z0-9_-]*)\\s*(?=\\{)",
      "beginCaptures": {
        "1": { "name": "keyword.control.match.ferron" },
        "2": { "name": "entity.name.matcher.ferron" }
      },
      "end": "(?<=\\})",
      "patterns": [
        {
          "name": "meta.matcher.expression.ferron",
          "patterns": [
            { "include": "#comment" },
            { "include": "#line-continuation" },
            { "include": "#identifier-path" },
            { "include": "#operator" },
            { "include": "#string" },
            { "include": "#number" },
            { "include": "#semicolon" }
          ]
        }
      ]
    },

    "identifier-path": {
      "name": "variable.other.property.ferron",
      "match": "[A-Za-z][A-Za-z0-9_-]*(?:\\.[A-Za-z][A-Za-z0-9_-]*)+"
    },

    "semicolon": {
      "name": "punctuation.delimiter.semicolon.ferron",
      "match": ";"
    },

    "line-continuation": {
      "name": "keyword.control.line-continuation.ferron",
      "match": "\\\\(?=\\s*(?:$|#))"
    }
  }
}