├── .python-version ├── CHANGELOG.md ├── Completions ├── Jinja Filter Names.sublime-completions ├── Jinja Filters.sublime-completions ├── Jinja Function Names.sublime-completions ├── Jinja Functions.sublime-completions ├── Jinja Loops.sublime-completions ├── Jinja Tags.sublime-completions ├── Jinja Test Names.sublime-completions └── Jinja Tests.sublime-completions ├── Default.sublime-commands ├── Default.sublime-keymap ├── LICENSE.md ├── Main.sublime-menu ├── README.md ├── Snippets ├── autoescape.sublime-snippet ├── block.sublime-snippet ├── call.sublime-snippet ├── expression_block.sublime-snippet ├── filter.sublime-snippet ├── for.sublime-snippet ├── if.sublime-snippet ├── if_else.sublime-snippet ├── jcomment.sublime-snippet ├── macro.sublime-snippet ├── raw.sublime-snippet ├── set.sublime-snippet ├── tags │ ├── autoescape.sublime-snippet │ ├── block.sublime-snippet │ ├── call.sublime-snippet │ ├── comment.sublime-snippet │ ├── elif.sublime-snippet │ ├── else.sublime-snippet │ ├── endautoescape.sublime-snippet │ ├── endblock.sublime-snippet │ ├── endcall.sublime-snippet │ ├── endcomment.sublime-snippet │ ├── endembed.sublime-snippet │ ├── endfilter.sublime-snippet │ ├── endfor.sublime-snippet │ ├── endif.sublime-snippet │ ├── endmacro.sublime-snippet │ ├── endraw.sublime-snippet │ ├── endset.sublime-snippet │ ├── endtrans.sublime-snippet │ ├── endwith.sublime-snippet │ ├── extends.sublime-snippet │ ├── filter.sublime-snippet │ ├── for.sublime-snippet │ ├── if.sublime-snippet │ ├── macro.sublime-snippet │ ├── pluralize.sublime-snippet │ └── set.sublime-snippet ├── trans.sublime-snippet └── with.sublime-snippet ├── Syntaxes ├── C++ │ ├── C (Jinja).sublime-syntax │ ├── C++ (Jinja).sublime-syntax │ ├── Comments.tmPreferences │ └── Snippet Variables.tmPreferences ├── CSS │ ├── CSS (Jinja).sublime-syntax │ ├── CSS (for HTML double-quoted).sublime-syntax │ ├── CSS (for HTML single-quoted).sublime-syntax │ ├── Comments.tmPreferences │ └── Snippet Variables.tmPreferences ├── HTML │ ├── Comments.tmPreferences │ ├── HTML (Jinja).sublime-syntax │ ├── Indentation Rules.tmPreferences │ └── Snippet Variables.tmPreferences ├── JSON │ ├── Comments.tmPreferences │ ├── JSON (Jinja).sublime-syntax │ └── Snippet Variables.tmPreferences ├── JavaScript │ ├── Comments.tmPreferences │ ├── JavaScript (Jinja).sublime-syntax │ ├── JavaScript (for HTML double-quoted).sublime-syntax │ ├── JavaScript (for HTML single-quoted).sublime-syntax │ └── Snippet Variables.tmPreferences ├── Markdown │ ├── Comments.tmPreferences │ ├── Markdown (Jinja).sublime-syntax │ └── Snippet Variables.tmPreferences ├── Text │ ├── Comments.tmPreferences │ ├── Indentation Rules.tmPreferences │ ├── Snippet Variables.tmPreferences │ ├── Symbol List - Blocks.tmPreferences │ ├── Symbol List - Variables.tmPreferences │ └── Text (Jinja).sublime-syntax ├── XML │ ├── Comments.tmPreferences │ ├── Snippet Variables.tmPreferences │ └── XML (Jinja).sublime-syntax └── YAML │ ├── Comments.tmPreferences │ ├── Snippet Variables.tmPreferences │ └── YAML (Jinja).sublime-syntax ├── make.cmd ├── messages.json └── messages └── install.txt /.python-version: -------------------------------------------------------------------------------- 1 | 3.8 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [1.0.0] - 2020-08-12 8 | 9 | ### Added 10 | - Indentation for Jinja code blocks. 11 | - Snippets for commonly used Jinja blocks. 12 | - The main syntax file along with syntax test for the scopes. 13 | - Auto completions for builtin tags, filters, tests and functions. 14 | - Ability to use ctrl + / for Jinja line comments & ctrl + shift + / for block comments. 15 | 16 | ## [1.1.0] - 2022-03-27 17 | 18 | ### Added 19 | - Added command palette entries to open key bindings & documentation. 20 | - Updated all the completion files to use kind, annotation & details. 21 | - Added ability to run syntax tests via GitHub actions. 22 | - Updated issue templates to use GitHub issue forms. 23 | 24 | ### Fixed 25 | - Prevent snippets from triggering in certain places like strings etc. 26 | - Better scoping for escape characters in strings. 27 | - Improved interpolation scopes. 28 | - Distinguish builtin filters/tests/globals/variables in a better way. 29 | - General syntax cleanups. 30 | 31 | ### Removed 32 | - Removed the settings file as it's not needed. 33 | 34 | ## [1.1.1] - 2024-05-12 35 | 36 | ### Fixed 37 | - Fix package name "Jinja2" in various resource files (fixes #15) 38 | - Fix syntax tests not running (fixes #18) 39 | - Fix snippets' indentation 40 | 41 | ## [2.0.0] 42 | 43 | - Reorganize whole package 44 | - Rewrite all syntax definitions extending ST's (CSS, JavaScript, JSON, HTML, Markdown, XML, YAML) 45 | - fix snippet indentation (now using tabs) 46 | -------------------------------------------------------------------------------- /Completions/Jinja Filter Names.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope": "source.jinja meta.filter meta.function-call.identifier", 3 | "completions": [ 4 | { 5 | "trigger": "abs", 6 | "kind": ["markup", "f", "Jinja filter"], 7 | "annotation": "Jinja filter", 8 | "details": "Return the absolute value of the argument.", 9 | }, 10 | { 11 | "trigger": "attr", 12 | "kind": ["markup", "f", "Jinja filter"], 13 | "annotation": "Jinja filter", 14 | "details": "Get an attribute of an object.", 15 | }, 16 | { 17 | "trigger": "batch", 18 | "kind": ["markup", "f", "Jinja filter"], 19 | "annotation": "Jinja filter", 20 | "details": "A filter that batches items.", 21 | }, 22 | { 23 | "trigger": "capitalize", 24 | "kind": ["markup", "f", "Jinja filter"], 25 | "annotation": "Jinja filter", 26 | "details": "Capitalize a value.", 27 | }, 28 | { 29 | "trigger": "center", 30 | "kind": ["markup", "f", "Jinja filter"], 31 | "annotation": "Jinja filter", 32 | "details": "Centers the value in a field of a given width.", 33 | }, 34 | { 35 | "trigger": "default", 36 | "kind": ["markup", "f", "Jinja filter"], 37 | "annotation": "Jinja filter", 38 | "details": "If the value is undefined it will return the passed default value, otherwise the value of the variable.", 39 | }, 40 | { 41 | "trigger": "dictsort", 42 | "kind": ["markup", "f", "Jinja filter"], 43 | "annotation": "Jinja filter", 44 | "details": "Sort a dict and yield (key, value) pairs.", 45 | }, 46 | { 47 | "trigger": "escape", 48 | "kind": ["markup", "f", "Jinja filter"], 49 | "annotation": "Jinja filter", 50 | "details": "Replace the characters &, <, >, ', and \" in the string with HTML-safe sequences.", 51 | }, 52 | { 53 | "trigger": "filesizeformat", 54 | "kind": ["markup", "f", "Jinja filter"], 55 | "annotation": "Jinja filter", 56 | "details": "Format the value like a ‘human-readable’ file size.", 57 | }, 58 | { 59 | "trigger": "first", 60 | "kind": ["markup", "f", "Jinja filter"], 61 | "annotation": "Jinja filter", 62 | "details": "Return the first item of a sequence.", 63 | }, 64 | { 65 | "trigger": "float", 66 | "kind": ["markup", "f", "Jinja filter"], 67 | "annotation": "Jinja filter", 68 | "details": "Convert the value into a floating point number.", 69 | }, 70 | { 71 | "trigger": "forceescape", 72 | "kind": ["markup", "f", "Jinja filter"], 73 | "annotation": "Jinja filter", 74 | "details": "Enforce HTML escaping.", 75 | }, 76 | { 77 | "trigger": "format", 78 | "kind": ["markup", "f", "Jinja filter"], 79 | "annotation": "Jinja filter", 80 | "details": "Apply the given values to a printf-style format string, like string % values.", 81 | }, 82 | { 83 | "trigger": "groupby", 84 | "kind": ["markup", "f", "Jinja filter"], 85 | "annotation": "Jinja filter", 86 | "details": "Group a sequence of objects by an attribute using Python’s itertools.groupby().", 87 | }, 88 | { 89 | "trigger": "indent", 90 | "kind": ["markup", "f", "Jinja filter"], 91 | "annotation": "Jinja filter", 92 | "details": "Return a copy of the string with each line indented by 4 spaces.", 93 | }, 94 | { 95 | "trigger": "int", 96 | "kind": ["markup", "f", "Jinja filter"], 97 | "annotation": "Jinja filter", 98 | "details": "Convert the value into an integer.", 99 | }, 100 | { 101 | "trigger": "items", 102 | "kind": ["markup", "f", "Jinja filter"], 103 | "annotation": "Jinja filter", 104 | "details": "Return an iterator over the (key, value) items of a mapping.", 105 | }, 106 | { 107 | "trigger": "join", 108 | "kind": ["markup", "f", "Jinja filter"], 109 | "annotation": "Jinja filter", 110 | "details": "Return a string which is the concatenation of the strings in the sequence.", 111 | }, 112 | { 113 | "trigger": "last", 114 | "kind": ["markup", "f", "Jinja filter"], 115 | "annotation": "Jinja filter", 116 | "details": "Return the last item of a sequence.", 117 | }, 118 | { 119 | "trigger": "length", 120 | "kind": ["markup", "f", "Jinja filter"], 121 | "annotation": "Jinja filter", 122 | "details": "Return the number of items in a container.", 123 | }, 124 | { 125 | "trigger": "list", 126 | "kind": ["markup", "f", "Jinja filter"], 127 | "annotation": "Jinja filter", 128 | "details": "Convert the value into a list.", 129 | }, 130 | { 131 | "trigger": "lower", 132 | "kind": ["markup", "f", "Jinja filter"], 133 | "annotation": "Jinja filter", 134 | "details": "Convert a value to lowercase.", 135 | }, 136 | { 137 | "trigger": "max", 138 | "kind": ["markup", "f", "Jinja filter"], 139 | "annotation": "Jinja filter", 140 | "details": "Return the largest item from the sequence.", 141 | }, 142 | { 143 | "trigger": "min", 144 | "kind": ["markup", "f", "Jinja filter"], 145 | "annotation": "Jinja filter", 146 | "details": "Return the smallest item from the sequence.", 147 | }, 148 | { 149 | "trigger": "map", 150 | "kind": ["markup", "f", "Jinja filter"], 151 | "annotation": "Jinja filter", 152 | "details": "Applies a filter on a sequence of objects or looks up an attribute.", 153 | }, 154 | { 155 | "trigger": "pprint", 156 | "kind": ["markup", "f", "Jinja filter"], 157 | "annotation": "Jinja filter", 158 | "details": "Pretty print a variable. Useful for debugging.", 159 | }, 160 | { 161 | "trigger": "random", 162 | "kind": ["markup", "f", "Jinja filter"], 163 | "annotation": "Jinja filter", 164 | "details": "Return a random item from the sequence.", 165 | }, 166 | { 167 | "trigger": "reject", 168 | "kind": ["markup", "f", "Jinja filter"], 169 | "annotation": "Jinja filter", 170 | "details": "Filters a sequence of objects by applying a test to each object, and rejecting the objects with the test succeeding.", 171 | }, 172 | { 173 | "trigger": "rejectattr", 174 | "kind": ["markup", "f", "Jinja filter"], 175 | "annotation": "Jinja filter", 176 | "details": "Filters a sequence of objects by applying a test to the specified attribute of each object, and rejecting the objects with the test succeeding.", 177 | }, 178 | { 179 | "trigger": "replace", 180 | "kind": ["markup", "f", "Jinja filter"], 181 | "annotation": "Jinja filter", 182 | "details": "Return a copy of the value with all occurrences of a substring replaced with a new one.", 183 | }, 184 | { 185 | "trigger": "reverse", 186 | "kind": ["markup", "f", "Jinja filter"], 187 | "annotation": "Jinja filter", 188 | "details": "Reverse the object or return an iterator that iterates over it the other way round.", 189 | }, 190 | { 191 | "trigger": "round", 192 | "kind": ["markup", "f", "Jinja filter"], 193 | "annotation": "Jinja filter", 194 | "details": "Round the number to a given precision.", 195 | }, 196 | { 197 | "trigger": "safe", 198 | "kind": ["markup", "f", "Jinja filter"], 199 | "annotation": "Jinja filter", 200 | "details": "Mark the value as safe which means that in an environment with automatic escaping enabled this variable will not be escaped.", 201 | }, 202 | { 203 | "trigger": "select", 204 | "kind": ["markup", "f", "Jinja filter"], 205 | "annotation": "Jinja filter", 206 | "details": "Filters a sequence of objects by applying a test to each object, and only selecting the objects with the test succeeding.", 207 | }, 208 | { 209 | "trigger": "selectattr", 210 | "kind": ["markup", "f", "Jinja filter"], 211 | "annotation": "Jinja filter", 212 | "details": "Filters a sequence of objects by applying a test to the specified attribute of each object, and only selecting the objects with the test succeeding.", 213 | }, 214 | { 215 | "trigger": "slice", 216 | "kind": ["markup", "f", "Jinja filter"], 217 | "annotation": "Jinja filter", 218 | "details": "Slice an iterator and return a list of lists containing those items.", 219 | }, 220 | { 221 | "trigger": "sort", 222 | "kind": ["markup", "f", "Jinja filter"], 223 | "annotation": "Jinja filter", 224 | "details": "Sort an iterable using Python’s sorted().", 225 | }, 226 | { 227 | "trigger": "string", 228 | "kind": ["markup", "f", "Jinja filter"], 229 | "annotation": "Jinja filter", 230 | "details": "Convert an object to a string if it isn’t already.", 231 | }, 232 | { 233 | "trigger": "striptags", 234 | "kind": ["markup", "f", "Jinja filter"], 235 | "annotation": "Jinja filter", 236 | "details": "Strip SGML/XML tags and replace adjacent whitespace by one space.", 237 | }, 238 | { 239 | "trigger": "sum", 240 | "kind": ["markup", "f", "Jinja filter"], 241 | "annotation": "Jinja filter", 242 | "details": "Returns the sum of a sequence of numbers plus the value of parameter ‘start’ (which defaults to 0).", 243 | }, 244 | { 245 | "trigger": "title", 246 | "kind": ["markup", "f", "Jinja filter"], 247 | "annotation": "Jinja filter", 248 | "details": "Return a title-cased version of the value.", 249 | }, 250 | { 251 | "trigger": "tojson", 252 | "kind": ["markup", "f", "Jinja filter"], 253 | "annotation": "Jinja filter", 254 | "details": "Serialize an object to a string of JSON, and mark it safe to render in HTML.", 255 | }, 256 | { 257 | "trigger": "trim", 258 | "kind": ["markup", "f", "Jinja filter"], 259 | "annotation": "Jinja filter", 260 | "details": "Strip leading and trailing characters, by default whitespace.", 261 | }, 262 | { 263 | "trigger": "truncate", 264 | "kind": ["markup", "f", "Jinja filter"], 265 | "annotation": "Jinja filter", 266 | "details": "Return a truncated copy of the string.", 267 | }, 268 | { 269 | "trigger": "unique", 270 | "kind": ["markup", "f", "Jinja filter"], 271 | "annotation": "Jinja filter", 272 | "details": "Returns a list of unique items from the given iterable.", 273 | }, 274 | { 275 | "trigger": "upper", 276 | "kind": ["markup", "f", "Jinja filter"], 277 | "annotation": "Jinja filter", 278 | "details": "Convert a value to uppercase.", 279 | }, 280 | { 281 | "trigger": "urlencode", 282 | "kind": ["markup", "f", "Jinja filter"], 283 | "annotation": "Jinja filter", 284 | "details": "Quote data for use in a URL path or query using UTF-8.", 285 | }, 286 | { 287 | "trigger": "urlize", 288 | "kind": ["markup", "f", "Jinja filter"], 289 | "annotation": "Jinja filter", 290 | "details": "Convert URLs in text into clickable links.", 291 | }, 292 | { 293 | "trigger": "wordcount", 294 | "kind": ["markup", "f", "Jinja filter"], 295 | "annotation": "Jinja filter", 296 | "details": "Count the words in that string.", 297 | }, 298 | { 299 | "trigger": "wordwrap", 300 | "kind": ["markup", "f", "Jinja filter"], 301 | "annotation": "Jinja filter", 302 | "details": "Wrap a string to the given width.", 303 | }, 304 | { 305 | "trigger": "xmlattr", 306 | "kind": ["markup", "f", "Jinja filter"], 307 | "annotation": "Jinja filter", 308 | "details": "Create an SGML/XML attribute string based on the items in a dict.", 309 | }, 310 | ], 311 | } 312 | -------------------------------------------------------------------------------- /Completions/Jinja Filters.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope": "source.jinja meta.filter - source.jinja meta.function-call.identifier", 3 | "completions": [ 4 | { 5 | "trigger": "abs", 6 | "contents": "abs()", 7 | "kind": ["markup", "f", "Jinja filter"], 8 | "annotation": "Jinja filter", 9 | "details": "Return the absolute value of the argument.", 10 | }, 11 | { 12 | "trigger": "attr", 13 | "contents": "attr()", 14 | "kind": ["markup", "f", "Jinja filter"], 15 | "annotation": "Jinja filter", 16 | "details": "Get an attribute of an object.", 17 | }, 18 | { 19 | "trigger": "batch", 20 | "contents": "batch()", 21 | "kind": ["markup", "f", "Jinja filter"], 22 | "annotation": "Jinja filter", 23 | "details": "A filter that batches items.", 24 | }, 25 | { 26 | "trigger": "capitalize", 27 | "contents": "capitalize()", 28 | "kind": ["markup", "f", "Jinja filter"], 29 | "annotation": "Jinja filter", 30 | "details": "Capitalize a value.", 31 | }, 32 | { 33 | "trigger": "center", 34 | "contents": "center()", 35 | "kind": ["markup", "f", "Jinja filter"], 36 | "annotation": "Jinja filter", 37 | "details": "Centers the value in a field of a given width.", 38 | }, 39 | { 40 | "trigger": "default", 41 | "contents": "default()", 42 | "kind": ["markup", "f", "Jinja filter"], 43 | "annotation": "Jinja filter", 44 | "details": "If the value is undefined it will return the passed default value, otherwise the value of the variable.", 45 | }, 46 | { 47 | "trigger": "dictsort", 48 | "contents": "dictsort()", 49 | "kind": ["markup", "f", "Jinja filter"], 50 | "annotation": "Jinja filter", 51 | "details": "Sort a dict and yield (key, value) pairs.", 52 | }, 53 | { 54 | "trigger": "escape", 55 | "contents": "escape()", 56 | "kind": ["markup", "f", "Jinja filter"], 57 | "annotation": "Jinja filter", 58 | "details": "Replace the characters &, <, >, ', and \" in the string with HTML-safe sequences.", 59 | }, 60 | { 61 | "trigger": "filesizeformat", 62 | "contents": "filesizeformat()", 63 | "kind": ["markup", "f", "Jinja filter"], 64 | "annotation": "Jinja filter", 65 | "details": "Format the value like a ‘human-readable’ file size.", 66 | }, 67 | { 68 | "trigger": "first", 69 | "contents": "first()", 70 | "kind": ["markup", "f", "Jinja filter"], 71 | "annotation": "Jinja filter", 72 | "details": "Return the first item of a sequence.", 73 | }, 74 | { 75 | "trigger": "float", 76 | "contents": "float()", 77 | "kind": ["markup", "f", "Jinja filter"], 78 | "annotation": "Jinja filter", 79 | "details": "Convert the value into a floating point number.", 80 | }, 81 | { 82 | "trigger": "forceescape", 83 | "contents": "forceescape()", 84 | "kind": ["markup", "f", "Jinja filter"], 85 | "annotation": "Jinja filter", 86 | "details": "Enforce HTML escaping.", 87 | }, 88 | { 89 | "trigger": "format", 90 | "contents": "format()", 91 | "kind": ["markup", "f", "Jinja filter"], 92 | "annotation": "Jinja filter", 93 | "details": "Apply the given values to a printf-style format string, like string % values.", 94 | }, 95 | { 96 | "trigger": "groupby", 97 | "contents": "groupby()", 98 | "kind": ["markup", "f", "Jinja filter"], 99 | "annotation": "Jinja filter", 100 | "details": "Group a sequence of objects by an attribute using Python’s itertools.groupby().", 101 | }, 102 | { 103 | "trigger": "indent", 104 | "contents": "indent()", 105 | "kind": ["markup", "f", "Jinja filter"], 106 | "annotation": "Jinja filter", 107 | "details": "Return a copy of the string with each line indented by 4 spaces.", 108 | }, 109 | { 110 | "trigger": "int", 111 | "contents": "int()", 112 | "kind": ["markup", "f", "Jinja filter"], 113 | "annotation": "Jinja filter", 114 | "details": "Convert the value into an integer.", 115 | }, 116 | { 117 | "trigger": "items", 118 | "contents": "items()", 119 | "kind": ["markup", "f", "Jinja filter"], 120 | "annotation": "Jinja filter", 121 | "details": "Return an iterator over the (key, value) items of a mapping.", 122 | }, 123 | { 124 | "trigger": "join", 125 | "contents": "join()", 126 | "kind": ["markup", "f", "Jinja filter"], 127 | "annotation": "Jinja filter", 128 | "details": "Return a string which is the concatenation of the strings in the sequence.", 129 | }, 130 | { 131 | "trigger": "last", 132 | "contents": "last()", 133 | "kind": ["markup", "f", "Jinja filter"], 134 | "annotation": "Jinja filter", 135 | "details": "Return the last item of a sequence.", 136 | }, 137 | { 138 | "trigger": "length", 139 | "contents": "length()", 140 | "kind": ["markup", "f", "Jinja filter"], 141 | "annotation": "Jinja filter", 142 | "details": "Return the number of items in a container.", 143 | }, 144 | { 145 | "trigger": "list", 146 | "contents": "list()", 147 | "kind": ["markup", "f", "Jinja filter"], 148 | "annotation": "Jinja filter", 149 | "details": "Convert the value into a list.", 150 | }, 151 | { 152 | "trigger": "lower", 153 | "contents": "lower()", 154 | "kind": ["markup", "f", "Jinja filter"], 155 | "annotation": "Jinja filter", 156 | "details": "Convert a value to lowercase.", 157 | }, 158 | { 159 | "trigger": "max", 160 | "contents": "max()", 161 | "kind": ["markup", "f", "Jinja filter"], 162 | "annotation": "Jinja filter", 163 | "details": "Return the largest item from the sequence.", 164 | }, 165 | { 166 | "trigger": "min", 167 | "contents": "min()", 168 | "kind": ["markup", "f", "Jinja filter"], 169 | "annotation": "Jinja filter", 170 | "details": "Return the smallest item from the sequence.", 171 | }, 172 | { 173 | "trigger": "map", 174 | "contents": "map()", 175 | "kind": ["markup", "f", "Jinja filter"], 176 | "annotation": "Jinja filter", 177 | "details": "Applies a filter on a sequence of objects or looks up an attribute.", 178 | }, 179 | { 180 | "trigger": "pprint", 181 | "contents": "pprint()", 182 | "kind": ["markup", "f", "Jinja filter"], 183 | "annotation": "Jinja filter", 184 | "details": "Pretty print a variable. Useful for debugging.", 185 | }, 186 | { 187 | "trigger": "random", 188 | "contents": "random()", 189 | "kind": ["markup", "f", "Jinja filter"], 190 | "annotation": "Jinja filter", 191 | "details": "Return a random item from the sequence.", 192 | }, 193 | { 194 | "trigger": "reject", 195 | "contents": "reject()", 196 | "kind": ["markup", "f", "Jinja filter"], 197 | "annotation": "Jinja filter", 198 | "details": "Filters a sequence of objects by applying a test to each object, and rejecting the objects with the test succeeding.", 199 | }, 200 | { 201 | "trigger": "rejectattr", 202 | "contents": "rejectattr()", 203 | "kind": ["markup", "f", "Jinja filter"], 204 | "annotation": "Jinja filter", 205 | "details": "Filters a sequence of objects by applying a test to the specified attribute of each object, and rejecting the objects with the test succeeding.", 206 | }, 207 | { 208 | "trigger": "replace", 209 | "contents": "replace()", 210 | "kind": ["markup", "f", "Jinja filter"], 211 | "annotation": "Jinja filter", 212 | "details": "Return a copy of the value with all occurrences of a substring replaced with a new one.", 213 | }, 214 | { 215 | "trigger": "reverse", 216 | "contents": "reverse()", 217 | "kind": ["markup", "f", "Jinja filter"], 218 | "annotation": "Jinja filter", 219 | "details": "Reverse the object or return an iterator that iterates over it the other way round.", 220 | }, 221 | { 222 | "trigger": "round", 223 | "contents": "round()", 224 | "kind": ["markup", "f", "Jinja filter"], 225 | "annotation": "Jinja filter", 226 | "details": "Round the number to a given precision.", 227 | }, 228 | { 229 | "trigger": "safe", 230 | "contents": "safe()", 231 | "kind": ["markup", "f", "Jinja filter"], 232 | "annotation": "Jinja filter", 233 | "details": "Mark the value as safe which means that in an environment with automatic escaping enabled this variable will not be escaped.", 234 | }, 235 | { 236 | "trigger": "select", 237 | "contents": "select()", 238 | "kind": ["markup", "f", "Jinja filter"], 239 | "annotation": "Jinja filter", 240 | "details": "Filters a sequence of objects by applying a test to each object, and only selecting the objects with the test succeeding.", 241 | }, 242 | { 243 | "trigger": "selectattr", 244 | "contents": "selectattr()", 245 | "kind": ["markup", "f", "Jinja filter"], 246 | "annotation": "Jinja filter", 247 | "details": "Filters a sequence of objects by applying a test to the specified attribute of each object, and only selecting the objects with the test succeeding.", 248 | }, 249 | { 250 | "trigger": "slice", 251 | "contents": "slice()", 252 | "kind": ["markup", "f", "Jinja filter"], 253 | "annotation": "Jinja filter", 254 | "details": "Slice an iterator and return a list of lists containing those items.", 255 | }, 256 | { 257 | "trigger": "sort", 258 | "contents": "sort()", 259 | "kind": ["markup", "f", "Jinja filter"], 260 | "annotation": "Jinja filter", 261 | "details": "Sort an iterable using Python’s sorted().", 262 | }, 263 | { 264 | "trigger": "string", 265 | "contents": "string()", 266 | "kind": ["markup", "f", "Jinja filter"], 267 | "annotation": "Jinja filter", 268 | "details": "Convert an object to a string if it isn’t already.", 269 | }, 270 | { 271 | "trigger": "striptags", 272 | "contents": "striptags()", 273 | "kind": ["markup", "f", "Jinja filter"], 274 | "annotation": "Jinja filter", 275 | "details": "Strip SGML/XML tags and replace adjacent whitespace by one space.", 276 | }, 277 | { 278 | "trigger": "sum", 279 | "contents": "sum()", 280 | "kind": ["markup", "f", "Jinja filter"], 281 | "annotation": "Jinja filter", 282 | "details": "Returns the sum of a sequence of numbers plus the value of parameter ‘start’ (which defaults to 0).", 283 | }, 284 | { 285 | "trigger": "title", 286 | "contents": "title()", 287 | "kind": ["markup", "f", "Jinja filter"], 288 | "annotation": "Jinja filter", 289 | "details": "Return a title-cased version of the value.", 290 | }, 291 | { 292 | "trigger": "tojson", 293 | "contents": "tojson()", 294 | "kind": ["markup", "f", "Jinja filter"], 295 | "annotation": "Jinja filter", 296 | "details": "Serialize an object to a string of JSON, and mark it safe to render in HTML.", 297 | }, 298 | { 299 | "trigger": "trim", 300 | "contents": "trim()", 301 | "kind": ["markup", "f", "Jinja filter"], 302 | "annotation": "Jinja filter", 303 | "details": "Strip leading and trailing characters, by default whitespace.", 304 | }, 305 | { 306 | "trigger": "truncate", 307 | "contents": "truncate()", 308 | "kind": ["markup", "f", "Jinja filter"], 309 | "annotation": "Jinja filter", 310 | "details": "Return a truncated copy of the string.", 311 | }, 312 | { 313 | "trigger": "unique", 314 | "contents": "unique()", 315 | "kind": ["markup", "f", "Jinja filter"], 316 | "annotation": "Jinja filter", 317 | "details": "Returns a list of unique items from the given iterable.", 318 | }, 319 | { 320 | "trigger": "upper", 321 | "contents": "upper()", 322 | "kind": ["markup", "f", "Jinja filter"], 323 | "annotation": "Jinja filter", 324 | "details": "Convert a value to uppercase.", 325 | }, 326 | { 327 | "trigger": "urlencode", 328 | "contents": "urlencode()", 329 | "kind": ["markup", "f", "Jinja filter"], 330 | "annotation": "Jinja filter", 331 | "details": "Quote data for use in a URL path or query using UTF-8.", 332 | }, 333 | { 334 | "trigger": "urlize", 335 | "contents": "urlize()", 336 | "kind": ["markup", "f", "Jinja filter"], 337 | "annotation": "Jinja filter", 338 | "details": "Convert URLs in text into clickable links.", 339 | }, 340 | { 341 | "trigger": "wordcount", 342 | "contents": "wordcount()", 343 | "kind": ["markup", "f", "Jinja filter"], 344 | "annotation": "Jinja filter", 345 | "details": "Count the words in that string.", 346 | }, 347 | { 348 | "trigger": "wordwrap", 349 | "contents": "wordwrap()", 350 | "kind": ["markup", "f", "Jinja filter"], 351 | "annotation": "Jinja filter", 352 | "details": "Wrap a string to the given width.", 353 | }, 354 | { 355 | "trigger": "xmlattr", 356 | "contents": "xmlattr()", 357 | "kind": ["markup", "f", "Jinja filter"], 358 | "annotation": "Jinja filter", 359 | "details": "Create an SGML/XML attribute string based on the items in a dict.", 360 | }, 361 | ], 362 | } 363 | -------------------------------------------------------------------------------- /Completions/Jinja Function Names.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | // Do not append redundant parentheses when completing within function calls 3 | "scope": "source.jinja meta.function-call.identifier", 4 | "completions": [ 5 | { 6 | "trigger": "range", 7 | "kind": ["function", "f", "Jinja function"], 8 | "annotation": "Jinja function", 9 | "details": "Return a list containing an arithmetic progression of integers.", 10 | }, 11 | { 12 | "trigger": "lipsum", 13 | "kind": ["function", "f", "Jinja function"], 14 | "annotation": "Jinja function", 15 | "details": "Generates some lorem ipsum for the template.", 16 | }, 17 | { 18 | "trigger": "dict", 19 | "kind": ["function", "f", "Jinja function"], 20 | "annotation": "Jinja function", 21 | "details": "A convenient alternative to dict literals.", 22 | }, 23 | { 24 | "trigger": "cycler", 25 | "kind": ["function", "f", "Jinja function"], 26 | "annotation": "Jinja function", 27 | "details": "Cycle through values by yielding them one at a time, then restarting once the end is reached.", 28 | }, 29 | { 30 | "trigger": "joiner", 31 | "kind": ["function", "f", "Jinja function"], 32 | "annotation": "Jinja function", 33 | "details": "A tiny helper that can be used to “join” multiple sections.", 34 | }, 35 | { 36 | "trigger": "namespace", 37 | "kind": ["function", "f", "Jinja function"], 38 | "annotation": "Jinja function", 39 | "details": "Creates a new container that allows attribute assignment using the {% set %} tag:", 40 | }, 41 | ], 42 | } 43 | -------------------------------------------------------------------------------- /Completions/Jinja Functions.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope": "source.jinja - source.jinja meta.function-call.identifier", 3 | "completions": [ 4 | { 5 | "trigger": "range", 6 | "contents": "range()", 7 | "kind": ["function", "f", "Jinja function"], 8 | "annotation": "Jinja function", 9 | "details": "Return a list containing an arithmetic progression of integers.", 10 | }, 11 | { 12 | "trigger": "lipsum", 13 | "contents": "lipsum()", 14 | "kind": ["function", "f", "Jinja function"], 15 | "annotation": "Jinja function", 16 | "details": "Generates some lorem ipsum for the template.", 17 | }, 18 | { 19 | "trigger": "dict", 20 | "contents": "dict()", 21 | "kind": ["function", "f", "Jinja function"], 22 | "annotation": "Jinja function", 23 | "details": "A convenient alternative to dict literals.", 24 | }, 25 | { 26 | "trigger": "cycler", 27 | "contents": "cycler()", 28 | "kind": ["function", "f", "Jinja function"], 29 | "annotation": "Jinja function", 30 | "details": "Cycle through values by yielding them one at a time, then restarting once the end is reached.", 31 | }, 32 | { 33 | "trigger": "joiner", 34 | "contents": "joiner()", 35 | "kind": ["function", "f", "Jinja function"], 36 | "annotation": "Jinja function", 37 | "details": "A tiny helper that can be used to “join” multiple sections.", 38 | }, 39 | { 40 | "trigger": "namespace", 41 | "contents": "namespace()", 42 | "kind": ["function", "f", "Jinja function"], 43 | "annotation": "Jinja function", 44 | "details": "Creates a new container that allows attribute assignment using the {% set %} tag:", 45 | }, 46 | ], 47 | } 48 | -------------------------------------------------------------------------------- /Completions/Jinja Loops.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope": "source.jinja", 3 | "completions": [ 4 | { 5 | "trigger": "loop.index", 6 | "contents": "loop.index", 7 | "kind": ["variable", "v", "Jinja Loop Variable"], 8 | "annotation": "Loop Variable", 9 | "details": "The current iteration of the loop (1 indexed).", 10 | }, 11 | { 12 | "trigger": "loop.index0", 13 | "contents": "loop.index0", 14 | "kind": ["variable", "v", "Jinja Loop Variable"], 15 | "annotation": "Loop Variable", 16 | "details": "The current iteration of the loop (0 indexed).", 17 | }, 18 | { 19 | "trigger": "loop.revindex", 20 | "contents": "loop.revindex", 21 | "kind": ["variable", "v", "Jinja Loop Variable"], 22 | "annotation": "Loop Variable", 23 | "details": "The number of iterations from the end of the loop (1 indexed).", 24 | }, 25 | { 26 | "trigger": "loop.revindex0", 27 | "contents": "loop.revindex0", 28 | "kind": ["variable", "v", "Jinja Loop Variable"], 29 | "annotation": "Loop Variable", 30 | "details": "The number of iterations from the end of the loop (0 indexed).", 31 | }, 32 | { 33 | "trigger": "loop.first", 34 | "contents": "loop.first", 35 | "kind": ["variable", "v", "Jinja Loop Variable"], 36 | "annotation": "Loop Variable", 37 | "details": "True if first iteration.", 38 | }, 39 | { 40 | "trigger": "loop.last", 41 | "contents": "loop.last", 42 | "kind": ["variable", "v", "Jinja Loop Variable"], 43 | "annotation": "Loop Variable", 44 | "details": "True if last iteration.", 45 | }, 46 | { 47 | "trigger": "loop.length", 48 | "contents": "loop.length", 49 | "kind": ["variable", "v", "Jinja Loop Variable"], 50 | "annotation": "Loop Variable", 51 | "details": "The number of items in the sequence.", 52 | }, 53 | { 54 | "trigger": "loop.cycle", 55 | "contents": "loop.cycle", 56 | "kind": ["variable", "v", "Jinja Loop Variable"], 57 | "annotation": "Loop Variable", 58 | "details": "A helper function to cycle between a list of sequences.", 59 | }, 60 | { 61 | "trigger": "loop.depth", 62 | "contents": "loop.depth", 63 | "kind": ["variable", "v", "Jinja Loop Variable"], 64 | "annotation": "Loop Variable", 65 | "details": "Indicates how deep in a recursive loop the rendering currently is. Starts at level 1.", 66 | }, 67 | { 68 | "trigger": "loop.depth0", 69 | "contents": "loop.depth0", 70 | "kind": ["variable", "v", "Jinja Loop Variable"], 71 | "annotation": "Loop Variable", 72 | "details": "Indicates how deep in a recursive loop the rendering currently is. Starts at level 0.", 73 | }, 74 | { 75 | "trigger": "loop.previtem", 76 | "contents": "loop.previtem", 77 | "kind": ["variable", "v", "Jinja Loop Variable"], 78 | "annotation": "Loop Variable", 79 | "details": "The item from the previous iteration of the loop. Undefined during the first iteration.", 80 | }, 81 | { 82 | "trigger": "loop.nextitem", 83 | "contents": "loop.nextitem", 84 | "kind": ["variable", "v", "Jinja Loop Variable"], 85 | "annotation": "Loop Variable", 86 | "details": "The item from the following iteration of the loop. Undefined during the first iteration.", 87 | }, 88 | { 89 | "trigger": "loop.changed", 90 | "contents": "loop.changed()", 91 | "kind": ["variable", "v", "Jinja Loop Variable"], 92 | "annotation": "Loop Variable", 93 | "details": "True if previously called with a different value (or not called at all).", 94 | }, 95 | ], 96 | } 97 | -------------------------------------------------------------------------------- /Completions/Jinja Tags.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope": "source.jinja", 3 | "completions": [ 4 | { 5 | "trigger": "for", 6 | "contents": "for", 7 | "kind": ["snippet", "t", "Jinja tag"], 8 | "annotation": "Jinja tag", 9 | "details": "A tag to loop over an iterable.", 10 | }, 11 | { 12 | "trigger": "if", 13 | "contents": "if", 14 | "kind": ["snippet", "t", "Jinja tag"], 15 | "annotation": "Jinja tag", 16 | "details": "A tag to execute conditional statements.", 17 | }, 18 | { 19 | "trigger": "raw", 20 | "contents": "raw", 21 | "kind": ["snippet", "t", "Jinja tag"], 22 | "annotation": "Jinja tag", 23 | "details": "A tag to escape any Jinja code.", 24 | }, 25 | { 26 | "trigger": "block", 27 | "contents": "block", 28 | "kind": ["snippet", "t", "Jinja tag"], 29 | "annotation": "Jinja tag", 30 | "details": "A tag to define a section to be used.", 31 | }, 32 | { 33 | "trigger": "extends", 34 | "contents": "extends", 35 | "kind": ["snippet", "t", "Jinja tag"], 36 | "annotation": "Jinja tag", 37 | "details": "A tag to extend one template from another.", 38 | }, 39 | { 40 | "trigger": "macro", 41 | "contents": "macro", 42 | "kind": ["snippet", "t", "Jinja tag"], 43 | "annotation": "Jinja tag", 44 | "details": "A tag to define reusable functions.", 45 | }, 46 | { 47 | "trigger": "call", 48 | "contents": "call", 49 | "kind": ["snippet", "t", "Jinja tag"], 50 | "annotation": "Jinja tag", 51 | "details": "A tag to pass one macro into another.", 52 | }, 53 | { 54 | "trigger": "filter", 55 | "contents": "filter", 56 | "kind": ["snippet", "t", "Jinja tag"], 57 | "annotation": "Jinja tag", 58 | "details": "A tag to apply Jinja filters on a block of template data.", 59 | }, 60 | { 61 | "trigger": "set", 62 | "contents": "set", 63 | "kind": ["snippet", "t", "Jinja tag"], 64 | "annotation": "Jinja tag", 65 | "details": "A tag to set the value of a variable.", 66 | }, 67 | { 68 | "trigger": "include", 69 | "contents": "include", 70 | "kind": ["snippet", "t", "Jinja tag"], 71 | "annotation": "Jinja tag", 72 | "details": "A tag to include a piece of template defined in another file.", 73 | }, 74 | { 75 | "trigger": "pluralize", 76 | "contents": "pluralize", 77 | "kind": ["snippet", "t", "Jinja tag"], 78 | "annotation": "Jinja tag", 79 | "details": "A tag to pluralize.", 80 | }, 81 | { 82 | "trigger": "trans", 83 | "contents": "trans", 84 | "kind": ["snippet", "t", "Jinja tag"], 85 | "annotation": "Jinja tag", 86 | "details": "A tag to mark a section as translatable.", 87 | }, 88 | { 89 | "trigger": "do", 90 | "contents": "do", 91 | "kind": ["snippet", "t", "Jinja tag"], 92 | "annotation": "Jinja tag", 93 | "details": "A tag.", 94 | }, 95 | { 96 | "trigger": "debug", 97 | "contents": "debug", 98 | "kind": ["snippet", "t", "Jinja tag"], 99 | "annotation": "Jinja tag", 100 | "details": "A tag to dump the current context, filters & tests. Useful for debugging.", 101 | }, 102 | { 103 | "trigger": "with", 104 | "contents": "with", 105 | "kind": ["snippet", "t", "Jinja tag"], 106 | "annotation": "Jinja tag", 107 | "details": "A tag to create a new inner scope.", 108 | }, 109 | { 110 | "trigger": "autoescape", 111 | "contents": "autoescape", 112 | "kind": ["snippet", "t", "Jinja tag"], 113 | "annotation": "Jinja tag", 114 | "details": "A tag for autoescaping.", 115 | }, 116 | { 117 | "trigger": "endautoescape", 118 | "contents": "endautoescape", 119 | "kind": ["snippet", "t", "Jinja tag"], 120 | "annotation": "Jinja tag", 121 | "details": "Ending tag for autoescape tag.", 122 | }, 123 | { 124 | "trigger": "endwith", 125 | "contents": "endwith", 126 | "kind": ["snippet", "t", "Jinja tag"], 127 | "annotation": "Jinja tag", 128 | "details": "Ending tag for with tag.", 129 | }, 130 | { 131 | "trigger": "endtrans", 132 | "contents": "endtrans", 133 | "kind": ["snippet", "t", "Jinja tag"], 134 | "annotation": "Jinja tag", 135 | "details": "Ending tag for trans tag.", 136 | }, 137 | { 138 | "trigger": "endset", 139 | "contents": "endset", 140 | "kind": ["snippet", "t", "Jinja tag"], 141 | "annotation": "Jinja tag", 142 | "details": "Ending tag for set tag.", 143 | }, 144 | { 145 | "trigger": "endfilter", 146 | "contents": "endfilter", 147 | "kind": ["snippet", "t", "Jinja tag"], 148 | "annotation": "Jinja tag", 149 | "details": "Ending tag for filter tag.", 150 | }, 151 | { 152 | "trigger": "endcall", 153 | "contents": "endcall", 154 | "kind": ["snippet", "t", "Jinja tag"], 155 | "annotation": "Jinja tag", 156 | "details": "Ending tag for call tag.", 157 | }, 158 | { 159 | "trigger": "endmacro", 160 | "contents": "endmacro", 161 | "kind": ["snippet", "t", "Jinja tag"], 162 | "annotation": "Jinja tag", 163 | "details": "Ending tag for macro tag.", 164 | }, 165 | { 166 | "trigger": "endblock", 167 | "contents": "endblock", 168 | "kind": ["snippet", "t", "Jinja tag"], 169 | "annotation": "Jinja tag", 170 | "details": "Ending tag for block tag.", 171 | }, 172 | { 173 | "trigger": "endraw", 174 | "contents": "endraw", 175 | "kind": ["snippet", "t", "Jinja tag"], 176 | "annotation": "Jinja tag", 177 | "details": "Ending tag for raw tag.", 178 | }, 179 | { 180 | "trigger": "endif", 181 | "contents": "endif", 182 | "kind": ["snippet", "t", "Jinja tag"], 183 | "annotation": "Jinja tag", 184 | "details": "Ending tag for if tag.", 185 | }, 186 | { 187 | "trigger": "endfor", 188 | "contents": "endfor", 189 | "kind": ["snippet", "t", "Jinja tag"], 190 | "annotation": "Jinja tag", 191 | "details": "Ending tag for for tag.", 192 | }, 193 | ], 194 | } 195 | -------------------------------------------------------------------------------- /Completions/Jinja Test Names.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope": "source.jinja meta.function-call.identifier", 3 | "completions": [ 4 | { 5 | "trigger": "boolean", 6 | "kind": ["namespace", "t", "Jinja test"], 7 | "annotation": "Jinja test", 8 | "details": "Return true if the object is a boolean value.", 9 | }, 10 | { 11 | "trigger": "callable", 12 | "kind": ["namespace", "t", "Jinja test"], 13 | "annotation": "Jinja test", 14 | "details": "Return whether the object is callable.", 15 | }, 16 | { 17 | "trigger": "defined", 18 | "kind": ["namespace", "t", "Jinja test"], 19 | "annotation": "Jinja test", 20 | "details": "Return true if the variable is defined.", 21 | }, 22 | { 23 | "trigger": "divisibleby", 24 | "kind": ["namespace", "t", "Jinja test"], 25 | "annotation": "Jinja test", 26 | "details": "Check if a variable is divisible by a number.", 27 | }, 28 | { 29 | "trigger": "eq", 30 | "kind": ["namespace", "t", "Jinja test"], 31 | "annotation": "Jinja test", 32 | "details": "Same as a == b.", 33 | }, 34 | { 35 | "trigger": "escaped", 36 | "kind": ["namespace", "t", "Jinja test"], 37 | "annotation": "Jinja test", 38 | "details": "Check if the value is escaped.", 39 | }, 40 | { 41 | "trigger": "even", 42 | "kind": ["namespace", "t", "Jinja test"], 43 | "annotation": "Jinja test", 44 | "details": "Return true if the variable is even.", 45 | }, 46 | { 47 | "trigger": "false", 48 | "kind": ["namespace", "t", "Jinja test"], 49 | "annotation": "Jinja test", 50 | "details": "Return true if the object is False.", 51 | }, 52 | { 53 | "trigger": "filter", 54 | "kind": ["namespace", "t", "Jinja test"], 55 | "annotation": "Jinja test", 56 | "details": "Check if a filter exists by name.", 57 | }, 58 | { 59 | "trigger": "float", 60 | "kind": ["namespace", "t", "Jinja test"], 61 | "annotation": "Jinja test", 62 | "details": "Return true if the object is a float.", 63 | }, 64 | { 65 | "trigger": "ge", 66 | "kind": ["namespace", "t", "Jinja test"], 67 | "annotation": "Jinja test", 68 | "details": "Same as a >= b.", 69 | }, 70 | { 71 | "trigger": "gt", 72 | "kind": ["namespace", "t", "Jinja test"], 73 | "annotation": "Jinja test", 74 | "details": "Same as a > b.", 75 | }, 76 | { 77 | "trigger": "in", 78 | "kind": ["namespace", "t", "Jinja test"], 79 | "annotation": "Jinja test", 80 | "details": "Check if value is in sequence.", 81 | }, 82 | { 83 | "trigger": "integer", 84 | "kind": ["namespace", "t", "Jinja test"], 85 | "annotation": "Jinja test", 86 | "details": "Return true if the object is an integer.", 87 | }, 88 | { 89 | "trigger": "iterable", 90 | "kind": ["namespace", "t", "Jinja test"], 91 | "annotation": "Jinja test", 92 | "details": "Check if it’s possible to iterate over an object.", 93 | }, 94 | { 95 | "trigger": "le", 96 | "kind": ["namespace", "t", "Jinja test"], 97 | "annotation": "Jinja test", 98 | "details": "Same as a <= b.", 99 | }, 100 | { 101 | "trigger": "lower", 102 | "kind": ["namespace", "t", "Jinja test"], 103 | "annotation": "Jinja test", 104 | "details": "Return true if the variable is lowercased.", 105 | }, 106 | { 107 | "trigger": "lt", 108 | "kind": ["namespace", "t", "Jinja test"], 109 | "annotation": "Jinja test", 110 | "details": "Same as a < b.", 111 | }, 112 | { 113 | "trigger": "mapping", 114 | "kind": ["namespace", "t", "Jinja test"], 115 | "annotation": "Jinja test", 116 | "details": "Return true if the object is a mapping (dict etc.).", 117 | }, 118 | { 119 | "trigger": "ne", 120 | "kind": ["namespace", "t", "Jinja test"], 121 | "annotation": "Jinja test", 122 | "details": "Same as a != b.", 123 | }, 124 | { 125 | "trigger": "none", 126 | "kind": ["namespace", "t", "Jinja test"], 127 | "annotation": "Jinja test", 128 | "details": "Return true if the variable is none.", 129 | }, 130 | { 131 | "trigger": "number", 132 | "kind": ["namespace", "t", "Jinja test"], 133 | "annotation": "Jinja test", 134 | "details": "Return true if the variable is a number.", 135 | }, 136 | { 137 | "trigger": "odd", 138 | "kind": ["namespace", "t", "Jinja test"], 139 | "annotation": "Jinja test", 140 | "details": "Return true if the variable is odd.", 141 | }, 142 | { 143 | "trigger": "sameas", 144 | "kind": ["namespace", "t", "Jinja test"], 145 | "annotation": "Jinja test", 146 | "details": "Check if an object points to the same memory address than another object.", 147 | }, 148 | { 149 | "trigger": "sequence", 150 | "kind": ["namespace", "t", "Jinja test"], 151 | "annotation": "Jinja test", 152 | "details": "Return true if the variable is a sequence (iterables).", 153 | }, 154 | { 155 | "trigger": "string", 156 | "kind": ["namespace", "t", "Jinja test"], 157 | "annotation": "Jinja test", 158 | "details": "Return true if the object is a string.", 159 | }, 160 | { 161 | "trigger": "test", 162 | "kind": ["namespace", "t", "Jinja test"], 163 | "annotation": "Jinja test", 164 | "details": "Check if a test exists by name.", 165 | }, 166 | { 167 | "trigger": "true", 168 | "kind": ["namespace", "t", "Jinja test"], 169 | "annotation": "Jinja test", 170 | "details": "Return true if the object is True.", 171 | }, 172 | { 173 | "trigger": "undefined", 174 | "kind": ["namespace", "t", "Jinja test"], 175 | "annotation": "Jinja test", 176 | "details": "Return true if the variable is defined.", 177 | }, 178 | { 179 | "trigger": "upper", 180 | "kind": ["namespace", "t", "Jinja test"], 181 | "annotation": "Jinja test", 182 | "details": "Return true if the variable is upper-cased.", 183 | }, 184 | ], 185 | } 186 | -------------------------------------------------------------------------------- /Completions/Jinja Tests.sublime-completions: -------------------------------------------------------------------------------- 1 | { 2 | "scope": "source.jinja - source.jinja meta.function-call.identifier", 3 | "completions": [ 4 | { 5 | "trigger": "boolean", 6 | "contents": "boolean()", 7 | "kind": ["namespace", "t", "Jinja test"], 8 | "annotation": "Jinja test", 9 | "details": "Return true if the object is a boolean value.", 10 | }, 11 | { 12 | "trigger": "callable", 13 | "contents": "callable()", 14 | "kind": ["namespace", "t", "Jinja test"], 15 | "annotation": "Jinja test", 16 | "details": "Return whether the object is callable.", 17 | }, 18 | { 19 | "trigger": "defined", 20 | "contents": "defined()", 21 | "kind": ["namespace", "t", "Jinja test"], 22 | "annotation": "Jinja test", 23 | "details": "Return true if the variable is defined.", 24 | }, 25 | { 26 | "trigger": "divisibleby", 27 | "contents": "divisibleby()", 28 | "kind": ["namespace", "t", "Jinja test"], 29 | "annotation": "Jinja test", 30 | "details": "Check if a variable is divisible by a number.", 31 | }, 32 | { 33 | "trigger": "eq", 34 | "contents": "eq()", 35 | "kind": ["namespace", "t", "Jinja test"], 36 | "annotation": "Jinja test", 37 | "details": "Same as a == b.", 38 | }, 39 | { 40 | "trigger": "escaped", 41 | "contents": "escaped()", 42 | "kind": ["namespace", "t", "Jinja test"], 43 | "annotation": "Jinja test", 44 | "details": "Check if the value is escaped.", 45 | }, 46 | { 47 | "trigger": "even", 48 | "contents": "even()", 49 | "kind": ["namespace", "t", "Jinja test"], 50 | "annotation": "Jinja test", 51 | "details": "Return true if the variable is even.", 52 | }, 53 | { 54 | "trigger": "false", 55 | "contents": "false()", 56 | "kind": ["namespace", "t", "Jinja test"], 57 | "annotation": "Jinja test", 58 | "details": "Return true if the object is False.", 59 | }, 60 | { 61 | "trigger": "filter", 62 | "contents": "filter()", 63 | "kind": ["namespace", "t", "Jinja test"], 64 | "annotation": "Jinja test", 65 | "details": "Check if a filter exists by name.", 66 | }, 67 | { 68 | "trigger": "float", 69 | "contents": "float()", 70 | "kind": ["namespace", "t", "Jinja test"], 71 | "annotation": "Jinja test", 72 | "details": "Return true if the object is a float.", 73 | }, 74 | { 75 | "trigger": "ge", 76 | "contents": "ge()", 77 | "kind": ["namespace", "t", "Jinja test"], 78 | "annotation": "Jinja test", 79 | "details": "Same as a >= b.", 80 | }, 81 | { 82 | "trigger": "gt", 83 | "contents": "gt()", 84 | "kind": ["namespace", "t", "Jinja test"], 85 | "annotation": "Jinja test", 86 | "details": "Same as a > b.", 87 | }, 88 | { 89 | "trigger": "in", 90 | "contents": "in()", 91 | "kind": ["namespace", "t", "Jinja test"], 92 | "annotation": "Jinja test", 93 | "details": "Check if value is in sequence.", 94 | }, 95 | { 96 | "trigger": "integer", 97 | "contents": "integer()", 98 | "kind": ["namespace", "t", "Jinja test"], 99 | "annotation": "Jinja test", 100 | "details": "Return true if the object is an integer.", 101 | }, 102 | { 103 | "trigger": "iterable", 104 | "contents": "iterable()", 105 | "kind": ["namespace", "t", "Jinja test"], 106 | "annotation": "Jinja test", 107 | "details": "Check if it’s possible to iterate over an object.", 108 | }, 109 | { 110 | "trigger": "le", 111 | "contents": "le()", 112 | "kind": ["namespace", "t", "Jinja test"], 113 | "annotation": "Jinja test", 114 | "details": "Same as a <= b.", 115 | }, 116 | { 117 | "trigger": "lower", 118 | "contents": "lower()", 119 | "kind": ["namespace", "t", "Jinja test"], 120 | "annotation": "Jinja test", 121 | "details": "Return true if the variable is lowercased.", 122 | }, 123 | { 124 | "trigger": "lt", 125 | "contents": "lt()", 126 | "kind": ["namespace", "t", "Jinja test"], 127 | "annotation": "Jinja test", 128 | "details": "Same as a < b.", 129 | }, 130 | { 131 | "trigger": "mapping", 132 | "contents": "mapping()", 133 | "kind": ["namespace", "t", "Jinja test"], 134 | "annotation": "Jinja test", 135 | "details": "Return true if the object is a mapping (dict etc.).", 136 | }, 137 | { 138 | "trigger": "ne", 139 | "contents": "ne()", 140 | "kind": ["namespace", "t", "Jinja test"], 141 | "annotation": "Jinja test", 142 | "details": "Same as a != b.", 143 | }, 144 | { 145 | "trigger": "none", 146 | "contents": "none()", 147 | "kind": ["namespace", "t", "Jinja test"], 148 | "annotation": "Jinja test", 149 | "details": "Return true if the variable is none.", 150 | }, 151 | { 152 | "trigger": "number", 153 | "contents": "number()", 154 | "kind": ["namespace", "t", "Jinja test"], 155 | "annotation": "Jinja test", 156 | "details": "Return true if the variable is a number.", 157 | }, 158 | { 159 | "trigger": "odd", 160 | "contents": "odd()", 161 | "kind": ["namespace", "t", "Jinja test"], 162 | "annotation": "Jinja test", 163 | "details": "Return true if the variable is odd.", 164 | }, 165 | { 166 | "trigger": "sameas", 167 | "contents": "sameas()", 168 | "kind": ["namespace", "t", "Jinja test"], 169 | "annotation": "Jinja test", 170 | "details": "Check if an object points to the same memory address than another object.", 171 | }, 172 | { 173 | "trigger": "sequence", 174 | "contents": "sequence()", 175 | "kind": ["namespace", "t", "Jinja test"], 176 | "annotation": "Jinja test", 177 | "details": "Return true if the variable is a sequence (iterables).", 178 | }, 179 | { 180 | "trigger": "string", 181 | "contents": "string()", 182 | "kind": ["namespace", "t", "Jinja test"], 183 | "annotation": "Jinja test", 184 | "details": "Return true if the object is a string.", 185 | }, 186 | { 187 | "trigger": "test", 188 | "contents": "test()", 189 | "kind": ["namespace", "t", "Jinja test"], 190 | "annotation": "Jinja test", 191 | "details": "Check if a test exists by name.", 192 | }, 193 | { 194 | "trigger": "true", 195 | "contents": "true()", 196 | "kind": ["namespace", "t", "Jinja test"], 197 | "annotation": "Jinja test", 198 | "details": "Return true if the object is True.", 199 | }, 200 | { 201 | "trigger": "undefined", 202 | "contents": "undefined()", 203 | "kind": ["namespace", "t", "Jinja test"], 204 | "annotation": "Jinja test", 205 | "details": "Return true if the variable is defined.", 206 | }, 207 | { 208 | "trigger": "upper", 209 | "contents": "upper()", 210 | "kind": ["namespace", "t", "Jinja test"], 211 | "annotation": "Jinja test", 212 | "details": "Return true if the variable is upper-cased.", 213 | }, 214 | ], 215 | } 216 | -------------------------------------------------------------------------------- /Default.sublime-commands: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "caption": "Preferences: Jinja2 Key Bindings", 4 | "command": "edit_settings", 5 | "args": { 6 | "base_file": "${packages}/Jinja2/Default.sublime-keymap", 7 | "user_file": "${packages}/User/Default ($platform).sublime-keymap", 8 | "default": "[\n\t${0}\n]\n" 9 | } 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /Default.sublime-keymap: -------------------------------------------------------------------------------- 1 | [ 2 | // Auto-pair braces also in front of , : ; so starting embeddings in CSS properties and values works well. 3 | 4 | { 5 | "keys": ["{"], 6 | "command": "insert_snippet", 7 | "args": { 8 | "contents": "{$0}" 9 | }, 10 | "context": [ 11 | { "key": "selector", "operand": "meta.template.jinja - meta.template.jinja meta.embedded - meta.template.jinja string" }, 12 | { "key": "setting.auto_match_enabled" }, 13 | { "key": "selection_empty", "match_all": true }, 14 | { "key": "following_text", "operator": "regex_contains", "operand": "^(?:[ \t\\)\\]\\},:;]|$)", "match_all": true } 15 | ] 16 | }, 17 | 18 | // Auto-pair braces also in front of closing ' and " in strings 19 | 20 | { 21 | "keys": ["{"], 22 | "command": "insert_snippet", 23 | "args": { 24 | "contents": "{$0}" 25 | }, 26 | "context": [ 27 | { "key": "selector", "operand": "meta.template.jinja string" }, 28 | { "key": "setting.auto_match_enabled" }, 29 | { "key": "selection_empty", "match_all": true }, 30 | { "key": "following_text", "operator": "regex_contains", "operand": "^(?:[ \t\\)\\]\\}\"',:;]|$)", "match_all": true } 31 | ] 32 | }, 33 | 34 | // Bindings for inserting and removing comment block. 35 | 36 | // Expand {|} to {# | #} when # is pressed 37 | { 38 | "keys": ["#"], 39 | "command": "insert_snippet", 40 | "args": { 41 | "contents": "# ${0} #" 42 | }, 43 | "context": [ 44 | { "key": "selector", "operand": "meta.template.jinja - meta.template.jinja meta.embedded" }, 45 | { "key": "setting.auto_match_enabled" }, 46 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{$", "match_all": true }, 47 | { "key": "following_text", "operator": "regex_contains", "operand": "^}", "match_all": true } 48 | ] 49 | }, 50 | // Reduce {#|#} to | when backspace is pressed 51 | { 52 | "keys": ["backspace"], 53 | "command": "chain", 54 | "args": { 55 | "commands": [ 56 | {"command": "left_delete" }, 57 | {"command": "right_delete" }, 58 | {"command": "left_delete" }, 59 | {"command": "right_delete" } 60 | ] 61 | }, 62 | "context": [ 63 | { "key": "selector", "operand": "meta.embedded.comment.jinja" }, 64 | { "key": "setting.auto_match_enabled" }, 65 | { "key": "selection_empty", "match_all": true }, 66 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{#$", "match_all": true }, 67 | { "key": "following_text", "operator": "regex_contains", "operand": "^#}", "match_all": true } 68 | ] 69 | }, 70 | // Expand {#|#} to {# | #} when space is pressed 71 | { 72 | "keys": [" "], 73 | "command": "insert_snippet", 74 | "args": { 75 | "contents": " ${0} " 76 | }, 77 | "context": [ 78 | { "key": "selector", "operand": "meta.embedded.comment.jinja" }, 79 | { "key": "setting.auto_match_enabled" }, 80 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{#$", "match_all": true }, 81 | { "key": "following_text", "operator": "regex_contains", "operand": "^#}", "match_all": true } 82 | ] 83 | }, 84 | // Reduce {# | #} to {#|#} when backspace is pressed 85 | { 86 | "keys": ["backspace"], 87 | "command": "chain", 88 | "args": { 89 | "commands": [ 90 | {"command": "left_delete" }, 91 | {"command": "right_delete" } 92 | ] 93 | }, 94 | "context": [ 95 | { "key": "selector", "operand": "meta.embedded.comment.jinja" }, 96 | { "key": "setting.auto_match_enabled" }, 97 | { "key": "selection_empty", "match_all": true }, 98 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{# $", "match_all": true }, 99 | { "key": "following_text", "operator": "regex_contains", "operand": "^ #}", "match_all": true } 100 | ] 101 | }, 102 | 103 | // Bindings for inserting and removing statement block. 104 | 105 | // Expand {|} to {% | %} when % is pressed 106 | { 107 | "keys": ["%"], 108 | "command": "insert_snippet", 109 | "args": { 110 | "contents": "% ${0} %" 111 | }, 112 | "context": [ 113 | { "key": "selector", "operand": "meta.template.jinja - meta.template.jinja meta.embedded" }, 114 | { "key": "setting.auto_match_enabled" }, 115 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{$", "match_all": true }, 116 | { "key": "following_text", "operator": "regex_contains", "operand": "^}", "match_all": true } 117 | ] 118 | }, 119 | // Reduce {%|%} to | when backspace is pressed 120 | { 121 | "keys": ["backspace"], 122 | "command": "chain", 123 | "args": { 124 | "commands": [ 125 | {"command": "left_delete" }, 126 | {"command": "right_delete" }, 127 | {"command": "left_delete" }, 128 | {"command": "right_delete" } 129 | ] 130 | }, 131 | "context": [ 132 | { "key": "selector", "operand": "meta.embedded.statement.jinja" }, 133 | { "key": "setting.auto_match_enabled" }, 134 | { "key": "selection_empty", "match_all": true }, 135 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{%$", "match_all": true }, 136 | { "key": "following_text", "operator": "regex_contains", "operand": "^%}", "match_all": true } 137 | ] 138 | }, 139 | // Expand {%|%} to {% | %} when space is pressed 140 | { 141 | "keys": [" "], 142 | "command": "insert_snippet", 143 | "args": { 144 | "contents": " ${0} " 145 | }, 146 | "context": [ 147 | { "key": "selector", "operand": "meta.embedded.statement.jinja" }, 148 | { "key": "setting.auto_match_enabled" }, 149 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{%$", "match_all": true }, 150 | { "key": "following_text", "operator": "regex_contains", "operand": "^%}", "match_all": true } 151 | ] 152 | }, 153 | // Reduce {% | %} to {%|%} when backspace is pressed 154 | { 155 | "keys": ["backspace"], 156 | "command": "chain", 157 | "args": { 158 | "commands": [ 159 | {"command": "left_delete" }, 160 | {"command": "right_delete" } 161 | ] 162 | }, 163 | "context": [ 164 | { "key": "selector", "operand": "meta.embedded.statement.jinja" }, 165 | { "key": "setting.auto_match_enabled" }, 166 | { "key": "selection_empty", "match_all": true }, 167 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{% $", "match_all": true }, 168 | { "key": "following_text", "operator": "regex_contains", "operand": "^ %}", "match_all": true } 169 | ] 170 | }, 171 | 172 | // Bindings for inserting and removing expression block. 173 | 174 | // Expand {|} to {{ | }} when { is pressed 175 | { 176 | "keys": ["{"], 177 | "command": "insert_snippet", 178 | "args": { 179 | "contents": "{ ${0} }" 180 | }, 181 | "context": [ 182 | { "key": "selector", "operand": "meta.template.jinja - meta.template.jinja meta.embedded" }, 183 | { "key": "setting.auto_match_enabled" }, 184 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{$", "match_all": true }, 185 | { "key": "following_text", "operator": "regex_contains", "operand": "^}", "match_all": true } 186 | ] 187 | }, 188 | // Reduce {{|}} to | when backspace is pressed 189 | { 190 | "keys": ["backspace"], 191 | "command": "chain", 192 | "args": { 193 | "commands": [ 194 | {"command": "left_delete" }, 195 | {"command": "right_delete" }, 196 | {"command": "left_delete" }, 197 | {"command": "right_delete" } 198 | ] 199 | }, 200 | "context": [ 201 | { "key": "selector", "operand": "meta.embedded.expression.jinja" }, 202 | { "key": "setting.auto_match_enabled" }, 203 | { "key": "selection_empty", "match_all": true }, 204 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{{$", "match_all": true }, 205 | { "key": "following_text", "operator": "regex_contains", "operand": "^}}", "match_all": true } 206 | ] 207 | }, 208 | // Expand {{|}} to {{ | }} when space is pressed 209 | { 210 | "keys": [" "], 211 | "command": "insert_snippet", 212 | "args": { 213 | "contents": " ${0} " 214 | }, 215 | "context": [ 216 | { "key": "selector", "operand": "meta.embedded.statement.jinja" }, 217 | { "key": "setting.auto_match_enabled" }, 218 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{{$", "match_all": true }, 219 | { "key": "following_text", "operator": "regex_contains", "operand": "^}}", "match_all": true } 220 | ] 221 | }, 222 | // Reduce {{ | }} to {{|}} when backspace is pressed 223 | { 224 | "keys": ["backspace"], 225 | "command": "chain", 226 | "args": { 227 | "commands": [ 228 | {"command": "left_delete" }, 229 | {"command": "right_delete" } 230 | ] 231 | }, 232 | "context": [ 233 | { "key": "selector", "operand": "meta.embedded.expression.jinja" }, 234 | { "key": "setting.auto_match_enabled" }, 235 | { "key": "selection_empty", "match_all": true }, 236 | { "key": "preceding_text", "operator": "regex_contains", "operand": "{{ $", "match_all": true }, 237 | { "key": "following_text", "operator": "regex_contains", "operand": "^ }}", "match_all": true } 238 | ] 239 | }, 240 | { 241 | "keys": ["enter"], 242 | "command": "run_macro_file", 243 | "args": {"file": "res://Packages/Default/Add Line in Braces.sublime-macro"}, 244 | "context": [ 245 | { "key": "selector", "operand": "meta.template.jinja - source.jinja" }, 246 | { "key": "setting.auto_indent", "operator": "equal", "operand": true }, 247 | { "key": "selection_empty", "operator": "equal", "operand": true, "match_all": true }, 248 | { "key": "preceding_text", "operator": "regex_contains", "operand": "%\\}\\s*$", "match_all": true }, 249 | { "key": "following_text", "operator": "regex_contains", "operand": "^\\{%", "match_all": true } 250 | ] 251 | } 252 | ] 253 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2020-2024 © Ashwin Shenoy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /Main.sublime-menu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "preferences", 4 | "children": 5 | [ 6 | { 7 | "caption": "Package Settings", 8 | "mnemonic": "P", 9 | "id": "package-settings", 10 | "children": 11 | [ 12 | { 13 | "caption": "Jinja2", 14 | "children": [ 15 | { 16 | "caption": "Documentation", 17 | "command": "open_url", 18 | "args": { 19 | "url": "https://github.com/Sublime-Instincts/BetterJinja/blob/master/README.md" 20 | } 21 | }, 22 | { "caption": "-", }, 23 | { 24 | "caption": "Key Bindings", 25 | "command": "edit_settings", 26 | "args": { 27 | "base_file": "${packages}/Jinja2/Default.sublime-keymap", 28 | "user_file": "${packages}/User/Default ($platform).sublime-keymap", 29 | "default": "[\n\t${0}\n]\n" 30 | } 31 | } 32 | ] 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | ] 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jinja2 2 | 3 | ![LICENSE](https://img.shields.io/badge/LICENSE-MIT-green?style=for-the-badge) ![LICENSE](https://img.shields.io/badge/ST-Build%204107+-orange?style=for-the-badge&logo=sublime-text) ![Tag](https://img.shields.io/github/v/tag/Sublime-Instincts/BetterJinja?style=for-the-badge&logo=github&sort=semver) ![Downloads](https://img.shields.io/packagecontrol/dt/Jinja2?style=for-the-badge) 4 | ![Syntax tests](https://img.shields.io/github/actions/workflow/status/Sublime-Instincts/BetterJinja/syntax_test.yml?color=green&label=Syntax%20Tests&logo=github&logoColor=white&style=for-the-badge) 5 | 6 | [Jinja2](https://jinja.palletsprojects.com/en/3.1.x/) and [Django Template Language](https://docs.djangoproject.com/en/5.1/topics/templates/) syntax definitions, 7 | completions and snippets for [Sublime Text](https://www.sublimetext.com) 8 | based on its bundled C/C++, CSS, HTML, JavaScript, JSON, Markdown, XML and YAML syntaxes. 9 | 10 | ## Features 11 | 12 | - Syntax highlighting for Jinja2 and Django templates 13 | _Supported languages: C/C++, CSS, HTML, JavaScript, JSON, Markdown, XML and YAML_ 14 | - Syntax specific indentation for code blocks 15 | - Completions for built in tags, filters, functions, tests & loop variables. 16 | - Key bindings to make your life easier 17 | - Snippets for tags and common code blocks 18 | 19 | ## Installation 20 | 21 | #### Package Control 22 | 23 | The best way is to install it via [Package Control](https://packagecontrol.io/). 24 | Once you have Package Control setup in Sublime Text, open the command palette 25 | and search for `Package Control: Install Package`. Search for `Jinja2` and 26 | install it. Package Control will take care for of automatically updating the 27 | package for you if there are new releases. 28 | 29 | You can also use `Package Control: Add Repository`. Copy the github url 30 | (without the `.git` at the end) and enter it into the input panel that pops up 31 | at the bottom when you select `Package Control: Add Repository`. Now use 32 | `Package Control: Install Package` and search for `Jinja2` and install it. 33 | 34 | ## Documentation 35 | 36 | ### How to use this package ? 37 | 38 | By default, this package supports the following Jinja extensions: 39 | 40 | `j2`, `jinja`, `jinja2`, `html.j2`, `html.jinja`, `html.jinja2`, `htm.j2`, `htm.jinja`, `htm.jinja2` 41 | 42 | and Django extensions: 43 | 44 | `djt`, `djhtml`, `dj.html`, `html.djt` 45 | 46 | Since a user can have more than one templating language package installed, 47 | this package doesn't support `.html` directly. To get highlighting for `.html` 48 | files with Jinja code and all the other features this package provides, you 49 | can follow any of the two approaches given below 50 | 51 | 1. Go to the bottom right status bar item that displays information on current 52 | syntax and click on that when the currently open file is any `.html` file. 53 | From there go to `Open all with current extensions as ...` and scroll to 54 | select `Jinja`. You should now be good to go. 55 | 56 | 2. When the currently open file has any of the aforementioned file extensions, 57 | from the main menu, go to `Preferences -> Settings -- Syntax Specific`. 58 | This should open a 2 column new window, with the default settings on the 59 | right and a user settings on the left. In the user settings, add the 60 | following, save & close. 61 | 62 | ```json 63 | { 64 | "extensions": [ 65 | ".html" 66 | ] 67 | } 68 | ``` 69 | 70 | ### Key bindings 71 | 72 | - The key bindings are configured so that pressing shift + { 73 | **twice** will automatically add spaces on both sides for the inner brace 74 | expression block & place the cursor in the center, like so `{{ | }}`. 75 | - |||ly pressing shift + % within `{}` will add spaces on both sides of the inner `%` like so `{% | %}` 76 | - You can use ctrl + / for inserting Jinja style line comments (`## This is a line comment`) 77 | - Similarly, use ctrl + shift + / for block style comments (`{# This is a block comment #}`) 78 | 79 | ### Auto completions 80 | 81 | No special configuration is required for completions to show while typing or snippets to expand. 82 | 83 | Completion behaviour of the primary syntax applies to normal content. 84 | Default behaviour of ST involves distinction between `source` and `text` scopes. 85 | 86 | - `source` (CSS, JavaScript, JSON, YAML): completions display while typing. 87 | - `text` (HTML, Markdown, Text, XML): only snippets expand by pressing tab key. 88 | 89 | Content of `{% %}` and `{{ }}` tags is scoped `source.jinja` to enable completions while typing. 90 | 91 | ### Snippets 92 | 93 | Basic snippets for each keyword are provided to create expressions without bothering with `{% %}`. 94 | 95 | | **Tab Trigger** | **Jinja Tag** | 96 | |-------------------|-----------------------| 97 | | `autoescape` | `{% autoescape %}` | 98 | | `endautoescape` | `{% endautoescape %}` | 99 | | ... | ... | 100 | 101 | Prefixed with `j` basic snippets for most common control structures are provided. 102 | 103 | | **Tab Trigger** | **Jinja Code Block** | 104 | |-------------------|---------------------------------------| 105 | | `jautoescape` | `{% autoescape %}{% endautoescape %}` | 106 | | `jblock` | `{% block %}{% endblock %}` | 107 | | `jcall` | `{% call %}{% endcall %}` | 108 | | `jextends` | `{% extends %}` | 109 | | `jexp` | `{% %}` | 110 | | `jfilter` | `{% filter %}{% endfilter %}` | 111 | | `jfor` | `{% for %}{% endfor %}` | 112 | | `jif` | `{% if %}{% endif %}` | 113 | | `jifelse` | `{% if %}{% else %}{% endif %}` | 114 | | `jmacro` | `{% macro %}{% endmacro %}` | 115 | | `jraw` | `{% raw %}{% endraw %}` | 116 | | `jwith` | `{% with %}{% endwith %}` | 117 | 118 | For more, please follow the official documentation on [snippets](https://www.sublimetext.com/docs/completions.html#snippets) to create your own. 119 | 120 | Snippets can be disabled (ignored) by adding the following to _Preferences.sublime-settings_: 121 | 122 | ```json 123 | { 124 | "ignored_snippets": ["Jinja2/*"] 125 | } 126 | ``` 127 | 128 | ## Troubleshooting 129 | 130 | Jinja2 extends Sublime Text's CSS, HTML, JavaScript, JSON, Markdown, XML and 131 | YAML syntax definitions. 132 | 133 | If Jinja2 syntax highlighting doesn't work and console displays syntax errors, 134 | 135 | 1. check if required bundled packages are enabled. 136 | 2. remove any out-dated syntax override. 137 | 138 | ### Enable bundled packages 139 | 140 | 1. Open `Command Palette` using ctrl+shift+P or menu item `Tools → Command Palette...` 141 | 2. Choose `Package Control: Enable Packages` 142 | 3. Find `CSS` and hit Enter 143 | 4. Repeat the steps for `JavaScript`, `HTML` ... 144 | 145 | ### Remove overrides 146 | 147 | 1. call _Menu > Preferences > Browse Packages.._ 148 | 2. Look for _CSS_, _HTML_, ... folders 149 | 3. Remove them or at least delete any syntax definition in them 150 | 151 | ## Issues & Feature requests 152 | 153 | There is always scope for improvements so please report [bug(s) or feature requests](https://github.com/Sublime-Instincts/BetterJinja/issues). 154 | 155 | Please follow the issue & feature request templates that have been setup while 156 | reporting any bug(s) or requesting for feature(s) (So as to stay as organised 157 | as possible). 158 | 159 | ## Acknowledgements 160 | 161 | The [syntax_test.yml](.github/workflows/syntax_test.yml) is taken & used (with some modifications) 162 | from the official [Packages](https://github.com/sublimehq/Packages) repository. So full credit goes to them for it. 163 | -------------------------------------------------------------------------------- /Snippets/autoescape.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jautoescape 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja autoescape statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/block.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jblock 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja block statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/call.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jcall 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja call statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/expression_block.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | jexp 6 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 7 | Jinja expression 8 | 9 | -------------------------------------------------------------------------------- /Snippets/filter.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jfilter 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja filter statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/for.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jfor 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja for loop statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/if.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jif 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja if statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/if_else.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 9 | jifelse 10 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 11 | Jinja if else statement 12 | 13 | -------------------------------------------------------------------------------- /Snippets/jcomment.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jcomment 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Django comment statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/macro.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jmacro 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja macro statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/raw.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jraw 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja raw statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/set.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jset 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja set statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/tags/autoescape.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | autoescape 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja autoescape tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/block.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | block 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja block tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/call.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | call 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja call tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/comment.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | comment 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Django comment tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/elif.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | elif 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja elif statement tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/else.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | else 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja else statement tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endautoescape.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endautoescape 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endautoescape tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endblock.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endblock 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endblock tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endcall.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endcall 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endcall tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endcomment.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endcomment 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Django endcomment tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endembed.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endembed 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endembed tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endfilter.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endfilter 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endfilter tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endfor.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endfor 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endfor tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endif.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endif 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endif tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endmacro.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endmacro 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endmacro tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endraw.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endraw 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endraw tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endset.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endset 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endset tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endtrans.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endtrans 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endtrans tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/endwith.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | endwith 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja endwith tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/extends.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 5 | extends 6 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 7 | Jinja extends tag 8 | 9 | -------------------------------------------------------------------------------- /Snippets/tags/filter.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | filter 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja filter tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/for.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | for 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja for tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/if.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | if 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja if tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/macro.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | macro 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja macro tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/pluralize.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | pluralize 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja pluralize statement tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/tags/set.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 3 | set 4 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 5 | Jinja set tag 6 | 7 | -------------------------------------------------------------------------------- /Snippets/trans.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jtrans 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja trans statement 10 | 11 | -------------------------------------------------------------------------------- /Snippets/with.sublime-snippet: -------------------------------------------------------------------------------- 1 | 2 | 7 | jwith 8 | meta.template.jinja - meta.embedded.expression - meta.embedded.statement 9 | Jinja with statement 10 | 11 | -------------------------------------------------------------------------------- /Syntaxes/C++/C (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: C (Jinja) 5 | scope: source.c.jinja 6 | 7 | extends: Packages/C++/C.sublime-syntax 8 | 9 | file_extensions: 10 | - c.jinja 11 | - c.jinja2 12 | - c.j2 13 | - jinja.c 14 | - jinja2.c 15 | - j2.c 16 | - c.in 17 | - h.in 18 | 19 | contexts: 20 | 21 | prototype: 22 | - meta_prepend: true 23 | - include: Text (Jinja).sublime-syntax 24 | 25 | main: 26 | - meta_prepend: true 27 | - meta_scope: meta.template.jinja 28 | -------------------------------------------------------------------------------- /Syntaxes/C++/C++ (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: C++ (Jinja) 5 | scope: source.c++.jinja 6 | 7 | extends: Packages/C++/C++.sublime-syntax 8 | 9 | file_extensions: 10 | - cpp.jinja 11 | - cpp.jinja2 12 | - cpp.j2 13 | - jinja.cpp 14 | - jinja2.cpp 15 | - j2.cpp 16 | - cpp.in 17 | - hpp.in 18 | 19 | contexts: 20 | 21 | prototype: 22 | - meta_prepend: true 23 | - include: Text (Jinja).sublime-syntax 24 | 25 | main: 26 | - meta_prepend: true 27 | - meta_scope: meta.template.jinja 28 | 29 | strings: 30 | - include: unique-strings 31 | - include: scope:source.c.jinja#strings 32 | -------------------------------------------------------------------------------- /Syntaxes/C++/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scope 6 | 7 | source.c.jinja, 8 | source.c++.jinja 9 | 10 | settings 11 | 12 | shellVariables 13 | 14 | 15 | name 16 | TM_COMMENT_START 17 | value 18 | {# 19 | 20 | 21 | name 22 | TM_COMMENT_END 23 | value 24 | #} 25 | 26 | 27 | name 28 | TM_COMMENT_START_2 29 | value 30 | {# 31 | 32 | 33 | name 34 | TM_COMMENT_END_2 35 | value 36 | #} 37 | 38 | 39 | name 40 | TM_COMMENT_START_3 41 | value 42 | // 43 | 44 | 45 | name 46 | TM_COMMENT_START_4 47 | value 48 | /* 49 | 50 | 51 | name 52 | TM_COMMENT_END_4 53 | value 54 | */ 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Syntaxes/C++/Snippet Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | 6 | source.c.jinja, 7 | source.c++.jinja 8 | 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | 15 | name 16 | TM_TEMPLATE_INDENT 17 | value 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Syntaxes/CSS/CSS (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: CSS (Jinja) 5 | scope: source.css.jinja 6 | version: 2 7 | 8 | extends: Packages/CSS/CSS.sublime-syntax 9 | 10 | file_extensions: 11 | - css.jinja 12 | - css.jinja2 13 | - css.j2 14 | - jinja.css 15 | - jinja2.css 16 | - j2.css 17 | # Django 18 | - djcss 19 | - dj.css 20 | - css.djt 21 | 22 | variables: 23 | 24 | # CSS overrides 25 | 26 | ident_start: (?:{{nmstart}}|{{) 27 | 28 | # required until ST4173 29 | selector_begin: (?={{selector_start}}|{{) 30 | # required until ST4173 31 | nested_selector_begin: (?={{nested_selector_start}}|{{) 32 | 33 | tag_name_begin: (?=[[:alpha:]]|{{) 34 | 35 | # CSS (Jinja) variables 36 | #... 37 | 38 | contexts: 39 | 40 | prototype: 41 | - meta_prepend: true 42 | - include: Text (Jinja).sublime-syntax 43 | 44 | main: 45 | # The top-level context must contain jinja statements only. 46 | # Jinja expressions are excluded as they are consumed by child contexts 47 | # such as selectors, property names or property values. 48 | - meta_prepend: true 49 | - meta_include_prototype: false 50 | - meta_scope: meta.template.jinja 51 | - include: Text (Jinja).sublime-syntax#jinja-comment-lines 52 | - include: Text (Jinja).sublime-syntax#jinja-statement-lines 53 | - include: Text (Jinja).sublime-syntax#jinja-comment-tags 54 | - include: Text (Jinja).sublime-syntax#jinja-statement-tags 55 | 56 | block-end: 57 | # This context is included in each style-rule block context, 58 | # which must contain jinja statements only. 59 | # Jinja expressions are excluded as they are consumed by child contexts 60 | # such as selectors, property names or property values. 61 | - meta_append: true 62 | - include: Text (Jinja).sublime-syntax#jinja-comment-lines 63 | - include: Text (Jinja).sublime-syntax#jinja-statement-lines 64 | - include: Text (Jinja).sublime-syntax#jinja-comment-tags 65 | - include: Text (Jinja).sublime-syntax#jinja-statement-tags 66 | 67 | at-rule-block-body: 68 | # required until ST4173 69 | # This context is included in each style-rule block context, 70 | # which must contain jinja statements only. 71 | # Jinja expressions are excluded as they are consumed by child contexts 72 | # such as selectors, property names or property values. 73 | - meta_prepend: true 74 | - meta_include_prototype: false 75 | - include: Text (Jinja).sublime-syntax#jinja-comment-lines 76 | - include: Text (Jinja).sublime-syntax#jinja-statement-lines 77 | - include: Text (Jinja).sublime-syntax#jinja-comment-tags 78 | - include: Text (Jinja).sublime-syntax#jinja-statement-tags 79 | 80 | at-supports-group-body: 81 | - meta_prepend: true 82 | - meta_include_prototype: false 83 | - include: Text (Jinja).sublime-syntax 84 | 85 | property-lists: 86 | # A `{{` indicates the beginning of a selector or property name context 87 | # beginning with a Jinja expression rather than a style rule block. 88 | - match: \{(?![{%#]) 89 | scope: punctuation.section.block.begin.css 90 | push: property-list-body 91 | 92 | property-list-body: 93 | # required until ST4173 94 | - meta_prepend: true 95 | - meta_include_prototype: false 96 | 97 | string-content: 98 | - meta_prepend: true 99 | - include: Text (Jinja).sublime-syntax#interpolations 100 | -------------------------------------------------------------------------------- /Syntaxes/CSS/CSS (for HTML double-quoted).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | scope: source.css.embedded.string.quoted.double.jinja 4 | version: 2 5 | hidden: true 6 | 7 | extends: CSS (Jinja).sublime-syntax 8 | 9 | contexts: 10 | main: 11 | - include: rule-list-body 12 | 13 | quoted-strings: 14 | - meta_prepend: true 15 | - match: (?=") 16 | pop: 1 17 | 18 | quoted-string: 19 | - meta_prepend: true 20 | - match: (?=") 21 | pop: 1 22 | 23 | quoted-urls: 24 | - meta_prepend: true 25 | - match: (?=") 26 | pop: 1 27 | -------------------------------------------------------------------------------- /Syntaxes/CSS/CSS (for HTML single-quoted).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | scope: source.css.embedded.string.quoted.single.jinja 4 | version: 2 5 | hidden: true 6 | 7 | extends: CSS (Jinja).sublime-syntax 8 | 9 | contexts: 10 | main: 11 | - include: rule-list-body 12 | 13 | quoted-strings: 14 | - meta_prepend: true 15 | - match: (?=') 16 | pop: 1 17 | 18 | quoted-string: 19 | - meta_prepend: true 20 | - match: (?=') 21 | pop: 1 22 | 23 | quoted-urls: 24 | - meta_prepend: true 25 | - match: (?=') 26 | pop: 1 27 | -------------------------------------------------------------------------------- /Syntaxes/CSS/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scope 6 | 7 | source.css.jinja, 8 | text.html.jinja source.css.embedded 9 | 10 | settings 11 | 12 | shellVariables 13 | 14 | 15 | name 16 | TM_COMMENT_START 17 | value 18 | ## 19 | 20 | 21 | name 22 | TM_COMMENT_START_2 23 | value 24 | {# 25 | 26 | 27 | name 28 | TM_COMMENT_END_2 29 | value 30 | #} 31 | 32 | 33 | name 34 | TM_COMMENT_START_3 35 | value 36 | /* 37 | 38 | 39 | name 40 | TM_COMMENT_END_3 41 | value 42 | */ 43 | 44 | 45 | name 46 | TM_COMMENT_START_4 47 | value 48 | /* 49 | 50 | 51 | name 52 | TM_COMMENT_END_4 53 | value 54 | */ 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Syntaxes/CSS/Snippet Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | 6 | source.css.jinja, 7 | text.html.jinja source.css.embedded 8 | 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | 15 | name 16 | TM_TEMPLATE_INDENT 17 | value 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Syntaxes/HTML/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scope 6 | text.html.jinja 7 | settings 8 | 9 | shellVariables 10 | 11 | 12 | name 13 | TM_COMMENT_START 14 | value 15 | ## 16 | 17 | 18 | name 19 | TM_COMMENT_START_2 20 | value 21 | {# 22 | 23 | 24 | name 25 | TM_COMMENT_END_2 26 | value 27 | #} 28 | 29 | 30 | name 31 | TM_COMMENT_START_3 32 | value 33 | 34 | 35 | 36 | name 37 | TM_COMMENT_END_3 38 | value 39 | ]]> 40 | 41 | 42 | name 43 | TM_COMMENT_START_4 44 | value 45 | 46 | 47 | 48 | name 49 | TM_COMMENT_END_4 50 | value 51 | ]]> 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Syntaxes/HTML/HTML (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: HTML (Jinja) 5 | scope: text.html.jinja 6 | version: 2 7 | 8 | file_extensions: 9 | - jinja 10 | - jinja2 11 | - j2 12 | - html.jinja 13 | - html.jinja2 14 | - html.j2 15 | - htm.jinja 16 | - htm.jinja2 17 | - htm.j2 18 | # Django 19 | - djt 20 | - djhtml 21 | - dj.html 22 | - html.djt 23 | 24 | extends: Packages/HTML/HTML.sublime-syntax 25 | 26 | variables: 27 | tag_name_start: (?:[A-Za-z]|{{) 28 | 29 | contexts: 30 | 31 | prototype: 32 | - meta_prepend: true 33 | - include: Text (Jinja).sublime-syntax 34 | 35 | main: 36 | - meta_prepend: true 37 | - meta_scope: meta.template.jinja 38 | 39 | ###[ CUSTOM HTML ]############################################################ 40 | 41 | tag-other: 42 | # override original context to add support for `{{tag_name_start}}` variable 43 | # required until ST4174 44 | - match: 67 | escape_captures: 68 | 0: meta.tag.sgml.cdata.html punctuation.definition.tag.end.html 69 | - match: '{{script_content_begin}}' 70 | captures: 71 | 1: comment.block.html punctuation.definition.comment.begin.html 72 | pop: 1 # make sure to match only once 73 | embed: scope:source.js.jinja 74 | embed_scope: source.js.embedded.html 75 | escape: '{{script_content_end}}' 76 | escape_captures: 77 | 1: source.js.embedded.html 78 | 2: comment.block.html punctuation.definition.comment.end.html 79 | 3: source.js.embedded.html 80 | 4: comment.block.html punctuation.definition.comment.end.html 81 | 82 | script-json-content: 83 | - meta_include_prototype: false 84 | - match: \s*(( 94 | escape_captures: 95 | 0: meta.tag.sgml.cdata.html punctuation.definition.tag.end.html 96 | - match: '{{script_content_begin}}' 97 | captures: 98 | 1: comment.block.html punctuation.definition.comment.begin.html 99 | pop: 1 # make sure to match only once 100 | embed: scope:source.json.jinja 101 | embed_scope: source.json.embedded.html 102 | escape: '{{script_content_end}}' 103 | escape_captures: 104 | 1: source.json.embedded.html 105 | 2: comment.block.html punctuation.definition.comment.end.html 106 | 3: source.json.embedded.html 107 | 4: comment.block.html punctuation.definition.comment.end.html 108 | 109 | style-css-content: 110 | - meta_include_prototype: false 111 | - match: \s*(( 121 | escape_captures: 122 | 0: meta.tag.sgml.cdata.html punctuation.definition.tag.end.html 123 | - match: '{{style_content_begin}}' 124 | captures: 125 | 1: comment.block.html punctuation.definition.comment.begin.html 126 | pop: 1 # make sure to match only once 127 | embed: scope:source.css.jinja 128 | embed_scope: source.css.embedded.html 129 | escape: '{{style_content_end}}' 130 | escape_captures: 131 | 1: source.css.embedded.html 132 | 2: comment.block.html punctuation.definition.comment.end.html 133 | 3: source.css.embedded.html 134 | 4: comment.block.html punctuation.definition.comment.end.html 135 | 136 | tag-attributes: 137 | # Include jinja statement tags to prevent them being scoped meta.attribute-with-value 138 | - meta_prepend: true 139 | - include: Text (Jinja).sublime-syntax#jinja-comment-lines 140 | - include: Text (Jinja).sublime-syntax#jinja-statement-lines 141 | - include: Text (Jinja).sublime-syntax#jinja-comment-tags 142 | - include: Text (Jinja).sublime-syntax#jinja-statement-tags 143 | 144 | tag-event-attribute-value: 145 | - meta_include_prototype: false 146 | - match: \" 147 | scope: string.quoted.double.html punctuation.definition.string.begin.html 148 | set: tag-event-attribute-value-double-quoted-body 149 | - match: \' 150 | scope: string.quoted.single.html punctuation.definition.string.begin.html 151 | set: tag-event-attribute-value-single-quoted-body 152 | - include: else-pop 153 | 154 | tag-event-attribute-value-double-quoted-body: 155 | - meta_include_prototype: false 156 | - meta_scope: meta.string.html 157 | - meta_content_scope: source.js.embedded.html 158 | - match: \" 159 | scope: string.quoted.double.html punctuation.definition.string.end.html 160 | pop: 1 161 | - include: scope:source.js.embedded.string.quoted.double.jinja 162 | 163 | tag-event-attribute-value-single-quoted-body: 164 | - meta_include_prototype: false 165 | - meta_scope: meta.string.html 166 | - meta_content_scope: source.js.embedded.html 167 | - match: \' 168 | scope: string.quoted.single.html punctuation.definition.string.end.html 169 | pop: 1 170 | - include: scope:source.js.embedded.string.quoted.single.jinja 171 | 172 | tag-style-attribute-value: 173 | - meta_include_prototype: false 174 | - match: \" 175 | scope: string.quoted.double.html punctuation.definition.string.begin.html 176 | set: tag-style-attribute-value-double-quoted-body 177 | - match: \' 178 | scope: string.quoted.single.html punctuation.definition.string.begin.html 179 | set: tag-style-attribute-value-single-quoted-body 180 | - include: else-pop 181 | 182 | tag-style-attribute-value-double-quoted-body: 183 | - meta_include_prototype: false 184 | - meta_scope: meta.string.html 185 | - meta_content_scope: source.css.embedded.html 186 | - match: \" 187 | scope: string.quoted.double.html punctuation.definition.string.end.html 188 | pop: 1 189 | - include: scope:source.css.embedded.string.quoted.double.jinja 190 | 191 | tag-style-attribute-value-single-quoted-body: 192 | - meta_include_prototype: false 193 | - meta_scope: meta.string.html 194 | - meta_content_scope: source.css.embedded.html 195 | - match: \' 196 | scope: string.quoted.single.html punctuation.definition.string.end.html 197 | pop: 1 198 | - include: scope:source.css.embedded.string.quoted.single.jinja 199 | 200 | tag-attribute-value-content: 201 | - meta_prepend: true 202 | - include: Text (Jinja).sublime-syntax#interpolations 203 | 204 | strings-common-content: 205 | - meta_prepend: true 206 | - include: Text (Jinja).sublime-syntax#interpolations 207 | -------------------------------------------------------------------------------- /Syntaxes/HTML/Indentation Rules.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | text.html.jinja 6 | settings 7 | 8 | decreaseIndentPattern 9 | ]*+ ])[^\t\n\f /<>]+ [^>]* > 13 | | ^[\t\n\f ]*+ 14 | ( 15 | # closing comment punctuation, optionally preceded by an end "comment selector" 16 | ( 17 | # closing directive/section punctuation 18 | | [?%]> 19 | # closing curly brace 20 | | \} 21 | ) 22 | # Jinja tags 23 | | ^\s*\{%[-+]?\s* 24 | # block end tags 25 | ( end(?: autoescape | block | call | filter | for | if | macro | raw | set | trans | with ) 26 | # intermediate block branches 27 | | elif | else | pluralize ) 28 | \b.*\s*%\}\s*?$ 29 | ]]> 30 | increaseIndentPattern 31 | ] 40 | )(?: 41 | # tag name 42 | (?[^\t\n\f /<>]+) 43 | # not self closing 44 | (?:(?!/>)[^>])* > 45 | # not closing in the same line 46 | (?! .* ) 47 | ) 48 | # comments that don't close themselves on the same line 49 | | ) 50 | # directives that don't close themselves on the same line 51 | | <\?(?!.*?\?>) 52 | # sections that don't close themselves on the same line 53 | | <\%(?!.*?\%>) 54 | # open curly braces at the end of a line with comments allowed 55 | | \{(?=\s*(?: 12 | name 13 | TM_TEMPLATE_INDENT 14 | value 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Syntaxes/JSON/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scope 6 | 7 | source.json.jinja, 8 | text.html.jinja source.json.embedded 9 | 10 | settings 11 | 12 | shellVariables 13 | 14 | 15 | name 16 | TM_COMMENT_START 17 | value 18 | ## 19 | 20 | 21 | name 22 | TM_COMMENT_START_2 23 | value 24 | {# 25 | 26 | 27 | name 28 | TM_COMMENT_END_2 29 | value 30 | #} 31 | 32 | 33 | name 34 | TM_COMMENT_START_3 35 | value 36 | /* 37 | 38 | 39 | name 40 | TM_COMMENT_END_3 41 | value 42 | */ 43 | 44 | 45 | name 46 | TM_COMMENT_START_4 47 | value 48 | /* 49 | 50 | 51 | name 52 | TM_COMMENT_END_4 53 | value 54 | */ 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Syntaxes/JSON/JSON (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: JSON (Jinja) 5 | scope: source.json.jinja 6 | version: 2 7 | 8 | extends: Packages/JSON/JSON.sublime-syntax 9 | 10 | file_extensions: 11 | - json.jinja 12 | - json.jinja2 13 | - json.j2 14 | - jinja.json 15 | - jinja2.json 16 | - j2.json 17 | # Django 18 | - djjson 19 | - dj.json 20 | - json.djt 21 | 22 | contexts: 23 | 24 | prototype: 25 | - meta_prepend: true 26 | - include: Text (Jinja).sublime-syntax 27 | 28 | main: 29 | - meta_prepend: true 30 | - meta_scope: meta.template.jinja 31 | 32 | string-prototype: 33 | # since ST4174 34 | - meta_prepend: true 35 | - include: Text (Jinja).sublime-syntax#interpolations 36 | 37 | inside-string: 38 | # until ST4173 39 | # override whole context to apply `meta.string.json` 40 | - meta_include_prototype: false 41 | - meta_scope: meta.string.json string.quoted.double.json 42 | - match: \" 43 | scope: punctuation.definition.string.end.json 44 | pop: 1 45 | - match: \n 46 | scope: invalid.illegal.unclosed-string.json 47 | pop: 1 48 | # string-escape (not avail in ST4174+) 49 | - match: |- 50 | (?x: # turn on extended mode 51 | \\ # a literal backslash 52 | (?: # ...followed by... 53 | ["\\/bfnrt] # one of these characters 54 | | # ...or... 55 | u # a u 56 | [0-9a-fA-F]{4} # and four hex digits 57 | ) 58 | ) 59 | scope: constant.character.escape.json 60 | - match: \\. 61 | scope: invalid.illegal.unrecognized-string-escape.json 62 | # finally interpolations 63 | - include: Text (Jinja).sublime-syntax#interpolations 64 | -------------------------------------------------------------------------------- /Syntaxes/JSON/Snippet Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | 6 | source.json.jinja, 7 | text.html.jinja source.json.embedded 8 | 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | 15 | name 16 | TM_TEMPLATE_INDENT 17 | value 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Syntaxes/JavaScript/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scope 6 | 7 | source.js.jinja, 8 | text.html.jinja source.js.embedded 9 | 10 | settings 11 | 12 | shellVariables 13 | 14 | 15 | name 16 | TM_COMMENT_START 17 | value 18 | ## 19 | 20 | 21 | name 22 | TM_COMMENT_START_2 23 | value 24 | {# 25 | 26 | 27 | name 28 | TM_COMMENT_END_2 29 | value 30 | #} 31 | 32 | 33 | name 34 | TM_COMMENT_START_3 35 | value 36 | // 37 | 38 | 39 | name 40 | TM_COMMENT_START_4 41 | value 42 | /* 43 | 44 | 45 | name 46 | TM_COMMENT_END_4 47 | value 48 | */ 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Syntaxes/JavaScript/JavaScript (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: JavaScript (Jinja) 5 | scope: source.js.jinja 6 | version: 2 7 | 8 | extends: Packages/JavaScript/JavaScript.sublime-syntax 9 | 10 | file_extensions: 11 | - js.jinja 12 | - js.jinja2 13 | - js.j2 14 | - jinja.js 15 | - jinja2.js 16 | - j2.js 17 | 18 | contexts: 19 | 20 | prototype: 21 | - meta_prepend: true 22 | - include: Text (Jinja).sublime-syntax 23 | 24 | main: 25 | - meta_prepend: true 26 | - meta_scope: meta.template.jinja 27 | 28 | expressions: 29 | # required until ST4178 30 | - match: (?=\S) 31 | push: [ expression-end, expression-begin ] 32 | 33 | string-content: 34 | - meta_prepend: true 35 | - include: Text (Jinja).sublime-syntax#interpolations 36 | -------------------------------------------------------------------------------- /Syntaxes/JavaScript/JavaScript (for HTML double-quoted).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | scope: source.js.embedded.string.quoted.double.jinja 4 | version: 2 5 | hidden: true 6 | 7 | extends: JavaScript (Jinja).sublime-syntax 8 | 9 | contexts: 10 | main: 11 | - include: expressions 12 | 13 | field-name: 14 | - meta_prepend: true 15 | - match: (?=") 16 | pop: 1 17 | 18 | method-name: 19 | - meta_prepend: true 20 | - match: (?=") 21 | pop: 1 22 | 23 | literal-double-quoted-string: 24 | - match: (?=") 25 | pop: 1 26 | 27 | -------------------------------------------------------------------------------- /Syntaxes/JavaScript/JavaScript (for HTML single-quoted).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | scope: source.js.embedded.string.quoted.single.jinja 4 | version: 2 5 | hidden: true 6 | 7 | extends: JavaScript (Jinja).sublime-syntax 8 | 9 | contexts: 10 | main: 11 | - include: expressions 12 | 13 | field-name: 14 | - meta_prepend: true 15 | - match: (?=') 16 | pop: 1 17 | 18 | method-name: 19 | - meta_prepend: true 20 | - match: (?=') 21 | pop: 1 22 | 23 | literal-single-quoted-string: 24 | - match: (?=') 25 | pop: 1 26 | -------------------------------------------------------------------------------- /Syntaxes/JavaScript/Snippet Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | 6 | source.js.jinja, 7 | text.html.jinja source.js.embedded 8 | 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | 15 | name 16 | TM_TEMPLATE_INDENT 17 | value 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Syntaxes/Markdown/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scope 6 | text.html.markdown.jinja 7 | settings 8 | 9 | shellVariables 10 | 11 | 12 | name 13 | TM_COMMENT_START 14 | value 15 | {# 16 | 17 | 18 | name 19 | TM_COMMENT_END 20 | value 21 | #} 22 | 23 | 24 | name 25 | TM_COMMENT_START_2 26 | value 27 | {# 28 | 29 | 30 | name 31 | TM_COMMENT_END_2 32 | value 33 | #} 34 | 35 | 36 | name 37 | TM_COMMENT_START_3 38 | value 39 | 40 | 41 | 42 | name 43 | TM_COMMENT_END_3 44 | value 45 | ]]> 46 | 47 | 48 | name 49 | TM_COMMENT_START_4 50 | value 51 | 52 | 53 | 54 | name 55 | TM_COMMENT_END_4 56 | value 57 | ]]> 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Syntaxes/Markdown/Markdown (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: Markdown (Jinja) 5 | scope: text.html.markdown.jinja 6 | version: 2 7 | 8 | extends: Packages/Markdown/Markdown.sublime-syntax 9 | 10 | file_extensions: 11 | - md.jinja 12 | - md.jinja2 13 | - md.j2 14 | - jinja.md 15 | - jinja2.md 16 | - j2.md 17 | 18 | contexts: 19 | prototype: 20 | - meta_prepend: true 21 | # exclude line comments and line statements 22 | # to avoid conflicts with atx headings 23 | - include: Text (Jinja).sublime-syntax#jinja-comment-tags 24 | - include: Text (Jinja).sublime-syntax#jinja-statement-tags 25 | - include: Text (Jinja).sublime-syntax#jinja-expression-tags 26 | 27 | main: 28 | - meta_prepend: true 29 | - meta_scope: meta.template.jinja 30 | 31 | html-content: 32 | - include: HTML (Jinja).sublime-syntax#html 33 | -------------------------------------------------------------------------------- /Syntaxes/Markdown/Snippet Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | text.html.markdown.jinja 6 | settings 7 | 8 | shellVariables 9 | 10 | 11 | 12 | name 13 | TM_TEMPLATE_INDENT 14 | value 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Syntaxes/Text/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scope 6 | text.jinja 7 | settings 8 | 9 | shellVariables 10 | 11 | 12 | name 13 | TM_COMMENT_START 14 | value 15 | ## 16 | 17 | 18 | name 19 | TM_COMMENT_START_2 20 | value 21 | {# 22 | 23 | 24 | name 25 | TM_COMMENT_END_2 26 | value 27 | #} 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Syntaxes/Text/Indentation Rules.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | text.jinja 6 | settings 7 | 8 | decreaseIndentPattern 9 | 17 | increaseIndentPattern 18 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Syntaxes/Text/Snippet Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | text.jinja 6 | settings 7 | 8 | shellVariables 9 | 10 | 11 | 12 | name 13 | TM_TEMPLATE_INDENT 14 | value 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Syntaxes/Text/Symbol List - Blocks.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | entity.name.section.block 6 | settings 7 | 8 | showInSymbolList 9 | 1 10 | showInIndexedSymbolList 11 | 1 12 | showInIndexedReferenceList 13 | 1 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Syntaxes/Text/Symbol List - Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | meta.declaration.identifier.jinja variable.other 6 | settings 7 | 8 | showInSymbolList 9 | 1 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Syntaxes/Text/Text (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # https://jinja.palletsprojects.com/en/3.1.x/templates/ 4 | # http://www.sublimetext.com/docs/syntax.html 5 | name: Text (Jinja) 6 | scope: text.jinja 7 | version: 2 8 | 9 | file_extensions: 10 | - txt.jinja 11 | - txt.jinja2 12 | - txt.j2 13 | - jinja.txt 14 | - jinja2.txt 15 | - j2.txt 16 | 17 | variables: 18 | 19 | ident: (?:{{ident_start}}{{ident_part}}*) 20 | ident_start: '[a-zA-Z_]' 21 | ident_part: '[a-zA-Z0-9_]*' 22 | 23 | dot_accessor: (?:\.(?!\.)) 24 | 25 | modifiers: '[-+]' 26 | 27 | builtin_filters: |- 28 | (?x: 29 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#list-of-builtin-filters 30 | abs | attr | batch | capitalize | center | default | dictsort | escape 31 | | filesizeformat | first | float | forceescape | format | groupby | indent 32 | | int | items | join | last | length | list | lower | map | max | min | pprint 33 | | random | reject | rejectattr | replace | reverse | round | safe | select 34 | | selectattr | slice | sort | string | striptags | sum | title | tojson 35 | | trim | truncate | unique | upper | urlencode | urlize | wordcount 36 | | wordwrap | xmlattr 37 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#html-escaping 38 | | e | safe ) 39 | 40 | builtin_tests: |- 41 | (?x: 42 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#list-of-builtin-tests 43 | boolean | callable | defined | divisibleby | eq | escaped | even 44 | | false | filter | float | ge | gt | in | integer | iterable | le | lower 45 | | lt | mapping | ne | none | number | odd | sameas | sequence | string 46 | | test | true | undefined | upper ) 47 | 48 | builtin_functions: |- 49 | (?x: 50 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#list-of-global-functions 51 | cycler | dict | joiner | lipsum | namespace | range 52 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#i18n 53 | | _ | gettext | ngettext ) 54 | 55 | ############################################################################### 56 | 57 | contexts: 58 | main: 59 | - meta_scope: meta.template.jinja 60 | - include: jinja 61 | 62 | interpolations: 63 | # to be included in strings to clear string scope within tags 64 | - match: (?={[{%#]) 65 | push: interpolation-body 66 | 67 | interpolation-body: 68 | - clear_scopes: 1 69 | - meta_include_prototype: false 70 | - include: jinja-comment-tags 71 | - include: jinja-statement-tags 72 | - include: jinja-expression-tags 73 | - include: immediately-pop 74 | 75 | jinja: 76 | - include: jinja-comment-lines 77 | - include: jinja-statement-lines 78 | - include: jinja-comment-tags 79 | - include: jinja-statement-tags 80 | - include: jinja-expression-tags 81 | 82 | ###[ JINJA COMMENT LINES ]##################################################### 83 | 84 | jinja-comment-lines: 85 | - match: \#\# 86 | scope: punctuation.definition.comment.jinja 87 | push: jinja-comment-line-body 88 | 89 | jinja-comment-line-body: 90 | - meta_scope: meta.embedded.comment.jinja comment.line.jinja 91 | - match: $\n? 92 | pop: 1 93 | 94 | ###[ JINJA COMMENT TAGS ]###################################################### 95 | 96 | jinja-comment-tags: 97 | - match: \{\# 98 | scope: punctuation.definition.comment.begin.jinja 99 | push: jinja-comment-tag-body 100 | 101 | jinja-comment-tag-body: 102 | - meta_scope: meta.embedded.comment.jinja comment.block.jinja 103 | - match: \#\} 104 | scope: punctuation.definition.comment.end.jinja 105 | pop: 1 106 | 107 | ###[ JINJA STATEMENT LINES ]################################################### 108 | 109 | jinja-statement-lines: 110 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#line-statements 111 | - match: ^\s*(#(?!#)) 112 | scope: meta.embedded.statement.jinja 113 | captures: 114 | 1: punctuation.section.embedded.jinja 115 | push: 116 | - jinja-statement-line-end 117 | - jinja-statement-line-begin 118 | 119 | jinja-statement-line-begin: 120 | - meta_include_prototype: false 121 | - include: control-statement 122 | - include: block-statement-line 123 | - include: import-statement-line 124 | - include: macro-statement-line 125 | - include: raw-statement-line 126 | - include: set-statement-line 127 | - include: comment-statement-line 128 | - include: other-statement 129 | - include: else-pop 130 | - include: eol-pop 131 | 132 | jinja-statement-line-end: 133 | - meta_content_scope: meta.embedded.statement.jinja source.jinja.embedded 134 | - match: \:?(?=\s*(?:##|$)) 135 | scope: meta.embedded.statement.jinja source.jinja.embedded punctuation.section.block.jinja 136 | pop: 1 137 | - include: expressions 138 | 139 | ###[ JINJA STATEMENT TAGS ]#################################################### 140 | 141 | jinja-statement-tags: 142 | - match: \{%{{modifiers}}? 143 | scope: meta.embedded.statement.jinja punctuation.section.embedded.begin.jinja 144 | push: 145 | - jinja-statement-tag-end 146 | - jinja-statement-tag-begin 147 | 148 | jinja-statement-tag-begin: 149 | - include: control-statement 150 | - include: block-statement-tag 151 | - include: import-statement-tag 152 | - include: macro-statement-tag 153 | - include: raw-statement-tag 154 | - include: set-statement-tag 155 | - include: comment-statement-tag 156 | - include: other-statement 157 | - include: else-pop 158 | 159 | jinja-statement-tag-end: 160 | - meta_content_scope: meta.embedded.statement.jinja source.jinja.embedded 161 | - match: '{{modifiers}}?%\}' 162 | scope: meta.embedded.statement.jinja punctuation.section.embedded.end.jinja 163 | pop: 1 164 | - include: expressions 165 | 166 | ###[ JINJA EXPRESSION TAGS ]################################################### 167 | 168 | jinja-expression-tags: 169 | - match: \{{2} 170 | scope: meta.embedded.expression.jinja punctuation.section.embedded.begin.jinja 171 | push: jinja-expression-tag-body 172 | 173 | jinja-expression-tag-body: 174 | - meta_content_scope: meta.embedded.expression.jinja source.jinja.embedded 175 | - match: \}{2} 176 | scope: meta.embedded.expression.jinja punctuation.section.embedded.end.jinja 177 | pop: 1 178 | - include: expressions 179 | 180 | ###[ IMPORT DECLARATIONS ]##################################################### 181 | 182 | import-statement-line: 183 | # extends keyword 184 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#extends 185 | - match: extends\b 186 | scope: keyword.control.import.extends.jinja 187 | set: import-statement-line-body 188 | # import keywords 189 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#import 190 | - match: import\b 191 | scope: keyword.control.import.jinja 192 | set: import-statement-line-body 193 | - match: from\b 194 | scope: keyword.control.import.from.jinja 195 | set: 196 | - import-statement-line-body 197 | - from-statement-line-body 198 | # include keywords 199 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#include 200 | - match: include\b 201 | scope: keyword.control.import.jinja 202 | set: import-statement-line-body 203 | 204 | from-statement-line-body: 205 | - include: from-statement-tag-body 206 | - include: eol-pop 207 | 208 | import-statement-line-body: 209 | - meta_scope: meta.import.jinja 210 | - include: import-keywords 211 | - include: expressions 212 | - include: eol-pop 213 | 214 | import-statement-tag: 215 | # extends keyword 216 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#extends 217 | - match: extends\b 218 | scope: keyword.control.import.extends.jinja 219 | set: import-statement-tag-body 220 | # import keywords 221 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#import 222 | - match: import\b 223 | scope: keyword.control.import.jinja 224 | set: import-statement-tag-body 225 | - match: from\b 226 | scope: keyword.control.import.from.jinja 227 | set: 228 | - import-statement-tag-body 229 | - from-statement-tag-body 230 | # include keywords 231 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#include 232 | - match: include\b 233 | scope: keyword.control.import.jinja 234 | set: import-statement-tag-body 235 | 236 | from-statement-tag-body: 237 | - match: import\b 238 | scope: keyword.control.import.jinja 239 | pop: 1 240 | - include: strings 241 | - include: else-pop 242 | 243 | import-statement-tag-body: 244 | - meta_scope: meta.import.jinja 245 | - include: block-pop 246 | - include: import-keywords 247 | - include: expressions 248 | 249 | import-keywords: 250 | - match: (ignore)(?:\s+(missing))?\b 251 | captures: 252 | 1: keyword.other.jinja 253 | 2: keyword.other.jinja 254 | - match: (with(?:out)?)(?:\s+(context))?\b 255 | captures: 256 | 1: keyword.other.jinja 257 | 2: keyword.other.jinja 258 | 259 | ###[ BLOCK DECLARATIONS ]###################################################### 260 | 261 | block-statement-line: 262 | - match: block\b 263 | scope: keyword.declaration.block.jinja 264 | set: block-statement-line-name 265 | - match: endblock\b 266 | scope: keyword.declaration.block.end.jinja 267 | pop: 1 268 | 269 | block-statement-line-name: 270 | - include: block-statement-tag-name 271 | - include: eol-pop 272 | 273 | block-statement-tag: 274 | - match: block\b 275 | scope: keyword.declaration.block.jinja 276 | set: block-statement-tag-name 277 | - match: endblock\b 278 | scope: keyword.declaration.block.end.jinja 279 | pop: 1 280 | 281 | block-statement-tag-name: 282 | - match: '{{ident}}\b' 283 | scope: entity.name.section.block.jinja 284 | pop: 1 285 | - include: else-pop 286 | 287 | ###[ MACRO DECLARATIONS ]###################################################### 288 | 289 | macro-statement-line: 290 | - match: macro\b 291 | scope: meta.function.jinja keyword.declaration.macro.jinja 292 | set: 293 | - macro-statement-line-parameter-list 294 | - macro-statement-line-name 295 | - match: endmacro\b 296 | scope: keyword.declaration.macro.end.jinja 297 | pop: 1 298 | 299 | macro-statement-line-name: 300 | - include: macro-statement-tag-name 301 | - include: eol-pop 302 | 303 | macro-statement-line-parameter-list: 304 | - meta_content_scope: meta.function.identifier.jinja 305 | - include: macro-statement-tag-parameter-list 306 | - include: eol-pop 307 | 308 | macro-statement-tag: 309 | - match: macro\b 310 | scope: meta.function.jinja keyword.declaration.macro.jinja 311 | set: 312 | - macro-statement-tag-parameter-list 313 | - macro-statement-tag-name 314 | - match: endmacro\b 315 | scope: keyword.declaration.macro.end.jinja 316 | pop: 1 317 | 318 | macro-statement-tag-name: 319 | - match: '{{ident}}\b' 320 | scope: entity.name.function.macro.jinja 321 | pop: 1 322 | - include: else-pop 323 | 324 | macro-statement-tag-parameter-list: 325 | - meta_content_scope: meta.function.identifier.jinja 326 | - match: \( 327 | scope: punctuation.section.parameters.begin.jinja 328 | set: macro-statement-tag-parameter-list-body 329 | - include: else-pop 330 | 331 | macro-statement-tag-parameter-list-body: 332 | - meta_scope: meta.function.parameters.jinja 333 | - match: \) 334 | scope: punctuation.section.parameters.end.jinja 335 | pop: 1 336 | - match: ',' 337 | scope: punctuation.separator.parameters.jinja 338 | - match: '[:=]' 339 | scope: keyword.operator.assignment.jinja 340 | push: parameter-value 341 | - match: '{{ident}}\b' 342 | scope: variable.parameter.jinja 343 | - include: block-pop 344 | 345 | parameter-value: 346 | - match: (?=[,)]) 347 | pop: 1 348 | - include: block-pop 349 | - include: expressions 350 | 351 | ###[ COMMENT BLOCK DECLARATIONS ]############################################## 352 | 353 | comment-statement-line: 354 | - match: comment\b 355 | scope: keyword.other.tag.jinja 356 | pop: 2 # skip default `statement-line-end` 357 | push: 358 | - comment-block 359 | - jinja-statement-line-end 360 | 361 | comment-statement-tag: 362 | - match: comment\b 363 | scope: keyword.other.tag.jinja 364 | pop: 2 # skip default `statement-tag-end` 365 | push: 366 | - comment-block 367 | - jinja-statement-tag-end 368 | 369 | comment-block: 370 | - meta_include_prototype: false 371 | # start block at new line or with next non-whitespace 372 | - match: ^|(?=\s*\S) 373 | set: comment-block-body 374 | 375 | comment-block-body: 376 | # All but final `{% endcomment %}` or `# endcomment` is treated literal 377 | - meta_content_scope: comment.block.jinja.django 378 | - match: (?:^\s*)?(({%{{modifiers}}?)(\s*(endcomment\b))) 379 | captures: 380 | 1: meta.embedded.statement.jinja 381 | 2: punctuation.section.embedded.begin.jinja 382 | 3: source.jinja.embedded 383 | 4: keyword.other.endtag.jinja.django 384 | set: jinja-statement-tag-end 385 | - match: ^\s*(#)(\s*(endcomment\b)) 386 | scope: meta.embedded.statement.jinja 387 | captures: 388 | 1: punctuation.section.embedded.begin.jinja 389 | 2: source.jinja.embedded 390 | 3: keyword.other.endtag.jinja.django 391 | set: jinja-statement-line-end 392 | 393 | ###[ RAW BLOCK DECLARATIONS ]################################################## 394 | 395 | raw-statement-line: 396 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#line-statements 397 | - match: raw\b 398 | scope: keyword.other.tag.jinja 399 | pop: 2 # skip default `statement-line-end` 400 | push: 401 | - raw-block 402 | - jinja-statement-line-end 403 | 404 | raw-statement-tag: 405 | - match: raw\b 406 | scope: keyword.other.tag.jinja 407 | pop: 2 # skip default `statement-tag-end` 408 | push: 409 | - raw-block 410 | - jinja-statement-tag-end 411 | 412 | raw-block: 413 | - meta_include_prototype: false 414 | # start block at new line or with next non-whitespace 415 | - match: ^|(?=\s*\S) 416 | set: raw-block-body 417 | 418 | raw-block-body: 419 | # All but final `{% endraw %}` or `# endraw` is treated literal 420 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#escaping 421 | - meta_content_scope: markup.raw.block.jinja 422 | - match: (?:^\s*)?(({%{{modifiers}}?)(\s*(endraw\b))) 423 | captures: 424 | 1: meta.embedded.statement.jinja 425 | 2: punctuation.section.embedded.begin.jinja 426 | 3: source.jinja.embedded 427 | 4: keyword.other.endtag.jinja 428 | set: jinja-statement-tag-end 429 | - match: ^\s*(#)(\s*(endraw\b)) 430 | scope: meta.embedded.statement.jinja 431 | captures: 432 | 1: punctuation.section.embedded.begin.jinja 433 | 2: source.jinja.embedded 434 | 3: keyword.other.endtag.jinja 435 | set: jinja-statement-line-end 436 | 437 | ###[ VARIABLE DECLARATIONS ]################################################### 438 | 439 | set-statement-line: 440 | - match: set\b 441 | scope: meta.declaration.jinja keyword.declaration.variable.jinja 442 | set: set-statement-line-name 443 | - match: endset\b 444 | scope: keyword.declaration.variable.jinja 445 | pop: 1 446 | 447 | set-statement-line-name: 448 | - meta_content_scope: meta.declaration.identifier.jinja 449 | - include: set-statement-tag-name 450 | - include: eol-pop 451 | 452 | set-statement-tag: 453 | - match: set\b 454 | scope: meta.declaration.jinja keyword.declaration.variable.jinja 455 | set: set-statement-tag-name 456 | - match: endset\b 457 | scope: keyword.declaration.variable.jinja 458 | pop: 1 459 | 460 | set-statement-tag-name: 461 | - meta_content_scope: meta.declaration.identifier.jinja 462 | - include: separators 463 | - include: tuples 464 | - include: variables 465 | - include: else-pop 466 | 467 | ###[ CONTROL STATEMENTS ]###################################################### 468 | 469 | control-statement: 470 | # control keywords 471 | # https://jinja.palletsprojects.com/en/3.1.x/templates/#list-of-control-structures 472 | # conditional 473 | - match: if\b 474 | scope: keyword.control.conditional.if.jinja 475 | pop: 1 476 | - match: else\b 477 | scope: keyword.control.conditional.else.jinja 478 | pop: 1 479 | - match: elif\b 480 | scope: keyword.control.conditional.elseif.jinja 481 | pop: 1 482 | - match: endif\b 483 | scope: keyword.control.conditional.endif.jinja 484 | pop: 1 485 | # loops 486 | - match: for\b 487 | scope: keyword.control.loop.for.jinja 488 | pop: 1 489 | - match: endfor\b 490 | scope: keyword.control.loop.endfor.jinja 491 | pop: 1 492 | - match: continue\b 493 | scope: keyword.control.flow.continue.jinja 494 | pop: 1 495 | - match: break\b 496 | scope: keyword.control.flow.break.jinja 497 | pop: 1 498 | 499 | ###[ OTHER STATEMENTS ]######################################################## 500 | 501 | other-statement: 502 | # filter block tags 503 | - match: filter\b 504 | scope: keyword.other.tag.jinja 505 | set: 506 | - filter-meta 507 | - filter-name 508 | # any block tags 509 | - match: end{{ident}}\b(?!\s*[=(]) 510 | scope: keyword.other.endtag.jinja 511 | pop: 1 512 | - match: '{{ident}}\b(?!\s*[=(])' 513 | scope: keyword.other.tag.jinja 514 | pop: 1 515 | 516 | ###[ EXPRESSIONS ]############################################################# 517 | 518 | expressions: 519 | - include: dictionaries 520 | - include: lists 521 | - include: parens 522 | - include: constants 523 | - include: numbers 524 | - include: strings 525 | - include: operators 526 | - include: separators 527 | - include: filters 528 | - include: function-calls 529 | - include: variables 530 | 531 | ###[ FILTERS ]################################################################# 532 | 533 | filters: 534 | - match: \| 535 | scope: keyword.operator.symbol.jinja keyword.operator.assignment.pipe.jinja 536 | push: 537 | - filter-meta 538 | - filter-name 539 | 540 | filter-meta: 541 | - meta_include_prototype: false 542 | - meta_scope: meta.filter.jinja 543 | - include: immediately-pop 544 | 545 | filter-name: 546 | - match: '{{builtin_filters}}\b' 547 | scope: meta.function-call.identifier.jinja support.function.filter.jinja 548 | set: function-call-argument-list 549 | - match: '{{ident}}\b' 550 | scope: meta.function-call.identifier.jinja variable.function.filter.jinja 551 | set: function-call-argument-list 552 | - include: else-pop 553 | - include: eol-pop 554 | 555 | ###[ FUNCTION CALLS ]########################################################## 556 | 557 | function-calls: 558 | - match: '{{builtin_functions}}(?=\()' 559 | scope: meta.function-call.identifier.jinja support.function.global.jinja 560 | push: function-call-argument-list 561 | - match: '{{ident}}(?=\()' 562 | scope: meta.function-call.identifier.jinja variable.function.jinja 563 | push: function-call-argument-list 564 | 565 | function-call-argument-list: 566 | - match: \( 567 | scope: punctuation.section.arguments.begin.jinja 568 | set: function-call-argument-list-body 569 | - match: ':' 570 | scope: punctuation.separator.arguments.jinja.django 571 | pop: 1 572 | - include: immediately-pop 573 | 574 | function-call-argument-list-body: 575 | - meta_scope: meta.function-call.arguments.jinja 576 | - match: \) 577 | scope: punctuation.section.arguments.end.jinja 578 | pop: 1 579 | - match: ',' 580 | scope: punctuation.separator.arguments.jinja 581 | - match: '{{ident}}(?=\s*=)' 582 | scope: variable.parameter.jinja 583 | - include: block-pop 584 | - include: expressions 585 | 586 | ###[ COLLECTIONS ]############################################################# 587 | 588 | dictionaries: 589 | - match: \{ 590 | scope: punctuation.section.mapping.begin.jinja 591 | push: dictionary-body 592 | 593 | dictionary-body: 594 | - meta_scope: meta.mapping.jinja 595 | - include: block-pop 596 | - match: \} 597 | scope: punctuation.section.mapping.end.jinja 598 | pop: 1 599 | - match: ',' 600 | scope: punctuation.separator.mapping.pair.jinja 601 | - match: ':' 602 | scope: punctuation.separator.mapping.key-value.jinja 603 | set: dictionary-value 604 | - match: (?=\S) 605 | set: dictionary-key 606 | 607 | dictionary-key: 608 | - meta_content_scope: meta.mapping.key.jinja 609 | - match: (?=[,:}]) 610 | set: dictionary-body 611 | - include: block-pop 612 | - include: expressions 613 | 614 | dictionary-value: 615 | - meta_content_scope: meta.mapping.value.jinja 616 | - match: (?=[,:}]) 617 | set: dictionary-body 618 | - include: block-pop 619 | - include: expressions 620 | 621 | lists: 622 | - match: \[ 623 | scope: punctuation.section.sequence.begin.jinja 624 | push: list-body 625 | 626 | list-body: 627 | - meta_scope: meta.sequence.list.jinja 628 | - match: \] 629 | scope: punctuation.section.sequence.end.jinja 630 | pop: 1 631 | - include: block-pop 632 | - include: expressions 633 | 634 | parens: 635 | - match: (?=\() 636 | branch_point: parens 637 | branch: 638 | - group 639 | - tuple 640 | 641 | group: 642 | - meta_include_prototype: false 643 | - match: \( 644 | scope: punctuation.section.group.begin.jinja 645 | set: group-body 646 | 647 | group-body: 648 | - meta_scope: meta.group.jinja 649 | - match: \) 650 | scope: punctuation.section.group.end.jinja 651 | pop: 1 652 | - match: (?=,) 653 | fail: parens 654 | - include: block-pop 655 | - include: expressions 656 | 657 | tuples: 658 | - match: \( 659 | scope: punctuation.section.sequence.begin.jinja 660 | push: tuple-body 661 | 662 | tuple: 663 | - meta_include_prototype: false 664 | - match: \( 665 | scope: punctuation.section.sequence.begin.jinja 666 | set: tuple-body 667 | 668 | tuple-body: 669 | - meta_scope: meta.sequence.tuple.jinja 670 | - match: \) 671 | scope: punctuation.section.sequence.end.jinja 672 | pop: 1 673 | - include: block-pop 674 | - include: expressions 675 | 676 | ###[ OPERATORS ]############################################################### 677 | 678 | operators: 679 | # alphanumeric operators 680 | - match: as\b 681 | scope: keyword.operator.word.jinja keyword.operator.assignment.as.jinja 682 | - match: in\b 683 | scope: keyword.operator.word.jinja keyword.operator.iteration.in.jinja 684 | - match: (?:and|or|not)\b 685 | scope: keyword.operator.word.jinja keyword.operator.logical.jinja 686 | - match: is\b 687 | scope: keyword.operator.word.jinja keyword.operator.logical.jinja 688 | push: expect-test-function 689 | # symbolic operators 690 | - match: \~ 691 | scope: keyword.operator.symbol.jinja keyword.operator.concatenation.jinja 692 | - match: '[=!]=|[<>]=?' 693 | scope: keyword.operator.symbol.jinja keyword.operator.comparison.jinja 694 | - match: '=' 695 | scope: keyword.operator.symbol.jinja keyword.operator.assignment.jinja 696 | - match: '[*/]{2}|[-+*/%]' 697 | scope: keyword.operator.symbol.jinja keyword.operator.arithmetic.jinja 698 | 699 | separators: 700 | - match: ',' 701 | scope: punctuation.separator.sequence.jinja 702 | 703 | expect-test-function: 704 | - match: not\b 705 | scope: keyword.operator.word.jinja keyword.operator.logical.jinja 706 | - match: '{{builtin_tests}}\b' 707 | scope: meta.function-call.identifier.jinja support.function.test.jinja 708 | set: function-call-argument-list 709 | - match: '{{ident}}\b' 710 | scope: meta.function-call.identifier.jinja variable.function.test.jinja 711 | set: function-call-argument-list 712 | - include: else-pop 713 | 714 | ###[ LITERALS ]################################################################ 715 | 716 | constants: 717 | - match: '[Ff]alse\b' 718 | scope: constant.language.boolean.false.jinja 719 | - match: '[Tt]rue\b' 720 | scope: constant.language.boolean.true.jinja 721 | - match: '[Nn]one\b' 722 | scope: constant.language.null.jinja 723 | 724 | numbers: 725 | - match: (?:\d[\d_]*)?(\.)\d+(?:[eE]\d*)? 726 | scope: meta.number.float.decimal.jinja constant.numeric.value.jinja 727 | captures: 728 | 1: punctuation.separator.decimal.jinja 729 | - match: \d[\d_]* 730 | scope: meta.number.integer.decimal.jinja constant.numeric.value.jinja 731 | 732 | strings: 733 | - match: \" 734 | scope: punctuation.definition.string.begin.jinja 735 | push: double-quoted-string-body 736 | - match: \' 737 | scope: punctuation.definition.string.begin.jinja 738 | push: single-quoted-string-body 739 | 740 | double-quoted-string-body: 741 | - meta_include_prototype: false 742 | - meta_scope: meta.string.jinja string.quoted.double.jinja 743 | - match: \" 744 | scope: punctuation.definition.string.end.jinja 745 | pop: 1 746 | - include: string-prototype 747 | - include: escaped-characters 748 | - include: string-placeholders 749 | - include: string-interpolations 750 | 751 | single-quoted-string-body: 752 | - meta_include_prototype: false 753 | - meta_scope: meta.string.jinja string.quoted.single.jinja 754 | - match: \' 755 | scope: punctuation.definition.string.end.jinja 756 | pop: 1 757 | - include: string-prototype 758 | - include: escaped-characters 759 | - include: string-placeholders 760 | 761 | string-prototype: [] 762 | 763 | string-interpolations: 764 | - match: \{ 765 | scope: punctuation.section.interpolation.begin.jinja 766 | push: string-interpolation-body 767 | 768 | string-interpolation-body: 769 | - clear_scopes: 1 770 | - meta_scope: meta.interpolation.jinja 771 | - match: \} 772 | scope: punctuation.section.interpolation.end.jinja 773 | pop: 1 774 | - match: ':' 775 | scope: punctuation.separator.format-spec.jinja 776 | push: string-interpolation-formatspec 777 | - match: '![ars]\b' 778 | scope: storage.modifier.conversion.jinja 779 | - include: expressions 780 | 781 | string-interpolation-formatspec: 782 | - meta_content_scope: meta.format-spec.jinja constant.other.format-spec.jinja 783 | - match: \} 784 | scope: punctuation.section.interpolation.end.jinja 785 | pop: 2 786 | - include: string-interpolations 787 | 788 | string-placeholders: 789 | # printf style (from Python) 790 | - match: |- 791 | (?x) 792 | % 793 | ( \( ({{ident}}) \) )? # mapping key 794 | \#? # alternate form 795 | 0? # pad with zeros 796 | \-? # left-adjust 797 | \ ? # implicit sign 798 | [+-]? # sign 799 | (\d*|\*) # width 800 | (\. (\d*|\*))? # precision 801 | [hlL]? # length modifier (but ignored) 802 | [acdeEfFgGiorsuxX%] 803 | scope: constant.other.placeholder.jinja 804 | captures: 805 | 2: variable.other.placeholder.jinja 806 | # strftime spec (from Python) 807 | - match: \%(?:[aAwdbBGmyYHIpMSfzZjuUVWcxX%]|-[dmHIMSj]) 808 | scope: constant.other.placeholder.jinja 809 | 810 | escaped-characters: 811 | # escaped string braces (from Python) 812 | - match: \{[{%]|[%}]\} 813 | scope: constant.character.escape.jinja 814 | # escapes (from Python) 815 | - match: \\x\h{2} 816 | scope: constant.character.escape.hex.jinja 817 | - match: \\[0-7]{1,3} 818 | scope: constant.character.escape.octal.jinja 819 | - match: \\[\\"'abfnrtv] 820 | scope: constant.character.escape.jinja 821 | # unicode (from Python) 822 | - match: \\u\h{4} 823 | scope: constant.character.escape.unicode.16bit.jinja 824 | - match: \\U\h{8} 825 | scope: constant.character.escape.unicode.32bit.jinja 826 | - match: \\N\{[-a-zA-Z ]+\} 827 | scope: constant.character.escape.unicode.name.jinja 828 | 829 | ###[ VARIABLES ]############################################################### 830 | 831 | variables: 832 | - match: _\b 833 | scope: variable.language.anonymous.jinja 834 | - match: loop\b 835 | scope: meta.path.jinja variable.language.loop.jinja 836 | - match: (?={{ident_start}}) 837 | branch_point: variable 838 | branch: 839 | - unqualified-variable 840 | - qualified-variable 841 | - match: '{{dot_accessor}}' 842 | scope: punctuation.accessor.dot.jinja 843 | push: 844 | - accessor 845 | - member 846 | 847 | unqualified-variable: 848 | - meta_include_prototype: false 849 | - match: '{{ident}}\b' 850 | scope: variable.other.readwrite.jinja 851 | set: 852 | - variable-check 853 | - subscription 854 | - include: immediately-pop 855 | 856 | variable-check: 857 | - match: (?={{dot_accessor}}) 858 | fail: variable 859 | - include: immediately-pop 860 | 861 | qualified-variable: 862 | - meta_include_prototype: false 863 | - match: '{{ident}}\b' 864 | scope: variable.other.object.jinja 865 | set: 866 | - accessor 867 | - subscription 868 | - include: immediately-pop 869 | 870 | accessor: 871 | - meta_include_prototype: false 872 | - meta_scope: meta.path.jinja 873 | - match: '{{dot_accessor}}' 874 | scope: punctuation.accessor.dot.jinja 875 | push: member 876 | - include: immediately-pop 877 | 878 | member: 879 | - match: '{{ident}}(?=\()' 880 | scope: meta.function-call.identifier.jinja variable.function.method.jinja 881 | set: 882 | - subscription 883 | - function-call-argument-list 884 | - match: (?={{ident_start}}) 885 | branch_point: property 886 | branch: 887 | - property 888 | - object 889 | pop: 1 890 | - include: subscription 891 | 892 | object: 893 | - match: '{{ident}}\b' 894 | scope: variable.other.object.jinja 895 | set: subscription 896 | - include: immediately-pop 897 | 898 | property: 899 | - match: '{{ident}}\b' 900 | scope: variable.other.member.jinja 901 | set: 902 | - property-check 903 | - subscription 904 | - include: immediately-pop 905 | 906 | property-check: 907 | - match: (?={{dot_accessor}}) 908 | fail: property 909 | - include: immediately-pop 910 | 911 | subscription: 912 | - match: \[ 913 | scope: punctuation.section.subscription.begin.jinja 914 | set: subscription-body 915 | - include: immediately-pop 916 | 917 | subscription-body: 918 | - meta_scope: meta.subscription.jinja 919 | - match: \] 920 | scope: punctuation.section.subscription.end.jinja 921 | set: subscription 922 | - match: ':' 923 | scope: punctuation.separator.slice.jinja 924 | - include: expressions 925 | 926 | ###[ PROTOTYPES ]############################################################## 927 | 928 | else-pop: 929 | - match: (?=\S) 930 | pop: 1 931 | 932 | immediately-pop: 933 | - match: '' 934 | pop: 1 935 | 936 | block-pop: 937 | - match: (?={{modifiers}}?[%}]}) 938 | pop: 1 939 | 940 | eol-pop: 941 | - match: (?=\:?\s*(?:##|$)) 942 | pop: 1 943 | -------------------------------------------------------------------------------- /Syntaxes/XML/Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | scope 6 | text.xml.jinja 7 | settings 8 | 9 | shellVariables 10 | 11 | 12 | name 13 | TM_COMMENT_START 14 | value 15 | ## 16 | 17 | 18 | name 19 | TM_COMMENT_START_2 20 | value 21 | {# 22 | 23 | 24 | name 25 | TM_COMMENT_END_2 26 | value 27 | #} 28 | 29 | 30 | name 31 | TM_COMMENT_START_3 32 | value 33 | 34 | 35 | 36 | name 37 | TM_COMMENT_END_3 38 | value 39 | ]]> 40 | 41 | 42 | name 43 | TM_COMMENT_START_4 44 | value 45 | 46 | 47 | 48 | name 49 | TM_COMMENT_END_4 50 | value 51 | ]]> 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Syntaxes/XML/Snippet Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | text.xml.jinja 6 | settings 7 | 8 | shellVariables 9 | 10 | 11 | 12 | name 13 | TM_TEMPLATE_INDENT 14 | value 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Syntaxes/XML/XML (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: XML (Jinja) 5 | scope: text.xml.jinja 6 | version: 2 7 | 8 | extends: Packages/XML/XML.sublime-syntax 9 | 10 | file_extensions: 11 | - xml.jinja 12 | - xml.jinja2 13 | - xml.j2 14 | - jinja.xml 15 | - jinja2.xml 16 | - j2.xml 17 | 18 | variables: 19 | tag_name_break: (?=[/<>\s]) 20 | tag_name_start: (?:[A-Za-z]|{{) 21 | 22 | contexts: 23 | 24 | prototype: 25 | - meta_prepend: true 26 | - include: Text (Jinja).sublime-syntax 27 | 28 | main: 29 | - meta_prepend: true 30 | - meta_scope: meta.template.jinja 31 | 32 | comment-content: 33 | - meta_prepend: true 34 | - include: Text (Jinja).sublime-syntax#interpolations 35 | 36 | cdata-content: 37 | - meta_prepend: true 38 | - include: Text (Jinja).sublime-syntax#interpolations 39 | 40 | string-common-content: 41 | - meta_prepend: true 42 | - include: Text (Jinja).sublime-syntax#interpolations 43 | 44 | tag: 45 | # overwrite context to support tag name interpolation 46 | - match: <(?={{tag_name_start}}) 47 | scope: punctuation.definition.tag.begin.opening.xml 48 | push: 49 | - begin-tag-content 50 | - tag-name 51 | - match: 2 | 3 | 4 | 5 | scope 6 | source.yaml.jinja 7 | settings 8 | 9 | shellVariables 10 | 11 | 12 | name 13 | TM_COMMENT_START 14 | value 15 | {# 16 | 17 | 18 | name 19 | TM_COMMENT_END 20 | value 21 | #} 22 | 23 | 24 | name 25 | TM_COMMENT_START_2 26 | value 27 | {# 28 | 29 | 30 | name 31 | TM_COMMENT_END_2 32 | value 33 | #} 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Syntaxes/YAML/Snippet Variables.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | scope 5 | source.yaml.jinja 6 | settings 7 | 8 | shellVariables 9 | 10 | 11 | 12 | name 13 | TM_TEMPLATE_INDENT 14 | value 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Syntaxes/YAML/YAML (Jinja).sublime-syntax: -------------------------------------------------------------------------------- 1 | %YAML 1.2 2 | --- 3 | # http://www.sublimetext.com/docs/syntax.html 4 | name: YAML (Jinja) 5 | scope: source.yaml.jinja 6 | version: 2 7 | 8 | extends: Packages/YAML/YAML.sublime-syntax 9 | 10 | file_extensions: 11 | - yaml.jinja 12 | - yaml.jinja2 13 | - yaml.j2 14 | - jinja.yaml 15 | - jinja2.yaml 16 | - j2.yaml 17 | - yml.jinja 18 | - yml.jinja2 19 | - yml.j2 20 | - jinja.yml 21 | - jinja2.yml 22 | - j2.yml 23 | # Django 24 | - djyml 25 | - dj.yml 26 | - yml.djt 27 | - djyaml 28 | - dj.yaml 29 | - yaml.djt 30 | 31 | variables: 32 | ns_plain_first_plain_in: |- # c=plain-in 33 | (?x: 34 | {{yaml_ns_plain_first_plain_in}} 35 | | (?:[?:-] )?{{ # begins with interpolation 36 | ) 37 | 38 | # original value from YAML 39 | yaml_ns_plain_first_plain_in: |- # c=plain-in 40 | (?x: 41 | [^\s{{c_indicator}}] 42 | | [?:-] [^\s{{c_flow_indicator}}] 43 | ) 44 | 45 | ns_plain_first_plain_out: |- # c=plain-out 46 | (?x: 47 | {{yaml_ns_plain_first_plain_out}} 48 | | (?:[?:-] )?{{ # begins with interpolation 49 | ) 50 | 51 | # original value from YAML 52 | yaml_ns_plain_first_plain_out: |- # c=plain-out 53 | (?x: 54 | [^\s{{c_indicator}}] 55 | | [?:-] \S 56 | ) 57 | 58 | _flow_key_in_lookahead: |- 59 | (?x: 60 | (?= 61 | ( 62 | (?: 63 | {{yaml_ns_plain_first_plain_in}} 64 | | {{jinja_interpolation}} # begins with interpolation 65 | ) 66 | ( [^\s:{{c_flow_indicator}}] 67 | | : [^\s{{c_flow_indicator}}] 68 | | \s+ (?![#\s]) 69 | | {{jinja_interpolation}} # ignore interpolation 70 | )* 71 | | \".*\" # simplified 72 | | \'.*\' 73 | ) 74 | \s* 75 | : 76 | (?:\s|$) 77 | ) 78 | ) 79 | 80 | _flow_key_out_lookahead: |- 81 | (?x: 82 | (?= 83 | 84 | ( 85 | (?: 86 | {{yaml_ns_plain_first_plain_out}} 87 | | {{jinja_interpolation}} # begins with interpolation 88 | ) 89 | ( [^\s:] 90 | | : \S 91 | | \s+ (?![#\s]) 92 | | {{jinja_interpolation}} # ignore interpolation 93 | )* 94 | | \".*\" # simplified 95 | | \'.*\' 96 | ) 97 | \s* 98 | : 99 | (?:\s|$) 100 | ) 101 | ) 102 | 103 | jinja_interpolation: '{{.*?}}' 104 | 105 | contexts: 106 | 107 | main: 108 | - meta_prepend: true 109 | - meta_scope: meta.template.jinja 110 | 111 | block-scalar-body: 112 | - meta_prepend: true 113 | - include: Text (Jinja).sublime-syntax#interpolations 114 | 115 | flow-scalar-plain-in-body: 116 | - meta_prepend: true 117 | - include: Text (Jinja).sublime-syntax#interpolations 118 | 119 | flow-scalar-plain-out-body: 120 | - meta_prepend: true 121 | - include: Text (Jinja).sublime-syntax#interpolations 122 | 123 | flow-scalar-double-quoted-body: 124 | - meta_prepend: true 125 | - include: Text (Jinja).sublime-syntax#interpolations 126 | 127 | flow-scalar-single-quoted-body: 128 | - meta_prepend: true 129 | - include: Text (Jinja).sublime-syntax#interpolations 130 | 131 | flow-collection: 132 | - meta_prepend: true 133 | - include: Text (Jinja).sublime-syntax#jinja-comment-tags 134 | - include: Text (Jinja).sublime-syntax#jinja-statement-tags 135 | 136 | flow-mapping: 137 | - match: \{(?![{%#]) 138 | scope: punctuation.definition.mapping.begin.yaml 139 | push: flow-mapping-body 140 | -------------------------------------------------------------------------------- /make.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | chcp 65001 >nul 4 | pushd %~dp0 5 | 6 | if /i "%1" == "release" goto RELEASE 7 | goto :usage 8 | 9 | :RELEASE 10 | if "%2"== "" goto :usage 11 | set version=%2 12 | 13 | for %%d in ("%~dp0.") do set package=%%~nxd 14 | 15 | echo Creating assets for "%package%"... 16 | 17 | :: create downloadable asset for ST4126+ 18 | set branch=master 19 | set tag=4152-%version% 20 | set archive=%package%.sublime-package 21 | set assets="%archive%#%archive%" 22 | call git push origin %branch% 23 | call git archive --format zip -o "%archive%" %branch% 24 | 25 | :: create the release 26 | gh release create --target %branch% -t "Release %version%" "%tag%" %assets% 27 | del /f /q *.sublime-package 28 | git fetch 29 | goto :eof 30 | 31 | :USAGE 32 | echo USAGE: 33 | echo. 34 | echo all ^[release^] 35 | echo prefs ^[release^] 36 | echo make ^[release^] 37 | echo. 38 | echo release ^ -- create and publish a release (e.g. 1.2.3) 39 | goto :eof 40 | -------------------------------------------------------------------------------- /messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "install": "messages/install.txt" 3 | } 4 | -------------------------------------------------------------------------------- /messages/install.txt: -------------------------------------------------------------------------------- 1 | _ _ _ ___ 2 | | (_) (_) |__ \ 3 | | |_ _ __ _ __ _ ) | 4 | _ | | | '_ \| |/ _` | / / 5 | | |__| | | | | | | (_| |/ /_ 6 | \____/|_|_| |_| |\__,_|____| 7 | _/ | 8 | |__/ by Ashwin Shenoy 9 | ====================================================================== 10 | 11 | Jinja2 package provides syntax definitions, snippets and completions 12 | for Jinja and Django templates in Sublime Text. 13 | 14 | Supported languages are: 15 | CSS, C++, JavaScript, JSON, HTML, Markdown, Text, XML and YAML. 16 | 17 | Quick start 18 | ----------- 19 | 20 | Each syntax definition is assigned to a default set of file extensions, 21 | following the schema of: 22 | 23 | - ..jinja 24 | - .jinja. 25 | - ..jinja2 26 | - .jinja2. 27 | - ..j2 28 | - .j2. 29 | 30 | Default templating language is HTML with following file extensions: 31 | 32 | - .j2 33 | - .jinja 34 | - .jinja2 35 | - .htm.j2 36 | - .htm.jinja 37 | - .htm.jinja2 38 | - .html.j2 39 | - .html.jinja 40 | - .html.jinja2 41 | - .djt 42 | - .djhtml 43 | - .dj.html 44 | - .html.djt 45 | 46 | Having Problems ? 47 | ----------------- 48 | 49 | If you encounter any problems with Jinja2, or you think that it 50 | can be improved to make your work easier, please log an issue with the 51 | issue tracker: 52 | 53 | https://github.com/Sublime-Instincts/BetterJinja/issues 54 | --------------------------------------------------------------------------------