You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/customlanguages.md
+50-8Lines changed: 50 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,17 +6,18 @@ Custom languages support can be added in the languages directory found at:
6
6
**macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/languages`
7
7
**Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\languages`
8
8
9
-
ecode will read each file located at that directory with `json` extension. Each file can contain one
10
-
or several languages. In order to set several languages the root element of the json file should be
11
-
an array, containing one object for each language, otherwise if the root element is an object, it
12
-
should contain the language definition. Language definitions can override any currently supported
13
-
definition. ecode will prioritize user defined definitions.
9
+
ecode will read each file located at that directory with `json` extension. Each file can contain one or several language definitions.
10
+
11
+
***Single Language:** If the root element of the JSON file is an object, it defines a single language.
12
+
***Multiple Languages / Sub-Grammars:** If the root element is an array, it can define multiple independent languages *or* a main language along with **sub-language definitions** used for nesting within the main language (see Nested Syntaxes below). Each object in the array must be a complete language definition with at least a unique `"name"`.
13
+
14
+
Language definitions can override any currently supported definition. ecode will prioritize user defined definitions. Sub-language definitions used only for nesting might not need fields like `"files"` or `"headers"` if they aren't intended to be selectable top-level languages.
14
15
15
16
### Language definition format
16
17
17
18
```json
18
19
{
19
-
"name": "language_name", // (Required) The display name of the language.
20
+
"name": "language_name", // (Required) The display name of the language. Must be unique, especially if referenced by other definitions for nesting.
20
21
"files": [ // (Required if `visible` is `true`) An array of Lua patterns matching filenames for this language.
21
22
"%.ext$", // Example: Matches files ending in .ext
22
23
"^Makefile$"// Example: Matches the exact filename Makefile
@@ -28,13 +29,13 @@ definition. ecode will prioritize user defined definitions.
28
29
// Rule using Lua patterns with capture groups mapping to different types:
{ "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" },// This rule highlights the entire block, including delimiters, with the specified `type_name`.
32
33
// Rule using Perl-compatible regular expressions (PCRE):
33
34
{ "regex": "perl_regex", "type": "type_name" },
34
35
// Rule using PCRE with capture groups mapping to different types:
{ "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" },// Similar to the Lua pattern block, highlights the entire block with `type_name`.
38
39
// Rule using a custom parser implemented in native code for performance (e.g., number parsing):
39
40
{ "parser": "custom_parser_name", "type": "type_name" } // Currently available: "cpp_number_parser", "c_number_parser", "js_number_parser", "common_number_parser" (matches decimal and hexa), "common_number_parser_o" (matches the same as "common_number_parser" plus octal numbers), "common_number_parser_ob" (matches the same as "common_number_parser_o" plus binary numbers)
40
41
@@ -54,6 +55,28 @@ definition. ecode will prioritize user defined definitions.
54
55
// - The third capture (word with extra allowed chars) is typed as "symbol".
55
56
// Similar to the above, when the third group matches text (e.g., "true"), ecode looks up "true" in the "symbols" definition.
56
57
// If { "true": "literal" } exists, the matched text "true" will be highlighted as "literal". Otherwise, it defaults to "normal".
58
+
59
+
// --- NESTED SYNTAX RULE ---
60
+
// Rule defining a multi-line block that switches to a DIFFERENT language syntax inside:
61
+
{
62
+
"pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], // Can also use "regex"
63
+
"syntax": "NestedLanguageName", // (Optional) The 'name' of another language definition to use for highlighting *within* this block.
64
+
"type": "type_name"// OR ["type_for_start_capture1", "type_for_start_capture2", ...] // (Optional) Defines the type(s) for the text matched by the START and END patterns themselves (using capture groups if needed). If omitted, delimiters usually get 'normal' type.
65
+
},
66
+
// How nesting works:
67
+
// 1. The `pattern` (or `regex`) defines the start and end delimiters of the block.
68
+
// 2. The `syntax` key specifies the `name` of another language definition (which must be loaded, often defined in the same JSON file using an array).
69
+
// 3. The text *between* the start and end delimiters will be highlighted using the rules defined in the "NestedLanguageName" language definition.
70
+
// 4. The `type` key here applies ONLY to the text matched by the start and end patterns themselves. If the start/end patterns have capture groups, you can provide an array of types matching those captures.
71
+
// 5. Nesting can occur up to 4 levels deep (e.g., Language A contains Language B, which contains Language C, etc.).
72
+
// Use Case: Essential for languages embedding other languages, like HTML containing CSS and JavaScript.
73
+
74
+
// Example of a nested syntax rule (C++ raw string containing XML):
"syntax": "XML", // Use the "XML" language definition inside.
78
+
"type": [ "string", "keyword2", "string", "keyword2" ] // Types for captures in start/end: "R\"(" + "xml" + ")(" and ")(" + "xml" + ")\"". Needs adjustment based on exact captures. Assumes captures are (xml) in start and (xml) in end. Often, the delimiters are just styled as 'string' or 'keyword2'. Example simplification: "type": "string" might apply to the whole delimiter match if no captures are typed.
79
+
},
57
80
],
58
81
"symbols": [ // (Optional) An array defining specific types for exact words, primarily used in conjunction with patterns having `type: "symbol"`.
59
82
// Structure: An array where each element is an object containing exactly one key-value pair.
@@ -102,6 +125,25 @@ definition. ecode will prioritize user defined definitions.
102
125
]
103
126
}
104
127
```
128
+
### Nested Syntaxes (Sub-Grammars)
129
+
130
+
ecode supports **nested syntaxes**, allowing a block of code within one language to be highlighted according to the rules of another language. This is crucial for accurately representing modern languages that often embed other languages or domain-specific languages.
131
+
132
+
**How it works:**
133
+
134
+
1.**Define Sub-Languages:** Define the syntax for the language to be embedded (e.g., "CSS", "JavaScript", "XML", "SQL") as a separate language definition. Often, these are defined within the *same JSON file* as the main language, using a JSON array as the root element (see [Custom languages support](#custom-languages-support)). The sub-language definition needs a unique `"name"`.
135
+
2.**Reference in Patterns:** In the main language's `"patterns"`, use a multi-line block rule (`pattern` or `regex` array). Add the `"syntax"` key to this rule, setting its value to the `"name"` of the sub-language definition you want to use inside the block.
136
+
3.**Highlighting:** When ecode encounters this block, it applies the highlighting rules from the specified sub-language to the content *between* the start and end delimiters. The delimiters themselves are styled according to the `type` specified in the *outer* rule.
137
+
138
+
**Example Use Cases:**
139
+
140
+
* HTML files containing `<style>` blocks (CSS) and `<script>` blocks (JavaScript).
0 commit comments