|
208 | 208 |
|
209 | 209 | (defvar elixir-mode--eval-filename "elixir-mode-tmp-eval-file.exs") |
210 | 210 |
|
211 | | -(defvar elixir-mode-define-names |
212 | | - '("def" |
213 | | - "defdelegate" |
214 | | - "defmacro" |
215 | | - "defmacrop" |
216 | | - "defoverridable" |
217 | | - "defp" |
218 | | - "defmacrop") |
219 | | - "Elixir mode def-like keywords.") |
220 | | -(defvar elixir-mode-keyword-names |
221 | | - '("->" |
222 | | - "bc" |
223 | | - "lc" |
224 | | - "in" |
225 | | - "inbits" |
226 | | - "inlist" |
227 | | - "quote" |
228 | | - "unquote" |
229 | | - "unquote_splicing" |
230 | | - "var" |
231 | | - "do" |
232 | | - "after" |
233 | | - "for" |
234 | | - "def" |
235 | | - "defdelegate" |
236 | | - "defimpl" |
237 | | - "defmacro" |
238 | | - "defmacrop" |
239 | | - "defmodule" |
240 | | - "defoverridable" |
241 | | - "defp" |
242 | | - "defprotocol" |
243 | | - "defrecord" |
244 | | - "defstruct" |
245 | | - "destructure" |
246 | | - "alias" |
247 | | - "require" |
248 | | - "import" |
249 | | - "use" |
250 | | - "if" |
251 | | - "unless" |
252 | | - "true" |
253 | | - "false" |
254 | | - "when" |
255 | | - "case" |
256 | | - "cond" |
257 | | - "throw" |
258 | | - "then" |
259 | | - "else" |
260 | | - "elsif" |
261 | | - "try" |
262 | | - "catch" |
263 | | - "rescue" |
264 | | - "fn" |
265 | | - "function" |
266 | | - "receive" |
267 | | - "end") |
268 | | - "Elixir mode keywords.") |
269 | | -(defvar elixir-mode-module-names |
270 | | - '("Agent" |
271 | | - "Base" |
272 | | - "Behavior" |
273 | | - "Binary" |
274 | | - "Bitwise" |
275 | | - "Builtin" |
276 | | - "Elixir" |
277 | | - "Code" |
278 | | - "EEx" |
279 | | - "Enum" |
280 | | - "ExUnit" |
281 | | - "Exception" |
282 | | - "File" |
283 | | - "GenServer" |
284 | | - "Function" |
285 | | - "GenServer" |
286 | | - "GenTCP" |
287 | | - "HashDict" |
288 | | - "IO" |
289 | | - "Keyword" |
290 | | - "List" |
291 | | - "Math" |
292 | | - "Module" |
293 | | - "Node" |
294 | | - "OptionParser" |
295 | | - "OrdDict" |
296 | | - "Port" |
297 | | - "Process" |
298 | | - "Record" |
299 | | - "Regexp" |
300 | | - "System" |
301 | | - "Task" |
302 | | - "Tuple" |
303 | | - "URI" |
304 | | - "UnboundMethod") |
305 | | - "Elixir mode modules.") |
306 | | -(defvar elixir-mode-builtin-names |
307 | | - '("Erlang" |
308 | | - "__MODULE__" |
309 | | - "__LINE__" |
310 | | - "__FILE__" |
311 | | - "__ENV__") |
312 | | - "Elixir mode builtins.") |
313 | | -(defvar elixir-mode-operator-names |
314 | | - '("+" |
315 | | - "++" |
316 | | - "<>" |
317 | | - "-" |
318 | | - "/" |
319 | | - "*" |
320 | | - "div" |
321 | | - "rem" |
322 | | - "==" |
323 | | - "!=" |
324 | | - "<=" |
325 | | - "<" |
326 | | - ">=" |
327 | | - ">" |
328 | | - "===" |
329 | | - "!==" |
330 | | - "and" |
331 | | - "or" |
332 | | - "not" |
333 | | - "&&" |
334 | | - "||" |
335 | | - "!" |
336 | | - "." |
337 | | - "#" |
338 | | - "=" |
339 | | - ":=" |
340 | | - "<-") |
341 | | - "Elixir mode operators.") |
342 | | - |
343 | | -(defvar elixir-mode-sigils '("B" "C" "R" "b" "c" "r") |
344 | | - "~-prefixed sigils that are understood by `elixir-mode'.") |
345 | | - |
346 | 211 | (defvar elixir-basic-offset 2) |
347 | 212 | (defvar elixir-key-label-offset 0) |
348 | 213 | (defvar elixir-match-label-offset 2) |
349 | 214 |
|
350 | | -(defvar font-lock-operator-face 'font-lock-operator-face) |
351 | | -(defface font-lock-operator-face |
352 | | - '((((type tty) (class color)) nil) |
353 | | - (((class color) (background light)) |
354 | | - (:foreground "darkred")) |
| 215 | +(defvar elixir-operator-face 'elixir-operator-face) |
| 216 | +(defface elixir-operator-face |
| 217 | + '((((class color) (min-colors 88) (background light)) |
| 218 | + :foreground "darkred") |
| 219 | + (((class color) (background dark)) |
| 220 | + (:foreground "lemonchiffon1")) |
355 | 221 | (t nil)) |
356 | 222 | "For use with operators." |
357 | 223 | :group 'font-lock-faces) |
358 | 224 |
|
359 | | -(defconst elixir-mode-font-lock-defaults |
360 | | - (list |
361 | | - ;; records and modules at point of definition: |
362 | | - '("^\\s *def\\(module\\|record\\|protocol\\|impl\\)\\s +\\([^( \t\n,]+\\)" 2 font-lock-type-face) |
363 | | - |
364 | | - ;; use/require/import: |
365 | | - '("^\\s *\\(use\\|require\\|import\\)\\s \\([^\n]+\\)" 2 font-lock-type-face) |
366 | | - |
367 | | - ;; methods: |
368 | | - `(,(concat "^\\s *\\<" (regexp-opt elixir-mode-define-names t) "\\>\\s +\\([^( \t\n]+\\)") 2 font-lock-function-name-face) |
369 | | - |
370 | | - ;; keywords: |
371 | | - `(,(concat "\\<" (regexp-opt elixir-mode-keyword-names t) "\\>") . font-lock-keyword-face) |
372 | | - |
373 | | - ;; ~ Sigils |
374 | | - `(,(concat "\\<~" (regexp-opt elixir-mode-sigils t) "\\>") . font-lock-builtin-face) |
375 | | - |
376 | | - ;; builtins: |
377 | | - `(,(concat "\\<" (regexp-opt elixir-mode-builtin-names t) "\\>") . font-lock-builtin-face) |
| 225 | +(eval-when-compile |
| 226 | + (defconst elixir-rx-constituents |
| 227 | + `( |
| 228 | + (keywords . ,(rx symbol-start |
| 229 | + (or "->" "bc" "lc" "in" "inbits" "inlist" "quote" |
| 230 | + "unquote" "unquote_splicing" "var" "do" "after" "for" |
| 231 | + "def" "defdelegate" "defimpl" "defmacro" "defmacrop" |
| 232 | + "defmodule" "defoverridable" "defp" "defprotocol" |
| 233 | + "defrecord" "defstruct" "destructure" "alias" |
| 234 | + "require" "import" "use" "if" "unless" "when" "case" |
| 235 | + "cond" "throw" "then" "else" "elsif" "try" "catch" |
| 236 | + "rescue" "fn" "function" "receive" "end") |
| 237 | + symbol-end)) |
| 238 | + (imports . ,(rx symbol-start |
| 239 | + (or "use" "require" "import") |
| 240 | + symbol-end)) |
| 241 | + (bool-and-nil . ,(rx symbol-start |
| 242 | + (or "true" "false" "nil") |
| 243 | + symbol-end)) |
| 244 | + (builtins . ,(rx symbol-start |
| 245 | + (or "Erlang" "__MODULE__" "__LINE__" "__FILE__" |
| 246 | + "__ENV__" "__DIR__") |
| 247 | + symbol-end)) |
| 248 | + (sigils . ,(rx "~" (or "B" "C" "R" "S" "b" "c" "r" "s" "w"))) |
| 249 | + (method-defines . ,(rx symbol-start |
| 250 | + (or "def" "defdelegate" "defmacro" "defmacrop" |
| 251 | + "defoverridable" "defp" "defmacrop") |
| 252 | + symbol-end)) |
| 253 | + (module-defines . ,(rx symbol-start |
| 254 | + (or "defmodule" "defprotocol" "defimpl" |
| 255 | + "defrecord") |
| 256 | + symbol-end)) |
| 257 | + (builtin-modules . ,(rx symbol-start |
| 258 | + (or "Agent" "Base" "Behavior" "Binary" "Bitwise" |
| 259 | + "Builtin" "Elixir" "Code" "EEx" "Enum" |
| 260 | + "ExUnit" "Exception" "File" "GenServer" |
| 261 | + "Function" "GenServer" "GenTCP" "HashDict" |
| 262 | + "IO" "Keyword" "List" "Math" "Module" "Node" |
| 263 | + "OptionParser" "OrdDict" "Port" "Process" |
| 264 | + "Record" "Regexp" "System" "Task" "Tuple" |
| 265 | + "URI" "UnboundMethod") |
| 266 | + symbol-end)) |
| 267 | + (operators . ,(rx symbol-start |
| 268 | + (or "+" "++" "<>" "-" "/" "*" "div" "rem" "==" "!=" "<=" |
| 269 | + "<" ">=" ">" "===" "!==" "and" "or" "not" "&&" "||" |
| 270 | + "!" "." "#" "=" ":=" "<-"))) |
| 271 | + (resource-name . ,(rx symbol-start |
| 272 | + (zero-or-more (any "A-Z") |
| 273 | + (zero-or-more |
| 274 | + (any "a-z")) |
| 275 | + "." |
| 276 | + (any "A-Z") |
| 277 | + (zero-or-more |
| 278 | + (any "a-z"))) |
| 279 | + symbol-end)) |
| 280 | + (variables . ,(rx symbol-start |
| 281 | + (one-or-more (any "A-Z" "a-z" "0-9" "_")) |
| 282 | + symbol-end)) |
| 283 | + (atoms . ,(rx ":" |
| 284 | + (or |
| 285 | + (one-or-more (any "a-z" "A-Z" "0-9" "_")) |
| 286 | + (and "\"" (one-or-more (not (any "\""))) "\"") |
| 287 | + (and "'" (one-or-more (not (any "'"))) "'")))) |
| 288 | + (code-point . ,(rx "?" anything)))) |
| 289 | + |
| 290 | + (defmacro elixir-rx (&rest sexps) |
| 291 | + (let ((rx-constituents (append elixir-rx-constituents rx-constituents))) |
| 292 | + (cond ((null sexps) |
| 293 | + (error "No regexp")) |
| 294 | + ((cdr sexps) |
| 295 | + (rx-to-string `(and ,@sexps) t)) |
| 296 | + (t |
| 297 | + (rx-to-string (car sexps) t)))))) |
378 | 298 |
|
379 | | - ;; core modules: |
380 | | - `(,(concat "\\<" (regexp-opt elixir-mode-module-names t) "\\>") . font-lock-type-face) |
381 | | - |
382 | | - ;; operators: |
383 | | - (when elixir-mode-highlight-operators |
384 | | - `(,(concat "\\<" (regexp-opt elixir-mode-operator-names t) "\\>") . font-lock-operator-face)) |
385 | | - |
386 | | - ;; variables: |
387 | | - '("\\(\\w+\\)\\s-*:?=[^=]" 1 font-lock-variable-name-face) |
388 | | - |
389 | | - ;; regexes: |
390 | | - '("~r/\\(.*\\)/[, \n\t]*" 1 font-lock-string-face) |
391 | | - |
392 | | - ;; atoms, boolean: |
393 | | - '("\\<\\(true\\|false\\|nil\\)\\>" . font-lock-reference-face) |
394 | | - |
395 | | - ;; atoms, generic |
396 | | - '("[@:]\\w*\\|\\w*:\\s-" . font-lock-reference-face)) |
397 | | - "Highlighting for Elixir mode.") |
| 299 | +(defconst elixir-mode-font-lock-defaults |
| 300 | + `( |
| 301 | + ;; Import, module- and method-defining keywords |
| 302 | + (,(elixir-rx (or method-defines module-defines imports) |
| 303 | + space |
| 304 | + (group resource-name)) |
| 305 | + 1 font-lock-type-face) |
| 306 | + |
| 307 | + ;; Keywords |
| 308 | + (,(elixir-rx (group keywords)) |
| 309 | + 1 font-lock-keyword-face) |
| 310 | + |
| 311 | + ;; Method names, i.e. `def foo do' |
| 312 | + (,(elixir-rx method-defines |
| 313 | + space |
| 314 | + (group (one-or-more (any "a-z" "_")))) |
| 315 | + 1 font-lock-function-name-face) |
| 316 | + |
| 317 | + ;; Variable definitions |
| 318 | + (,(elixir-rx (group variables) |
| 319 | + (one-or-more space) |
| 320 | + "=" |
| 321 | + (one-or-more space)) |
| 322 | + 1 font-lock-variable-name-face) |
| 323 | + |
| 324 | + ;; Built-in constants |
| 325 | + (,(elixir-rx (group builtins)) |
| 326 | + 1 font-lock-builtin-face) |
| 327 | + |
| 328 | + ;; Sigils |
| 329 | + (,(elixir-rx (group sigils)) |
| 330 | + 1 font-lock-builtin-face) |
| 331 | + |
| 332 | + ;; Regex patterns. Elixir has support for eight different regex delimiters. |
| 333 | + ;; This isn't a very DRY approach here but it gets the job done. |
| 334 | + (,(elixir-rx "~r" |
| 335 | + (and "/" (group (one-or-more (not (any "/")))) "/")) |
| 336 | + 1 font-lock-string-face) |
| 337 | + (,(elixir-rx "~r" |
| 338 | + (and "[" (group (one-or-more (not (any "]")))) "]")) |
| 339 | + 1 font-lock-string-face) |
| 340 | + (,(elixir-rx "~r" |
| 341 | + (and "{" (group (one-or-more (not (any "}")))) "}")) |
| 342 | + 1 font-lock-string-face) |
| 343 | + (,(elixir-rx "~r" |
| 344 | + (and "(" (group (one-or-more (not (any ")")))) ")")) |
| 345 | + 1 font-lock-string-face) |
| 346 | + (,(elixir-rx "~r" |
| 347 | + (and "|" (group (one-or-more (not (any "|")))) "|")) |
| 348 | + 1 font-lock-string-face) |
| 349 | + (,(elixir-rx "~r" |
| 350 | + (and "\"" (group (one-or-more (not (any "\"")))) "\"")) |
| 351 | + 1 font-lock-string-face) |
| 352 | + (,(elixir-rx "~r" |
| 353 | + (and "'" (group (one-or-more (not (any "'")))) "'")) |
| 354 | + 1 font-lock-string-face) |
| 355 | + (,(elixir-rx "~r" |
| 356 | + (and "<" (group (one-or-more (not (any ">")))) ">")) |
| 357 | + 1 font-lock-string-face) |
| 358 | + |
| 359 | + ;; Built-in modules |
| 360 | + (,(elixir-rx (group builtin-modules)) |
| 361 | + 1 font-lock-constant-face) |
| 362 | + |
| 363 | + ;; Operators |
| 364 | + (,(elixir-rx (group operators)) |
| 365 | + 1 elixir-operator-face) |
| 366 | + |
| 367 | + ;; Atoms and singleton-like words like true/false/nil. |
| 368 | + (,(elixir-rx (group (or atoms bool-and-nil))) |
| 369 | + 1 font-lock-reference-face))) |
398 | 370 |
|
399 | 371 | (defun elixir-mode-cygwin-path (expanded-file-name) |
400 | 372 | "Elixir mode get Cygwin absolute path name. |
|
0 commit comments