mirror of https://github.com/helix-editor/helix
Compare commits
93 Commits
5bc0a198f9
...
c4415119fd
Author | SHA1 | Date |
---|---|---|
Michael Davis | c4415119fd | 2 months ago |
Michael Davis | b1d90d1931 | 2 months ago |
Michael Davis | d5e4cf8009 | 2 months ago |
Michael Davis | cfa8dbb5a4 | 2 months ago |
Michael Davis | 72c37af9b9 | 2 months ago |
Michael Davis | 1ebb515cf3 | 2 months ago |
Michael Davis | 3a164ebf60 | 2 months ago |
Michael Davis | b814b3e347 | 2 months ago |
Michael Davis | 8a07f357e5 | 2 months ago |
Michael Davis | 4908438de0 | 2 months ago |
Michael Davis | cac0930674 | 2 months ago |
Armando Pérez Marqués | 47995bfb0c | 2 months ago |
Tobias Brunner | 7bce9530d3 | 2 months ago |
Florent Nuttens | da2dec174a | 2 months ago |
Florent Nuttens | 628dcd5c56 | 2 months ago |
Florent Nuttens | 2178adfe93 | 2 months ago |
ves | 54fab657be | 2 months ago |
Yomain | 8f65bfe089 | 2 months ago |
Pascal Kuthe | b46064b8c4 | 2 months ago |
Pascal Kuthe | 3001f22b31 | 2 months ago |
Pascal Kuthe | 66b9ff1d2a | 2 months ago |
Pascal Kuthe | 69e07ab61e | 2 months ago |
Michael Davis | 68b21578ac | 2 months ago |
Michael Davis | b1222f0664 | 2 months ago |
Michael Davis | 6dd46bfe1c | 2 months ago |
Jaakko Paju | d5c2973cd1 | 2 months ago |
Carter Watson | be307a4204 | 2 months ago |
David Else | c9e34c556b | 2 months ago |
Michael Davis | f5d95de227 | 2 months ago |
Michael Davis | c099dde2a7 | 2 months ago |
Michael Davis | 9ceeea5a83 | 2 months ago |
Michael Davis | fdcd461e65 | 2 months ago |
Michael Davis | 459eb9a4c1 | 2 months ago |
Michael Davis | 961025433d | 2 months ago |
JR | 51739f1290 | 2 months ago |
Jordan Reger | 5ba36fe9b3 | 2 months ago |
Michael Davis | 7f5fd63835 | 2 months ago |
David Else | 52a0734120 | 2 months ago |
Hendrik Norkowski | b8e79c0ef5 | 2 months ago |
Szabin | bcf7b26393 | 2 months ago |
Arthur Deierlein | 427dd2f383 | 2 months ago |
Kirawi | d9de809a57 | 2 months ago |
Tobias Hunger | 1d1806c85a | 2 months ago |
Arthur Deierlein | 4b4947639a | 2 months ago |
Cyrill Schenkel | 5b8bfc5476 | 2 months ago |
Damian Zaręba | 485c5cf0b8 | 2 months ago |
Arthur Deierlein | 0b6dea6dc2 | 2 months ago |
Luis Useche | 6a22d7d1ca | 2 months ago |
Khang Nguyen Duy | 4d2282cbcc | 2 months ago |
dependabot[bot] | 3d4889ce9a | 2 months ago |
mo8it | 0f5430ab9e | 2 months ago |
mo8it | e91ec8e880 | 2 months ago |
mo8it | 6ed93b6e49 | 2 months ago |
mo8it | 6607938bf8 | 2 months ago |
Blaž Hrastnik | 13533cb99c | 2 months ago |
dependabot[bot] | df8352ec05 | 2 months ago |
dependabot[bot] | ef797acf0d | 2 months ago |
dependabot[bot] | 7ef583bea7 | 2 months ago |
dependabot[bot] | 326c078356 | 2 months ago |
dependabot[bot] | 8dc50bded9 | 2 months ago |
Jaakko Paju | 58022586a0 | 2 months ago |
Matthew Toohey | 2e4653ea31 | 2 months ago |
Phil | 94d210c9bf | 2 months ago |
Michael Davis | 4ffe993533 | 2 months ago |
Michael Davis | 38af99f05f | 2 months ago |
Joey Hain | 476e6baf8f | 2 months ago |
Leonardo Eugênio | d99b6177c2 | 2 months ago |
Carsten Führmann | eead105f94 | 2 months ago |
Erasin Wang | 64389f97fe | 2 months ago |
Benedikt Ritter | f7913c1a3b | 2 months ago |
Alexis Mousset | 8457652da1 | 2 months ago |
Jonas De Vuyst | 0301d01e78 | 2 months ago |
Dan Cardamore | 3890376a23 | 2 months ago |
George "Riye" Hollister | e36774c2c8 | 2 months ago |
Arthur Deierlein | 9ec0271873 | 2 months ago |
Arthur Deierlein | 61f7d9ce2f | 2 months ago |
Emi | 761df60077 | 2 months ago |
Nick | 6fea7876a4 | 2 months ago |
Michael Davis | 9282f1b8e5 | 2 months ago |
Mike Trinkala | b961acf746 | 2 months ago |
Kirawi | 0c51ab16d0 | 2 months ago |
Michael Davis | 6c4d986c1b | 2 months ago |
dependabot[bot] | b44b627b14 | 2 months ago |
dependabot[bot] | e01a558294 | 2 months ago |
fnuttens | 3915b04bd9 | 2 months ago |
dependabot[bot] | 2d15acdf60 | 2 months ago |
dependabot[bot] | ab61874efb | 2 months ago |
dependabot[bot] | 2e2a1d6f61 | 2 months ago |
dependabot[bot] | 2d589e74f0 | 2 months ago |
Kalpaj Chaudhari | c145999bff | 2 months ago |
Aidan Gauland | 3bd493299f | 2 months ago |
Markus F.X.J. Oberhumer | 0dc67ff885 | 2 months ago |
Matthew Toohey | e3c6c82828 | 2 months ago |
@ -0,0 +1,160 @@
|
||||
use std::{cmp::Reverse, ops::Range};
|
||||
|
||||
use super::{LanguageLayer, LayerId};
|
||||
|
||||
use slotmap::HopSlotMap;
|
||||
use tree_sitter::Node;
|
||||
|
||||
/// The byte range of an injection layer.
|
||||
///
|
||||
/// Injection ranges may overlap, but all overlapping parts are subsets of their parent ranges.
|
||||
/// This allows us to sort the ranges ahead of time in order to efficiently find a range that
|
||||
/// contains a point with maximum depth.
|
||||
#[derive(Debug)]
|
||||
struct InjectionRange {
|
||||
start: usize,
|
||||
end: usize,
|
||||
layer_id: LayerId,
|
||||
depth: u32,
|
||||
}
|
||||
|
||||
pub struct TreeCursor<'a> {
|
||||
layers: &'a HopSlotMap<LayerId, LanguageLayer>,
|
||||
root: LayerId,
|
||||
current: LayerId,
|
||||
injection_ranges: Vec<InjectionRange>,
|
||||
// TODO: Ideally this would be a `tree_sitter::TreeCursor<'a>` but
|
||||
// that returns very surprising results in testing.
|
||||
cursor: Node<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TreeCursor<'a> {
|
||||
pub(super) fn new(layers: &'a HopSlotMap<LayerId, LanguageLayer>, root: LayerId) -> Self {
|
||||
let mut injection_ranges = Vec::new();
|
||||
|
||||
for (layer_id, layer) in layers.iter() {
|
||||
// Skip the root layer
|
||||
if layer.parent.is_none() {
|
||||
continue;
|
||||
}
|
||||
for byte_range in layer.ranges.iter() {
|
||||
let range = InjectionRange {
|
||||
start: byte_range.start_byte,
|
||||
end: byte_range.end_byte,
|
||||
layer_id,
|
||||
depth: layer.depth,
|
||||
};
|
||||
injection_ranges.push(range);
|
||||
}
|
||||
}
|
||||
|
||||
injection_ranges.sort_unstable_by_key(|range| (range.end, Reverse(range.depth)));
|
||||
|
||||
let cursor = layers[root].tree().root_node();
|
||||
|
||||
Self {
|
||||
layers,
|
||||
root,
|
||||
current: root,
|
||||
injection_ranges,
|
||||
cursor,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn node(&self) -> Node<'a> {
|
||||
self.cursor
|
||||
}
|
||||
|
||||
pub fn goto_parent(&mut self) -> bool {
|
||||
if let Some(parent) = self.node().parent() {
|
||||
self.cursor = parent;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we are already on the root layer, we cannot ascend.
|
||||
if self.current == self.root {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ascend to the parent layer.
|
||||
let range = self.node().byte_range();
|
||||
let parent_id = self.layers[self.current]
|
||||
.parent
|
||||
.expect("non-root layers have a parent");
|
||||
self.current = parent_id;
|
||||
let root = self.layers[self.current].tree().root_node();
|
||||
self.cursor = root
|
||||
.descendant_for_byte_range(range.start, range.end)
|
||||
.unwrap_or(root);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Finds the injection layer that has exactly the same range as the given `range`.
|
||||
fn layer_id_of_byte_range(&self, search_range: Range<usize>) -> Option<LayerId> {
|
||||
let start_idx = self
|
||||
.injection_ranges
|
||||
.partition_point(|range| range.end < search_range.end);
|
||||
|
||||
self.injection_ranges[start_idx..]
|
||||
.iter()
|
||||
.take_while(|range| range.end == search_range.end)
|
||||
.find_map(|range| (range.start == search_range.start).then_some(range.layer_id))
|
||||
}
|
||||
|
||||
pub fn goto_first_child(&mut self) -> bool {
|
||||
// Check if the current node's range is an exact injection layer range.
|
||||
if let Some(layer_id) = self
|
||||
.layer_id_of_byte_range(self.node().byte_range())
|
||||
.filter(|&layer_id| layer_id != self.current)
|
||||
{
|
||||
// Switch to the child layer.
|
||||
self.current = layer_id;
|
||||
self.cursor = self.layers[self.current].tree().root_node();
|
||||
true
|
||||
} else if let Some(child) = self.cursor.child(0) {
|
||||
// Otherwise descend in the current tree.
|
||||
self.cursor = child;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn goto_next_sibling(&mut self) -> bool {
|
||||
if let Some(sibling) = self.cursor.next_sibling() {
|
||||
self.cursor = sibling;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn goto_prev_sibling(&mut self) -> bool {
|
||||
if let Some(sibling) = self.cursor.prev_sibling() {
|
||||
self.cursor = sibling;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds the injection layer that contains the given start-end range.
|
||||
fn layer_id_containing_byte_range(&self, start: usize, end: usize) -> LayerId {
|
||||
let start_idx = self
|
||||
.injection_ranges
|
||||
.partition_point(|range| range.end < end);
|
||||
|
||||
self.injection_ranges[start_idx..]
|
||||
.iter()
|
||||
.take_while(|range| range.start < end)
|
||||
.find_map(|range| (range.start <= start).then_some(range.layer_id))
|
||||
.unwrap_or(self.root)
|
||||
}
|
||||
|
||||
pub fn reset_to_byte_range(&mut self, start: usize, end: usize) {
|
||||
self.current = self.layer_id_containing_byte_range(start, end);
|
||||
let root = self.layers[self.current].tree().root_node();
|
||||
self.cursor = root.descendant_for_byte_range(start, end).unwrap_or(root);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,170 @@
|
||||
use std::{
|
||||
path::Path,
|
||||
sync::{atomic, Arc},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use helix_event::AsyncHook;
|
||||
use tokio::time::Instant;
|
||||
|
||||
use crate::{job, ui::overlay::Overlay};
|
||||
|
||||
use super::{CachedPreview, DynQueryCallback, Picker};
|
||||
|
||||
pub(super) struct PreviewHighlightHandler<T: 'static + Send + Sync, D: 'static + Send + Sync> {
|
||||
trigger: Option<Arc<Path>>,
|
||||
phantom_data: std::marker::PhantomData<(T, D)>,
|
||||
}
|
||||
|
||||
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Default for PreviewHighlightHandler<T, D> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
trigger: None,
|
||||
phantom_data: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> AsyncHook
|
||||
for PreviewHighlightHandler<T, D>
|
||||
{
|
||||
type Event = Arc<Path>;
|
||||
|
||||
fn handle_event(
|
||||
&mut self,
|
||||
path: Self::Event,
|
||||
timeout: Option<tokio::time::Instant>,
|
||||
) -> Option<tokio::time::Instant> {
|
||||
if self
|
||||
.trigger
|
||||
.as_ref()
|
||||
.is_some_and(|trigger| trigger == &path)
|
||||
{
|
||||
// If the path hasn't changed, don't reset the debounce
|
||||
timeout
|
||||
} else {
|
||||
self.trigger = Some(path);
|
||||
Some(Instant::now() + Duration::from_millis(150))
|
||||
}
|
||||
}
|
||||
|
||||
fn finish_debounce(&mut self) {
|
||||
let Some(path) = self.trigger.take() else { return };
|
||||
|
||||
job::dispatch_blocking(move |editor, compositor| {
|
||||
let Some(Overlay { content: picker, .. }) = compositor.find::<Overlay<Picker<T, D>>>() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(CachedPreview::Document(ref mut doc)) = picker.preview_cache.get_mut(&path) else {
|
||||
return
|
||||
};
|
||||
|
||||
if doc.language_config().is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(language_config) = doc.detect_language_config(&editor.syn_loader.load()) else { return };
|
||||
doc.language = Some(language_config.clone());
|
||||
let text = doc.text().clone();
|
||||
let loader = editor.syn_loader.clone();
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let Some(syntax) =
|
||||
language_config
|
||||
.highlight_config(&loader.load().scopes())
|
||||
.and_then(|highlight_config| {
|
||||
helix_core::Syntax::new(
|
||||
text.slice(..),
|
||||
highlight_config,
|
||||
loader,
|
||||
)
|
||||
}) else {
|
||||
log::info!("highlighting picker item failed");
|
||||
return;
|
||||
};
|
||||
|
||||
job::dispatch_blocking(move |editor, compositor| {
|
||||
let Some(Overlay { content: picker, .. }) = compositor.find::<Overlay<Picker<T, D>>>() else {
|
||||
log::info!("picker closed before syntax highlighting finished");
|
||||
return;
|
||||
};
|
||||
let Some(CachedPreview::Document(ref mut doc)) = picker.preview_cache.get_mut(&path) else {
|
||||
return
|
||||
};
|
||||
let diagnostics = helix_view::Editor::doc_diagnostics(
|
||||
&editor.language_servers,
|
||||
&editor.diagnostics,
|
||||
doc,
|
||||
);
|
||||
doc.replace_diagnostics(diagnostics, &[], None);
|
||||
doc.syntax = Some(syntax);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct DynamicQueryHandler<T: 'static + Send + Sync, D: 'static + Send + Sync> {
|
||||
callback: Arc<DynQueryCallback<T, D>>,
|
||||
// Duration used as a debounce.
|
||||
// Defaults to 100ms if not provided via `Picker::with_dynamic_query`. Callers may want to set
|
||||
// this higher if the dynamic query is expensive - for example global search.
|
||||
debounce: Duration,
|
||||
last_query: Arc<str>,
|
||||
query: Option<Arc<str>>,
|
||||
}
|
||||
|
||||
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> DynamicQueryHandler<T, D> {
|
||||
pub(super) fn new(callback: DynQueryCallback<T, D>, duration_ms: Option<u64>) -> Self {
|
||||
Self {
|
||||
callback: Arc::new(callback),
|
||||
debounce: Duration::from_millis(duration_ms.unwrap_or(100)),
|
||||
last_query: "".into(),
|
||||
query: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> AsyncHook for DynamicQueryHandler<T, D> {
|
||||
type Event = Arc<str>;
|
||||
|
||||
fn handle_event(&mut self, query: Self::Event, _timeout: Option<Instant>) -> Option<Instant> {
|
||||
if query == self.last_query {
|
||||
// If the search query reverts to the last one we requested, no need to
|
||||
// make a new request.
|
||||
self.query = None;
|
||||
None
|
||||
} else {
|
||||
self.query = Some(query);
|
||||
Some(Instant::now() + self.debounce)
|
||||
}
|
||||
}
|
||||
|
||||
fn finish_debounce(&mut self) {
|
||||
let Some(query) = self.query.take() else { return };
|
||||
self.last_query = query.clone();
|
||||
let callback = self.callback.clone();
|
||||
|
||||
job::dispatch_blocking(move |editor, compositor| {
|
||||
let Some(Overlay { content: picker, .. }) = compositor.find::<Overlay<Picker<T, D>>>() else {
|
||||
return;
|
||||
};
|
||||
// Increment the version number to cancel any ongoing requests.
|
||||
picker.version.fetch_add(1, atomic::Ordering::Relaxed);
|
||||
picker.matcher.restart(false);
|
||||
let injector = picker.injector();
|
||||
let get_options = (callback)(&query, editor, picker.editor_data.clone(), &injector);
|
||||
tokio::spawn(async move {
|
||||
if let Err(err) = get_options.await {
|
||||
log::info!("Dynamic request failed: {err}");
|
||||
}
|
||||
// The picker's shows its running indicator when there are any active
|
||||
// injectors. When we're done injecting new options, drop the injector
|
||||
// and request a redraw to remove the running indicator.
|
||||
drop(injector);
|
||||
helix_event::request_redraw();
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,210 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
pub(super) type PickerQuery = HashMap<Arc<str>, Arc<str>>;
|
||||
|
||||
pub(super) fn parse(column_names: &[Arc<str>], primary_column: usize, input: &str) -> PickerQuery {
|
||||
let mut fields: HashMap<Arc<str>, String> = HashMap::new();
|
||||
let primary_field = &column_names[primary_column];
|
||||
let mut escaped = false;
|
||||
let mut quoted = false;
|
||||
let mut in_field = false;
|
||||
let mut field = None;
|
||||
let mut text = String::new();
|
||||
|
||||
macro_rules! finish_field {
|
||||
() => {
|
||||
let key = field.take().unwrap_or(primary_field);
|
||||
|
||||
if let Some(pattern) = fields.get_mut(key) {
|
||||
pattern.push(' ');
|
||||
pattern.push_str(&text);
|
||||
text.clear();
|
||||
} else {
|
||||
fields.insert(key.clone(), std::mem::take(&mut text));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for ch in input.chars() {
|
||||
match ch {
|
||||
// Backslash escaping
|
||||
'\\' => escaped = !escaped,
|
||||
_ if escaped => {
|
||||
// Allow escaping '%' and '"'
|
||||
if !matches!(ch, '%' | '"') {
|
||||
text.push('\\');
|
||||
}
|
||||
text.push(ch);
|
||||
escaped = false;
|
||||
}
|
||||
// Double quoting
|
||||
'"' => quoted = !quoted,
|
||||
'%' | ':' | ' ' if quoted => text.push(ch),
|
||||
// Space either completes the current word if no field is specified
|
||||
// or field if one is specified.
|
||||
'%' | ' ' if !text.is_empty() => {
|
||||
finish_field!();
|
||||
in_field = ch == '%';
|
||||
}
|
||||
'%' => in_field = true,
|
||||
':' if in_field => {
|
||||
// Go over all columns and their indices, find all that starts with field key,
|
||||
// select a column that fits key the most.
|
||||
field = column_names
|
||||
.iter()
|
||||
.filter(|col| col.starts_with(&text))
|
||||
// select "fittest" column
|
||||
.min_by_key(|col| col.len());
|
||||
text.clear();
|
||||
in_field = false;
|
||||
}
|
||||
_ => text.push(ch),
|
||||
}
|
||||
}
|
||||
|
||||
if !in_field && !text.is_empty() {
|
||||
finish_field!();
|
||||
}
|
||||
|
||||
fields
|
||||
.into_iter()
|
||||
.map(|(field, query)| (field, query.as_str().into()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use helix_core::hashmap;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parse_query_test() {
|
||||
let columns = &[
|
||||
"primary".into(),
|
||||
"field1".into(),
|
||||
"field2".into(),
|
||||
"another".into(),
|
||||
"anode".into(),
|
||||
];
|
||||
let primary_column = 0;
|
||||
|
||||
// Basic field splitting
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "hello world"),
|
||||
hashmap!(
|
||||
"primary".into() => "hello world".into(),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "hello %field1:world %field2:!"),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
"field1".into() => "world".into(),
|
||||
"field2".into() => "!".into(),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "%field1:abc %field2:def xyz"),
|
||||
hashmap!(
|
||||
"primary".into() => "xyz".into(),
|
||||
"field1".into() => "abc".into(),
|
||||
"field2".into() => "def".into(),
|
||||
)
|
||||
);
|
||||
|
||||
// Trailing space is trimmed
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "hello "),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
)
|
||||
);
|
||||
|
||||
// Trailing fields are trimmed.
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "hello %foo"),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
)
|
||||
);
|
||||
|
||||
// Quoting
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, r#"hello %field1:"a b c""#),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
"field1".into() => "a b c".into(),
|
||||
)
|
||||
);
|
||||
|
||||
// Escaping
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, r#"hello\ world"#),
|
||||
hashmap!(
|
||||
"primary".into() => r#"hello\ world"#.into(),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, r#"hello \%field1:world"#),
|
||||
hashmap!(
|
||||
"primary".into() => "hello %field1:world".into(),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, r#"hello %field1:"a\"b""#),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
"field1".into() => r#"a"b"#.into(),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, r#"%field1:hello\ world"#),
|
||||
hashmap!(
|
||||
"field1".into() => r#"hello\ world"#.into(),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, r#"%field1:"hello\ world""#),
|
||||
hashmap!(
|
||||
"field1".into() => r#"hello\ world"#.into(),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, r#"\bfoo\b"#),
|
||||
hashmap!(
|
||||
"primary".into() => r#"\bfoo\b"#.into(),
|
||||
)
|
||||
);
|
||||
|
||||
// Prefix
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "hello %anot:abc"),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
"another".into() => "abc".into(),
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "hello %ano:abc"),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
"anode".into() => "abc".into()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "hello %field1:xyz %fie:abc"),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
"field1".into() => "xyz abc".into()
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
parse(columns, primary_column, "hello %fie:abc"),
|
||||
hashmap!(
|
||||
"primary".into() => "hello".into(),
|
||||
"field1".into() => "abc".into()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
; Support for folding in Ada
|
||||
;; za toggles folding a package, subprogram, if statement or loop
|
||||
|
||||
[
|
||||
(package_declaration)
|
||||
(generic_package_declaration)
|
||||
(package_body)
|
||||
(subprogram_declaration)
|
||||
(subprogram_body)
|
||||
(block_statement)
|
||||
(if_statement)
|
||||
(loop_statement)
|
||||
(gnatprep_declarative_if_statement)
|
||||
(gnatprep_if_statement)
|
||||
] @fold
|
@ -0,0 +1,176 @@
|
||||
;; highlight queries.
|
||||
;; See the syntax at https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries
|
||||
;; See also https://github.com/nvim-treesitter/nvim-treesitter/blob/master/CONTRIBUTING.md#parser-configurations
|
||||
;; for a list of recommended @ tags, though not all of them have matching
|
||||
;; highlights in neovim.
|
||||
|
||||
[
|
||||
"abort"
|
||||
"abs"
|
||||
"abstract"
|
||||
"accept"
|
||||
"access"
|
||||
"all"
|
||||
"array"
|
||||
"at"
|
||||
"begin"
|
||||
"declare"
|
||||
"delay"
|
||||
"delta"
|
||||
"digits"
|
||||
"do"
|
||||
"end"
|
||||
"entry"
|
||||
"exit"
|
||||
"generic"
|
||||
"interface"
|
||||
"is"
|
||||
"limited"
|
||||
"of"
|
||||
"others"
|
||||
"out"
|
||||
"pragma"
|
||||
"private"
|
||||
"range"
|
||||
"synchronized"
|
||||
"tagged"
|
||||
"task"
|
||||
"terminate"
|
||||
"until"
|
||||
"when"
|
||||
] @keyword
|
||||
[
|
||||
"null"
|
||||
] @constant.builtin
|
||||
[
|
||||
"aliased"
|
||||
"constant"
|
||||
"renames"
|
||||
] @keyword.storage
|
||||
[
|
||||
"mod"
|
||||
"new"
|
||||
"protected"
|
||||
"record"
|
||||
"subtype"
|
||||
"type"
|
||||
] @type.builtin
|
||||
[
|
||||
"with"
|
||||
"use"
|
||||
] @keyword.control.import
|
||||
[
|
||||
"body"
|
||||
"function"
|
||||
"overriding"
|
||||
"procedure"
|
||||
"package"
|
||||
"separate"
|
||||
] @keyword.function
|
||||
[
|
||||
"and"
|
||||
"in"
|
||||
"not"
|
||||
"or"
|
||||
"xor"
|
||||
] @operator
|
||||
[
|
||||
"while"
|
||||
"loop"
|
||||
"for"
|
||||
"parallel"
|
||||
"reverse"
|
||||
"some"
|
||||
] @kewyord.control.repeat
|
||||
[
|
||||
"return"
|
||||
] @keyword.control.return
|
||||
[
|
||||
"case"
|
||||
"if"
|
||||
"else"
|
||||
"then"
|
||||
"elsif"
|
||||
"select"
|
||||
] @keyword.control.conditional
|
||||
[
|
||||
"exception"
|
||||
"raise"
|
||||
] @keyword.control.exception
|
||||
(comment) @comment
|
||||
(string_literal) @string
|
||||
(character_literal) @string
|
||||
(numeric_literal) @constant.numeric
|
||||
|
||||
;; Highlight the name of subprograms
|
||||
(procedure_specification name: (_) @function.builtin)
|
||||
(function_specification name: (_) @function.builtin)
|
||||
(package_declaration name: (_) @function.builtin)
|
||||
(package_body name: (_) @function.builtin)
|
||||
(generic_instantiation name: (_) @function.builtin)
|
||||
(entry_declaration . (identifier) @function.builtin)
|
||||
|
||||
;; Some keywords should take different categories depending on the context
|
||||
(use_clause "use" @keyword.control.import "type" @keyword.control.import)
|
||||
(with_clause "private" @keyword.control.import)
|
||||
(with_clause "limited" @keyword.control.import)
|
||||
(use_clause (_) @namespace)
|
||||
(with_clause (_) @namespace)
|
||||
|
||||
(loop_statement "end" @keyword.control.repeat)
|
||||
(if_statement "end" @keyword.control.conditional)
|
||||
(loop_parameter_specification "in" @keyword.control.repeat)
|
||||
(loop_parameter_specification "in" @keyword.control.repeat)
|
||||
(iterator_specification ["in" "of"] @keyword.control.repeat)
|
||||
(range_attribute_designator "range" @keyword.control.repeat)
|
||||
|
||||
(raise_statement "with" @keyword.control.exception)
|
||||
|
||||
(gnatprep_declarative_if_statement) @keyword.directive
|
||||
(gnatprep_if_statement) @keyword.directive
|
||||
(gnatprep_identifier) @keyword.directive
|
||||
|
||||
(subprogram_declaration "is" @keyword.function "abstract" @keyword.function)
|
||||
(aspect_specification "with" @keyword.function)
|
||||
|
||||
(full_type_declaration "is" @type.builtin)
|
||||
(subtype_declaration "is" @type.builtin)
|
||||
(record_definition "end" @type.builtin)
|
||||
(full_type_declaration (_ "access" @type.builtin))
|
||||
(array_type_definition "array" @type.builtin "of" @type.builtin)
|
||||
(access_to_object_definition "access" @type.builtin)
|
||||
(access_to_object_definition "access" @type.builtin
|
||||
[
|
||||
(general_access_modifier "constant" @type.builtin)
|
||||
(general_access_modifier "all" @type.builtin)
|
||||
]
|
||||
)
|
||||
(range_constraint "range" @type.builtin)
|
||||
(signed_integer_type_definition "range" @type.builtin)
|
||||
(index_subtype_definition "range" @type.builtin)
|
||||
(record_type_definition "abstract" @type.builtin)
|
||||
(record_type_definition "tagged" @type.builtin)
|
||||
(record_type_definition "limited" @type.builtin)
|
||||
(record_type_definition (record_definition "null" @type.builtin))
|
||||
(private_type_declaration "is" @type.builtin "private" @type.builtin)
|
||||
(private_type_declaration "tagged" @type.builtin)
|
||||
(private_type_declaration "limited" @type.builtin)
|
||||
(task_type_declaration "task" @type.builtin "is" @type.builtin)
|
||||
|
||||
;; Gray the body of expression functions
|
||||
(expression_function_declaration
|
||||
(function_specification)
|
||||
"is"
|
||||
(_) @attribute
|
||||
)
|
||||
(subprogram_declaration (aspect_specification) @attribute)
|
||||
|
||||
;; Highlight full subprogram specifications
|
||||
; (subprogram_body
|
||||
; [
|
||||
; (procedure_specification)
|
||||
; (function_specification)
|
||||
; ] @function.builtin.spec
|
||||
; )
|
||||
|
||||
|
@ -0,0 +1,32 @@
|
||||
;; Better highlighting by referencing to the definition, for variable references.
|
||||
;; See https://tree-sitter.github.io/tree-sitter/syntax-highlighting#local-variables
|
||||
|
||||
(compilation) @local.scope
|
||||
(package_declaration) @local.scope
|
||||
(package_body) @local.scope
|
||||
(subprogram_declaration) @local.scope
|
||||
(subprogram_body) @local.scope
|
||||
(block_statement) @local.scope
|
||||
|
||||
(with_clause (_) @local.definition)
|
||||
(procedure_specification name: (_) @local.definition)
|
||||
(function_specification name: (_) @local.definition)
|
||||
(package_declaration name: (_) @local.definition)
|
||||
(package_body name: (_) @local.definition)
|
||||
(generic_instantiation . name: (_) @local.definition)
|
||||
(component_declaration . (identifier) @local.definition)
|
||||
(exception_declaration . (identifier) @local.definition)
|
||||
(formal_object_declaration . (identifier) @local.definition)
|
||||
(object_declaration . (identifier) @local.definition)
|
||||
(parameter_specification . (identifier) @local.definition)
|
||||
(full_type_declaration . (identifier) @local.definition)
|
||||
(private_type_declaration . (identifier) @local.definition)
|
||||
(private_extension_declaration . (identifier) @local.definition)
|
||||
(incomplete_type_declaration . (identifier) @local.definition)
|
||||
(protected_type_declaration . (identifier) @local.definition)
|
||||
(formal_complete_type_declaration . (identifier) @local.definition)
|
||||
(formal_incomplete_type_declaration . (identifier) @local.definition)
|
||||
(task_type_declaration . (identifier) @local.definition)
|
||||
(subtype_declaration . (identifier) @local.definition)
|
||||
|
||||
(identifier) @local.reference
|
@ -0,0 +1,21 @@
|
||||
;; Support for high-level text objects selections.
|
||||
;; For instance:
|
||||
;; maf (v)isually select (a) (f)unction or subprogram
|
||||
;; mif (v)isually select (i)nside a (f)unction or subprogram
|
||||
;; mai (v)isually select (a) (i)f statement (or loop)
|
||||
;; mii (v)isually select (i)nside an (i)f statement (or loop)
|
||||
;;
|
||||
;; For navigations using textobjects, check link below:
|
||||
;; https://docs.helix-editor.com/master/usage.html#navigating-using-tree-sitter-textobjects
|
||||
;;
|
||||
;; For Textobject queries explaination, check out link below:
|
||||
;; https://docs.helix-editor.com/master/guides/textobject.html
|
||||
|
||||
(subprogram_body) @function.around
|
||||
(subprogram_body (non_empty_declarative_part) @function.inside)
|
||||
(subprogram_body (handled_sequence_of_statements) @function.inside)
|
||||
(function_specification) @function.around
|
||||
(procedure_specification) @function.around
|
||||
(package_declaration) @function.around
|
||||
(generic_package_declaration) @function.around
|
||||
(package_body) @function.around
|
@ -0,0 +1,8 @@
|
||||
((directive_start) @start
|
||||
(directive_end) @end.after
|
||||
(#set! role block))
|
||||
|
||||
|
||||
((bracket_start) @start
|
||||
(bracket_end) @end
|
||||
(#set! role block))
|
@ -0,0 +1,4 @@
|
||||
(directive) @tag
|
||||
(directive_start) @tag
|
||||
(directive_end) @tag
|
||||
(comment) @comment
|
@ -0,0 +1,9 @@
|
||||
((text) @injection.content
|
||||
(#set! injection.combined)
|
||||
(#set! injection.language php))
|
||||
|
||||
((php_only) @injection.content
|
||||
(#set! injection.language php-only))
|
||||
((parameter) @injection.content
|
||||
(#set! injection.language php-only))
|
||||
|
@ -0,0 +1,94 @@
|
||||
; === Tag Names ===
|
||||
|
||||
; Tags that start with a lower case letter are HTML tags
|
||||
; We'll also use this highlighting for named blocks (which start with `:`)
|
||||
((tag_name) @tag
|
||||
(#match? @tag "^(:)?[a-z]"))
|
||||
; Tags that start with a capital letter are Glimmer components
|
||||
((tag_name) @constructor
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
(attribute_name) @attribute
|
||||
|
||||
(string_literal) @string
|
||||
(number_literal) @constant.numeric.integer
|
||||
(boolean_literal) @constant.builtin.boolean
|
||||
|
||||
(concat_statement) @string
|
||||
|
||||
; === Block Statements ===
|
||||
|
||||
; Highlight the brackets
|
||||
(block_statement_start) @punctuation.delimiter
|
||||
(block_statement_end) @punctuation.delimiter
|
||||
|
||||
; Highlight `if`/`each`/`let`
|
||||
(block_statement_start path: (identifier) @keyword.control.conditional)
|
||||
(block_statement_end path: (identifier) @keyword.control.conditional)
|
||||
((mustache_statement (identifier) @keyword.control.conditional)
|
||||
(#eq? @keyword.control.conditional "else"))
|
||||
|
||||
; == Mustache Statements ===
|
||||
|
||||
; Hightlight the whole statement, to color brackets and separators
|
||||
(mustache_statement) @punctuation.delimiter
|
||||
|
||||
; An identifier in a mustache expression is a variable
|
||||
((mustache_statement [
|
||||
(path_expression (identifier) @variable)
|
||||
(identifier) @variable
|
||||
])
|
||||
(#not-any-of? @variable "yield" "outlet" "this" "else"))
|
||||
; As are arguments in a block statement
|
||||
((block_statement_start argument: [
|
||||
(path_expression (identifier) @variable)
|
||||
(identifier) @variable
|
||||
])
|
||||
(#not-eq? @variable "this"))
|
||||
; As is an identifier in a block param
|
||||
(block_params (identifier) @variable)
|
||||
; As are helper arguments
|
||||
((helper_invocation argument: [
|
||||
(path_expression (identifier) @variable)
|
||||
(identifier) @variable
|
||||
])
|
||||
(#not-eq? @variable "this"))
|
||||
; `this` should be highlighted as a built-in variable
|
||||
((identifier) @variable.builtin
|
||||
(#eq? @variable.builtin "this"))
|
||||
|
||||
; If the identifier is just "yield" or "outlet", it's a keyword
|
||||
((mustache_statement (identifier) @keyword.control.return)
|
||||
(#any-of? @keyword.control.return "yield" "outlet"))
|
||||
|
||||
; Helpers are functions
|
||||
((helper_invocation helper: [
|
||||
(path_expression (identifier) @function)
|
||||
(identifier) @function
|
||||
])
|
||||
(#not-any-of? @function "if" "yield"))
|
||||
|
||||
((helper_invocation helper: (identifier) @keyword.control.conditional)
|
||||
(#any-of? @keyword.control.conditional "if" "yield"))
|
||||
|
||||
(hash_pair key: (identifier) @variable)
|
||||
(hash_pair value: (identifier) @variable)
|
||||
(hash_pair [
|
||||
(path_expression (identifier) @variable)
|
||||
(identifier) @variable
|
||||
])
|
||||
|
||||
(comment_statement) @comment
|
||||
|
||||
(attribute_node "=" @operator)
|
||||
|
||||
(block_params "as" @keyword.control)
|
||||
(block_params "|" @operator)
|
||||
|
||||
[
|
||||
"<"
|
||||
">"
|
||||
"</"
|
||||
"/>"
|
||||
] @punctuation.delimiter
|
||||
|
@ -0,0 +1,6 @@
|
||||
[
|
||||
(argument_list)
|
||||
(closure)
|
||||
(list)
|
||||
(map)
|
||||
] @fold
|
@ -1,96 +1,268 @@
|
||||
(unit
|
||||
(identifier) @variable)
|
||||
[
|
||||
"!instanceof"
|
||||
"assert"
|
||||
"class"
|
||||
"extends"
|
||||
"instanceof"
|
||||
"package"
|
||||
] @keyword
|
||||
|
||||
(string
|
||||
(identifier) @variable)
|
||||
[
|
||||
"!in"
|
||||
"as"
|
||||
"in"
|
||||
] @keyword.operator
|
||||
|
||||
[
|
||||
"case"
|
||||
"default"
|
||||
"else"
|
||||
"if"
|
||||
"switch"
|
||||
] @keyword.control.conditional
|
||||
|
||||
(escape_sequence) @constant.character.escape
|
||||
[
|
||||
"catch"
|
||||
"finally"
|
||||
"try"
|
||||
] @keyword.control.exception
|
||||
|
||||
(block
|
||||
(unit
|
||||
(identifier) @namespace))
|
||||
"def" @keyword.function
|
||||
|
||||
(func
|
||||
(identifier) @function)
|
||||
"import" @keyword.control.import
|
||||
|
||||
(number) @constant.numeric
|
||||
[
|
||||
"for"
|
||||
"while"
|
||||
(break)
|
||||
(continue)
|
||||
] @keyword.control.repeat
|
||||
|
||||
((identifier) @constant.builtin.boolean
|
||||
(#any-of? @constant.builtin.boolean "true" "false"))
|
||||
"return" @keyword.control.return
|
||||
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
|
||||
|
||||
((identifier) @constant.builtin
|
||||
(#eq? @constant.builtin "null"))
|
||||
|
||||
((identifier) @type
|
||||
(#any-of? @type
|
||||
"String"
|
||||
"Map"
|
||||
"Object"
|
||||
"Boolean"
|
||||
"Integer"
|
||||
"List"))
|
||||
|
||||
((identifier) @function.builtin
|
||||
(#any-of? @function.builtin
|
||||
"void"
|
||||
"id"
|
||||
"version"
|
||||
"apply"
|
||||
"implementation"
|
||||
"testImplementation"
|
||||
"androidTestImplementation"
|
||||
"debugImplementation"))
|
||||
|
||||
((identifier) @keyword.storage.modifier
|
||||
(#eq? @keyword.storage.modifier "static"))
|
||||
|
||||
((identifier) @keyword.storage.type
|
||||
(#any-of? @keyword.storage.type "class" "def" "interface"))
|
||||
|
||||
((identifier) @keyword
|
||||
(#any-of? @keyword
|
||||
"assert"
|
||||
"new"
|
||||
"extends"
|
||||
"implements"
|
||||
"instanceof"))
|
||||
|
||||
((identifier) @keyword.control.import
|
||||
(#any-of? @keyword.control.import "import" "package"))
|
||||
|
||||
((identifier) @keyword.storage.modifier
|
||||
(#any-of? @keyword.storage.modifier
|
||||
"abstract"
|
||||
"protected"
|
||||
"private"
|
||||
"public"))
|
||||
|
||||
((identifier) @keyword.control.exception
|
||||
(#any-of? @keyword.control.exception
|
||||
"throw"
|
||||
"finally"
|
||||
"try"
|
||||
"catch"))
|
||||
[
|
||||
"true"
|
||||
"false"
|
||||
] @constant.builtin.boolean
|
||||
|
||||
(null) @constant.builtin
|
||||
|
||||
"this" @variable.builtin
|
||||
|
||||
[
|
||||
"int"
|
||||
"char"
|
||||
"short"
|
||||
"long"
|
||||
"boolean"
|
||||
"float"
|
||||
"double"
|
||||
"void"
|
||||
] @type.builtin
|
||||
|
||||
[
|
||||
"final"
|
||||
"private"
|
||||
"protected"
|
||||
"public"
|
||||
"static"
|
||||
"synchronized"
|
||||
] @keyword.storage.modifier
|
||||
|
||||
(comment) @comment
|
||||
|
||||
(shebang) @keyword.directive
|
||||
|
||||
(string) @string
|
||||
|
||||
(string
|
||||
(escape_sequence) @constant.character.escape)
|
||||
|
||||
(string
|
||||
(interpolation
|
||||
"$" @punctuation.special))
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
(line_comment)
|
||||
(block_comment)
|
||||
] @comment
|
||||
":"
|
||||
","
|
||||
"."
|
||||
] @punctuation.delimiter
|
||||
|
||||
(number_literal) @constant.numeric
|
||||
|
||||
((block_comment) @comment.block.documentation
|
||||
(#match? @comment.block.documentation "^/[*][*][^*](?s:.)*[*]/$"))
|
||||
(identifier) @variable
|
||||
|
||||
((line_comment) @comment.block.documentation
|
||||
(#match? @comment.block.documentation "^///[^/]*.*$"))
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z_]+"))
|
||||
|
||||
[
|
||||
(operators)
|
||||
(leading_key)
|
||||
"%"
|
||||
"*"
|
||||
"/"
|
||||
"+"
|
||||
"-"
|
||||
"<<"
|
||||
">>"
|
||||
">>>"
|
||||
".."
|
||||
"..<"
|
||||
"<..<"
|
||||
"<.."
|
||||
"<"
|
||||
"<="
|
||||
">"
|
||||
">="
|
||||
"=="
|
||||
"!="
|
||||
"<=>"
|
||||
"==="
|
||||
"!=="
|
||||
"=~"
|
||||
"==~"
|
||||
"&"
|
||||
"^"
|
||||
"|"
|
||||
"&&"
|
||||
"||"
|
||||
"?:"
|
||||
"+"
|
||||
"*"
|
||||
".&"
|
||||
".@"
|
||||
"?."
|
||||
"*."
|
||||
"*"
|
||||
"*:"
|
||||
"++"
|
||||
"--"
|
||||
"!"
|
||||
] @operator
|
||||
|
||||
["(" ")" "[" "]" "{" "}"] @punctuation.bracket
|
||||
(string
|
||||
"/" @string)
|
||||
|
||||
(ternary_op
|
||||
([
|
||||
"?"
|
||||
":"
|
||||
]) @keyword.operator)
|
||||
|
||||
(map
|
||||
(map_item
|
||||
key: (identifier) @variable.parameter))
|
||||
|
||||
(parameter
|
||||
type: (identifier) @type
|
||||
name: (identifier) @variable.parameter)
|
||||
|
||||
(generic_param
|
||||
name: (identifier) @variable.parameter)
|
||||
|
||||
(declaration
|
||||
type: (identifier) @type)
|
||||
|
||||
(function_definition
|
||||
type: (identifier) @type)
|
||||
|
||||
(function_declaration
|
||||
type: (identifier) @type)
|
||||
|
||||
(class_definition
|
||||
name: (identifier) @type)
|
||||
|
||||
(class_definition
|
||||
superclass: (identifier) @type)
|
||||
|
||||
(generic_param
|
||||
superclass: (identifier) @type)
|
||||
|
||||
(type_with_generics
|
||||
(identifier) @type)
|
||||
|
||||
(type_with_generics
|
||||
(generics
|
||||
(identifier) @type))
|
||||
|
||||
(generics
|
||||
[
|
||||
"<"
|
||||
">"
|
||||
] @punctuation.bracket)
|
||||
|
||||
(generic_parameters
|
||||
[
|
||||
"<"
|
||||
">"
|
||||
] @punctuation.bracket)
|
||||
|
||||
; TODO: Class literals with PascalCase
|
||||
(declaration
|
||||
"=" @operator)
|
||||
|
||||
(assignment
|
||||
"=" @operator)
|
||||
|
||||
(function_call
|
||||
function: (identifier) @function)
|
||||
|
||||
(function_call
|
||||
function:
|
||||
(dotted_identifier
|
||||
(identifier) @function .))
|
||||
|
||||
(function_call
|
||||
(argument_list
|
||||
(map_item
|
||||
key: (identifier) @variable.parameter)))
|
||||
|
||||
(juxt_function_call
|
||||
function: (identifier) @function)
|
||||
|
||||
(juxt_function_call
|
||||
function:
|
||||
(dotted_identifier
|
||||
(identifier) @function .))
|
||||
|
||||
(juxt_function_call
|
||||
(argument_list
|
||||
(map_item
|
||||
key: (identifier) @variable.parameter)))
|
||||
|
||||
(function_definition
|
||||
function: (identifier) @function)
|
||||
|
||||
(function_declaration
|
||||
function: (identifier) @function)
|
||||
|
||||
(annotation) @function.macro
|
||||
|
||||
(annotation
|
||||
(identifier) @function.macro)
|
||||
|
||||
"@interface" @function.macro
|
||||
|
||||
(groovy_doc) @comment.block.documentation
|
||||
|
||||
(groovy_doc
|
||||
[
|
||||
(groovy_doc_param)
|
||||
(groovy_doc_throws)
|
||||
(groovy_doc_tag)
|
||||
] @string.special)
|
||||
|
||||
(groovy_doc
|
||||
(groovy_doc_param
|
||||
(identifier) @variable.parameter))
|
||||
|
||||
(groovy_doc
|
||||
(groovy_doc_throws
|
||||
(identifier) @type))
|
||||
|
@ -1,2 +1,5 @@
|
||||
([(line_comment) (block_comment)] @injection.content
|
||||
(#set! injection.language "comment"))
|
||||
((comment) @injection.content
|
||||
(#set! injection.language "comment"))
|
||||
|
||||
((groovy_doc) @injection.content
|
||||
(#set! injection.language "comment"))
|
||||
|
@ -0,0 +1,6 @@
|
||||
(function_definition) @local.scope
|
||||
|
||||
(parameter
|
||||
name: (identifier) @local.definition)
|
||||
|
||||
(identifier) @local.reference
|
@ -0,0 +1 @@
|
||||
; inherits: gotmpl
|
@ -0,0 +1 @@
|
||||
; inherits: gotmpl
|
@ -0,0 +1,58 @@
|
||||
(comment) @comment
|
||||
|
||||
[
|
||||
"source"
|
||||
"exec"
|
||||
"exec-once"
|
||||
] @function.builtin
|
||||
|
||||
(keyword
|
||||
(name) @keyword)
|
||||
|
||||
(assignment
|
||||
(name) @variable.other.member)
|
||||
|
||||
(section
|
||||
(name) @namespace)
|
||||
|
||||
(section
|
||||
device: (device_name) @type)
|
||||
|
||||
(variable) @variable
|
||||
|
||||
"$" @punctuation.special
|
||||
|
||||
(boolean) @constant.builtin.boolean
|
||||
|
||||
(string) @string
|
||||
|
||||
(mod) @constant
|
||||
|
||||
[
|
||||
"rgb"
|
||||
"rgba"
|
||||
] @function.builtin
|
||||
|
||||
[
|
||||
(number)
|
||||
(legacy_hex)
|
||||
(angle)
|
||||
(hex)
|
||||
] @constant.numeric
|
||||
|
||||
"deg" @type
|
||||
|
||||
"," @punctuation.delimiter
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
"="
|
||||
"-"
|
||||
"+"
|
||||
] @operator
|
@ -0,0 +1,6 @@
|
||||
(section) @indent
|
||||
|
||||
(section
|
||||
"}" @outdent)
|
||||
|
||||
"}" @extend
|
@ -0,0 +1,3 @@
|
||||
(exec
|
||||
(string) @injection.content
|
||||
(#set! injection.language "bash"))
|
@ -0,0 +1,2 @@
|
||||
; inherits: json
|
||||
(comment) @comment
|
@ -0,0 +1 @@
|
||||
; inherits: json
|
@ -0,0 +1,272 @@
|
||||
; Function calls
|
||||
|
||||
(appexpr
|
||||
function: (appexpr
|
||||
(atom
|
||||
(qidentifier
|
||||
[
|
||||
(qvarid) @function
|
||||
(qidop) @function
|
||||
(identifier
|
||||
[(varid) (idop)] @function)
|
||||
])))
|
||||
["(" (block) (fnexpr)])
|
||||
|
||||
(ntlappexpr
|
||||
function: (ntlappexpr
|
||||
(atom
|
||||
(qidentifier
|
||||
[
|
||||
(qvarid) @function
|
||||
(qidop) @function
|
||||
(identifier
|
||||
[(varid) (idop)] @function)
|
||||
])))
|
||||
["(" (block) (fnexpr)])
|
||||
|
||||
(appexpr
|
||||
field: (atom
|
||||
(qidentifier
|
||||
[
|
||||
(qvarid) @function
|
||||
(qidop) @function
|
||||
(identifier
|
||||
[(varid) (idop)] @function)
|
||||
])))
|
||||
|
||||
(appexpr
|
||||
(appexpr
|
||||
field: (atom
|
||||
(qidentifier
|
||||
[
|
||||
(qvarid) @variable
|
||||
(qidop) @variable
|
||||
(identifier
|
||||
[(varid) (idop)] @variable)
|
||||
])))
|
||||
"[")
|
||||
|
||||
(ntlappexpr
|
||||
field: (atom
|
||||
(qidentifier
|
||||
[
|
||||
(qvarid) @function
|
||||
(qidop) @function
|
||||
(identifier
|
||||
[(varid) (idop)] @function)
|
||||
])))
|
||||
|
||||
(ntlappexpr
|
||||
(ntlappexpr
|
||||
field: (atom
|
||||
(qidentifier
|
||||
[
|
||||
(qvarid) @variable
|
||||
(qidop) @variable
|
||||
(identifier
|
||||
[(varid) (idop)] @variable)
|
||||
])))
|
||||
"[")
|
||||
|
||||
[
|
||||
"initially"
|
||||
"finally"
|
||||
] @function.special
|
||||
|
||||
; Function definitions
|
||||
|
||||
(puredecl
|
||||
(funid
|
||||
(identifier
|
||||
[(varid) (idop)] @function)))
|
||||
|
||||
(fundecl
|
||||
(funid
|
||||
(identifier
|
||||
[(varid) (idop)] @function)))
|
||||
|
||||
(operation
|
||||
(identifier
|
||||
[(varid) (idop)] @function))
|
||||
|
||||
; Identifiers
|
||||
|
||||
(puredecl
|
||||
(binder
|
||||
(identifier
|
||||
[(varid) (idop)] @constant)))
|
||||
|
||||
; TODO: Highlight vars differently once helix has an appropriate highlight query
|
||||
; for that purpose.
|
||||
|
||||
(pparameter
|
||||
(pattern
|
||||
(identifier
|
||||
(varid) @variable.parameter)))
|
||||
|
||||
(paramid
|
||||
(identifier
|
||||
(varid) @variable.parameter))
|
||||
|
||||
(typedecl
|
||||
"effect"
|
||||
(varid) @type)
|
||||
|
||||
(typeid
|
||||
(varid) @type)
|
||||
|
||||
(tbinder
|
||||
(varid) @type)
|
||||
|
||||
(typecon
|
||||
(varid) @type)
|
||||
|
||||
(qvarid
|
||||
(qid) @namespace)
|
||||
|
||||
(modulepath (varid) @namespace)
|
||||
|
||||
(qconid) @namespace
|
||||
|
||||
(qidop) @namespace
|
||||
|
||||
(varid) @variable
|
||||
|
||||
(conid) @constructor
|
||||
|
||||
; Operators
|
||||
|
||||
[
|
||||
"!"
|
||||
"~"
|
||||
"="
|
||||
":="
|
||||
(idop)
|
||||
(op)
|
||||
(qidop)
|
||||
] @operator
|
||||
|
||||
; Keywords
|
||||
|
||||
[
|
||||
"as"
|
||||
"behind"
|
||||
(externtarget)
|
||||
"forall"
|
||||
"handle"
|
||||
"handler"
|
||||
"in"
|
||||
"infix"
|
||||
"infixl"
|
||||
"infixr"
|
||||
"inject"
|
||||
"mask"
|
||||
"other"
|
||||
"pub"
|
||||
"public"
|
||||
"some"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"con"
|
||||
"control"
|
||||
"ctl"
|
||||
"fn"
|
||||
"fun"
|
||||
"rawctl"
|
||||
"rcontrol"
|
||||
] @keyword.function
|
||||
|
||||
"with" @keyword.control
|
||||
|
||||
[
|
||||
"elif"
|
||||
"else"
|
||||
"if"
|
||||
"match"
|
||||
"then"
|
||||
] @keyword.control.conditional
|
||||
|
||||
[
|
||||
"import"
|
||||
"include"
|
||||
"module"
|
||||
] @keyword.control.import
|
||||
|
||||
[
|
||||
"alias"
|
||||
"effect"
|
||||
"struct"
|
||||
"type"
|
||||
"val"
|
||||
"var"
|
||||
] @keyword.storage.type
|
||||
|
||||
[
|
||||
"abstract"
|
||||
"co"
|
||||
"extend"
|
||||
"extern"
|
||||
"fbip"
|
||||
"final"
|
||||
"fip"
|
||||
"inline"
|
||||
"linear"
|
||||
"named"
|
||||
"noinline"
|
||||
"open"
|
||||
"override"
|
||||
"raw"
|
||||
"rec"
|
||||
"ref"
|
||||
"reference"
|
||||
"scoped"
|
||||
"tail"
|
||||
"value"
|
||||
] @keyword.storage.modifier
|
||||
|
||||
"return" @keyword.control.return
|
||||
|
||||
; Delimiters
|
||||
|
||||
(matchrule "|" @punctuation.delimiter)
|
||||
|
||||
[
|
||||
","
|
||||
"->"
|
||||
"."
|
||||
":"
|
||||
"::"
|
||||
"<-"
|
||||
";"
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"<"
|
||||
">"
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
; Literals
|
||||
|
||||
[
|
||||
(string)
|
||||
(char)
|
||||
] @string
|
||||
|
||||
(escape) @constant.character.escape
|
||||
|
||||
(float) @constant.numeric.float
|
||||
(int) @constant.numeric.integer
|
||||
|
||||
; Comment
|
||||
|
||||
[
|
||||
(linecomment)
|
||||
(blockcomment)
|
||||
] @comment
|
@ -0,0 +1,39 @@
|
||||
[
|
||||
(appexpr ["[" "("]) ; Applications.
|
||||
(ntlappexpr ["[" "("])
|
||||
(atom ["[" "("]) ; Lists and tuples.
|
||||
(program (moduledecl "{")) ; Braced module declarations.
|
||||
(funbody)
|
||||
(block)
|
||||
(handlerexpr)
|
||||
(opclausex)
|
||||
] @indent
|
||||
|
||||
[
|
||||
(typedecl
|
||||
[(typeid) (opdecls)]) ; Avoid matching single-operation effects.
|
||||
(externdecl)
|
||||
(matchexpr)
|
||||
(matchrule)
|
||||
|
||||
; For ifexprs, branches (once they exist) will contain blocks if they're
|
||||
; indented so we just need to make sure the initial indent happens when we're
|
||||
; creating them.
|
||||
"then"
|
||||
"else"
|
||||
] @indent @extend
|
||||
|
||||
(matchrule "->" @indent @extend)
|
||||
|
||||
; Handling for error recovery.
|
||||
(ERROR "fun") @indent @extend
|
||||
(ERROR "match") @indent @extend
|
||||
(ERROR "->" @indent.always @extend)
|
||||
|
||||
; Don't outdent on function parameter declarations.
|
||||
(atom ")" @outdent @extend.prevent-once)
|
||||
|
||||
[
|
||||
"]"
|
||||
"}"
|
||||
] @outdent @extend.prevent-once
|
@ -0,0 +1,2 @@
|
||||
([(linecomment) (blockcomment)] @injection.content
|
||||
(#set! injection.language "comment"))
|
@ -0,0 +1,30 @@
|
||||
(modulebody) @local.scope
|
||||
|
||||
(block) @local.scope
|
||||
|
||||
(pattern
|
||||
(identifier
|
||||
(varid) @local.definition))
|
||||
|
||||
(decl
|
||||
(apattern
|
||||
(pattern
|
||||
(identifier
|
||||
(varid) @local.definition))))
|
||||
|
||||
(puredecl
|
||||
(funid
|
||||
(identifier
|
||||
(varid) @local.definition)))
|
||||
|
||||
(puredecl
|
||||
(binder
|
||||
(identifier
|
||||
(varid) @local.definition)))
|
||||
|
||||
(decl
|
||||
(binder
|
||||
(identifier
|
||||
(varid) @local.definition)))
|
||||
|
||||
(identifier (varid) @local.reference)
|
@ -0,0 +1,173 @@
|
||||
; Identifiers
|
||||
|
||||
(section
|
||||
.
|
||||
(NAME) @namespace)
|
||||
|
||||
(NAME) @variable
|
||||
|
||||
; Operators
|
||||
|
||||
[
|
||||
"="
|
||||
"+="
|
||||
"-="
|
||||
"*="
|
||||
"/="
|
||||
"<<="
|
||||
">>="
|
||||
"&="
|
||||
"|="
|
||||
"^="
|
||||
"*"
|
||||
"/"
|
||||
"%"
|
||||
"+"
|
||||
"-"
|
||||
"<<"
|
||||
">>"
|
||||
"=="
|
||||
"!="
|
||||
"<="
|
||||
">="
|
||||
"<"
|
||||
">"
|
||||
"&"
|
||||
"^"
|
||||
"|"
|
||||
"&&"
|
||||
"||"
|
||||
"?"
|
||||
] @operator
|
||||
|
||||
; Keywords
|
||||
|
||||
[
|
||||
"ABSOLUTE"
|
||||
"ADDR"
|
||||
"ALIGNOF"
|
||||
"ASSERT"
|
||||
"BYTE"
|
||||
"CONSTANT"
|
||||
"DATA_SEGMENT_ALIGN"
|
||||
"DATA_SEGMENT_END"
|
||||
"DATA_SEGMENT_RELRO_END"
|
||||
"DEFINED"
|
||||
"LOADADDR"
|
||||
"LOG2CEIL"
|
||||
"LONG"
|
||||
"MAX"
|
||||
"MIN"
|
||||
"NEXT"
|
||||
"QUAD"
|
||||
"SHORT"
|
||||
"SIZEOF"
|
||||
"SQUAD"
|
||||
"FILL"
|
||||
"SEGMENT_START"
|
||||
] @function.builtin
|
||||
|
||||
[
|
||||
"CONSTRUCTORS"
|
||||
"CREATE_OBJECT_SYMBOLS"
|
||||
"LINKER_VERSION"
|
||||
"SIZEOF_HEADERS"
|
||||
] @constant.builtin
|
||||
|
||||
[
|
||||
"AFTER"
|
||||
"ALIGN"
|
||||
"ALIGN_WITH_INPUT"
|
||||
"ASCIZ"
|
||||
"AS_NEEDED"
|
||||
"AT"
|
||||
"BEFORE"
|
||||
"BIND"
|
||||
"BLOCK"
|
||||
"COPY"
|
||||
"DSECT"
|
||||
"ENTRY"
|
||||
"EXCLUDE_FILE"
|
||||
"EXTERN"
|
||||
"extern"
|
||||
"FLOAT"
|
||||
"FORCE_COMMON_ALLOCATION"
|
||||
"FORCE_GROUP_ALLOCATION"
|
||||
"global"
|
||||
"GROUP"
|
||||
"HIDDEN"
|
||||
"HLL"
|
||||
"INCLUDE"
|
||||
"INFO"
|
||||
"INHIBIT_COMMON_ALLOCATION"
|
||||
"INPUT"
|
||||
"INPUT_SECTION_FLAGS"
|
||||
"KEEP"
|
||||
"l"
|
||||
"LD_FEATURE"
|
||||
"len"
|
||||
"LENGTH"
|
||||
"local"
|
||||
"MAP"
|
||||
"MEMORY"
|
||||
"NOCROSSREFS"
|
||||
"NOCROSSREFS_TO"
|
||||
"NOFLOAT"
|
||||
"NOLOAD"
|
||||
"o"
|
||||
"ONLY_IF_RO"
|
||||
"ONLY_IF_RW"
|
||||
"org"
|
||||
"ORIGIN"
|
||||
"OUTPUT"
|
||||
"OUTPUT_ARCH"
|
||||
"OUTPUT_FORMAT"
|
||||
"OVERLAY"
|
||||
"PHDRS"
|
||||
"PROVIDE"
|
||||
"PROVIDE_HIDDEN"
|
||||
"READONLY"
|
||||
"REGION_ALIAS"
|
||||
"REVERSE"
|
||||
"SEARCH_DIR"
|
||||
"SECTIONS"
|
||||
"SORT"
|
||||
"SORT_BY_ALIGNMENT"
|
||||
"SORT_BY_INIT_PRIORITY"
|
||||
"SORT_BY_NAME"
|
||||
"SORT_NONE"
|
||||
"SPECIAL"
|
||||
"STARTUP"
|
||||
"SUBALIGN"
|
||||
"SYSLIB"
|
||||
"TARGET"
|
||||
"TYPE"
|
||||
"VERSION"
|
||||
] @keyword
|
||||
|
||||
; Delimiters
|
||||
|
||||
[
|
||||
","
|
||||
";"
|
||||
"&"
|
||||
":"
|
||||
">"
|
||||
] @punctuation.delimiter
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
; Literals
|
||||
|
||||
(INT) @constant.numeric.integer
|
||||
|
||||
; Comment
|
||||
|
||||
(comment) @comment
|
@ -0,0 +1,12 @@
|
||||
[
|
||||
(sections)
|
||||
(memory)
|
||||
(section)
|
||||
(phdrs)
|
||||
(overlay_section)
|
||||
(version)
|
||||
(vers_node)
|
||||
(vers_defns)
|
||||
] @indent
|
||||
|
||||
"}" @outdent @extend.prevent-once
|
@ -0,0 +1,2 @@
|
||||
((comment) @injection.content
|
||||
(#set! injection.language "comment"))
|
@ -0,0 +1,123 @@
|
||||
(php_tag) @tag
|
||||
"?>" @tag
|
||||
|
||||
; Types
|
||||
|
||||
(primitive_type) @type.builtin
|
||||
(cast_type) @type.builtin
|
||||
(named_type (name) @type) @type
|
||||
(named_type (qualified_name) @type) @type
|
||||
|
||||
; Functions
|
||||
|
||||
(array_creation_expression "array" @function.builtin)
|
||||
(list_literal "list" @function.builtin)
|
||||
|
||||
(method_declaration
|
||||
name: (name) @function.method)
|
||||
|
||||
(function_call_expression
|
||||
function: [(qualified_name (name)) (name)] @function)
|
||||
|
||||
(scoped_call_expression
|
||||
name: (name) @function)
|
||||
|
||||
(member_call_expression
|
||||
name: (name) @function.method)
|
||||
|
||||
(function_definition
|
||||
name: (name) @function)
|
||||
|
||||
; Member
|
||||
|
||||
(property_element
|
||||
(variable_name) @variable.other.member)
|
||||
|
||||
(member_access_expression
|
||||
name: (variable_name (name)) @variable.other.member)
|
||||
(member_access_expression
|
||||
name: (name) @variable.other.member)
|
||||
|
||||
; Variables
|
||||
|
||||
(relative_scope) @variable.builtin
|
||||
|
||||
((name) @constant
|
||||
(#match? @constant "^_?[A-Z][A-Z\\d_]+$"))
|
||||
((name) @constant.builtin
|
||||
(#match? @constant.builtin "^__[A-Z][A-Z\d_]+__$"))
|
||||
|
||||
((name) @constructor
|
||||
(#match? @constructor "^[A-Z]"))
|
||||
|
||||
((name) @variable.builtin
|
||||
(#eq? @variable.builtin "this"))
|
||||
|
||||
(variable_name) @variable
|
||||
|
||||
; Basic tokens
|
||||
[
|
||||
(string)
|
||||
(string_value)
|
||||
(encapsed_string)
|
||||
(heredoc)
|
||||
(heredoc_body)
|
||||
(nowdoc_body)
|
||||
] @string
|
||||
(boolean) @constant.builtin.boolean
|
||||
(null) @constant.builtin
|
||||
(integer) @constant.builtin.integer
|
||||
(float) @constant.builtin.float
|
||||
(comment) @comment
|
||||
|
||||
"$" @operator
|
||||
|
||||
; Keywords
|
||||
|
||||
"abstract" @keyword
|
||||
"as" @keyword
|
||||
"break" @keyword
|
||||
"case" @keyword
|
||||
"catch" @keyword
|
||||
"class" @keyword
|
||||
"const" @keyword
|
||||
"continue" @keyword
|
||||
"declare" @keyword
|
||||
"default" @keyword
|
||||
"do" @keyword
|
||||
"echo" @keyword
|
||||
"else" @keyword
|
||||
"elseif" @keyword
|
||||
"enddeclare" @keyword
|
||||
"endforeach" @keyword
|
||||
"endif" @keyword
|
||||
"endswitch" @keyword
|
||||
"endwhile" @keyword
|
||||
"extends" @keyword
|
||||
"final" @keyword
|
||||
"finally" @keyword
|
||||
"for" @keyword
|
||||
"foreach" @keyword
|
||||
"function" @keyword
|
||||
"global" @keyword
|
||||
"if" @keyword
|
||||
"implements" @keyword
|
||||
"include_once" @keyword
|
||||
"include" @keyword
|
||||
"insteadof" @keyword
|
||||
"interface" @keyword
|
||||
"namespace" @keyword
|
||||
"new" @keyword
|
||||
"private" @keyword
|
||||
"protected" @keyword
|
||||
"public" @keyword
|
||||
"require_once" @keyword
|
||||
"require" @keyword
|
||||
"return" @keyword
|
||||
"static" @keyword
|
||||
"switch" @keyword
|
||||
"throw" @keyword
|
||||
"trait" @keyword
|
||||
"try" @keyword
|
||||
"use" @keyword
|
||||
"while" @keyword
|
@ -0,0 +1,10 @@
|
||||
((comment) @injection.content
|
||||
(#set! injection.language "comment"))
|
||||
|
||||
(heredoc
|
||||
(heredoc_body) @injection.content
|
||||
(heredoc_end) @injection.language)
|
||||
|
||||
(nowdoc
|
||||
(nowdoc_body) @injection.content
|
||||
(heredoc_end) @injection.language)
|
@ -0,0 +1,40 @@
|
||||
(namespace_definition
|
||||
name: (namespace_name) @name) @module
|
||||
|
||||
(interface_declaration
|
||||
name: (name) @name) @definition.interface
|
||||
|
||||
(trait_declaration
|
||||
name: (name) @name) @definition.interface
|
||||
|
||||
(class_declaration
|
||||
name: (name) @name) @definition.class
|
||||
|
||||
(class_interface_clause [(name) (qualified_name)] @name) @impl
|
||||
|
||||
(property_declaration
|
||||
(property_element (variable_name (name) @name))) @definition.field
|
||||
|
||||
(function_definition
|
||||
name: (name) @name) @definition.function
|
||||
|
||||
(method_declaration
|
||||
name: (name) @name) @definition.function
|
||||
|
||||
(object_creation_expression
|
||||
[
|
||||
(qualified_name (name) @name)
|
||||
(variable_name (name) @name)
|
||||
]) @reference.class
|
||||
|
||||
(function_call_expression
|
||||
function: [
|
||||
(qualified_name (name) @name)
|
||||
(variable_name (name)) @name
|
||||
]) @reference.call
|
||||
|
||||
(scoped_call_expression
|
||||
name: (name) @name) @reference.call
|
||||
|
||||
(member_call_expression
|
||||
name: (name) @name) @reference.call
|
@ -0,0 +1 @@
|
||||
; inherits: bash
|
@ -0,0 +1 @@
|
||||
; inherits: bash
|
@ -0,0 +1 @@
|
||||
; inherits: bash
|
@ -0,0 +1 @@
|
||||
; inherits: bash
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
(function_call)
|
||||
(code_block)
|
||||
(function_block)
|
||||
(control_structure)
|
||||
] @fold
|
||||
|
@ -0,0 +1,76 @@
|
||||
(line_comment) @comment.line
|
||||
(block_comment) @comment.block
|
||||
|
||||
(argument name: (identifier) @variable.parameter)
|
||||
|
||||
(local_var name: (identifier) @variable)
|
||||
(environment_var name:(identifier) @variable.builtin)
|
||||
(builtin_var) @constant.builtin
|
||||
|
||||
(function_definition name: (variable) @function)
|
||||
|
||||
(named_argument name: (identifier) @variable.other.member)
|
||||
|
||||
(method_call name: (method_name) @function.method)
|
||||
|
||||
(class) @keyword.storage.type
|
||||
|
||||
(number) @constant.numeric
|
||||
(float) @constant.numeric.float
|
||||
|
||||
(string) @string
|
||||
(symbol) @string.special.symbol
|
||||
|
||||
[
|
||||
"&&"
|
||||
"||"
|
||||
"&"
|
||||
"|"
|
||||
"^"
|
||||
"=="
|
||||
"!="
|
||||
"<"
|
||||
"<="
|
||||
">"
|
||||
">="
|
||||
"<<"
|
||||
">>"
|
||||
"+"
|
||||
"-"
|
||||
"*"
|
||||
"/"
|
||||
"%"
|
||||
"="
|
||||
"|@|"
|
||||
"@@"
|
||||
"@|@"
|
||||
] @operator
|
||||
|
||||
[
|
||||
"arg"
|
||||
"classvar"
|
||||
"const"
|
||||
"var"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
"|"
|
||||
] @punctuation.bracket
|
||||
|
||||
[
|
||||
";"
|
||||
"."
|
||||
","
|
||||
] @punctuation.delimiter
|
||||
|
||||
(control_structure) @keyword.control.conditional
|
||||
|
||||
(escape_sequence) @string.special
|
||||
|
||||
(duplicated_statement) @keyword.control.repeat
|
@ -0,0 +1,27 @@
|
||||
(method_declaration
|
||||
(block) @function.inside) @function.around
|
||||
|
||||
(creation_method_declaration
|
||||
(block) @function.inside) @function.around
|
||||
|
||||
(method_declaration
|
||||
((parameter) @parameter.inside . ","? @parameter.around) @parameter.around)
|
||||
|
||||
[
|
||||
(class_declaration)
|
||||
(struct_declaration)
|
||||
(interface_declaration)
|
||||
] @class.around
|
||||
|
||||
(type_arguments
|
||||
((_) @parameter.inside . ","? @parameter.around) @parameter.around)
|
||||
|
||||
(creation_method_declaration
|
||||
((parameter) @parameter.inside . ","? @parameter.around) @parameter.around)
|
||||
|
||||
(method_call_expression
|
||||
((argument) @parameter.inside . ","? @parameter.around) @parameter.around)
|
||||
|
||||
(comment) @comment.inside
|
||||
|
||||
(comment)+ @comment.around
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue