-
Notifications
You must be signed in to change notification settings - Fork 795
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First pass at adding a language mode for elixir (#1571)
I am not an elixir expert but I think this covers the basics. I wasn't able to find an elixir example in community forks so I put this together on my own. When this gets merged I will be on the lookout for feedback to improve it incrementally in subsequent changes. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Phil Cohen <[email protected]>
- Loading branch information
1 parent
3c19361
commit 899770b
Showing
4 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
from talon import Context, Module, actions, settings | ||
|
||
ctx = Context() | ||
mod = Module() | ||
ctx.matches = r""" | ||
code.language: elixir | ||
""" | ||
|
||
# Elixir keywords and constructs | ||
ctx.lists["user.code_keyword"] = { | ||
"def": "def ", | ||
"def p": "defp ", | ||
"def module": "defmodule ", | ||
"do": "do ", | ||
"end": "end", | ||
"if": "if ", | ||
"else": "else ", | ||
"cond": "cond ", | ||
"case": "case ", | ||
"when": "when ", | ||
"f n": "fn ", | ||
"receive": "receive ", | ||
"after": "after ", | ||
"try": "try ", | ||
"catch": "catch ", | ||
"rescue": "rescue ", | ||
"raise": "raise ", | ||
"with": "with ", | ||
"unless": "unless ", | ||
"import": "import ", | ||
"alias": "alias ", | ||
"require": "require ", | ||
"use": "use ", | ||
} | ||
|
||
|
||
@ctx.action_class("user") | ||
class UserActions: | ||
def code_comment_line_prefix(): | ||
actions.insert("# ") | ||
|
||
def code_operator_lambda(): | ||
actions.auto_insert("->") | ||
|
||
def code_operator_assignment(): | ||
actions.auto_insert(" = ") | ||
|
||
def code_operator_addition(): | ||
actions.auto_insert(" + ") | ||
|
||
def code_operator_subtraction(): | ||
actions.auto_insert(" - ") | ||
|
||
def code_operator_multiplication(): | ||
actions.auto_insert(" * ") | ||
|
||
def code_operator_division(): | ||
actions.auto_insert(" / ") | ||
|
||
def code_operator_equal(): | ||
actions.auto_insert(" == ") | ||
|
||
def code_operator_not_equal(): | ||
actions.auto_insert(" != ") | ||
|
||
def code_operator_greater_than(): | ||
actions.auto_insert(" > ") | ||
|
||
def code_operator_greater_than_or_equal_to(): | ||
actions.auto_insert(" >= ") | ||
|
||
def code_operator_less_than(): | ||
actions.auto_insert(" < ") | ||
|
||
def code_operator_less_than_or_equal_to(): | ||
actions.auto_insert(" <= ") | ||
|
||
def code_operator_and(): | ||
actions.auto_insert(" and ") | ||
|
||
def code_operator_or(): | ||
actions.auto_insert(" or ") | ||
|
||
def code_self(): | ||
actions.auto_insert("self") | ||
|
||
def code_insert_true(): | ||
actions.auto_insert("true") | ||
|
||
def code_insert_false(): | ||
actions.auto_insert("false") | ||
|
||
def code_insert_null(): | ||
actions.insert("nil") | ||
|
||
def code_insert_is_null(): | ||
actions.insert(" == nil") | ||
|
||
def code_insert_is_not_null(): | ||
actions.insert(" != nil") | ||
|
||
def code_state_if(): | ||
actions.user.insert_between("if ", " do\nend") | ||
|
||
def code_state_else_if(): | ||
actions.user.insert_between("else if ", " do\nend") | ||
|
||
def code_state_else(): | ||
actions.insert("else\nend") | ||
actions.key("enter") | ||
|
||
def code_state_case(): | ||
actions.user.insert_between("case ", " do\nend") | ||
|
||
def code_state_for(): | ||
actions.user.insert_between("for ", " do\nend") | ||
|
||
def code_state_while(): | ||
actions.user.insert_between("while ", " do\nend") | ||
|
||
def code_define_class(): | ||
# Elixir doesn't have classes, so this is not applicable | ||
pass | ||
|
||
def code_state_return(): | ||
# Elixir functions automatically return the last evaluated expression | ||
pass | ||
|
||
def code_insert_function(text: str, selection: str): | ||
text += f"({selection or ''})" | ||
actions.user.paste(text) | ||
actions.edit.left() | ||
|
||
def code_default_function(text: str): | ||
result = "def {}".format( | ||
actions.user.formatted_text( | ||
text, settings.get("user.code_protected_function_formatter") | ||
) | ||
) | ||
actions.user.code_insert_function(result, None) | ||
|
||
def code_public_function(text: str): | ||
actions.user.code_default_function(text) | ||
|
||
def code_private_function(text: str): | ||
"""Inserts private function declaration""" | ||
result = "defp {}".format( | ||
actions.user.formatted_text( | ||
text, settings.get("user.code_private_function_formatter") | ||
) | ||
) | ||
actions.user.code_insert_function(result, None) | ||
|
||
def code_import_module(text: str): | ||
actions.auto_insert("import ") | ||
actions.insert(text) | ||
|
||
def code_alias_module(text: str): | ||
actions.auto_insert("alias ") | ||
actions.insert(text) | ||
|
||
def code_require_module(text: str): | ||
actions.auto_insert("require ") | ||
actions.insert(text) | ||
|
||
def code_use_module(text: str): | ||
actions.auto_insert("use ") | ||
actions.insert(text) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
code.language: elixir | ||
- | ||
tag(): user.code_functional | ||
tag(): user.code_concurrent | ||
|
||
tag(): user.code_comment_line | ||
tag(): user.code_data_bool | ||
tag(): user.code_data_null | ||
tag(): user.code_functions | ||
tag(): user.code_keywords | ||
tag(): user.code_libraries | ||
tag(): user.code_operators_array | ||
tag(): user.code_operators_assignment | ||
tag(): user.code_operators_math | ||
tag(): user.code_operators_lambda | ||
|
||
settings(): | ||
user.code_private_function_formatter = "snake_case" | ||
user.code_public_function_formatter = "snake_case" | ||
user.code_private_variable_formatter = "snake_case" | ||
user.code_public_variable_formatter = "snake_case" | ||
|
||
# Elixir-specific grammars | ||
state def: "def " | ||
state defp: "defp " | ||
state if: "if " | ||
state else: "else" | ||
state case: "case " | ||
state cond: "cond do" | ||
state try: "try do" | ||
state rescue: "rescue" | ||
state after: "after" | ||
state end: "end" | ||
|
||
op pipe: " |> " | ||
|
||
# Elixir-specific keywords and symbols | ||
[state] raise {user.elixir_exception}: user.insert_between("raise ", "") | ||
|
||
[state] rescue {user.elixir_exception}: "rescue {elixir_exception}" |