|
| 1 | +## Custom languages support |
| 2 | + |
| 3 | +Custom languages support can be added in the languages directory found at: |
| 4 | + |
| 5 | +* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/languages` |
| 6 | +* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/languages` |
| 7 | +* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\languages` |
| 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. |
| 14 | + |
| 15 | +### Language definition format |
| 16 | + |
| 17 | +```json |
| 18 | +{ |
| 19 | + "name": "language_name", |
| 20 | + "files": [ "Array of file extensions supported" ], |
| 21 | + "comment": "Sets the comment string used for auto-comment functionality.", |
| 22 | + "patterns": [ |
| 23 | + { "pattern": "lua_pattern", "type": "type_name" }, |
| 24 | + { "pattern": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": { "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" } }, |
| 25 | + { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" } |
| 26 | + { "regex": "perl_regex", "type": "type_name" }, |
| 27 | + { "regex": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": { "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" } }, |
| 28 | + { "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" } |
| 29 | + ], |
| 30 | + "symbols": [ |
| 31 | + { "symbol_name": "type_name" } |
| 32 | + ], |
| 33 | + "visible": true, /* sets if the language is visible as a main language in the editor, optional parameter, true by default */ |
| 34 | + "auto_close_xml_tag": false, /* sets if the language defined supports auto close XML tags, optional parameter, false by default */ |
| 35 | + "lsp_name": "sets the LSP name assigned for the language, optional parameter, it will use the _name_ in lowercase if not set" |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +### Porting language definitions |
| 40 | + |
| 41 | +ecode uses the same format for language definition as [lite](https://github.com/rxi/lite) and [lite-xl](https://github.com/lite-xl/lite-xl) editors. |
| 42 | +This makes much easier to add new languages to ecode. There's also a helper tool that can be download from |
| 43 | +ecode repository located [here](https://github.com/SpartanJ/ecode/tree/develop/tools/data-migration/lite/language) |
| 44 | +that allows to directly export a lite language definition to the JSON file format used in ecode. |
| 45 | + |
| 46 | +### Extending language definitions |
| 47 | + |
| 48 | +It's possible to easily extend any language definition by exporting it using the CLI arguments provided: |
| 49 | +`--export-lang` and `--export-lang-path`. A user wanting to extend or improve a language definition can |
| 50 | +export it, modify it and install the definition with a `.json` extension in the [custom languages path](#custom-languages-support). |
| 51 | +For example, to extend the language `vue` you will need to run: |
| 52 | +`ecode --export-lang=vue --export-lang-path=./vue.json`, exit the exported file and move it to the |
| 53 | +[custom languages path](#custom-languages-support). |
| 54 | + |
| 55 | +### Language definition example |
| 56 | + |
| 57 | +```json |
| 58 | +{ |
| 59 | + "name": "Elixir", |
| 60 | + "files": [ "%.ex$", "%.exs$" ], |
| 61 | + "comment": "#", |
| 62 | + "patterns": [ |
| 63 | + { "pattern": "#.*\n", "type": "comment" }, |
| 64 | + { "pattern": [ ":\"", "\"", "\\" ], "type": "number" }, |
| 65 | + { "pattern": [ "\"\"\"", "\"\"\"", "\\" ], "type": "string" }, |
| 66 | + { "pattern": [ "\"", "\"", "\\" ], "type": "string" }, |
| 67 | + { "pattern": [ "'", "'", "\\" ], "type": "string" }, |
| 68 | + { "pattern": [ "~%a[/\"|'%(%[%{<]", "[/\"|'%)%]%}>]", "\\" ], "type": "string"}, |
| 69 | + { "pattern": "-?0x%x+", "type": "number" }, |
| 70 | + { "pattern": "-?%d+[%d%.eE]*f?", "type": "number" }, |
| 71 | + { "pattern": "-?%.?%d+f?", "type": "number" }, |
| 72 | + { "pattern": ":\"?[%a_][%w_]*\"?", "type": "number" }, |
| 73 | + { "pattern": "[%a][%w_!?]*%f[(]", "type": "function" }, |
| 74 | + { "pattern": "%u%w+", "type": "normal" }, |
| 75 | + { "pattern": "@[%a_][%w_]*", "type": "keyword2" }, |
| 76 | + { "pattern": "_%a[%w_]*", "type": "keyword2" }, |
| 77 | + { "pattern": "[%+%-=/%*<>!|&]", "type": "operator" }, |
| 78 | + { "pattern": "[%a_][%w_]*", "type": "symbol" } |
| 79 | + ], |
| 80 | + "symbols": [ |
| 81 | + {"def": "keyword"}, |
| 82 | + {"defp": "keyword"}, |
| 83 | + {"defguard": "keyword"}, |
| 84 | + {"defguardp": "keyword"}, |
| 85 | + {"defmodule": "keyword"}, |
| 86 | + {"defprotocol": "keyword"}, |
| 87 | + {"defimpl": "keyword"}, |
| 88 | + {"defrecord": "keyword"}, |
| 89 | + {"defrecordp": "keyword"}, |
| 90 | + {"defmacro": "keyword"}, |
| 91 | + {"defmacrop": "keyword"}, |
| 92 | + {"defdelegate": "keyword"}, |
| 93 | + {"defoverridable": "keyword"}, |
| 94 | + {"defexception": "keyword"}, |
| 95 | + {"defcallback": "keyword"}, |
| 96 | + {"defstruct": "keyword"}, |
| 97 | + {"for": "keyword"}, |
| 98 | + {"case": "keyword"}, |
| 99 | + {"when": "keyword"}, |
| 100 | + {"with": "keyword"}, |
| 101 | + {"cond": "keyword"}, |
| 102 | + {"if": "keyword"}, |
| 103 | + {"unless": "keyword"}, |
| 104 | + {"try": "keyword"}, |
| 105 | + {"receive": "keyword"}, |
| 106 | + {"after": "keyword"}, |
| 107 | + {"raise": "keyword"}, |
| 108 | + {"rescue": "keyword"}, |
| 109 | + {"catch": "keyword"}, |
| 110 | + {"else": "keyword"}, |
| 111 | + {"quote": "keyword"}, |
| 112 | + {"unquote": "keyword"}, |
| 113 | + {"super": "keyword"}, |
| 114 | + {"unquote_splicing": "keyword"}, |
| 115 | + {"do": "keyword"}, |
| 116 | + {"end": "keyword"}, |
| 117 | + {"fn": "keyword"}, |
| 118 | + {"import": "keyword2"}, |
| 119 | + {"alias": "keyword2"}, |
| 120 | + {"use": "keyword2"}, |
| 121 | + {"require": "keyword2"}, |
| 122 | + {"and": "operator"}, |
| 123 | + {"or": "operator"}, |
| 124 | + {"true": "literal"}, |
| 125 | + {"false": "literal"}, |
| 126 | + {"nil": "literal"} |
| 127 | + ] |
| 128 | +} |
| 129 | +``` |
| 130 | + |
| 131 | +For more complex syntax definitions please see the definition of all the native languages supported |
| 132 | +by ecode [here](https://github.com/SpartanJ/eepp/tree/develop/src/eepp/ui/doc/languages) and |
| 133 | +[here](https://github.com/SpartanJ/eepp/tree/develop/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages). |
0 commit comments