This commit is contained in:
Ben Woodward 2026-04-03 11:22:10 +03:00 committed by GitHub
commit c893157825
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 404 additions and 0 deletions

View file

@ -123,6 +123,7 @@ ecma (queries only)[^ecma] | unstable | `HFIJL` | @steelsojka
[haskell_persistent](https://github.com/MercuryTechnologies/tree-sitter-haskell-persistent) | unstable | `HF   ` | @lykahb
[hcl](https://github.com/tree-sitter-grammars/tree-sitter-hcl) | unstable | `HFIJ ` | @MichaHoffmann
[heex](https://github.com/connorlay/tree-sitter-heex) | unstable | `HFIJL` | @connorlay
[helixql](https://github.com/benwoodward/tree-sitter-helixql) | unstable | `HF   ` | @benwoodward
[helm](https://github.com/ngalaiko/tree-sitter-go-template) | unstable | `HF JL` | @qvalentin
[hjson](https://github.com/winston0410/tree-sitter-hjson) | unstable | `HFIJL` | @winston0410
[hlsl](https://github.com/tree-sitter-grammars/tree-sitter-hlsl) | unstable | `HFIJL` | @theHamsta

View file

@ -919,6 +919,14 @@ return {
maintainers = { '@qvalentin' },
tier = 2,
},
helixql = {
install_info = {
revision = '259d2b68c56ae40ef7d190919ed49e0f17d1f3ee',
url = 'https://github.com/benwoodward/tree-sitter-helixql',
},
maintainers = { '@benwoodward' },
tier = 2,
},
hjson = {
install_info = {
revision = '02fa3b79b3ff9a296066da6277adfc3f26cbc9e0',

View file

@ -0,0 +1,12 @@
; =============================================================================
; HelixQL Folds for Neovim Tree-sitter
; =============================================================================
[
(node_def)
(edge_def)
(vector_def)
(query_def)
(for_loop)
(object_step)
(create_field)
] @fold

View file

@ -0,0 +1,259 @@
; =============================================================================
; HelixQL Syntax Highlighting for Neovim Tree-sitter
; =============================================================================
; NOTE: In tree-sitter queries, later patterns override earlier ones.
; Put general patterns first, then specific overrides after.
; -----------------------------------------------------------------------------
; Comments
; -----------------------------------------------------------------------------
(comment) @comment @spell
; -----------------------------------------------------------------------------
; Literals
; -----------------------------------------------------------------------------
(string_literal) @string
(integer) @number
(float) @number.float
(boolean) @boolean
(none) @constant.builtin
(now) @constant.builtin
; -----------------------------------------------------------------------------
; Generic identifiers
; -----------------------------------------------------------------------------
(identifier) @variable
(identifier_upper) @type
; -----------------------------------------------------------------------------
; Keywords
; -----------------------------------------------------------------------------
[
"QUERY"
"RETURN"
"FOR"
"IN"
] @keyword
; Node type keywords (wrapped in their own rules)
(index) @keyword
(default) @keyword
(count) @keyword
(ID) @constant.builtin
; Keywords inside node types
(where_step
"WHERE" @keyword)
(range_step
"RANGE" @keyword)
(update
"UPDATE" @keyword)
(drop
"DROP" @keyword)
(exists
"EXISTS" @keyword)
; Boolean and logical operators
(and
"AND" @keyword.operator)
(or
"OR" @keyword.operator)
(GT
"GT" @keyword.operator)
(GTE
"GTE" @keyword.operator)
(LT
"LT" @keyword.operator)
(LTE
"LTE" @keyword.operator)
(EQ
"EQ" @keyword.operator)
(NEQ
"NEQ" @keyword.operator)
; Creation operation keywords
(AddN
"AddN" @function.builtin)
(AddE
"AddE" @function.builtin)
(AddV
"AddV" @function.builtin)
(BatchAddV
"BatchAddV" @function.builtin)
(search_vector
"SearchV" @function.builtin)
; -----------------------------------------------------------------------------
; Schema definition keywords
; -----------------------------------------------------------------------------
[
"N::"
"E::"
"V::"
] @keyword.directive
[
"From:"
"To:"
"Properties"
] @keyword.modifier
; -----------------------------------------------------------------------------
; Graph traversal methods
; -----------------------------------------------------------------------------
(out_e
"OutE" @function.method)
(in_e
"InE" @function.method)
(from_n) @function.method
(to_n) @function.method
(out
"Out" @function.method)
(in_nodes
"In" @function.method)
(shortest_path
"ShortestPath" @function.method)
; -----------------------------------------------------------------------------
; Start nodes - highlight N, E, V as keywords
; -----------------------------------------------------------------------------
(start_node
"N" @keyword)
(start_edge
"E" @keyword)
(start_vector
"V" @keyword)
; -----------------------------------------------------------------------------
; Types
; -----------------------------------------------------------------------------
(named_type) @type.builtin
(date_type) @type.builtin
(ID_TYPE) @type.builtin
; Type arguments in angle brackets
(type_args
(identifier_upper) @type)
; -----------------------------------------------------------------------------
; Specific identifier patterns (override generic rules)
; -----------------------------------------------------------------------------
; Query/function names
(query_def
name: (identifier) @function)
; Schema definition names
(node_def
name: (identifier_upper) @type.definition)
(edge_def
name: (identifier_upper) @type.definition)
(vector_def
name: (identifier_upper) @type.definition)
; Parameter names in function signatures
(param_def
name: (identifier) @variable.parameter)
; Field names in schema definitions
(field_def
name: (identifier) @property)
; Property keys in object creation
(new_field
key: (identifier) @property)
; Property keys in updates
(update_field
key: (identifier) @property)
; Property keys in object mapping (left of :)
(mapping_field
(identifier) @property
":")
; Object access field
(object_access
field: (identifier) @property)
; Variable assignment targets (left of <-)
(get_stmt
variable: (identifier) @variable)
; For loop iterable
(for_loop
iterable: (identifier) @variable)
; -----------------------------------------------------------------------------
; Operators
; -----------------------------------------------------------------------------
[
"<-"
"=>"
"::"
"."
".."
"!"
] @operator
; -----------------------------------------------------------------------------
; Punctuation
; -----------------------------------------------------------------------------
[
":"
","
] @punctuation.delimiter
[
"("
")"
"{"
"}"
"["
"]"
"<"
">"
] @punctuation.bracket
"|" @punctuation.special
; -----------------------------------------------------------------------------
; Special patterns
; -----------------------------------------------------------------------------
; Anonymous traversal underscore
(anonymous_traversal
"_" @variable.builtin)

View file

@ -0,0 +1,124 @@
// Schema definitions
// <- @comment
N::User {
// <- @keyword.directive
// ^ @type.definition
INDEX id: ID,
//^ @keyword
// ^ @type.builtin
name: String,
//^ @property
// ^ @type.builtin
email: String,
age: I32,
// ^ @type.builtin
created_at: Date DEFAULT NOW
// ^ @type.builtin
// ^ @keyword
// ^ @constant.builtin
}
E::Follows {
// <- @keyword.directive
From: User,
//^ @keyword.modifier
To: User,
//^ @keyword.modifier
Properties: {
//^ @keyword.modifier
since: Date
}
}
V::UserEmbedding {
// <- @keyword.directive
user_id: ID,
embedding: [F32]
}
// Simple query
QUERY getUser(userId: ID) =>
// <- @keyword
// ^ @function
// ^ @variable.parameter
user <- N<User>(userId)
//^ @variable
// ^ @operator
// ^ @keyword
// ^ @type
RETURN user
//^ @keyword
// Query with traversal
QUERY getFollowers(userId: ID) =>
user <- N<User>(userId)
followers <- user::InE<Follows>::FromN
// ^ @function.method
// ^ @function.method
RETURN followers
// Query with filtering
QUERY getAdults(minAge: I32) =>
users <- N<User>::WHERE(_::age::GTE(minAge))
// ^ @keyword
// ^ @variable.builtin
// ^ @keyword.operator
RETURN users
// Query with object return
QUERY getUserStats(userId: ID) =>
user <- N<User>(userId)
followCount <- user::OutE<Follows>::COUNT
// ^ @keyword
RETURN {
userId: userId,
// ^ @property
followCount: followCount
}
// Query with AddN
QUERY createUser(name: String, email: String) =>
user <- AddN<User>({
// ^ @function.builtin
name: name,
email: email
})
RETURN user
// Query with AddE
QUERY followUser(fromId: ID, toId: ID) =>
from <- N<User>(fromId)
to <- N<User>(toId)
AddE<Follows>::From(from::ID)::To(to::ID)
//^ @function.builtin
RETURN from
// Query with FOR loop
QUERY createMultipleUsers(names: [String]) =>
FOR name IN names {
//^ @keyword
// ^ @keyword
user <- AddN<User>({name: name})
}
RETURN NONE
// ^ @constant.builtin
// Vector search
QUERY findSimilar(embedding: [F32], limit: I32) =>
results <- SearchV<UserEmbedding>(embedding, limit)
// ^ @function.builtin
RETURN results
// Literals
QUERY testLiterals() =>
str <- "hello world"
// ^ @string
num <- 42
// ^ @number
flt <- 3.14
// ^ @number.float
b <- true
// ^ @boolean
RETURN NONE
// vim: set filetype=helixql: