From a057d37d651d76a4a69c8e5c62ef31dd62b24d99 Mon Sep 17 00:00:00 2001 From: Dmitry Salin Date: Sun, 12 May 2024 21:07:34 +0300 Subject: [PATCH 1/5] Add support for Mojo --- book/src/generated/lang-support.md | 1 + languages.toml | 17 ++ runtime/queries/mojo/highlights.scm | 241 +++++++++++++++++++++++++++ runtime/queries/mojo/indents.scm | 83 +++++++++ runtime/queries/mojo/injections.scm | 2 + runtime/queries/mojo/locals.scm | 43 +++++ runtime/queries/mojo/textobjects.scm | 35 ++++ 7 files changed, 422 insertions(+) create mode 100644 runtime/queries/mojo/highlights.scm create mode 100644 runtime/queries/mojo/indents.scm create mode 100644 runtime/queries/mojo/injections.scm create mode 100644 runtime/queries/mojo/locals.scm create mode 100644 runtime/queries/mojo/textobjects.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 27fd583c230b..33f13e57c610 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -125,6 +125,7 @@ | mermaid | ✓ | | | | | meson | ✓ | | ✓ | | | mint | | | | `mint` | +| mojo | ✓ | | | `mojo-lsp-server` | | move | ✓ | | | | | msbuild | ✓ | | ✓ | | | nasm | ✓ | ✓ | | | diff --git a/languages.toml b/languages.toml index ded3b656e063..1722c90ff9e2 100644 --- a/languages.toml +++ b/languages.toml @@ -55,6 +55,7 @@ markdown-oxide = { command = "markdown-oxide" } marksman = { command = "marksman", args = ["server"] } metals = { command = "metals", config = { "isHttpEnabled" = true, metals = { inlayHints = { typeParameters = {enable = true} , hintsInPatternMatch = {enable = true} } } } } mint = { command = "mint", args = ["ls"] } +mojo-lsp = { command = "mojo-lsp-server" } nil = { command = "nil" } nimlangserver = { command = "nimlangserver" } nimlsp = { command = "nimlsp" } @@ -372,6 +373,22 @@ block-comment-tokens = { start = "/*", end = "*/" } language-servers = [ "mint" ] indent = { tab-width = 2, unit = " " } +[[language]] +name = "mojo" +scope = "source.mojo" +roots = ["__init__.mojo"] +injection-regex = "mojo" +file-types = ["mojo", "🔥"] +language-servers = [ "mojo-lsp" ] +comment-token = "#" +indent = { tab-width = 4, unit = " " } +auto-format = true +formatter = { command = "mojo", args = ["format", "-q", "-"]} + +[[grammar]] +name = "mojo" +source = { git = "https://github.com/garam-kim1/tree-sitter-mojo", rev = "46f89a2a6554789d534faf56e4ce2ebb3a1a5160" } + [[language]] name = "janet" scope = "source.janet" diff --git a/runtime/queries/mojo/highlights.scm b/runtime/queries/mojo/highlights.scm new file mode 100644 index 000000000000..c981e1165434 --- /dev/null +++ b/runtime/queries/mojo/highlights.scm @@ -0,0 +1,241 @@ +; Imports + +(dotted_name + (identifier)* @namespace) + +(aliased_import + alias: (identifier) @namespace) + +; Builtin functions + +((call + function: (identifier) @function.builtin) + (#match? + @function.builtin + "^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__|__mlir_attr|__mlir_op|__mlir_type)$")) + +; Function calls + +[ + "def" + "lambda" + "fn" + "class" + "struct" + "trait" + "var" + "let" + "alias" + "async" + "owned" + "borrowed" + "inout" +] @keyword.function + +(call + function: (attribute attribute: (identifier) @constructor) + (#match? @constructor "^[A-Z]")) +(call + function: (identifier) @constructor + (#match? @constructor "^[A-Z]")) + +(call + function: (attribute attribute: (identifier) @function.method)) + +(call + function: (identifier) @function) + +; Function definitions + +(function_definition + name: (identifier) @constructor + (#match? @constructor "^(__new__|__init__)$")) + +(function_definition + name: (identifier) @function) + +; Decorators + +(decorator) @function +(decorator (identifier) @function) +(decorator (attribute attribute: (identifier) @function)) +(decorator (call + function: (attribute attribute: (identifier) @function))) + +; Parameters + +((identifier) @variable.builtin + (#match? @variable.builtin "^(self|cls)$")) + +(parameters (identifier) @variable.parameter) +(parameters (typed_parameter (identifier) @variable.parameter)) +(parameters (default_parameter name: (identifier) @variable.parameter)) +(parameters (typed_default_parameter name: (identifier) @variable.parameter)) + +(parameters + (list_splat_pattern ; *args + (identifier) @variable.parameter)) +(parameters + (dictionary_splat_pattern ; **kwargs + (identifier) @variable.parameter)) + +(lambda_parameters + (identifier) @variable.parameter) + +; Types + +((identifier) @type.builtin + (#match? + @type.builtin + "^(bool|bytes|dict|float|frozenset|int|list|set|str|tuple)$")) + +; In type hints make everything types to catch non-conforming identifiers +; (e.g., datetime.datetime) and None +(type [(identifier) (none)] @type) +; Handle [] . and | nesting 4 levels deep +(type + (_ [(identifier) (none)]? @type + (_ [(identifier) (none)]? @type + (_ [(identifier) (none)]? @type + (_ [(identifier) (none)]? @type))))) + +(class_definition name: (identifier) @type) +(class_definition superclasses: (argument_list (identifier) @type)) + +; Variables + +((identifier) @constant + (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) + +((identifier) @type + (#match? @type "^[A-Z]")) + +(attribute attribute: (identifier) @variable.other.member) +(identifier) @variable + +; Literals +(none) @constant.builtin +[ + (true) + (false) +] @constant.builtin.boolean + +(integer) @constant.numeric.integer +(float) @constant.numeric.float +(comment) @comment +(string) @string +(escape_sequence) @constant.character.escape + +["," "." ":" ";" (ellipsis)] @punctuation.delimiter +(interpolation + "{" @punctuation.special + "}" @punctuation.special) @embedded +["(" ")" "[" "]" "{" "}"] @punctuation.bracket + +[ + "-" + "-=" + "!=" + "*" + "**" + "**=" + "*=" + "/" + "//" + "//=" + "/=" + "&" + "&=" + "%" + "%=" + "^" + "^=" + "+" + "->" + "+=" + "<" + "<<" + "<<=" + "<=" + "<>" + "=" + ":=" + "==" + ">" + ">=" + ">>" + ">>=" + "|" + "|=" + "~" + "@=" +] @operator + +[ + "as" + "assert" + "await" + "from" + "pass" + + "with" +] @keyword.control + +[ + "if" + "elif" + "else" + "match" + "case" +] @keyword.control.conditional + +[ + "while" + "for" + "break" + "continue" +] @keyword.control.repeat + +[ + "return" + "yield" +] @keyword.control.return +(yield "from" @keyword.control.return) + +[ + "raise" + "try" + "except" + "finally" +] @keyword.control.except +(raise_statement "from" @keyword.control.except) +"import" @keyword.control.import + +(for_statement "in" @keyword.control) +(for_in_clause "in" @keyword.control) + +[ + "async" + "class" + "exec" + "global" + "nonlocal" + "print" + "type" +] @keyword +[ + "and" + "or" + "not in" + "in" + "not" + "del" + "is not" + "is" +] @keyword.operator + +((identifier) @type.builtin + (#match? @type.builtin + "^(BaseException|Exception|ArithmeticError|BufferError|LookupError|AssertionError|AttributeError|EOFError|FloatingPointError|GeneratorExit|ImportError|ModuleNotFoundError|IndexError|KeyError|KeyboardInterrupt|MemoryError|NameError|NotImplementedError|OSError|OverflowError|RecursionError|ReferenceError|RuntimeError|StopIteration|StopAsyncIteration|SyntaxError|IndentationError|TabError|SystemError|SystemExit|TypeError|UnboundLocalError|UnicodeError|UnicodeEncodeError|UnicodeDecodeError|UnicodeTranslateError|ValueError|ZeroDivisionError|EnvironmentError|IOError|WindowsError|BlockingIOError|ChildProcessError|ConnectionError|BrokenPipeError|ConnectionAbortedError|ConnectionRefusedError|ConnectionResetError|FileExistsError|FileNotFoundError|InterruptedError|IsADirectoryError|NotADirectoryError|PermissionError|ProcessLookupError|TimeoutError|Warning|UserWarning|DeprecationWarning|PendingDeprecationWarning|SyntaxWarning|RuntimeWarning|FutureWarning|ImportWarning|UnicodeWarning|BytesWarning|ResourceWarning)$")) + +(ERROR) @error diff --git a/runtime/queries/mojo/indents.scm b/runtime/queries/mojo/indents.scm new file mode 100644 index 000000000000..5ee0bfe83380 --- /dev/null +++ b/runtime/queries/mojo/indents.scm @@ -0,0 +1,83 @@ +[ + (list) + (tuple) + (dictionary) + (set) + + (if_statement) + (for_statement) + (while_statement) + (with_statement) + (try_statement) + (match_statement) + (case_clause) + (import_from_statement) + + (parenthesized_expression) + (generator_expression) + (list_comprehension) + (set_comprehension) + (dictionary_comprehension) + + (tuple_pattern) + (list_pattern) + (argument_list) + (parameters) + (binary_operator) + + (function_definition) + (class_definition) +] @indent + +; Workaround for the tree-sitter grammar creating large errors when a +; try_statement is missing the except/finally clause +(ERROR + "try" + . + ":" @indent @extend) +(ERROR + . + "def") @indent @extend +(ERROR + (block) @indent @extend + (#set! "scope" "all")) + +[ + (if_statement) + (for_statement) + (while_statement) + (with_statement) + (try_statement) + (match_statement) + (case_clause) + + (function_definition) + (class_definition) +] @extend + +[ + (return_statement) + (break_statement) + (continue_statement) + (raise_statement) + (pass_statement) +] @extend.prevent-once + +[ + ")" + "]" + "}" +] @outdent +(elif_clause + "elif" @outdent) +(else_clause + "else" @outdent) + +(parameters + . + (identifier) @anchor + (#set! "scope" "tail")) @align +(argument_list + . + (_) @anchor + (#set! "scope" "tail")) @align diff --git a/runtime/queries/mojo/injections.scm b/runtime/queries/mojo/injections.scm new file mode 100644 index 000000000000..321c90add371 --- /dev/null +++ b/runtime/queries/mojo/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/mojo/locals.scm b/runtime/queries/mojo/locals.scm new file mode 100644 index 000000000000..9cef6f795691 --- /dev/null +++ b/runtime/queries/mojo/locals.scm @@ -0,0 +1,43 @@ +;; Scopes + +[ + (module) + (function_definition) + (lambda) +] @local.scope + +;; Definitions + +; Parameters +(parameters + (identifier) @local.definition) +(parameters + (typed_parameter + (identifier) @local.definition)) +(parameters + (default_parameter + name: (identifier) @local.definition)) +(parameters + (typed_default_parameter + name: (identifier) @local.definition)) +(parameters + (list_splat_pattern ; *args + (identifier) @local.definition)) +(parameters + (dictionary_splat_pattern ; **kwargs + (identifier) @local.definition)) + +(lambda_parameters + (identifier) @local.definition) + +; Imports +(import_statement + name: (dotted_name + (identifier) @local.definition)) + +(aliased_import + alias: (identifier) @local.definition) + +;; References + +(identifier) @local.reference diff --git a/runtime/queries/mojo/textobjects.scm b/runtime/queries/mojo/textobjects.scm new file mode 100644 index 000000000000..2b9556fca7bc --- /dev/null +++ b/runtime/queries/mojo/textobjects.scm @@ -0,0 +1,35 @@ +(function_definition + body: (block)? @function.inside) @function.around + +(class_definition + body: (block)? @class.inside) @class.around + +(parameters + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(lambda_parameters + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(argument_list + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(comment) @comment.inside + +(comment)+ @comment.around + +((function_definition + name: (identifier) @_name + body: (block)? @test.inside) @test.around + (#match? @_name "^test_")) + +(list + (_) @entry.around) + +(tuple + (_) @entry.around) + +(set + (_) @entry.around) + +(pair + (_) @entry.inside) @entry.around From 7957aa2ae7ec33368a02ccea620d1656e59748a1 Mon Sep 17 00:00:00 2001 From: Dmitry Salin Date: Sun, 12 May 2024 22:11:37 +0300 Subject: [PATCH 2/5] Update grammar --- languages.toml | 2 +- runtime/queries/mojo/highlights.scm | 237 +++++++++------------------ runtime/queries/mojo/indents.scm | 83 ---------- runtime/queries/mojo/injections.scm | 2 - runtime/queries/mojo/locals.scm | 43 ----- runtime/queries/mojo/textobjects.scm | 35 ---- 6 files changed, 75 insertions(+), 327 deletions(-) delete mode 100644 runtime/queries/mojo/indents.scm delete mode 100644 runtime/queries/mojo/injections.scm delete mode 100644 runtime/queries/mojo/locals.scm delete mode 100644 runtime/queries/mojo/textobjects.scm diff --git a/languages.toml b/languages.toml index 1722c90ff9e2..696d56134ee5 100644 --- a/languages.toml +++ b/languages.toml @@ -387,7 +387,7 @@ formatter = { command = "mojo", args = ["format", "-q", "-"]} [[grammar]] name = "mojo" -source = { git = "https://github.com/garam-kim1/tree-sitter-mojo", rev = "46f89a2a6554789d534faf56e4ce2ebb3a1a5160" } +source = { git = "https://github.com/lsh/tree-sitter-mojo", rev = "3d7c53b8038f9ebbb57cd2e61296180aa5c1cf64" } [[language]] name = "janet" diff --git a/runtime/queries/mojo/highlights.scm b/runtime/queries/mojo/highlights.scm index c981e1165434..4ad37a39b988 100644 --- a/runtime/queries/mojo/highlights.scm +++ b/runtime/queries/mojo/highlights.scm @@ -1,136 +1,73 @@ -; Imports - -(dotted_name - (identifier)* @namespace) - -(aliased_import - alias: (identifier) @namespace) - -; Builtin functions - -((call - function: (identifier) @function.builtin) - (#match? - @function.builtin - "^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__|__mlir_attr|__mlir_op|__mlir_type)$")) +(attribute attribute: (identifier) @property) +(type (identifier) @type) ; Function calls -[ - "def" - "lambda" - "fn" - "class" - "struct" - "trait" - "var" - "let" - "alias" - "async" - "owned" - "borrowed" - "inout" -] @keyword.function - -(call - function: (attribute attribute: (identifier) @constructor) - (#match? @constructor "^[A-Z]")) -(call - function: (identifier) @constructor - (#match? @constructor "^[A-Z]")) +(decorator) @function (call function: (attribute attribute: (identifier) @function.method)) - (call function: (identifier) @function) ; Function definitions -(function_definition - name: (identifier) @constructor - (#match? @constructor "^(__new__|__init__)$")) - (function_definition name: (identifier) @function) -; Decorators - -(decorator) @function -(decorator (identifier) @function) -(decorator (attribute attribute: (identifier) @function)) -(decorator (call - function: (attribute attribute: (identifier) @function))) - -; Parameters - -((identifier) @variable.builtin - (#match? @variable.builtin "^(self|cls)$")) - -(parameters (identifier) @variable.parameter) -(parameters (typed_parameter (identifier) @variable.parameter)) -(parameters (default_parameter name: (identifier) @variable.parameter)) -(parameters (typed_default_parameter name: (identifier) @variable.parameter)) +; Identifier naming conventions -(parameters - (list_splat_pattern ; *args - (identifier) @variable.parameter)) -(parameters - (dictionary_splat_pattern ; **kwargs - (identifier) @variable.parameter)) - -(lambda_parameters - (identifier) @variable.parameter) - -; Types - -((identifier) @type.builtin - (#match? - @type.builtin - "^(bool|bytes|dict|float|frozenset|int|list|set|str|tuple)$")) - -; In type hints make everything types to catch non-conforming identifiers -; (e.g., datetime.datetime) and None -(type [(identifier) (none)] @type) -; Handle [] . and | nesting 4 levels deep -(type - (_ [(identifier) (none)]? @type - (_ [(identifier) (none)]? @type - (_ [(identifier) (none)]? @type - (_ [(identifier) (none)]? @type))))) - -(class_definition name: (identifier) @type) -(class_definition superclasses: (argument_list (identifier) @type)) - -; Variables +((identifier) @type + (#match? @type "^[A-Z]")) ((identifier) @constant (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) -((identifier) @type - (#match? @type "^[A-Z]")) +; Builtin functions -(attribute attribute: (identifier) @variable.other.member) -(identifier) @variable +((call + function: (identifier) @function.builtin) + (#match? + @function.builtin + "^(abs|all|always_inline|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|constrained|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unroll|vars|zip|__mlir_attr|__mlir_op|__mlir_type|__import__)$")) ; Literals -(none) @constant.builtin + [ + (none) (true) (false) -] @constant.builtin.boolean +] @constant.builtin + +[ + (integer) + (float) +] @number -(integer) @constant.numeric.integer -(float) @constant.numeric.float (comment) @comment (string) @string -(escape_sequence) @constant.character.escape +(escape_sequence) @escape + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket -["," "." ":" ";" (ellipsis)] @punctuation.delimiter (interpolation "{" @punctuation.special "}" @punctuation.special) @embedded -["(" ")" "[" "]" "{" "}"] @punctuation.bracket + +; Docstrings. +(function_definition + "async"? + "def" + name: (_) + (parameters)? + body: (block (expression_statement (string) @string.doc))) [ "-" @@ -145,17 +82,14 @@ "//=" "/=" "&" - "&=" "%" "%=" "^" - "^=" "+" "->" "+=" "<" "<<" - "<<=" "<=" "<>" "=" @@ -164,78 +98,55 @@ ">" ">=" ">>" - ">>=" "|" - "|=" "~" - "@=" + "and" + "in" + "is" + "not" + "or" + "is not" + "not in" ] @operator [ "as" + "alias" "assert" + "async" "await" - "from" - "pass" - - "with" -] @keyword.control - -[ - "if" - "elif" - "else" - "match" - "case" -] @keyword.control.conditional - -[ - "while" - "for" + "borrowed" "break" + "class" "continue" -] @keyword.control.repeat - -[ - "return" - "yield" -] @keyword.control.return -(yield "from" @keyword.control.return) - -[ - "raise" - "try" + "def" + "del" + "elif" + "else" "except" - "finally" -] @keyword.control.except -(raise_statement "from" @keyword.control.except) -"import" @keyword.control.import - -(for_statement "in" @keyword.control) -(for_in_clause "in" @keyword.control) - -[ - "async" - "class" "exec" + "finally" + "fn" + "for" + "from" "global" + "if" + "import" + "inout" + "lambda" "nonlocal" + "owned" + "pass" "print" - "type" + "raise" + "raises" + "return" + "struct" + "try" + "var" + "while" + "with" + "yield" + "match" + "case" ] @keyword -[ - "and" - "or" - "not in" - "in" - "not" - "del" - "is not" - "is" -] @keyword.operator - -((identifier) @type.builtin - (#match? @type.builtin - "^(BaseException|Exception|ArithmeticError|BufferError|LookupError|AssertionError|AttributeError|EOFError|FloatingPointError|GeneratorExit|ImportError|ModuleNotFoundError|IndexError|KeyError|KeyboardInterrupt|MemoryError|NameError|NotImplementedError|OSError|OverflowError|RecursionError|ReferenceError|RuntimeError|StopIteration|StopAsyncIteration|SyntaxError|IndentationError|TabError|SystemError|SystemExit|TypeError|UnboundLocalError|UnicodeError|UnicodeEncodeError|UnicodeDecodeError|UnicodeTranslateError|ValueError|ZeroDivisionError|EnvironmentError|IOError|WindowsError|BlockingIOError|ChildProcessError|ConnectionError|BrokenPipeError|ConnectionAbortedError|ConnectionRefusedError|ConnectionResetError|FileExistsError|FileNotFoundError|InterruptedError|IsADirectoryError|NotADirectoryError|PermissionError|ProcessLookupError|TimeoutError|Warning|UserWarning|DeprecationWarning|PendingDeprecationWarning|SyntaxWarning|RuntimeWarning|FutureWarning|ImportWarning|UnicodeWarning|BytesWarning|ResourceWarning)$")) - -(ERROR) @error diff --git a/runtime/queries/mojo/indents.scm b/runtime/queries/mojo/indents.scm deleted file mode 100644 index 5ee0bfe83380..000000000000 --- a/runtime/queries/mojo/indents.scm +++ /dev/null @@ -1,83 +0,0 @@ -[ - (list) - (tuple) - (dictionary) - (set) - - (if_statement) - (for_statement) - (while_statement) - (with_statement) - (try_statement) - (match_statement) - (case_clause) - (import_from_statement) - - (parenthesized_expression) - (generator_expression) - (list_comprehension) - (set_comprehension) - (dictionary_comprehension) - - (tuple_pattern) - (list_pattern) - (argument_list) - (parameters) - (binary_operator) - - (function_definition) - (class_definition) -] @indent - -; Workaround for the tree-sitter grammar creating large errors when a -; try_statement is missing the except/finally clause -(ERROR - "try" - . - ":" @indent @extend) -(ERROR - . - "def") @indent @extend -(ERROR - (block) @indent @extend - (#set! "scope" "all")) - -[ - (if_statement) - (for_statement) - (while_statement) - (with_statement) - (try_statement) - (match_statement) - (case_clause) - - (function_definition) - (class_definition) -] @extend - -[ - (return_statement) - (break_statement) - (continue_statement) - (raise_statement) - (pass_statement) -] @extend.prevent-once - -[ - ")" - "]" - "}" -] @outdent -(elif_clause - "elif" @outdent) -(else_clause - "else" @outdent) - -(parameters - . - (identifier) @anchor - (#set! "scope" "tail")) @align -(argument_list - . - (_) @anchor - (#set! "scope" "tail")) @align diff --git a/runtime/queries/mojo/injections.scm b/runtime/queries/mojo/injections.scm deleted file mode 100644 index 321c90add371..000000000000 --- a/runtime/queries/mojo/injections.scm +++ /dev/null @@ -1,2 +0,0 @@ -((comment) @injection.content - (#set! injection.language "comment")) diff --git a/runtime/queries/mojo/locals.scm b/runtime/queries/mojo/locals.scm deleted file mode 100644 index 9cef6f795691..000000000000 --- a/runtime/queries/mojo/locals.scm +++ /dev/null @@ -1,43 +0,0 @@ -;; Scopes - -[ - (module) - (function_definition) - (lambda) -] @local.scope - -;; Definitions - -; Parameters -(parameters - (identifier) @local.definition) -(parameters - (typed_parameter - (identifier) @local.definition)) -(parameters - (default_parameter - name: (identifier) @local.definition)) -(parameters - (typed_default_parameter - name: (identifier) @local.definition)) -(parameters - (list_splat_pattern ; *args - (identifier) @local.definition)) -(parameters - (dictionary_splat_pattern ; **kwargs - (identifier) @local.definition)) - -(lambda_parameters - (identifier) @local.definition) - -; Imports -(import_statement - name: (dotted_name - (identifier) @local.definition)) - -(aliased_import - alias: (identifier) @local.definition) - -;; References - -(identifier) @local.reference diff --git a/runtime/queries/mojo/textobjects.scm b/runtime/queries/mojo/textobjects.scm deleted file mode 100644 index 2b9556fca7bc..000000000000 --- a/runtime/queries/mojo/textobjects.scm +++ /dev/null @@ -1,35 +0,0 @@ -(function_definition - body: (block)? @function.inside) @function.around - -(class_definition - body: (block)? @class.inside) @class.around - -(parameters - ((_) @parameter.inside . ","? @parameter.around) @parameter.around) - -(lambda_parameters - ((_) @parameter.inside . ","? @parameter.around) @parameter.around) - -(argument_list - ((_) @parameter.inside . ","? @parameter.around) @parameter.around) - -(comment) @comment.inside - -(comment)+ @comment.around - -((function_definition - name: (identifier) @_name - body: (block)? @test.inside) @test.around - (#match? @_name "^test_")) - -(list - (_) @entry.around) - -(tuple - (_) @entry.around) - -(set - (_) @entry.around) - -(pair - (_) @entry.inside) @entry.around From 96812a20913924522593a7f6f9ecb8fb637f5320 Mon Sep 17 00:00:00 2001 From: Dmitry Salin Date: Tue, 14 May 2024 05:44:48 +0300 Subject: [PATCH 3/5] Fix queries --- runtime/queries/mojo/highlights.scm | 246 +++++++++++++++++++-------- runtime/queries/mojo/indents.scm | 86 ++++++++++ runtime/queries/mojo/injections.scm | 2 + runtime/queries/mojo/locals.scm | 48 ++++++ runtime/queries/mojo/textobjects.scm | 35 ++++ 5 files changed, 343 insertions(+), 74 deletions(-) create mode 100644 runtime/queries/mojo/indents.scm create mode 100644 runtime/queries/mojo/injections.scm create mode 100644 runtime/queries/mojo/locals.scm create mode 100644 runtime/queries/mojo/textobjects.scm diff --git a/runtime/queries/mojo/highlights.scm b/runtime/queries/mojo/highlights.scm index 4ad37a39b988..7acaf1eadeb8 100644 --- a/runtime/queries/mojo/highlights.scm +++ b/runtime/queries/mojo/highlights.scm @@ -1,73 +1,132 @@ -(attribute attribute: (identifier) @property) -(type (identifier) @type) +; Docstrings + +(expression_statement (string) @comment.block.documentation) + +; Imports + +(dotted_name + (identifier)* @namespace) + +(aliased_import + alias: (identifier) @namespace) + +; Builtin functions + +((call + function: (identifier) @function.builtin) + (#match? + @function.builtin + "^(abs|all|always_inline|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|constrained|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unroll|vars|zip|__mlir_attr|__mlir_op|__mlir_type|__import__)$")) ; Function calls -(decorator) @function +[ + "def" + "lambda" + "fn" +] @keyword.function + +(call + function: (attribute attribute: (identifier) @constructor) + (#match? @constructor "^[A-Z]")) + +(call + function: (identifier) @constructor + (#match? @constructor "^[A-Z]")) (call function: (attribute attribute: (identifier) @function.method)) + (call function: (identifier) @function) ; Function definitions +(function_definition + name: (identifier) @constructor + (#match? @constructor "^(__new__|__init__|__moveinit__|__copyinit__)$")) + (function_definition name: (identifier) @function) -; Identifier naming conventions +; Decorators -((identifier) @type - (#match? @type "^[A-Z]")) +(decorator) @function +(decorator (identifier) @function) +(decorator (attribute attribute: (identifier) @function)) +(decorator (call + function: (attribute attribute: (identifier) @function))) + +; Parameters + +((identifier) @variable.builtin + (#match? @variable.builtin "^(self|cls)$")) + +(parameters (identifier) @variable.parameter) +(parameters (typed_parameter (identifier) @variable.parameter)) +(parameters (default_parameter name: (identifier) @variable.parameter)) +(parameters (typed_default_parameter name: (identifier) @variable.parameter)) + +(parameters + (list_splat_pattern ; *args + (identifier) @variable.parameter)) + +(parameters + (dictionary_splat_pattern ; **kwargs + (identifier) @variable.parameter)) + +(lambda_parameters + (identifier) @variable.parameter) + +; Types + +((identifier) @type.builtin + (#match? + @type.builtin + "^(bool|bytes|dict|float|frozenset|int|list|set|str|tuple)$")) + +; In type hints make everything types to catch non-conforming identifiers +; (e.g., datetime.datetime) and None +(type [(identifier) (none)] @type) +; Handle [] . and | nesting 4 levels deep +(type + (_ [(identifier) (none)]? @type + (_ [(identifier) (none)]? @type + (_ [(identifier) (none)]? @type + (_ [(identifier) (none)]? @type))))) + +(class_definition name: (identifier) @type) +(class_definition superclasses: (argument_list (identifier) @type)) + +; Variables ((identifier) @constant - (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) + (#match? @constant "^_*[A-Z][A-Z\\d_]*$")) -; Builtin functions +((identifier) @type + (#match? @type "^[A-Z]")) -((call - function: (identifier) @function.builtin) - (#match? - @function.builtin - "^(abs|all|always_inline|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|constrained|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unroll|vars|zip|__mlir_attr|__mlir_op|__mlir_type|__import__)$")) +(attribute attribute: (identifier) @variable.other.member) +(identifier) @variable ; Literals - +(none) @constant.builtin [ - (none) (true) (false) -] @constant.builtin - -[ - (integer) - (float) -] @number +] @constant.builtin.boolean +(integer) @constant.numeric.integer +(float) @constant.numeric.float (comment) @comment (string) @string -(escape_sequence) @escape - -[ - "(" - ")" - "[" - "]" - "{" - "}" -] @punctuation.bracket +(escape_sequence) @constant.character.escape +["," "." ":" ";" (ellipsis)] @punctuation.delimiter (interpolation "{" @punctuation.special "}" @punctuation.special) @embedded - -; Docstrings. -(function_definition - "async"? - "def" - name: (_) - (parameters)? - body: (block (expression_statement (string) @string.doc))) +["(" ")" "[" "]" "{" "}"] @punctuation.bracket [ "-" @@ -82,14 +141,17 @@ "//=" "/=" "&" + "&=" "%" "%=" "^" + "^=" "+" "->" "+=" "<" "<<" + "<<=" "<=" "<>" "=" @@ -98,55 +160,91 @@ ">" ">=" ">>" + ">>=" "|" + "|=" "~" - "and" - "in" - "is" - "not" - "or" - "is not" - "not in" + "@=" ] @operator [ "as" - "alias" "assert" - "async" "await" - "borrowed" - "break" - "class" - "continue" - "def" - "del" + "from" + "pass" + "with" +] @keyword.control + +[ + "if" "elif" "else" + "match" + "case" +] @keyword.control.conditional + +[ + "while" + "for" + "break" + "continue" +] @keyword.control.repeat + +[ + "return" + "yield" +] @keyword.control.return + +(yield "from" @keyword.control.return) + +[ + "raise" + "raises" + "try" "except" - "exec" "finally" - "fn" - "for" - "from" +] @keyword.control.exception + +(raise_statement "from" @keyword.control.exception) +"import" @keyword.control.import + +(for_statement "in" @keyword.control) +(for_in_clause "in" @keyword.control) + +[ + "alias" + "async" + "class" + "exec" "global" - "if" - "import" - "inout" - "lambda" "nonlocal" - "owned" - "pass" "print" - "raise" - "raises" - "return" "struct" - "try" - "var" - "while" - "with" - "yield" - "match" - "case" + ; "trait" ] @keyword + +[ + "and" + "or" + "not in" + "in" + "not" + "del" + "is not" + "is" +] @keyword.operator + +"var" @keyword.storage + +[ + "borrowed" + "inout" + "owned" +] @keyword.storage.modifier + +((identifier) @type.builtin + (#match? @type.builtin + "^(BaseException|Exception|ArithmeticError|BufferError|LookupError|AssertionError|AttributeError|EOFError|FloatingPointError|GeneratorExit|ImportError|ModuleNotFoundError|IndexError|KeyError|KeyboardInterrupt|MemoryError|NameError|NotImplementedError|OSError|OverflowError|RecursionError|ReferenceError|RuntimeError|StopIteration|StopAsyncIteration|SyntaxError|IndentationError|TabError|SystemError|SystemExit|TypeError|UnboundLocalError|UnicodeError|UnicodeEncodeError|UnicodeDecodeError|UnicodeTranslateError|ValueError|ZeroDivisionError|EnvironmentError|IOError|WindowsError|BlockingIOError|ChildProcessError|ConnectionError|BrokenPipeError|ConnectionAbortedError|ConnectionRefusedError|ConnectionResetError|FileExistsError|FileNotFoundError|InterruptedError|IsADirectoryError|NotADirectoryError|PermissionError|ProcessLookupError|TimeoutError|Warning|UserWarning|DeprecationWarning|PendingDeprecationWarning|SyntaxWarning|RuntimeWarning|FutureWarning|ImportWarning|UnicodeWarning|BytesWarning|ResourceWarning)$")) + +(ERROR) @error diff --git a/runtime/queries/mojo/indents.scm b/runtime/queries/mojo/indents.scm new file mode 100644 index 000000000000..9bab4478ed3c --- /dev/null +++ b/runtime/queries/mojo/indents.scm @@ -0,0 +1,86 @@ +[ + (list) + (tuple) + (dictionary) + (set) + + (if_statement) + (for_statement) + (while_statement) + (with_statement) + (try_statement) + (match_statement) + (case_clause) + (import_from_statement) + + (parenthesized_expression) + (generator_expression) + (list_comprehension) + (set_comprehension) + (dictionary_comprehension) + + (tuple_pattern) + (list_pattern) + (argument_list) + (parameters) + (binary_operator) + + (function_definition) + (class_definition) +] @indent + +; Workaround for the tree-sitter grammar creating large errors when a +; try_statement is missing the except/finally clause +(ERROR + "try" + . + ":" @indent @extend) +(ERROR + . + "def") @indent @extend +(ERROR + (block) @indent @extend + (#set! "scope" "all")) + +[ + (if_statement) + (for_statement) + (while_statement) + (with_statement) + (try_statement) + (match_statement) + (case_clause) + + (function_definition) + (class_definition) +] @extend + +[ + (return_statement) + (break_statement) + (continue_statement) + (raise_statement) + (pass_statement) +] @extend.prevent-once + +[ + ")" + "]" + "}" +] @outdent + +(elif_clause + "elif" @outdent) + +(else_clause + "else" @outdent) + +(parameters + . + (identifier) @anchor + (#set! "scope" "tail")) @align + +(argument_list + . + (_) @anchor + (#set! "scope" "tail")) @align diff --git a/runtime/queries/mojo/injections.scm b/runtime/queries/mojo/injections.scm new file mode 100644 index 000000000000..2f0e58eb6431 --- /dev/null +++ b/runtime/queries/mojo/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/mojo/locals.scm b/runtime/queries/mojo/locals.scm new file mode 100644 index 000000000000..ddf4c8085a29 --- /dev/null +++ b/runtime/queries/mojo/locals.scm @@ -0,0 +1,48 @@ +; Scopes + +[ + (module) + (function_definition) + (lambda) +] @local.scope + +; Definitions + +; Parameters +(parameters + (identifier) @local.definition) + +(parameters + (typed_parameter + (identifier) @local.definition)) + +(parameters + (default_parameter + name: (identifier) @local.definition)) + +(parameters + (typed_default_parameter + name: (identifier) @local.definition)) + +(parameters + (list_splat_pattern ; *args + (identifier) @local.definition)) + +(parameters + (dictionary_splat_pattern ; **kwargs + (identifier) @local.definition)) + +(lambda_parameters + (identifier) @local.definition) + +; Imports +(import_statement + name: (dotted_name + (identifier) @local.definition)) + +(aliased_import + alias: (identifier) @local.definition) + +; References + +(identifier) @local.reference diff --git a/runtime/queries/mojo/textobjects.scm b/runtime/queries/mojo/textobjects.scm new file mode 100644 index 000000000000..5ad5229ed2ee --- /dev/null +++ b/runtime/queries/mojo/textobjects.scm @@ -0,0 +1,35 @@ +(function_definition + body: (block)? @function.inside) @function.around + +(class_definition + body: (block)? @class.inside) @class.around + +(parameters + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(lambda_parameters + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(argument_list + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(comment) @comment.inside + +(comment)+ @comment.around + +((function_definition + name: (identifier) @_name + body: (block)? @test.inside) @test.around + (#match? @_name "^test_")) + +(list + (_) @entry.around) + +(tuple + (_) @entry.around) + +(set + (_) @entry.around) + +(pair + (_) @entry.inside) @entry.around From 2d0404ac6f43746bbc3734702077155e36092694 Mon Sep 17 00:00:00 2001 From: Dmitry Salin Date: Tue, 14 May 2024 18:03:04 +0300 Subject: [PATCH 4/5] Fix docs --- book/src/generated/lang-support.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 33f13e57c610..d013f20120b8 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -125,7 +125,7 @@ | mermaid | ✓ | | | | | meson | ✓ | | ✓ | | | mint | | | | `mint` | -| mojo | ✓ | | | `mojo-lsp-server` | +| mojo | ✓ | ✓ | ✓ | `mojo-lsp-server` | | move | ✓ | | | | | msbuild | ✓ | | ✓ | | | nasm | ✓ | ✓ | | | From 9b05bfce7a01148330c986874714759da9d2b278 Mon Sep 17 00:00:00 2001 From: Dmitry Salin Date: Tue, 14 May 2024 18:51:07 +0300 Subject: [PATCH 5/5] Use inheritance for some files --- runtime/queries/mojo/indents.scm | 87 +--------------------------- runtime/queries/mojo/injections.scm | 3 +- runtime/queries/mojo/locals.scm | 49 +--------------- runtime/queries/mojo/textobjects.scm | 36 +----------- 4 files changed, 4 insertions(+), 171 deletions(-) diff --git a/runtime/queries/mojo/indents.scm b/runtime/queries/mojo/indents.scm index 9bab4478ed3c..0b920cbf91ca 100644 --- a/runtime/queries/mojo/indents.scm +++ b/runtime/queries/mojo/indents.scm @@ -1,86 +1 @@ -[ - (list) - (tuple) - (dictionary) - (set) - - (if_statement) - (for_statement) - (while_statement) - (with_statement) - (try_statement) - (match_statement) - (case_clause) - (import_from_statement) - - (parenthesized_expression) - (generator_expression) - (list_comprehension) - (set_comprehension) - (dictionary_comprehension) - - (tuple_pattern) - (list_pattern) - (argument_list) - (parameters) - (binary_operator) - - (function_definition) - (class_definition) -] @indent - -; Workaround for the tree-sitter grammar creating large errors when a -; try_statement is missing the except/finally clause -(ERROR - "try" - . - ":" @indent @extend) -(ERROR - . - "def") @indent @extend -(ERROR - (block) @indent @extend - (#set! "scope" "all")) - -[ - (if_statement) - (for_statement) - (while_statement) - (with_statement) - (try_statement) - (match_statement) - (case_clause) - - (function_definition) - (class_definition) -] @extend - -[ - (return_statement) - (break_statement) - (continue_statement) - (raise_statement) - (pass_statement) -] @extend.prevent-once - -[ - ")" - "]" - "}" -] @outdent - -(elif_clause - "elif" @outdent) - -(else_clause - "else" @outdent) - -(parameters - . - (identifier) @anchor - (#set! "scope" "tail")) @align - -(argument_list - . - (_) @anchor - (#set! "scope" "tail")) @align +; inherits: python diff --git a/runtime/queries/mojo/injections.scm b/runtime/queries/mojo/injections.scm index 2f0e58eb6431..0b920cbf91ca 100644 --- a/runtime/queries/mojo/injections.scm +++ b/runtime/queries/mojo/injections.scm @@ -1,2 +1 @@ -((comment) @injection.content - (#set! injection.language "comment")) +; inherits: python diff --git a/runtime/queries/mojo/locals.scm b/runtime/queries/mojo/locals.scm index ddf4c8085a29..0b920cbf91ca 100644 --- a/runtime/queries/mojo/locals.scm +++ b/runtime/queries/mojo/locals.scm @@ -1,48 +1 @@ -; Scopes - -[ - (module) - (function_definition) - (lambda) -] @local.scope - -; Definitions - -; Parameters -(parameters - (identifier) @local.definition) - -(parameters - (typed_parameter - (identifier) @local.definition)) - -(parameters - (default_parameter - name: (identifier) @local.definition)) - -(parameters - (typed_default_parameter - name: (identifier) @local.definition)) - -(parameters - (list_splat_pattern ; *args - (identifier) @local.definition)) - -(parameters - (dictionary_splat_pattern ; **kwargs - (identifier) @local.definition)) - -(lambda_parameters - (identifier) @local.definition) - -; Imports -(import_statement - name: (dotted_name - (identifier) @local.definition)) - -(aliased_import - alias: (identifier) @local.definition) - -; References - -(identifier) @local.reference +; inherits: python diff --git a/runtime/queries/mojo/textobjects.scm b/runtime/queries/mojo/textobjects.scm index 5ad5229ed2ee..0b920cbf91ca 100644 --- a/runtime/queries/mojo/textobjects.scm +++ b/runtime/queries/mojo/textobjects.scm @@ -1,35 +1 @@ -(function_definition - body: (block)? @function.inside) @function.around - -(class_definition - body: (block)? @class.inside) @class.around - -(parameters - ((_) @parameter.inside . ","? @parameter.around) @parameter.around) - -(lambda_parameters - ((_) @parameter.inside . ","? @parameter.around) @parameter.around) - -(argument_list - ((_) @parameter.inside . ","? @parameter.around) @parameter.around) - -(comment) @comment.inside - -(comment)+ @comment.around - -((function_definition - name: (identifier) @_name - body: (block)? @test.inside) @test.around - (#match? @_name "^test_")) - -(list - (_) @entry.around) - -(tuple - (_) @entry.around) - -(set - (_) @entry.around) - -(pair - (_) @entry.inside) @entry.around +; inherits: python