mirror of https://github.com/helix-editor/helix
Compare commits
14 Commits
9f37f75868
...
e284038e07
Author | SHA1 | Date |
---|---|---|
|
e284038e07 | |
|
4281228da3 | |
|
a2f219968a | |
|
e610e7dd80 | |
|
b273b89249 | |
|
963475d7bf | |
|
df1ea8cba3 | |
|
db15411f63 | |
|
6ddadd3fa7 | |
|
36c4fa6ab4 | |
|
9de1c7213b | |
|
b5a07f9974 | |
|
42db29a32d | |
|
fd11bd26cb |
|
@ -179,6 +179,7 @@ We use a similar set of scopes as
|
||||||
- `variable` - Variables
|
- `variable` - Variables
|
||||||
- `builtin` - Reserved language variables (`self`, `this`, `super`, etc.)
|
- `builtin` - Reserved language variables (`self`, `this`, `super`, etc.)
|
||||||
- `parameter` - Function parameters
|
- `parameter` - Function parameters
|
||||||
|
- `mutable` - Mutable variables (e.g. marked with `mut` in Rust)
|
||||||
- `other`
|
- `other`
|
||||||
- `member` - Fields of composite data types (e.g. structs, unions)
|
- `member` - Fields of composite data types (e.g. structs, unions)
|
||||||
- `private` - Private fields that use a unique syntax (currently just ECMAScript-based languages)
|
- `private` - Private fields that use a unique syntax (currently just ECMAScript-based languages)
|
||||||
|
|
|
@ -88,9 +88,14 @@
|
||||||
((type_arguments (type_identifier) @constant)
|
((type_arguments (type_identifier) @constant)
|
||||||
(#match? @constant "^[A-Z_]+$"))
|
(#match? @constant "^[A-Z_]+$"))
|
||||||
(type_arguments (type_identifier) @type)
|
(type_arguments (type_identifier) @type)
|
||||||
|
; `_` in `(_, _)`
|
||||||
(tuple_struct_pattern "_" @comment.unused)
|
(tuple_struct_pattern "_" @comment.unused)
|
||||||
|
; `_` in `Vec<_>`
|
||||||
((type_arguments (type_identifier) @comment.unused)
|
((type_arguments (type_identifier) @comment.unused)
|
||||||
(#eq? @comment.unused "_"))
|
(#eq? @comment.unused "_"))
|
||||||
|
; `_` in `Rc<[_]>`
|
||||||
|
((array_type (type_identifier) @comment.unused)
|
||||||
|
(#eq? @comment.unused "_"))
|
||||||
|
|
||||||
; ---
|
; ---
|
||||||
; Primitives
|
; Primitives
|
||||||
|
@ -201,11 +206,6 @@
|
||||||
value: (identifier)? @variable
|
value: (identifier)? @variable
|
||||||
field: (field_identifier) @variable.other.member))
|
field: (field_identifier) @variable.other.member))
|
||||||
|
|
||||||
(parameter
|
|
||||||
pattern: (identifier) @variable.parameter)
|
|
||||||
(closure_parameters
|
|
||||||
(identifier) @variable.parameter)
|
|
||||||
|
|
||||||
; -------
|
; -------
|
||||||
; Keywords
|
; Keywords
|
||||||
; -------
|
; -------
|
||||||
|
@ -289,8 +289,6 @@
|
||||||
"dyn"
|
"dyn"
|
||||||
] @keyword.storage.modifier
|
] @keyword.storage.modifier
|
||||||
|
|
||||||
; TODO: variable.mut to highlight mutable identifiers via locals.scm
|
|
||||||
|
|
||||||
; ---
|
; ---
|
||||||
; Remaining Paths
|
; Remaining Paths
|
||||||
; ---
|
; ---
|
||||||
|
@ -305,6 +303,146 @@
|
||||||
; Functions
|
; Functions
|
||||||
; -------
|
; -------
|
||||||
|
|
||||||
|
; highlight `baz` in `any_function(foo::bar::baz)` as function
|
||||||
|
; This generically works for an unlimited number of path segments:
|
||||||
|
;
|
||||||
|
; - `f(foo::bar)`
|
||||||
|
; - `f(foo::bar::baz)`
|
||||||
|
; - `f(foo::bar::baz::quux)`
|
||||||
|
;
|
||||||
|
; We know that in the above examples, the last component of each path is a function
|
||||||
|
; as the only other valid thing (following Rust naming conventions) would be a module at
|
||||||
|
; that position, however you cannot pass modules as arguments
|
||||||
|
(call_expression
|
||||||
|
function: _
|
||||||
|
arguments: (arguments
|
||||||
|
(scoped_identifier
|
||||||
|
path: _
|
||||||
|
name: (identifier) @function)))
|
||||||
|
|
||||||
|
; Special handling for point-free functions that are not part of a path
|
||||||
|
; but are just passed as variables to some "well-known"
|
||||||
|
; methods, which are known to take a closure as the first argument
|
||||||
|
;
|
||||||
|
; For example, `foo` in `a.map(foo)` is a @function
|
||||||
|
(call_expression
|
||||||
|
function: (field_expression
|
||||||
|
value: _
|
||||||
|
field: (field_identifier) @_method_name)
|
||||||
|
arguments:
|
||||||
|
; first argument is `@function`
|
||||||
|
(arguments
|
||||||
|
.
|
||||||
|
(identifier) @function)
|
||||||
|
(#any-of? @_method_name
|
||||||
|
; methods on `core::iter::Iterator`
|
||||||
|
"map" "map_while" "filter_map" "flat_map" "map_windows"
|
||||||
|
"try_for_each" "for_each"
|
||||||
|
"is_sorted_by" "is_sorted_by_key"
|
||||||
|
"all" "any" "reduce" "try_reduce"
|
||||||
|
"find" "find_map" "try_find" "position" "rposition"
|
||||||
|
"max_by" "max_by_key" "min_by" "min_by_key"
|
||||||
|
"filter" "inspect" "intersperse_with"
|
||||||
|
"partition" "partition_in_place" "is_partitioned"
|
||||||
|
"skip_while" "take_while"
|
||||||
|
|
||||||
|
; methods on `Option`
|
||||||
|
"and_then" "is_some_and" "is_none_or" "unwrap_or_else"
|
||||||
|
"ok_or_else" "or_else" "get_or_insert_with" "take_if"
|
||||||
|
"map_or_else" ; NOTE: both arguments are closures, so it is here and also in the block to
|
||||||
|
; highlight the 2nd argument
|
||||||
|
|
||||||
|
; methods on `Result
|
||||||
|
"map_err" "inspect_err"
|
||||||
|
|
||||||
|
; methods on `Entry`
|
||||||
|
"or_insert_with" "or_insert_with_key" "and_modify"
|
||||||
|
|
||||||
|
; method on `bool
|
||||||
|
"then"
|
||||||
|
|
||||||
|
; method on `Vec`
|
||||||
|
"chunk_by_mut" "split" "split_mut" "split_inclusive" "split_inclusive_mut"
|
||||||
|
"rsplit" "rsplit_mut" "binary_search_by"
|
||||||
|
"sort_unstable_by" "sort_unstable_by_key" "partition_dedup_by"
|
||||||
|
"partition_dedup_by_key" "fill_with" "partition_point" "sort_by"
|
||||||
|
"sort_by_key"
|
||||||
|
|
||||||
|
; methods on `HashMap`
|
||||||
|
"extract_if" "retain"
|
||||||
|
|
||||||
|
; methods on `itertools::Itertools`
|
||||||
|
"batching" "chunk_by" "group_by" "map_ok"
|
||||||
|
"filter_ok" "filter_map_ok" "process_results"
|
||||||
|
"kmerge_by" "coalesce" "dedup_by" "dedup_by_with_count"
|
||||||
|
"duplicates_by" "unique_by" "peeking_take_while"
|
||||||
|
"take_while_ref" "take_while_inclusive" "positions"
|
||||||
|
"update" "find_position" "find_or_last" "find_or_first"
|
||||||
|
"fold1" "tree_reduce" "tree_fold1" "partition_map"
|
||||||
|
"into_group_map_by" "into_grouping_map_by"
|
||||||
|
"min_set_by" "min_set_by_key" "max_set_by" "max_set_by_key"
|
||||||
|
"minmax_by_key" "minmax_by" "position_max_by_key"
|
||||||
|
"position_max_by" "position_min_by_key" "position_min_by"
|
||||||
|
"position_minmax_by_key" "position_minmax_by"
|
||||||
|
"sorted_unstable_by" "sorted_unstable_by_key" "sorted_by"
|
||||||
|
"sorted_by_key" "sorted_by_cached_key"
|
||||||
|
|
||||||
|
; method on `core::iter::Peekable`
|
||||||
|
"next_if"
|
||||||
|
|
||||||
|
; methods on `rayon::ParallelIterator`
|
||||||
|
;
|
||||||
|
; note: some of these methods are also
|
||||||
|
; present in the 2nd argument highlights, because
|
||||||
|
; those methods take a closure both as a 1st and 2nd arg
|
||||||
|
"for_each_init" "try_for_each_init" "map_init"
|
||||||
|
"update"
|
||||||
|
"flat_map_iter" "reduce_with" "try_reduce"
|
||||||
|
"try_reduce_with" "fold_with" "try_fold_with"
|
||||||
|
"find_any" "find_first" "find_last" "find_map_any"
|
||||||
|
"find_map_first" "find_map_last"
|
||||||
|
"take_any_while" "skip_any_while"
|
||||||
|
|
||||||
|
; method on `tap::Pipe`
|
||||||
|
"pipe" "pipe_ref" "pipe_ref_mut" "pipe_borrow" "pipe_deref_mut"
|
||||||
|
"pipe_borrow_mut" "pipe_as_ref" "pipe_as_mut" "pipe_deref"))
|
||||||
|
|
||||||
|
; Here, we do something similar to the above except for
|
||||||
|
; methods that take a closure as a 2nd argument instead of the first
|
||||||
|
(call_expression
|
||||||
|
function: (field_expression
|
||||||
|
value: _
|
||||||
|
field: (field_identifier) @_method_name)
|
||||||
|
arguments:
|
||||||
|
; handles `a.map_or_else(..., foo)`
|
||||||
|
(arguments
|
||||||
|
; first argument is ignored
|
||||||
|
.
|
||||||
|
; second argument is @function
|
||||||
|
(_)
|
||||||
|
.
|
||||||
|
(identifier) @function)
|
||||||
|
(#any-of? @_method_name
|
||||||
|
; methods on `Option`
|
||||||
|
"map_or_else" "zip_with"
|
||||||
|
|
||||||
|
; methods on `Iterator`
|
||||||
|
"try_fold" "scan" "fold" "cmp_by" "partial_cmp_by" "eq_by"
|
||||||
|
|
||||||
|
; methods on `rayon::ParallelIterator`
|
||||||
|
"for_each_with" "for_each_init" "try_for_each_with" "try_for_each_init"
|
||||||
|
"map_with" "map_init" "try_reduce" "fold_with" "try_fold_with"
|
||||||
|
|
||||||
|
; methods on `Vec`
|
||||||
|
"splitn" "splitn_mut" "rsplitn" "rsplitn_mut" "split_once"
|
||||||
|
"rsplit_once" "binary_search_by_key" "select_nth_unstable_by"
|
||||||
|
"select_nth_unstable_by_key"
|
||||||
|
; methods on `Itertools`
|
||||||
|
"k_largest_by" "k_largest_by_key" "k_largest_relaxed_by"
|
||||||
|
"k_largest_relaxed_by_key"
|
||||||
|
"k_smallest_by" "k_smallest_by_key" "k_smallest_relaxed_by" "k_smallest_relaxed_by_key"
|
||||||
|
"fold_while" "fold_ok" "fold_options" "merge_by" "merge_join_by" "pad_using" "format_with"))
|
||||||
|
|
||||||
(call_expression
|
(call_expression
|
||||||
function: [
|
function: [
|
||||||
((identifier) @function)
|
((identifier) @function)
|
||||||
|
|
|
@ -150,31 +150,11 @@
|
||||||
|
|
||||||
; std
|
; std
|
||||||
"assert_eq" "debug_assert_eq" "assert_ne" "debug_assert_ne"
|
"assert_eq" "debug_assert_eq" "assert_ne" "debug_assert_ne"
|
||||||
|
|
||||||
|
; Dioxus's rsx! macro accepts string interpolation
|
||||||
|
; in all strings, across the entire token tree
|
||||||
|
"rsx"
|
||||||
)
|
)
|
||||||
(#set! injection.language "rust-format-args-macro")
|
(#set! injection.language "rust-format-args-macro")
|
||||||
(#set! injection.include-children)
|
(#set! injection.include-children)
|
||||||
)
|
)
|
||||||
|
|
||||||
; Dioxus' "rsx!" macro relies heavily on string interpolation as well. The strings can be nested very deeply
|
|
||||||
(
|
|
||||||
(macro_invocation
|
|
||||||
macro: [
|
|
||||||
(scoped_identifier
|
|
||||||
name: (_) @_macro_name)
|
|
||||||
(identifier) @_macro_name
|
|
||||||
]
|
|
||||||
; TODO: This only captures 1 level of string literals. But in dioxus you can have
|
|
||||||
; nested string literals. For instance:
|
|
||||||
;
|
|
||||||
; rsx! { "{hello} world" }:
|
|
||||||
; -> (token_tree (string_literal))
|
|
||||||
; rsx! { div { "{hello} world" } }
|
|
||||||
; -> (token_tree (token_tree (string_literal)))
|
|
||||||
; rsx! { div { div { "{hello} world" } } }
|
|
||||||
; -> (token_tree (token_tree (token_tree (string_literal))))
|
|
||||||
(token_tree (string_literal) @injection.content)
|
|
||||||
)
|
|
||||||
(#eq? @_macro_name "rsx")
|
|
||||||
(#set! injection.language "rust-format-args")
|
|
||||||
(#set! injection.include-children)
|
|
||||||
)
|
|
||||||
|
|
|
@ -12,14 +12,46 @@
|
||||||
(block)
|
(block)
|
||||||
] @local.scope
|
] @local.scope
|
||||||
|
|
||||||
; Definitions
|
; Parameters
|
||||||
|
|
||||||
(function_item
|
(parameter
|
||||||
(parameters
|
pattern: [
|
||||||
|
; `foo` in `fn x(foo: !) {}`
|
||||||
|
(identifier) @local.definition.variable.parameter @variable.parameter
|
||||||
|
; `foo` and `bar` in `fn x((foo, bar): !) {}`
|
||||||
|
(tuple_pattern (identifier)* (identifier) @local.definition.variable.parameter @variable.parameter)
|
||||||
|
; `foo` and `bar` in `fn x(Struct { foo, bar }: !) {}`
|
||||||
|
(struct_pattern
|
||||||
|
(field_pattern)*
|
||||||
|
(field_pattern
|
||||||
|
name: (shorthand_field_identifier) @local.definition.variable.parameter @variable.parameter)
|
||||||
|
)
|
||||||
|
; `foo` and `bar` in `fn x(TupleStruct(foo, bar): !) {}`
|
||||||
|
(tuple_struct_pattern
|
||||||
|
type: _
|
||||||
|
(identifier)*
|
||||||
|
(identifier) @local.definition.variable.parameter @variable.parameter
|
||||||
|
)
|
||||||
|
; `foo` and `bar` in `fn x([foo, bar]: !) {}`
|
||||||
|
(slice_pattern
|
||||||
|
(identifier)*
|
||||||
|
(identifier) @local.definition.variable.parameter @variable.parameter
|
||||||
|
)
|
||||||
|
])
|
||||||
|
|
||||||
|
; Mutable variables
|
||||||
|
|
||||||
|
[
|
||||||
|
(let_declaration
|
||||||
|
(mutable_specifier)
|
||||||
|
pattern: (identifier) @local.definition.variable.mutable @variable.mutable)
|
||||||
(parameter
|
(parameter
|
||||||
pattern: (identifier) @local.definition.variable.parameter)))
|
(mutable_specifier)
|
||||||
|
pattern: (identifier) @local.definition.variable.mutable @variable.mutable)
|
||||||
(closure_parameters (identifier) @local.definition.variable.parameter)
|
(mut_pattern
|
||||||
|
(mutable_specifier)
|
||||||
|
(identifier) @local.definition.variable.mutable @variable.mutable)
|
||||||
|
]
|
||||||
|
|
||||||
; References
|
; References
|
||||||
(identifier) @local.reference
|
(identifier) @local.reference
|
||||||
|
|
Loading…
Reference in New Issue