From 977e9327268196ace4d7839c6d44feb7978952c4 Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Thu, 17 Aug 2023 00:49:36 -0400 Subject: [PATCH] feat: add BitBake --- README.md | 1 + lockfile.json | 3 + lua/nvim-treesitter/parsers.lua | 8 + queries/bitbake/folds.scm | 29 +++ queries/bitbake/highlights.scm | 360 ++++++++++++++++++++++++++++++++ queries/bitbake/indents.scm | 127 +++++++++++ queries/bitbake/injections.scm | 14 ++ queries/bitbake/locals.scm | 99 +++++++++ 8 files changed, 641 insertions(+) create mode 100644 queries/bitbake/folds.scm create mode 100644 queries/bitbake/highlights.scm create mode 100644 queries/bitbake/indents.scm create mode 100644 queries/bitbake/injections.scm create mode 100644 queries/bitbake/locals.scm diff --git a/README.md b/README.md index 12faa4d76..8aa827f7a 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,7 @@ We are looking for maintainers to add more parsers and to write query files for - [x] [beancount](https://github.com/polarmutex/tree-sitter-beancount) (maintained by @polarmutex) - [x] [bibtex](https://github.com/latex-lsp/tree-sitter-bibtex) (maintained by @theHamsta, @clason) - [x] [bicep](https://github.com/amaanq/tree-sitter-bicep) (maintained by @amaanq) +- [x] [bitbake](https://github.com/amaanq/tree-sitter-bitbake) (maintained by @amaanq) - [x] [blueprint](https://gitlab.com/gabmus/tree-sitter-blueprint.git) (experimental, maintained by @gabmus) - [x] [c](https://github.com/tree-sitter/tree-sitter-c) (maintained by @amaanq) - [x] [c_sharp](https://github.com/tree-sitter/tree-sitter-c-sharp) (maintained by @Luxed) diff --git a/lockfile.json b/lockfile.json index 14923f000..bb5303fe1 100644 --- a/lockfile.json +++ b/lockfile.json @@ -29,6 +29,9 @@ "bicep": { "revision": "3604d8c961ab129d2bfc6dfca56419c236ccdb83" }, + "bitbake": { + "revision": "ed92abd7b67ab66a6fa3a747a0157f01d2e467d8" + }, "blueprint": { "revision": "7f1a5df44861291d6951b6b2146a9fef4c226e14" }, diff --git a/lua/nvim-treesitter/parsers.lua b/lua/nvim-treesitter/parsers.lua index b40113a38..847c07837 100644 --- a/lua/nvim-treesitter/parsers.lua +++ b/lua/nvim-treesitter/parsers.lua @@ -156,6 +156,14 @@ list.bicep = { maintainers = { "@amaanq" }, } +list.bitbake = { + install_info = { + url = "https://github.com/amaanq/tree-sitter-bitbake", + files = { "src/parser.c", "src/scanner.c" }, + }, + maintainers = { "@amaanq" }, +} + list.blueprint = { install_info = { url = "https://gitlab.com/gabmus/tree-sitter-blueprint.git", diff --git a/queries/bitbake/folds.scm b/queries/bitbake/folds.scm new file mode 100644 index 000000000..9fc865e84 --- /dev/null +++ b/queries/bitbake/folds.scm @@ -0,0 +1,29 @@ +[ + (function_definition) + (anonymous_python_function) + (python_function_definition) + + (while_statement) + (for_statement) + (if_statement) + (with_statement) + (try_statement) + + (import_from_statement) + (parameters) + (argument_list) + + (parenthesized_expression) + (generator_expression) + (list_comprehension) + (set_comprehension) + (dictionary_comprehension) + + (tuple) + (list) + (set) + (dictionary) + + (string) + (python_string) +] @fold diff --git a/queries/bitbake/highlights.scm b/queries/bitbake/highlights.scm new file mode 100644 index 000000000..eb37b1b36 --- /dev/null +++ b/queries/bitbake/highlights.scm @@ -0,0 +1,360 @@ +; Includes + +[ + "inherit" + "include" + "require" + "export" + "import" +] @include + +; Keywords + +[ + "unset" + "EXPORT_FUNCTIONS" + "python" + + "assert" + "exec" + "global" + "nonlocal" + "pass" + "print" + "with" + "as" +] @keyword + +[ + "async" + "await" +] @keyword.coroutine + +[ + "return" + "yield" +] @keyword.return +(yield "from" @keyword.return) + +(future_import_statement + "from" @include + "__future__" @constant.builtin) +(import_from_statement "from" @include) +"import" @include + +(aliased_import "as" @include) + +["if" "elif" "else"] @conditional + +["for" "while" "break" "continue"] @repeat + +[ + "try" + "except" + "except*" + "raise" + "finally" +] @exception + +(raise_statement "from" @exception) + +(try_statement + (else_clause + "else" @exception)) + +[ + "addtask" + "deltask" + "addhandler" + "def" + "lambda" +] @keyword.function + +[ + "before" + "after" +] @storageclass + +[ + "append" + "prepend" + "remove" +] @type.qualifier + +; Variables + +[ + (identifier) + (python_identifier) +] @variable + +[ + "noexec" + "INHERIT" + "OVERRIDES" + "$BB_ENV_PASSTHROUGH" + "$BB_ENV_PASSTHROUGH_ADDITIONS" +] @variable.builtin + +; Reset highlighting in f-string interpolations +(interpolation) @none + +;; Identifier naming conventions +((python_identifier) @type + (#lua-match? @type "^[A-Z].*[a-z]")) +([(identifier) (python_identifier)] @constant + (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) + +((python_identifier) @constant.builtin + (#lua-match? @constant.builtin "^__[a-zA-Z0-9_]*__$")) + +((python_identifier) @constant.builtin + (#any-of? @constant.builtin + ;; https://docs.python.org/3/library/constants.html + "NotImplemented" + "Ellipsis" + "quit" + "exit" + "copyright" + "credits" + "license")) + +((assignment + left: (python_identifier) @type.definition + (type (python_identifier) @_annotation)) + (#eq? @_annotation "TypeAlias")) + +((assignment + left: (python_identifier) @type.definition + right: (call + function: (python_identifier) @_func)) + (#any-of? @_func "TypeVar" "NewType")) + +; Fields + +(flag) @field + +((attribute + attribute: (python_identifier) @field) + (#lua-match? @field "^[%l_].*$")) + +; Functions + +(call + function: (python_identifier) @function.call) + +(call + function: (attribute + attribute: (python_identifier) @method.call)) + +((call + function: (python_identifier) @constructor) + (#lua-match? @constructor "^%u")) + +((call + function: (attribute + attribute: (python_identifier) @constructor)) + (#lua-match? @constructor "^%u")) + +((call + function: (python_identifier) @function.builtin) + (#any-of? @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__")) + +(python_function_definition + name: (python_identifier) @function) + +(type (python_identifier) @type) +(type + (subscript + (python_identifier) @type)) ; type subscript: Tuple[int] + +((call + function: (python_identifier) @_isinstance + arguments: (argument_list + (_) + (python_identifier) @type)) + (#eq? @_isinstance "isinstance")) + +(anonymous_python_function (identifier) @function) + +(function_definition (identifier) @function) + +(addtask_statement (identifier) @function) + +(deltask_statement (identifier) @function) + +(export_functions_statement (identifier) @function) + +(addhandler_statement (identifier) @function) + +(python_function_definition + body: + (block + . (expression_statement (python_string) @string.documentation @spell))) + +; Namespace + +(inherit_directive (identifier) @namespace) + +;; Normal parameters +(parameters + (python_identifier) @parameter) +;; Lambda parameters +(lambda_parameters + (python_identifier) @parameter) +(lambda_parameters + (tuple_pattern + (python_identifier) @parameter)) +; Default parameters +(keyword_argument + name: (python_identifier) @parameter) +; Naming parameters on call-site +(default_parameter + name: (python_identifier) @parameter) +(typed_parameter + (python_identifier) @parameter) +(typed_default_parameter + (python_identifier) @parameter) +; Variadic parameters *args, **kwargs +(parameters + (list_splat_pattern ; *args + (python_identifier) @parameter)) +(parameters + (dictionary_splat_pattern ; **kwargs + (python_identifier) @parameter)) + +;; Literals + +(none) @constant.builtin +[(true) (false)] @boolean +((python_identifier) @variable.builtin + (#eq? @variable.builtin "self")) +((python_identifier) @variable.builtin + (#eq? @variable.builtin "cls")) + +(integer) @number +(float) @float + +; Operators + +[ + "?=" + "??=" + ":=" + "=+" + ".=" + "=." + "-" + "-=" + ":=" + "!=" + "*" + "**" + "**=" + "*=" + "/" + "//" + "//=" + "/=" + "&" + "&=" + "%" + "%=" + "^" + "^=" + "+" + "+=" + "<" + "<<" + "<<=" + "<=" + "<>" + "=" + "==" + ">" + ">=" + ">>" + ">>=" + "@" + "@=" + "|" + "|=" + "~" + "->" +] @operator + +[ + "and" + "in" + "is" + "not" + "or" + "is not" + "not in" + + "del" +] @keyword.operator + +; Literals + +[ + (string) + (python_string) + "\"" +] @string + +(include_path) @string.special + +[ + (escape_sequence) + (escape_interpolation) +] @string.escape + +; Punctuation + +[ "(" ")" "{" "}" "[" "]" ] @punctuation.bracket + +[ + ":" + "->" + ";" + "." + "," + (ellipsis) +] @punctuation.delimiter + +(variable_expansion [ "${" "}" ] @punctuation.special) +(inline_python [ "${@" "}" ] @punctuation.special) +(interpolation + "{" @punctuation.special + "}" @punctuation.special) + +(type_conversion) @function.macro + +([(identifier) (python_identifier)] @type.builtin + (#any-of? @type.builtin + ;; https://docs.python.org/3/library/exceptions.html + "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" + ;; https://docs.python.org/3/library/stdtypes.html + "bool" "int" "float" "complex" "list" "tuple" "range" "str" + "bytes" "bytearray" "memoryview" "set" "frozenset" "dict" "type" "object")) + +(comment) @comment @spell + +(ERROR) @error diff --git a/queries/bitbake/indents.scm b/queries/bitbake/indents.scm new file mode 100644 index 000000000..01d8aeb3c --- /dev/null +++ b/queries/bitbake/indents.scm @@ -0,0 +1,127 @@ +[ + (import_from_statement) + + (parenthesized_expression) + (generator_expression) + (list_comprehension) + (set_comprehension) + (dictionary_comprehension) + + (tuple_pattern) + (list_pattern) + (binary_operator) + + (lambda) + + (concatenated_string) +] @indent.begin + +((list) @indent.align + (#set! indent.open_delimiter "[") + (#set! indent.close_delimiter "]") +) +((dictionary) @indent.align + (#set! indent.open_delimiter "{") + (#set! indent.close_delimiter "}") +) +((set) @indent.align + (#set! indent.open_delimiter "{") + (#set! indent.close_delimiter "}") +) + +((for_statement) @indent.begin + (#set! indent.immediate 1)) +((if_statement) @indent.begin + (#set! indent.immediate 1)) +((while_statement) @indent.begin + (#set! indent.immediate 1)) +((try_statement) @indent.begin + (#set! indent.immediate 1)) +(ERROR "try" ":" @indent.begin (#set! indent.immediate 1)) +((python_function_definition) @indent.begin + (#set! indent.immediate 1)) +(function_definition) @indent.begin +(anonymous_python_function) @indent.begin +((with_statement) @indent.begin + (#set! indent.immediate 1)) + +(if_statement + condition: (parenthesized_expression) @indent.align + (#set! indent.open_delimiter "(") + (#set! indent.close_delimiter ")") + (#set! indent.avoid_last_matching_next 1)) +(while_statement + condition: (parenthesized_expression) @indent.align + (#set! indent.open_delimiter "(") + (#set! indent.close_delimiter ")") + (#set! indent.avoid_last_matching_next 1)) + +(ERROR "(" @indent.align (#set! indent.open_delimiter "(") (#set! indent.close_delimiter ")") . (_)) +((argument_list) @indent.align + (#set! indent.open_delimiter "(") + (#set! indent.close_delimiter ")")) +((parameters) @indent.align + (#set! indent.open_delimiter "(") + (#set! indent.close_delimiter ")") + (#set! indent.avoid_last_matching_next 1)) +((tuple) @indent.align + (#set! indent.open_delimiter "(") + (#set! indent.close_delimiter ")")) + +(ERROR "[" @indent.align (#set! indent.open_delimiter "[") (#set! indent.close_delimiter "]") . (_)) + +(ERROR "{" @indent.align (#set! indent.open_delimiter "{") (#set! indent.close_delimiter "}") . (_)) + +[ + (break_statement) + (continue_statement) +] @indent.dedent + +(ERROR + (_) @indent.branch ":" . + (#lua-match? @indent.branch "^else")) + +(ERROR + (_) @indent.branch @indent.dedent ":" . + (#lua-match? @indent.branch "^elif")) + +(parenthesized_expression ")" @indent.end) +(generator_expression ")" @indent.end) +(list_comprehension "]" @indent.end) +(set_comprehension "}" @indent.end) +(dictionary_comprehension "}" @indent.end) + +(tuple_pattern ")" @indent.end) +(list_pattern "]" @indent.end) + +(function_definition "}" @indent.end) +(anonymous_python_function "}" @indent.end) + +(return_statement + [ + (_) @indent.end + (_ + [ + (_) + ")" + "}" + "]" + ] @indent.end .) + (attribute + attribute: (_) @indent.end) + (call + arguments: (_ ")" @indent.end)) + "return" @indent.end + ] .) + +[ + ")" + "]" + "}" + (elif_clause) + (else_clause) + (except_clause) + (finally_clause) +] @indent.branch + +(string) @indent.auto diff --git a/queries/bitbake/injections.scm b/queries/bitbake/injections.scm new file mode 100644 index 000000000..819487bc5 --- /dev/null +++ b/queries/bitbake/injections.scm @@ -0,0 +1,14 @@ +(call + function: (attribute + object: (python_identifier) @_re) + arguments: (argument_list (python_string + (string_content) @injection.content) @_string) + (#eq? @_re "re") + (#lua-match? @_string "^r.*") + (#set! injection.language "regex")) + +((shell_content) @injection.content + (#set! injection.language "bash")) + +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/queries/bitbake/locals.scm b/queries/bitbake/locals.scm new file mode 100644 index 000000000..baf835cc5 --- /dev/null +++ b/queries/bitbake/locals.scm @@ -0,0 +1,99 @@ +; References +[ + (python_identifier) + (identifier) +] @reference + +; Imports +(aliased_import + alias: (python_identifier) @definition.import) +(import_statement + name: (dotted_name ((python_identifier) @definition.import))) +(import_from_statement + name: (dotted_name ((python_identifier) @definition.import))) + +; Function with parameters, defines parameters +(parameters + (python_identifier) @definition.parameter) + +(default_parameter + (python_identifier) @definition.parameter) + +(typed_parameter + (python_identifier) @definition.parameter) + +(typed_default_parameter + (python_identifier) @definition.parameter) + +; *args parameter +(parameters + (list_splat_pattern + (python_identifier) @definition.parameter)) + +; **kwargs parameter +(parameters + (dictionary_splat_pattern + (python_identifier) @definition.parameter)) + +; Function defines function and scope +((python_function_definition + name: (python_identifier) @definition.function) @scope + (#set! definition.function.scope "parent")) + +(function_definition (identifier) @definition.function) + +(anonymous_python_function (identifier) @definition.function) + +;;; Loops +; not a scope! +(for_statement + left: (pattern_list + (python_identifier) @definition.var)) +(for_statement + left: (tuple_pattern + (python_identifier) @definition.var)) +(for_statement + left: (python_identifier) @definition.var) + +; not a scope! +;(while_statement) @scope + +; for in list comprehension +(for_in_clause + left: (python_identifier) @definition.var) +(for_in_clause + left: (tuple_pattern + (python_identifier) @definition.var)) +(for_in_clause + left: (pattern_list + (python_identifier) @definition.var)) + +(dictionary_comprehension) @scope +(list_comprehension) @scope +(set_comprehension) @scope + +;;; Assignments + +(assignment + left: (python_identifier) @definition.var) + +(assignment + left: (pattern_list + (python_identifier) @definition.var)) +(assignment + left: (tuple_pattern + (python_identifier) @definition.var)) + +(assignment + left: (attribute + (python_identifier) + (python_identifier) @definition.field)) + +(variable_assignment (identifier) operator: [ "=" "?=" "??=" ":=" ] @definition.var) + +; Walrus operator x := 1 +(named_expression + (python_identifier) @definition.var) + +(as_pattern + alias: (as_pattern_target) @definition.var)