feat(parsers): Add objectscript

This commit is contained in:
Dave McCaldon 2025-11-04 06:20:54 -05:00
parent 65a266bf69
commit b8085c5aec
No known key found for this signature in database
GPG key ID: 9A28A772F21A6342
7 changed files with 444 additions and 0 deletions

View file

@ -196,6 +196,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](https://github.com/intersystems/tree-sitter-objectscript) | unstable | `H IJL` | @davem-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

View file

@ -1509,6 +1509,15 @@ return {
maintainers = { '@ColinKennedy' },
tier = 2,
},
objectscript = {
install_info = {
revision = '4d34cb2d4a4924f0b9c9524ffaba1b9c0644067e',
url = 'https://github.com/intersystems/tree-sitter-objectscript',
location = 'udl',
},
maintainers = { '@davem-intersys' },
tier = 2,
},
ocaml = {
install_info = {
location = 'grammars/ocaml',

View file

@ -31,6 +31,7 @@ local filetypes = {
make = { 'automake' },
markdown = { 'pandoc' },
muttrc = { 'neomuttrc' },
objectscript = { 'objectscript', 'udl' },
ocaml_interface = { 'ocamlinterface' },
perl = { 'pl' },
poe_filter = { 'poefilter' },

View file

@ -0,0 +1,273 @@
; -------------- Objectscript -------------
; Variables
; ^| e.g. '^||ppg', 'do', 'D'
; -----------------------------------------
(gvn) @variable.builtin
(ssvn) @variable.builtin
(lvn) @variable
(instance_variable) @variable.member
; String literals
; e.g. "Fo345349*_)(*_)8023841-40"" "
; -----------------------------------------
(string_literal) @string
(pattern_expression) @string.regexp
; Operators
(_
operator: _ @operator)
; Numeric literals
; e.g. 12345
(numeric_literal) @number
; System variable name
; e.g. $IO, $SY[SYTEM]
(system_defined_variable) @function.builtin
; System defined functions
; e.g. $ASCII(62)
(system_defined_function) @function.builtin
(dollarsf
; $SYSTEM.Foo.Bar()
(dollar_system_keyword) @function.builtin)
(property_name) @property
(parameter_name) @constant
(_
parameter: _ @variable.parameter)
; Method invcoations
(instance_method_call) @function.method.call
(class_method_call
(class_ref
(class_name) @type.definition)
(method_name) @function.method.call)
(oref_method
(method_name) @function.method.call)
(_
preproc_keyword: (_) @keyword.directive)
(_
modifier: (_) @keyword.directive)
; User-defined functions
(extrinsic_function) @function.call
; Goto labels and locations
(_
label: (_) @label)
(_
offset: (_) @number)
(_
routine: (_) @module)
; JSON literals
(json_boolean_literal) @boolean
(json_null_literal) @constant.builtin
(json_number_literal) @number
(json_string_literal) @string.escape
; Macros
(macro
(macro_constant)) @constant.macro
(macro
(macro_function)) @function.macro
; -------------- Objectscript Core -------------
; Commands
; e.g. 'set', 'do', 'D'
; -----------------------------------------
(_
command_name: (_) @keyword)
(_
macro_name: (_) @function.macro)
(_
macro_arg: (_) @constant.macro)
(_
mnemonic: (_) @constant.macro)
; Functions that can be on the LHS of a SET
(doable_dollar_functions) @function.builtin
; non-extrinsic routine call
(routine_tag_call) @function.call
; Technically elseif and else_block are not statements,
; so we need ot query them explicitly
;(elseif_block command_name: (_) @keyword)
;(else_block command_name: (_) @keyword)
"{" @punctuation.bracket
"}" @punctuation.bracket
; Comments
; e.g. '// fj;lkasdfj', '#; sklfjas;k', '; sklfjas','/* sdfs */'
[
(line_comment_1)
(line_comment_2)
(line_comment_3)
(block_comment)
] @comment
(embedded_html
(keyword_embedded_html) @keyword.directive
"<" @keyword.directive
">" @keyword.directive)
; (embedded_sql_hash
; (keyword_embedded_sql_hash) @keyword.directive
; )
; (embedded_sql_amp
; (keyword_embedded_sql_amp) @keyword.directive
; "(" @keyword.directive
; ")" @keyword.directive
; (embedded_sql_reverse_marker) @keyword.directive
; )
(embedded_sql_amp
(keyword_embedded_sql_amp) @keyword.directive
"(" @keyword.directive
")" @keyword.directive)
(embedded_sql_hash
(keyword_embedded_sql_hash) @keyword.directive
"(" @keyword.directive
")" @keyword.directive)
(embedded_js
(keyword_embedded_js) @keyword.directive
"<" @keyword.directive
">" @keyword.directive)
(embedded_xml
(keyword_embedded_xml) @keyword.directive
"<" @keyword.directive
">" @keyword.directive)
(tag) @label
; Lock type specifications
(locktype) @variable.parameter.builtin
(_
keyword: (_) @keyword)
; (identifier) @variable
; Alternatively
; (class_statement (_ class_statement_keyword: (_) @keyword ) .)
"{" @punctuation.bracket
"}" @punctuation.bracket
; @class.name capture group is not suppported in nvim highlighter
; (class_definition class_name: (identifier) @class.name)
(include_clause
(identifier) @keyword.import)
(property
(identifier) @property)
(parameter
(identifier) @constant)
(projection
(identifier) @type.definition)
(trigger
(identifier) @type.definition)
(index
(identifier) @type.definition)
(relationship
(identifier) @type.definition)
(foreignkey
(identifier) @type.definition)
(xdata
(identifier) @constant)
(typename) @type
(class_definition
class_name: (identifier) @type
(class_extends
(identifier) @type))
(method_definition
(identifier
(identifier)) @function)
(query
(identifier) @function)
(argument
(identifier) @variable.parameter)
(keyword_name) @keyword
(class_keywords
(_
rhs: _ @constant.builtin))
(parameter_keywords
(_
rhs: _ @constant.builtin))
(property_keywords
(_
rhs: _ @constant.builtin))
(xdata_keywords
(_
rhs: _ @constant.builtin))
(method_keywords
(_
rhs: _ @constant.builtin))
(trigger_keywords
(_
rhs: _ @constant.builtin))
(query_keywords
(_
rhs: _ @constant.builtin))
(index_keywords
(_
rhs: _ @constant.builtin))
(foreignkey_keywords
(_
rhs: _ @constant.builtin))
(projection_keywords
(_
rhs: _ @constant.builtin))
(relationship_keywords
(_
rhs: _ @constant.builtin))
(documatic_line) @comment.documentation

View file

@ -0,0 +1,35 @@
; Indentation rules for ObjectScript UDL (nvim-treesitter)
; --- Class Definition ---
(class_body
"{" @indent.begin
"}" @indent.end)
; --- Block-style commands with braces ---
(command_while
"{" @indent.begin
"}" @indent.end)
(command_for
"{" @indent.begin
"}" @indent.end)
(command_if
"{" @indent.begin
"}" @indent.end)
(elseif_block
"{" @indent.begin
"}" @indent.end)
(else_block
"{" @indent.begin
"}" @indent.end)
; --- Generic brace and parenthesis handling ---
"{" @indent.begin
"}" @indent.end
("(" @indent.align
(#set! indent.open_delimiter "(")
(#set! indent.close_delimiter ")"))

View file

@ -0,0 +1,124 @@
; Target method_body_content and reparse it using
; objectscript_core
(embedded_html
(angled_bracket_fenced_text) @injection.content
(#set! injection.language "html")
(#set! injection.include-children "false")
(#set! injection.combined "true"))
(embedded_sql
(_
(paren_fenced_text) @injection.content)
(#set! injection.language "sql")
(#set! injection.include-children "false")
(#set! injection.combined "true"))
(embedded_js
(angled_bracket_fenced_text) @injection.content
(#set! injection.language "javascript")
(#set! injection.include-children "false")
(#set! injection.combined "true"))
(embedded_xml
(angled_bracket_fenced_text) @injection.content
(#set! injection.language "xml")
(#set! injection.include-children "false")
(#set! injection.combined "true"))
([
(line_comment_1)
(line_comment_2)
(line_comment_3)
(block_comment)
(documatic_line)
] @injection.content
(#set! injection.language "comment"))
; Keywords, one of type language = "python", none of type codemode
(method_definition
keywords: (_
(kw_External_Language
rhs: _ @injection.language))
body: (_) @injection.content
(#set! injection.include-children "true"))
(trigger
keywords: (_
(kw_External_Language
rhs: _ @injection.language))
body: (_) @injection.content
(#set! injection.include-children "true"))
; A query must be of type %SQLQuery to have an SQL body, otherwise the body
; is empty
(query
type: (_
(typename
(identifier) @_querytype
(#eq? @_querytype "%SQLQuery")))
(_
(query_body_content) @injection.content)
(#set! injection.language "sql")
(#set! injection.include-children "true"))
; XDATA blocks. There's a MimeType keyword that defines the content-type
; To prevent overlapping matches, we use a different body for the case where
; no MimeType is given and default to XML, otherwise we extract the language
; from the mimetype.
(xdata
keywords: (_
(kw_MimeType
rhs: _ @_mimetype
(#eq? @_mimetype "\"text/markdown\"")))
body: (xdata_body_content_any) @injection.content
(#set! injection.language "markdown")
(#set! injection.include-children "true"))
(xdata
keywords: (_
(kw_MimeType
rhs: _ @_mimetype
(#eq? @_mimetype "\"text/xml\"")))
; NOTE: Since MimeType is given, we match xdata_body_content_any not xml
body: (xdata_body_content_any) @injection.content
(#set! injection.language "xml")
(#set! injection.include-children "true"))
(xdata
keywords: (_
(kw_MimeType
rhs: _ @_mimetype
(#eq? @_mimetype "\"text/html\"")))
body: (xdata_body_content_any) @injection.content
(#set! injection.language "html")
(#set! injection.include-children "true"))
(xdata
keywords: (_
(kw_MimeType
rhs: _ @_mimetype
(#eq? @_mimetype "\"application/json\"")))
body: (xdata_body_content_any) @injection.content
(#set! injection.language "json")
(#set! injection.include-children "true"))
(xdata
keywords: (_
(kw_MimeType
rhs: _ @_mimetype
(#eq? @_mimetype "\"text/css\"")))
body: (xdata_body_content_any) @injection.content
(#set! injection.language "css")
(#set! injection.include-children "true"))
; Match an unspecified XDATA -- defaults to XML
(xdata
body: (xdata_body_content_xml) @injection.content
(#set! injection.language "xml")
(#set! injection.include-children "true"))
; Storage definition is XML
(storage
body: (_) @injection.content
(#set! injection.language "xml")
(#set! injection.include-children "true"))

View file

@ -0,0 +1 @@