From bb4b04c82dbbe453ffbc580176c25fac49059513 Mon Sep 17 00:00:00 2001 From: Hannah Date: Mon, 16 Mar 2026 10:19:15 -0400 Subject: [PATCH] feat(parser): add objectscript UDL parser --- SUPPORTED_LANGUAGES.md | 1 + lua/nvim-treesitter/parsers.lua | 9 + plugin/filetypes.lua | 1 + .../queries/objectscript_udl/highlights.scm | 289 ++++++++++++++++++ runtime/queries/objectscript_udl/indents.scm | 3 + .../queries/objectscript_udl/injections.scm | 159 ++++++++++ 6 files changed, 462 insertions(+) create mode 100644 runtime/queries/objectscript_udl/highlights.scm create mode 100644 runtime/queries/objectscript_udl/indents.scm create mode 100644 runtime/queries/objectscript_udl/injections.scm diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index 978a4b8ed..c7846003e 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -195,6 +195,7 @@ jsx (queries only)[^jsx] | unstable | `HFIJ ` | @steelsojka [nu](https://github.com/nushell/tree-sitter-nu) | unstable | `HFIJ ` | @abhisheksingh0x558 [objc](https://github.com/tree-sitter-grammars/tree-sitter-objc) | unstable | `HFIJL` | @amaanq [objdump](https://github.com/ColinKennedy/tree-sitter-objdump) | unstable | `H  J ` | @ColinKennedy +[objectscript_udl](https://github.com/intersystems/tree-sitter-objectscript) | unstable | `H IJ ` | @davem-intersys, @hkimura-intersys [ocaml](https://github.com/tree-sitter/tree-sitter-ocaml) | unstable | `HFIJL` | @undu [ocaml_interface](https://github.com/tree-sitter/tree-sitter-ocaml) | unstable | `HFIJL` | @undu [ocamllex](https://github.com/atom-ocaml/tree-sitter-ocamllex) | unstable | `H  J ` | @undu diff --git a/lua/nvim-treesitter/parsers.lua b/lua/nvim-treesitter/parsers.lua index d894046cc..96d882d8d 100644 --- a/lua/nvim-treesitter/parsers.lua +++ b/lua/nvim-treesitter/parsers.lua @@ -1498,6 +1498,15 @@ return { maintainers = { '@ColinKennedy' }, tier = 2, }, + objectscript_udl = { + install_info = { + location = 'udl', + revision = '7aa01969d0fea2e75dc69f2be2244b13d8269d6f', + url = 'https://github.com/intersystems/tree-sitter-objectscript', + }, + maintainers = { '@davem-intersys', '@hkimura-intersys' }, + tier = 2, + }, ocaml = { install_info = { location = 'grammars/ocaml', diff --git a/plugin/filetypes.lua b/plugin/filetypes.lua index f8fe0c287..927389aa5 100644 --- a/plugin/filetypes.lua +++ b/plugin/filetypes.lua @@ -32,6 +32,7 @@ local filetypes = { make = { 'automake' }, markdown = { 'pandoc' }, muttrc = { 'neomuttrc' }, + objectscript_udl = { 'objectscript' }, ocaml_interface = { 'ocamlinterface' }, perl = { 'pl' }, poe_filter = { 'poefilter' }, diff --git a/runtime/queries/objectscript_udl/highlights.scm b/runtime/queries/objectscript_udl/highlights.scm new file mode 100644 index 000000000..1daa15305 --- /dev/null +++ b/runtime/queries/objectscript_udl/highlights.scm @@ -0,0 +1,289 @@ +(pattern_expression) @string.regexp + +(numeric_literal) @number + +(string_literal) @string + +(keyword_pound_pound_class) @keyword + +(keyword_pound_pound_super) @keyword + +(system_defined_variable) @variable.builtin + +(system_defined_function) @function.builtin + +(sql_field_modifier) @keyword.modifier + +(property_name) @property + +(method_name) @function + +(parameter_name) @property + +(class_name) @type + +(macro) @constant + +(routine_ref) @variable + +(sql_field_identifier) @variable + +(lvn) @variable + +(gvn) @variable + +(ssvn) @variable + +(instance_variable) @variable + +(objectscript_identifier) @variable + +(method_arg) @variable.parameter + +; I didn't include ( or ) in this, because they are often grouped +; as part of a sequence that gets turned into a single token, so they +; don't get matched, and one ends up getting colored differently than the other. +[ + "_" + "," + ":" + ".." + "..." + "'[" + "']" + "']]" + "\"" + "\"\"" + "[" + "]" + "]]" + "{" + "}" + "/" + "\\" + "#" + "|" + "||" + "$$" +] @punctuation.delimiter + +[ + "'&" + "&" + "&&" + "'<" + "'=" + "'>" + "^" + "-" + "^$" + "+" + "<" + "<=" + "=" + ">" + ">=" + "@" + "*" + "**" + "'" + "'!" + "'?" + "!" + "?" +] @operator + +(json_string_literal) @string + +(json_boolean_literal) @boolean + +(json_number_literal) @number + +(json_null_literal) @string + +(bracket) @punctuation.bracket + +; === END EXPR === +; === BEGIN CORE === +(locktype) @variable + +(macro_arg) @variable + +(macro_value) @constant.builtin + +[ + (keyword_for) + (keyword_while) + (keyword_continue) +] @keyword.repeat + +[ + (keyword_if) + (keyword_elseif) + (keyword_else) + (keyword_oldelse) +] @keyword.conditional + +[ + (keyword_throw) + (keyword_try) + (keyword_catch) +] @keyword.exception + +[ + (keyword_return) + (keyword_quit) +] @keyword.return + +[ + (keyword_break) + (keyword_debug) + (keyword_trace) + (keyword_step) + (keyword_nostep) + (keyword_stepmethod) +] @keyword.debug + +[ + (keyword_pound_define) + (keyword_pound_def1arg) + (keyword_pound_if) + (keyword_pound_elseif) + (keyword_pound_else) + (keyword_pound_endif) + (keyword_pound_ifdef) + (keyword_pound_ifndef) + (keyword_dim) +] @keyword.directive + +[ + (keyword_pound_import) + (keyword_pound_include) +] @keyword.import + +[ + (keyword_as) + (keyword_of) + (keyword_public) + (keyword_private) + (keyword_methodimpl) +] @keyword.modifier + +keyword: (_) @keyword + +(embedded_js_special_case_complete) @punctuation.special + +(embedded_sql_marker) @punctuation.special + +(embedded_sql_reverse_marker) @punctuation.special + +(html_marker) @punctuation.special + +(html_marker_reversed) @punctuation.special + +(attribute) @attribute + +(open_keywords) @keyword.modifier + +(use_keywords) @keyword.modifier + +(close_parameter_option_value) @keyword.modifier + +[ + (line_comment_1) + (line_comment_2) + (line_comment_3) + (line_comment_4) + (block_comment) +] @comment @spell + +(tag) @tag + +[ + (keyword_import) + (keyword_include) + (keyword_includegenerator) +] @keyword.import + +[ + (keyword_method) + (keyword_classmethod) +] @keyword.function + +[ + (keyword_class) + (keyword_extends) + (keyword_property) + (keyword_relationship) + (keyword_foreignkey) + (keyword_parameter) + (keyword_projection) + (keyword_index) + (keyword_query) + (keyword_trigger) + (keyword_xdata) + (keyword_storage) +] @keyword.type + +[ + (keyword_as) + (keyword_of) + (keyword_on) + (keyword_not) + (keyword_references) +] @keyword.modifier + +[ + (method_keyword_codemode_expression) + (call_method_keyword) + (method_keyword) + (class_keywords) + (query_keywords) + (trigger_keyword) + (method_keyword_language) + (relationship_keyword) + (foreignkey_keyword) + (parameter_keyword) + (projection_keyword) + (index_keyword) + (index_keyword_extent) + (xdata_keyword) + (xdata_keyword_mimetype) + (property_keyword) +] @keyword.modifier + +(documatic_line) @comment.documentation + +(query_name) @property + +(property_name) @property + +(relationship_name) @property + +(foreignkey_name) @property + +(parameter_name) @property + +(projection_name) @property + +(index_name) @property + +(xdata_name) @property + +(storage_name) @property + +(return_type) @type.builtin + +(typename) @type + +(parameter_type) @type.builtin + +(index_type) @type.builtin + +(projection_type) @type.builtin + +(property_type) @type.builtin + +(index_property_type) @type.builtin + +(identifier) @variable diff --git a/runtime/queries/objectscript_udl/indents.scm b/runtime/queries/objectscript_udl/indents.scm new file mode 100644 index 000000000..a49aa039e --- /dev/null +++ b/runtime/queries/objectscript_udl/indents.scm @@ -0,0 +1,3 @@ +"{" @indent.begin + +"}" @indent.end diff --git a/runtime/queries/objectscript_udl/injections.scm b/runtime/queries/objectscript_udl/injections.scm new file mode 100644 index 000000000..862af545a --- /dev/null +++ b/runtime/queries/objectscript_udl/injections.scm @@ -0,0 +1,159 @@ +(embedded_html + (angled_bracket_fenced_text) @injection.content + (#set! injection.language "html")) + +(embedded_sql + (_ + (paren_fenced_text) @injection.content) + (#set! injection.language "sql")) + +(embedded_js + [ + (angled_bracket_fenced_text) + (embedded_js_special_case) + ] @injection.content + (#set! injection.language "javascript")) + +(embedded_xml + (angled_bracket_fenced_text) @injection.content + (#set! injection.language "xml")) + +([ + (line_comment_1) + (line_comment_2) + (line_comment_3) + (block_comment) +] @injection.content + (#set! injection.language "comment")) + +(method_definition + (external_method_keywords + (method_keyword_language + (rhs) @_lang)) + (external_method_body_content) @injection.content + (#set! injection.include-children "true") + (#match? @_lang "^[Pp][Yy][Tt][Hh][Oo][Nn]$") + (#set! injection.language "python")) + +(method_definition + (external_method_keywords + (method_keyword_language + (rhs) @_lang)) + (external_method_body_content) @injection.content + (#set! injection.include-children "true") + (#match? @_lang "^[Tt][Ss][Qq][Ll]$") + (#set! injection.language "tsql")) + +(method_definition + (external_method_keywords + (method_keyword_language + (rhs) @_lang)) + (external_method_body_content) @injection.content + (#set! injection.include-children "true") + (#match? @_lang "^[Ii][Ss][Pp][Ll]$") + (#set! injection.language "ispl")) + +((trigger + (external_trigger + (trigger_keywords + (method_keyword_language + (rhs) @_lang)) + (external_method_body_content) @injection.content)) + (#set! injection.include-children "true") + (#match? @_lang "^[Pp][Yy][Tt][Hh][Oo][Nn]$") + (#set! injection.language "python")) + +((trigger + (external_trigger + (trigger_keywords + (method_keyword_language + (rhs) @_lang)) + (external_method_body_content) @injection.content)) + (#set! injection.include-children "true") + (#match? @_lang "^[Tt][Ss][Qq][Ll]$") + (#set! injection.language "tsql")) + +(query + (return_type + (typename + (identifier) @_querytype + (#match? @_querytype "^%[Ss][Qq][Ll][Qq][Uu][Ee][Rr][Yy]$"))) + (query_body + (query_body_content) @injection.content) + (#set! injection.language "sql") + (#set! injection.include-children "true")) + +(xdata + (xdata_any + (xdata_keywords + (xdata_keyword_mimetype + (rhs) @_mt)) + (external_method_body_content) @injection.content) + (#set! injection.include-children "true") + (#match? @_mt "^\"?text/markdown\"?$") + (#set! injection.language "markdown")) + +(xdata + (xdata_any + (xdata_keywords + (xdata_keyword_mimetype + (rhs) @_mt)) + (external_method_body_content) @injection.content) + (#set! injection.include-children "true") + (#match? @_mt + "^\"?([Tt][Ee][Xx][Tt]|[Aa][Pp][Pp][Ll][Ii][Cc][Aa][Tt][Ii][Oo][Nn])/[Xx][Mm][Ll]\"?$") + (#set! injection.language "xml")) + +(xdata + (xdata_any + (xdata_keywords + (xdata_keyword_mimetype + (rhs) @_mt)) + (external_method_body_content) @injection.content) + (#set! injection.include-children "true") + (#match? @_mt "^\"?text/html\"?$") + (#set! injection.language "html")) + +(xdata + (xdata_any + (xdata_keywords + (xdata_keyword_mimetype + (rhs) @_mt)) + (external_method_body_content) @injection.content) + (#set! injection.include-children "true") + (#match? @_mt "^\"?application/json\"?$") + (#set! injection.language "json")) + +(xdata + (xdata_any + (xdata_keywords + (xdata_keyword_mimetype + (rhs) @_mt)) + (external_method_body_content) @injection.content) + (#set! injection.include-children "true") + (#match? @_mt + "^\"?([Tt][Ee][Xx][Tt]|[Aa][Pp][Pp][Ll][Ii][Cc][Aa][Tt][Ii][Oo][Nn])/[Yy][Aa][Mm][Ll]\"?$") + (#set! injection.language "yaml")) + +(xdata + (xdata_any + (xdata_keywords + (xdata_keyword_mimetype + (rhs) @_mt)) + (external_method_body_content) @injection.content) + (#set! injection.include-children "true") + (#match? @_mt "^\"?text/css\"?$") + (#set! injection.language "css")) + +(xdata + (xdata_xml + (xdata_keywords)? + (external_method_body_content) @injection.content) + (#set! injection.include-children "true") + (#set! injection.language "xml")) + +(storage + (storage_body + (external_method_body_content) @injection.content) + (#set! injection.language "xml") + (#set! injection.include-children "true"))