diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index a21d9da96311..a506e6a5a11c 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -93,6 +93,7 @@ | pascal | ✓ | ✓ | | `pasls` | | perl | ✓ | ✓ | ✓ | | | php | ✓ | ✓ | ✓ | `intelephense` | +| ponylang | ✓ | ✓ | ✓ | | | prisma | ✓ | | | `prisma-language-server` | | prolog | | | | `swipl` | | protobuf | ✓ | | ✓ | | diff --git a/languages.toml b/languages.toml index 3ade3ea9866e..076e63632166 100644 --- a/languages.toml +++ b/languages.toml @@ -2079,3 +2079,16 @@ indent = { tab-width = 2, unit = " " } [[grammar]] name = "matlab" source = { git = "https://github.com/mstanciu552/tree-sitter-matlab", rev = "2d5d3d5193718a86477d4335aba5b34e79147326" } + +[[language]] +name = "ponylang" +scope = "source.pony" +file-types = ["pony"] +injection-regex = "pony" +roots = ["corral.json", "lock.json"] +indent = { tab-width = 2, unit = " " } +comment-token = "//" + +[[grammar]] +name = "ponylang" +source = { git = "https://github.com/mfelsche/tree-sitter-ponylang", rev = "ef66b151bc2604f431b5668fcec4747db4290e11" } diff --git a/runtime/queries/ponylang/highlights.scm b/runtime/queries/ponylang/highlights.scm new file mode 100644 index 000000000000..2d0594a7cb69 --- /dev/null +++ b/runtime/queries/ponylang/highlights.scm @@ -0,0 +1,176 @@ +[ + (line_comment) + (block_comment) +] @comment + +(bool) @constant.builtin.boolean +(integer) @constant.numeric.integer +(float) @constant.numeric.float +(character) @constant.character + +;; strings and docstring +(source_file docstring: (string) @string.special) +(entity docstring: (string) @string.special) +(method docstring: (string) @string.special) ; docstring for methods without body +(behavior docstring: (string) @string.special) ; docstring for methods without body +(constructor docstring: (string) @string.special) ; docstring for methods without body +(method body: (block . (string) @string.special)) ; docstring for methods with body +(behavior body: (block . (string) @string.special)) +(constructor body: (block . (string) @string.special)) +(field docstring: (string) @string.special) +(string) @string + +;; Punctuation +[ + "(" + ")" + "{" + "}" + "[" + "]" +] @punctuation.bracket +[ + ";" + "." + "," +] @punctuation.delimiter + +(this) @variable.builtin + +(field name: (identifier) @variable.other.member) + +"use" @keyword.control.import +[ + "for" + "in" + "while" + "do" + "repeat" + "until" +] @keyword.control.repeat +[ + "if" + "ifdef" + "iftype" + "then" + "elseif" + "else" + "match" +] @keyword.control.conditional +[ + "break" + "continue" + "return" + "error" + "compile_error" + "compile_intrinsic" +] @keyword.control.return +[ + "recover" + "consume" + "end" + "try" + "with" +] @keyword.control + +[ + "as" + "is" + "isnt" + "not" + "and" + "or" + "xor" + "digestof" + "addressof" + (location) +] @keyword.operator + +(entity_type) @keyword.storage.type + +[ + "var" + "let" + "embed" +] @keyword.storage + +[ + "fun" + "be" + "new" +] @keyword.function + +[ + (cap) + (gencap) + "where" +] @keyword + +[ + (partial) + "=>" + "~" + ".>" + "+" + "-" + "*" + "/" + "%" + "%%" + "+~" + "-~" + "/~" + "*~" + "%~" + "%%~" + + ">>" + "<<" + ">>~" + "<<~" + + "==" + "!=" + ">" + "<" + ">=" + "<=" +] @operator + +;; Types +(entity name: (identifier) @type) +(nominal_type name: (identifier) @type) +(typeparams (typeparam name: (identifier) @type)) + +;; constructors / methods / behaviors +(constructor name: (identifier) @constructor) +(method name: (identifier) @function.method) +(behavior name: (identifier) @function.method) + +;; method calls +; TODO: be more specific about what is the actual function reference +(call callee: (field_access field: (identifier) @function.method)) +(call callee: (_) @function.method) +(ffi_call name: (_) @function) +(partial_application function: (identifier) @function.method) +(chain function: (identifier) @function.method) + +;; fields and params +(field name: (identifier) @variable.other.member) +(param (identifier) @variable.parameter) +(lambdaparam (identifier) @variable.parameter) + +;; this.field is considered a member access +(field_access base: (this) field: (identifier) @variable.other.member) + +;; annotations +(annotations (identifier) @attribute) + +;; variables +;; references to upper case things are considered constructors +( + (identifier) @constructor + (#match @constructor "^[A-Z]") +) +(identifier) @variable + diff --git a/runtime/queries/ponylang/indents.scm b/runtime/queries/ponylang/indents.scm new file mode 100644 index 000000000000..ef9c82036572 --- /dev/null +++ b/runtime/queries/ponylang/indents.scm @@ -0,0 +1,32 @@ +; queries for helix to do automatic indentation upon hitting enter +; TODO: needs more work, cover more cases +[ + (entity) + (method) + (behavior) + (constructor) + (block) + (tuple) + (grouped) +] @indent +(match_case body: (block) @indent) +; ffi_call and call +(_ arguments: (_) @indent) +(assignment right: (_) @indent + (#set! "scope" "all") +) + +[ + (params) + (object) + ("if") +] @extend +(lambda params: (_) @extend) + +[ + "end" + "}" + "]" + ")" + "|" +] @outdent diff --git a/runtime/queries/ponylang/locals.scm b/runtime/queries/ponylang/locals.scm new file mode 100644 index 000000000000..e9efd69e7f95 --- /dev/null +++ b/runtime/queries/ponylang/locals.scm @@ -0,0 +1,37 @@ +[ + (entity) + (method) + (behavior) + (constructor) + ("if") + (elseif) + (ifdef) + (elseifdef) + (iftype) + (elseiftype) + (match) + (match_case) + ("while") + ("repeat") + ("for") + (lambda) + (try_block) + (with) +] @local.scope +(match else_block: (block) @local.scope) +(try_block else_block: (block) @local.scope) +(try_block then_block: (block) @local.scope) +(with else_block: (block) @local.scope) + +(field name: (identifier) @local.definition) +(local name: (identifier) @local.definition) +(param name: (identifier) @local.definition) +(lambdaparam name: (identifier) @local.definition) +("for" element: (idseq (identifier) @local.definition)) +(withelem name: (idseq (identifier) @local.definition)) + +; only lower case identifiers are references +( + (identifier) @local.reference + (#match? @local.reference "^[a-z_][a-zA-Z_]*") +) diff --git a/runtime/queries/ponylang/textobjects.scm b/runtime/queries/ponylang/textobjects.scm new file mode 100644 index 000000000000..0f24583d2597 --- /dev/null +++ b/runtime/queries/ponylang/textobjects.scm @@ -0,0 +1,64 @@ +;; Queries for helix to select textobjects: https://docs.helix-editor.com/usage.html#textobjects +;; function.inside +;; function.around +;; class.inside +;; class.around +;; test.inside +;; test.around +;; parameter.inside +;; comment.inside +;; comment.around + +;; Queries for navigating using textobjects + +[ + (line_comment) + (block_comment) +] @comment.inside + +(line_comment)+ @comment.around +(block_comment) @comment.around + +(entity members: (members)? @class.inside) @class.around +(object members: (members)? @class.inside) @class.around + +(method + body: (block)? @function.inside +) @function.around +(behavior + body: (block)? @function.inside +) @function.around +(constructor + body: (block)? @function.inside +) @function.around +(lambda + body: (block)? @function.inside +) @function.outside + +(params + ((_) @parameter.inside . ","? @parameter.around) @parameter.around +) +(lambda + params: ((_) @parameter.inside . ","? @parameter.around) @parameter.around +) +(typeargs + ((_) @parameter.inside . ","? @parameter.around) @parameter.around +) +(typeparams + ((_) @parameter.inside . ","? @parameter.around) @parameter.around +) +(arguments + positional: (positional_args + ((_) @parameter.inside . ","? @parameter.around)? @parameter.around) + ; TODO: get named args right + named: (named_args ((_) @parameter.inside . ","? @parameter.around)? @parameter.around) +) + +( + (entity + provides: (type (nominal_type name: (identifier) @_provides)) + members: (members) @test.inside + ) @test.outside + (#eq? @_provides "UnitTest") +) +