|
220 | 220 | (((class color) (background dark))
|
221 | 221 | (:foreground "#ff4500"))
|
222 | 222 | (t nil))
|
223 |
| - "For use with escape characters." |
| 223 | + "For use with standalone \"?\" to indicate code point." |
224 | 224 | :group 'font-lock-faces)
|
225 | 225 |
|
| 226 | +(defvar elixir-attribute-face 'elixir-attribute-face) |
| 227 | +(defface elixir-attribute-face |
| 228 | + '((((class color) (min-colors 88) (background light)) |
| 229 | + :foreground "MediumPurple4") |
| 230 | + (((class color) (background dark)) |
| 231 | + (:foreground "thistle")) |
| 232 | + (t nil)) |
| 233 | + "For use with module attribute tokens." |
| 234 | + :group 'font-lock-faces) |
| 235 | + |
| 236 | +(defvar elixir-atom-face 'elixir-atom-face) |
| 237 | +(defface elixir-atom-face |
| 238 | + '((((class color) (min-colors 88) (background light)) |
| 239 | + :foreground "RoyalBlue4") |
| 240 | + (((class color) (background dark)) |
| 241 | + (:foreground "light sky blue")) |
| 242 | + (t nil)) |
| 243 | + "For use with atoms & map keys." |
| 244 | + :group 'font-lock-faces) |
| 245 | + |
| 246 | + |
226 | 247 | (eval-when-compile
|
227 | 248 | (defconst elixir-rx-constituents
|
228 | 249 | `(
|
229 |
| - ;; Match `@doc' or `@moduledoc' syntax, with or without triple quotes. |
230 |
| - (heredocs . ,(rx symbol-start |
231 |
| - (or "@doc" "@moduledoc" "~s") |
232 |
| - symbol-end)) |
233 |
| - (keywords . ,(rx symbol-start |
234 |
| - (or "->" "bc" "lc" "in" "inbits" "inlist" "quote" |
235 |
| - "unquote" "unquote_splicing" "var" "do" "after" "for" |
236 |
| - "def" "defdelegate" "defimpl" "defmacro" "defmacrop" |
237 |
| - "defmodule" "defoverridable" "defp" "defprotocol" |
238 |
| - "defrecord" "defstruct" "destructure" "alias" |
239 |
| - "require" "import" "use" "if" "unless" "when" "case" |
240 |
| - "cond" "throw" "then" "else" "elsif" "try" "catch" |
241 |
| - "rescue" "fn" "function" "receive" "end") |
242 |
| - symbol-end)) |
243 |
| - (imports . ,(rx symbol-start |
244 |
| - (or "use" "require" "import") |
245 |
| - symbol-end)) |
246 |
| - (bool-and-nil . ,(rx symbol-start |
247 |
| - (or "true" "false" "nil") |
248 |
| - symbol-end)) |
249 |
| - (builtins . ,(rx symbol-start |
250 |
| - (or "_" "Erlang" "__MODULE__" "__LINE__" "__FILE__" |
251 |
| - "__ENV__" "__DIR__") |
252 |
| - symbol-end)) |
253 |
| - (sigils . ,(rx "~" (or "B" "C" "R" "S" "b" "c" "r" "s" "w"))) |
254 |
| - (method-defines . ,(rx symbol-start |
255 |
| - (or "def" "defdelegate" "defmacro" "defmacrop" |
256 |
| - "defoverridable" "defp" "defmacrop") |
| 250 | + (atoms . ,(rx ":" |
| 251 | + (or |
| 252 | + (one-or-more (any "a-z" "A-Z" "_" "\"" "'")) |
| 253 | + (and "\"" (one-or-more (not (any "\""))) "\"") |
| 254 | + (and "'" (one-or-more (not (any "'"))) "'")))) |
| 255 | + (builtin . ,(rx symbol-start |
| 256 | + (or "case" "cond" "for" "if" "unless" "try" "receive" |
| 257 | + "raise" "quote" "unquote" "unquote_splicing" "throw" |
| 258 | + "super") |
257 | 259 | symbol-end))
|
258 |
| - (module-defines . ,(rx symbol-start |
259 |
| - (or "defmodule" "defprotocol" "defimpl" |
260 |
| - "defrecord") |
261 |
| - symbol-end)) |
| 260 | + (builtin-declaration . ,(rx symbol-start |
| 261 | + (or "def" "defp" "defmodule" "defprotocol" |
| 262 | + "defmacro" "defmacrop" "defdelegate" |
| 263 | + "defexception" "defstruct" "defimpl" |
| 264 | + "defcallback") |
| 265 | + symbol-end)) |
262 | 266 | (builtin-modules . ,(rx symbol-start
|
263 | 267 | (or "Agent" "Application" "Atom" "Base"
|
264 | 268 | "Behaviour" "Bitwise" "Builtin" "Code" "Dict"
|
|
278 | 282 | "Task.Supervisor" "Tuple" "URI"
|
279 | 283 | "UnboundMethod" "Version")
|
280 | 284 | symbol-end))
|
281 |
| - (operators . ,(rx symbol-start |
282 |
| - (or "+" "++" "<>" "-" "/" "*" "div" "rem" "==" "!=" "<=" |
283 |
| - "<" ">=" ">" "===" "!==" "and" "or" "not" "&&" "||" |
284 |
| - "!" "." "#" "=" ":=" "<-"))) |
| 285 | + (builtin-namespace . ,(rx symbol-start |
| 286 | + (or "import" "require" "use" "alias") |
| 287 | + symbol-end)) |
| 288 | + ;; Set aside code point syntax for `elixir-negation-face'. |
| 289 | + (code-point . ,(rx symbol-start |
| 290 | + "?" |
| 291 | + anything |
| 292 | + symbol-end)) |
| 293 | + (function-declaration . ,(rx symbol-start |
| 294 | + (or "def" "defp") |
| 295 | + symbol-end)) |
| 296 | + ;; Match `@doc' or `@moduledoc' syntax, with or without triple quotes. |
| 297 | + (heredocs . ,(rx symbol-start |
| 298 | + (or "@doc" "@moduledoc" "~s") |
| 299 | + symbol-end)) |
| 300 | + ;; The first character of an identifier must be a letter or an underscore. |
| 301 | + ;; After that, they may contain any alphanumeric character + underscore. |
| 302 | + ;; Additionally, the final character may be either `?' or `!'. |
| 303 | + (identifiers . ,(rx (one-or-more (any "A-Z" "a-z""_")) |
| 304 | + (zero-or-more (any "A-Z" "a-z" "0-9" "_")) |
| 305 | + (optional (or "?" "!")))) |
| 306 | + (keyword . ,(rx symbol-start |
| 307 | + (or "fn" "do" "end" "after" "else" "rescue" "catch") |
| 308 | + symbol-end)) |
| 309 | + (keyword-operator . ,(rx symbol-start |
| 310 | + (or "not" "and" "or" "when" "in") |
| 311 | + symbol-end)) |
285 | 312 | ;; Module and submodule names start with upper case letter or `_'. This
|
286 | 313 | ;; can then be followed by any combination of alphanumeric chars + `_'.
|
287 | 314 | ;; In turn, this can be followed by a `.' which begins the notation of
|
|
297 | 324 | (zero-or-more (any "A-Z" "a-z" "_" "0-9"))))
|
298 | 325 | (optional (or "!" "?"))
|
299 | 326 | symbol-end))
|
300 |
| - ;; The first character of an identifier must be a letter or an underscore. |
301 |
| - ;; After that, they may contain any alphanumeric character + underscore. |
302 |
| - ;; Additionally, the final character may be either `?' or `!'. |
303 |
| - (identifiers . ,(rx symbol-start |
304 |
| - (one-or-more (any "A-Z" "a-z""_")) |
305 |
| - (zero-or-more (any "A-Z" "a-z" "0-9" "_")) |
306 |
| - (optional (or "?" "!")) |
| 327 | + (operators1 . ,(rx symbol-start |
| 328 | + (or "<" ">" "+" "-" "*" "/" "!" "^" "&") |
| 329 | + symbol-end)) |
| 330 | + (operators2 . ,(rx symbol-start |
| 331 | + (or |
| 332 | + "==" "!=" "<=" ">=" "&&" "||" "<>" "++" "--" "|>" "=~" |
| 333 | + "->" "<-" "|" "." "=") |
| 334 | + symbol-end)) |
| 335 | + (operators3 . ,(rx symbol-start |
| 336 | + (or "<<<" ">>>" "|||" "&&&" "^^^" "~~~" "===" "!==") |
| 337 | + symbol-end)) |
| 338 | + (pseudo-var . ,(rx symbol-start |
| 339 | + (or "_" "__MODULE__" "__DIR__" "__ENV__" "__CALLER__" |
| 340 | + "__block__" "__aliases__") |
| 341 | + symbol-end)) |
| 342 | + (punctuation . ,(rx symbol-start |
| 343 | + (or "\\" "<<" ">>" "=>" "(" ")" ":" ";" "" "[" "]") |
307 | 344 | symbol-end))
|
308 |
| - (atoms . ,(rx ":" |
309 |
| - (or |
310 |
| - (one-or-more (any "a-z" "A-Z" "0-9" "_")) |
311 |
| - (and "\"" (one-or-more (not (any "\""))) "\"") |
312 |
| - (and "'" (one-or-more (not (any "'"))) "'")))) |
313 |
| - (code-point . ,(rx symbol-start |
314 |
| - "?" |
315 |
| - anything |
316 |
| - symbol-end)))) |
| 345 | + (sigils . ,(rx "~" (or "B" "C" "R" "S" "b" "c" "r" "s" "w"))))) |
317 | 346 |
|
318 | 347 | (defmacro elixir-rx (&rest sexps)
|
319 | 348 | (let ((rx-constituents (append elixir-rx-constituents rx-constituents)))
|
|
327 | 356 | (defconst elixir-mode-font-lock-defaults
|
328 | 357 | `(
|
329 | 358 | ;; Module-defining & namespace builtins
|
330 |
| - (,(elixir-rx (or module-defines imports) |
| 359 | + (,(elixir-rx (or builtin-declaration builtin-namespace) |
331 | 360 | space
|
332 | 361 | (group module-names))
|
333 | 362 | 1 font-lock-type-face)
|
334 | 363 |
|
335 |
| - ;; Heredoc |
336 |
| - (,(elixir-rx (group heredocs)) |
337 |
| - 1 font-lock-builtin-face) |
| 364 | + ;; Module attributes |
| 365 | + (,(elixir-rx (group (or heredocs |
| 366 | + (and "@" (1+ identifiers))))) |
| 367 | + 1 elixir-attribute-face) |
338 | 368 |
|
339 | 369 | ;; Keywords
|
340 |
| - (,(elixir-rx (group keywords)) |
| 370 | + (,(elixir-rx (group (or builtin builtin-declaration builtin-namespace |
| 371 | + keyword keyword-operator))) |
341 | 372 | 1 font-lock-keyword-face)
|
342 | 373 |
|
343 |
| - ;; Method names, i.e. `def foo do' |
344 |
| - (,(elixir-rx method-defines |
| 374 | + ;; Function names, i.e. `def foo do'. |
| 375 | + (,(elixir-rx (group function-declaration) |
345 | 376 | space
|
346 | 377 | (group identifiers))
|
347 |
| - 1 font-lock-function-name-face) |
| 378 | + 2 font-lock-function-name-face) |
348 | 379 |
|
349 | 380 | ;; Variable definitions
|
350 | 381 | (,(elixir-rx (group identifiers)
|
|
353 | 384 | (one-or-more space))
|
354 | 385 | 1 font-lock-variable-name-face)
|
355 | 386 |
|
356 |
| - ;; Built-in constants |
357 |
| - (,(elixir-rx (group builtins)) |
358 |
| - 1 font-lock-builtin-face) |
359 |
| - |
360 | 387 | ;; Sigils
|
361 | 388 | (,(elixir-rx (group sigils))
|
362 | 389 | 1 font-lock-builtin-face)
|
|
367 | 394 | (and "/" (group (one-or-more (not (any "/")))) "/"))
|
368 | 395 | 1 font-lock-string-face)
|
369 | 396 | (,(elixir-rx "~r"
|
370 |
| - (and "[" (group (one-or-more (not (any "]")))) "]")) |
| 397 | + (and "[" (group (one-or-more (not (any "]")))) "]")) |
371 | 398 | 1 font-lock-string-face)
|
372 | 399 | (,(elixir-rx "~r"
|
373 |
| - (and "{" (group (one-or-more (not (any "}")))) "}")) |
| 400 | + (and "{" (group (one-or-more (not (any "}")))) "}")) |
374 | 401 | 1 font-lock-string-face)
|
375 | 402 | (,(elixir-rx "~r"
|
376 |
| - (and "(" (group (one-or-more (not (any ")")))) ")")) |
| 403 | + (and "(" (group (one-or-more (not (any ")")))) ")")) |
377 | 404 | 1 font-lock-string-face)
|
378 | 405 | (,(elixir-rx "~r"
|
379 |
| - (and "|" (group (one-or-more (not (any "|")))) "|")) |
| 406 | + (and "|" (group (one-or-more (not (any "|")))) "|")) |
380 | 407 | 1 font-lock-string-face)
|
381 | 408 | (,(elixir-rx "~r"
|
382 |
| - (and "\"" (group (one-or-more (not (any "\"")))) "\"")) |
| 409 | + (and "\"" (group (one-or-more (not (any "\"")))) "\"")) |
383 | 410 | 1 font-lock-string-face)
|
384 | 411 | (,(elixir-rx "~r"
|
385 |
| - (and "'" (group (one-or-more (not (any "'")))) "'")) |
| 412 | + (and "'" (group (one-or-more (not (any "'")))) "'")) |
386 | 413 | 1 font-lock-string-face)
|
387 | 414 | (,(elixir-rx "~r"
|
388 |
| - (and "<" (group (one-or-more (not (any ">")))) ">")) |
| 415 | + (and "<" (group (one-or-more (not (any ">")))) ">")) |
389 | 416 | 1 font-lock-string-face)
|
390 | 417 |
|
391 |
| - ;; TODO: Figure out why atoms are not being colored with `reference-face' |
392 | 418 | ;; Atoms and singleton-like words like true/false/nil.
|
393 |
| - (,(elixir-rx (or (group atoms) (group bool-and-nil))) |
394 |
| - 1 font-lock-reference-face) |
| 419 | + (,(elixir-rx (group atoms)) |
| 420 | + 1 elixir-atom-face) |
| 421 | + |
| 422 | + ;; Map keys |
| 423 | + (,(elixir-rx (group (and (one-or-more identifiers) ":"))) |
| 424 | + 1 elixir-atom-face) |
395 | 425 |
|
396 |
| - ;; Built-in modules |
397 |
| - (,(elixir-rx (group builtin-modules)) |
| 426 | + ;; Built-in modules and pseudovariables |
| 427 | + (,(elixir-rx (group (or builtin-modules pseudo-var))) |
398 | 428 | 1 font-lock-constant-face)
|
399 | 429 |
|
400 | 430 | ;; Operators
|
401 |
| - (,(elixir-rx (group operators)) |
| 431 | + (,(elixir-rx (group (or operators1 operators2 operators3))) |
402 | 432 | 1 elixir-operator-face)
|
403 | 433 |
|
404 | 434 | ;; Code points
|
|
0 commit comments