mirror of https://github.com/helix-editor/helix
Compare commits
7 Commits
0ff2804740
...
b48ec9339f
Author | SHA1 | Date |
---|---|---|
|
b48ec9339f | |
|
362e97e927 | |
|
ba54b6afe4 | |
|
837627dd8a | |
|
1246549afd | |
|
ada8004ea5 | |
|
e1247d6739 |
|
@ -2810,9 +2810,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree-house"
|
name = "tree-house"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "679e3296e503901cd9f6e116be5a43a9270222215bf6c78b4b1f4af5c3dcc62d"
|
checksum = "d00ea55222392f171ae004dd13b62edd09d995633abf0c13406a8df3547fb999"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"hashbrown 0.15.4",
|
"hashbrown 0.15.4",
|
||||||
|
|
|
@ -37,7 +37,7 @@ package.helix-tui.opt-level = 2
|
||||||
package.helix-term.opt-level = 2
|
package.helix-term.opt-level = 2
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
tree-house = { version = "0.2.0", default-features = false }
|
tree-house = { version = "0.3.0", default-features = false }
|
||||||
nucleo = "0.5.0"
|
nucleo = "0.5.0"
|
||||||
slotmap = "1.0.7"
|
slotmap = "1.0.7"
|
||||||
thiserror = "2.0"
|
thiserror = "2.0"
|
||||||
|
|
|
@ -16,6 +16,7 @@ function or block of code.
|
||||||
| `w` | Word |
|
| `w` | Word |
|
||||||
| `W` | WORD |
|
| `W` | WORD |
|
||||||
| `p` | Paragraph |
|
| `p` | Paragraph |
|
||||||
|
| `i` | Indentation level |
|
||||||
| `(`, `[`, `'`, etc. | Specified surround pairs |
|
| `(`, `[`, `'`, etc. | Specified surround pairs |
|
||||||
| `m` | The closest surround pair |
|
| `m` | The closest surround pair |
|
||||||
| `f` | Function |
|
| `f` | Function |
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
use std::cmp;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use ropey::RopeSlice;
|
use ropey::RopeSlice;
|
||||||
|
|
||||||
use crate::chars::{categorize_char, char_is_whitespace, CharCategory};
|
use crate::chars::{categorize_char, char_is_whitespace, CharCategory};
|
||||||
use crate::graphemes::{next_grapheme_boundary, prev_grapheme_boundary};
|
use crate::graphemes::{next_grapheme_boundary, prev_grapheme_boundary};
|
||||||
use crate::line_ending::rope_is_line_ending;
|
use crate::indent::indent_level_for_line;
|
||||||
|
use crate::line_ending::{get_line_ending, rope_is_line_ending};
|
||||||
use crate::movement::Direction;
|
use crate::movement::Direction;
|
||||||
use crate::syntax;
|
use crate::syntax;
|
||||||
use crate::Range;
|
use crate::Range;
|
||||||
|
@ -197,6 +199,92 @@ pub fn textobject_paragraph(
|
||||||
Range::new(anchor, head)
|
Range::new(anchor, head)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn textobject_indentation_level(
|
||||||
|
slice: RopeSlice,
|
||||||
|
range: Range,
|
||||||
|
textobject: TextObject,
|
||||||
|
count: usize,
|
||||||
|
indent_width: usize,
|
||||||
|
tab_width: usize,
|
||||||
|
) -> Range {
|
||||||
|
let (mut line_start, mut line_end) = range.line_range(slice);
|
||||||
|
let mut min_indent: Option<usize> = None;
|
||||||
|
|
||||||
|
// Find the innermost indent represented by the current selection range.
|
||||||
|
// Range could be only on one line, so we need an inclusive range in the
|
||||||
|
// loop definition.
|
||||||
|
for i in line_start..=line_end {
|
||||||
|
let line = slice.line(i);
|
||||||
|
|
||||||
|
// Including empty lines leads to pathological behaviour, where having
|
||||||
|
// an empty line in a multi-line selection causes the entire buffer to
|
||||||
|
// be selected, which is not intuitively what we want.
|
||||||
|
if !rope_is_line_ending(line) {
|
||||||
|
let indent_level = indent_level_for_line(line, tab_width, indent_width);
|
||||||
|
min_indent = if let Some(prev_min_indent) = min_indent {
|
||||||
|
Some(cmp::min(indent_level, prev_min_indent))
|
||||||
|
} else {
|
||||||
|
Some(indent_level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It can happen that the selection consists of an empty line, so min_indent
|
||||||
|
// will be untouched, in which case we can skip the rest of the function
|
||||||
|
// and no-op.
|
||||||
|
if min_indent.is_none() {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
let min_indent = min_indent.unwrap() + 1 - count;
|
||||||
|
|
||||||
|
// Traverse backwards until there are no more lines indented the same or
|
||||||
|
// greater, and extend the start of the range to it.
|
||||||
|
if line_start > 0 {
|
||||||
|
for line in slice.lines_at(line_start).reversed() {
|
||||||
|
let indent_level = indent_level_for_line(line, tab_width, indent_width);
|
||||||
|
let empty_line = rope_is_line_ending(line);
|
||||||
|
if (min_indent > 0 && indent_level >= min_indent)
|
||||||
|
|| (min_indent == 0 && !empty_line)
|
||||||
|
|| (textobject == TextObject::Around && empty_line)
|
||||||
|
{
|
||||||
|
line_start -= 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse forwards until there are no more lines indented the same or
|
||||||
|
// greater, and extend the end of the range to it.
|
||||||
|
if line_end < slice.len_lines() {
|
||||||
|
for line in slice.lines_at(line_end + 1) {
|
||||||
|
let indent_level = indent_level_for_line(line, tab_width, indent_width);
|
||||||
|
let empty_line = rope_is_line_ending(line);
|
||||||
|
if (min_indent > 0 && indent_level >= min_indent)
|
||||||
|
|| (min_indent == 0 && !empty_line)
|
||||||
|
|| (textobject == TextObject::Around && empty_line)
|
||||||
|
{
|
||||||
|
line_end += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_char_start = slice.line_to_char(line_start);
|
||||||
|
let new_line_end_slice = slice.line(line_end);
|
||||||
|
let mut new_char_end = new_line_end_slice.chars().count() + slice.line_to_char(line_end);
|
||||||
|
|
||||||
|
// Unless the end of the new range is to the end of the buffer, we want to
|
||||||
|
// trim the final line ending from the selection.
|
||||||
|
if let Some(line_ending) = get_line_ending(&new_line_end_slice) {
|
||||||
|
new_char_end = new_char_end.saturating_sub(line_ending.len_chars());
|
||||||
|
}
|
||||||
|
|
||||||
|
Range::new(new_char_start, new_char_end).with_direction(range.direction())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn textobject_pair_surround(
|
pub fn textobject_pair_surround(
|
||||||
syntax: Option<&Syntax>,
|
syntax: Option<&Syntax>,
|
||||||
slice: RopeSlice,
|
slice: RopeSlice,
|
||||||
|
@ -497,6 +585,160 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_textobject_indentation_level_inside() {
|
||||||
|
let tests = [
|
||||||
|
("#[|]#", "#[|]#", 1),
|
||||||
|
(
|
||||||
|
"unindented\n\t#[i|]#ndented once",
|
||||||
|
"unindented\n#[\tindented once|]#",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\t#[i|]#ndented once\n",
|
||||||
|
"unindented\n#[\tindented once|]#\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\t#[|in]#dented once\n",
|
||||||
|
"unindented\n#[|\tindented once]#\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"#[u|]#nindented\n\tindented once\n",
|
||||||
|
"#[unindented\n\tindented once|]#\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\n\t#[i|]#ndented once and separated\n",
|
||||||
|
"unindented\n\n#[\tindented once and separated|]#\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"#[u|]#nindented\n\n\tindented once and separated\n",
|
||||||
|
"#[unindented|]#\n\n\tindented once and separated\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\nunindented again\n\tindented #[once|]#\nunindented one more time",
|
||||||
|
"unindented\n\nunindented again\n#[\tindented once|]#\nunindented one more time",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\nunindented #[again\n\tindented|]# once\nunindented one more time\n",
|
||||||
|
"unindented\n\n#[unindented again\n\tindented once\nunindented one more time|]#\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\tindented #[once\n\n\tindented once|]# and separated\n\tindented once again\nunindented one more time\n",
|
||||||
|
"unindented\n#[\tindented once\n\n\tindented once and separated\n\tindented once again|]#\nunindented one more time\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\tindented once\n#[\n|]#\tindented once and separated\n\tindented once again\nunindented one more time\n",
|
||||||
|
"unindented\n\tindented once\n#[\n|]#\tindented once and separated\n\tindented once again\nunindented one more time\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\tindented once\n\t\tindented #[twice|]#\n\tindented once again\nunindented\n",
|
||||||
|
"unindented\n#[\tindented once\n\t\tindented twice\n\tindented once again|]#\nunindented\n",
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\tindented once\n\t\tindented #[twice|]#\n\tindented once again\nunindented\n",
|
||||||
|
"#[unindented\n\tindented once\n\t\tindented twice\n\tindented once again\nunindented|]#\n",
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (before, expected, count) in tests {
|
||||||
|
let (s, selection) = crate::test::print(before);
|
||||||
|
let text = Rope::from(s.as_str());
|
||||||
|
let selection = selection.transform(|r| {
|
||||||
|
textobject_indentation_level(text.slice(..), r, TextObject::Inside, count, 4, 4)
|
||||||
|
});
|
||||||
|
let actual = crate::test::plain(s.as_ref(), &selection);
|
||||||
|
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_textobject_indentation_level_around() {
|
||||||
|
let tests = [
|
||||||
|
("#[|]#", "#[|]#", 1),
|
||||||
|
(
|
||||||
|
"unindented\n\t#[i|]#ndented once",
|
||||||
|
"unindented\n#[\tindented once|]#",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\t#[i|]#ndented once\n",
|
||||||
|
"unindented\n#[\tindented once\n|]#",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\t#[|in]#dented once\n",
|
||||||
|
"unindented\n#[|\tindented once\n]#",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"#[u|]#nindented\n\tindented once\n",
|
||||||
|
"#[unindented\n\tindented once\n|]#",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\n\t#[i|]#ndented once and separated\n",
|
||||||
|
"unindented\n#[\n\tindented once and separated\n|]#",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"#[u|]#nindented\n\n\tindented once and separated\n",
|
||||||
|
"#[unindented\n\n\tindented once and separated\n|]#",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\nunindented again\n\tindented #[once|]#\nunindented one more time",
|
||||||
|
"unindented\n\nunindented again\n#[\tindented once|]#\nunindented one more time",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\nunindented #[again\n\tindented|]# once\nunindented one more time\n",
|
||||||
|
"#[unindented\n\nunindented again\n\tindented once\nunindented one more time\n|]#",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\tindented #[once\n\n\tindented once|]# and separated\n\tindented once again\nunindented one more time\n",
|
||||||
|
"unindented\n#[\tindented once\n\n\tindented once and separated\n\tindented once again|]#\nunindented one more time\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\tindented once\n#[\n|]#\tindented once and separated\n\tindented once again\nunindented one more time\n",
|
||||||
|
"unindented\n\tindented once\n#[\n|]#\tindented once and separated\n\tindented once again\nunindented one more time\n",
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\tindented once\n\t\tindented #[twice|]#\n\tindented once again\nunindented\n",
|
||||||
|
"unindented\n#[\tindented once\n\t\tindented twice\n\tindented once again|]#\nunindented\n",
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unindented\n\tindented once\n\t\tindented #[twice|]#\n\tindented once again\nunindented\n",
|
||||||
|
"#[unindented\n\tindented once\n\t\tindented twice\n\tindented once again\nunindented\n|]#",
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (before, expected, count) in tests {
|
||||||
|
let (s, selection) = crate::test::print(before);
|
||||||
|
let text = Rope::from(s.as_str());
|
||||||
|
let selection = selection.transform(|r| {
|
||||||
|
textobject_indentation_level(text.slice(..), r, TextObject::Around, count, 4, 4)
|
||||||
|
});
|
||||||
|
let actual = crate::test::plain(s.as_ref(), &selection);
|
||||||
|
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_textobject_surround() {
|
fn test_textobject_surround() {
|
||||||
// (text, [(cursor position, textobject, final range, surround char, count), ...])
|
// (text, [(cursor position, textobject, final range, surround char, count), ...])
|
||||||
|
|
|
@ -5948,6 +5948,14 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
|
||||||
'T' => textobject_treesitter("test", range),
|
'T' => textobject_treesitter("test", range),
|
||||||
'e' => textobject_treesitter("entry", range),
|
'e' => textobject_treesitter("entry", range),
|
||||||
'p' => textobject::textobject_paragraph(text, range, objtype, count),
|
'p' => textobject::textobject_paragraph(text, range, objtype, count),
|
||||||
|
'i' => textobject::textobject_indentation_level(
|
||||||
|
text,
|
||||||
|
range,
|
||||||
|
objtype,
|
||||||
|
count,
|
||||||
|
doc.indent_width(),
|
||||||
|
doc.tab_width(),
|
||||||
|
),
|
||||||
'm' => textobject::textobject_pair_surround_closest(
|
'm' => textobject::textobject_pair_surround_closest(
|
||||||
doc.syntax(),
|
doc.syntax(),
|
||||||
text,
|
text,
|
||||||
|
@ -5983,6 +5991,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
|
||||||
("w", "Word"),
|
("w", "Word"),
|
||||||
("W", "WORD"),
|
("W", "WORD"),
|
||||||
("p", "Paragraph"),
|
("p", "Paragraph"),
|
||||||
|
("i", "Indentation level"),
|
||||||
("t", "Type definition (tree-sitter)"),
|
("t", "Type definition (tree-sitter)"),
|
||||||
("f", "Function (tree-sitter)"),
|
("f", "Function (tree-sitter)"),
|
||||||
("a", "Argument/parameter (tree-sitter)"),
|
("a", "Argument/parameter (tree-sitter)"),
|
||||||
|
|
|
@ -81,6 +81,10 @@ fn request_document_colors(editor: &mut Editor, doc_id: DocumentId) {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
if futures.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut all_colors = Vec::new();
|
let mut all_colors = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -1437,7 +1437,11 @@ impl Editor {
|
||||||
log::error!("failed to apply workspace edit: {err:?}")
|
log::error!("failed to apply workspace edit: {err:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs::rename(old_path, &new_path)?;
|
|
||||||
|
if old_path.exists() {
|
||||||
|
fs::rename(old_path, &new_path)?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(doc) = self.document_by_path(old_path) {
|
if let Some(doc) = self.document_by_path(old_path) {
|
||||||
self.set_doc_path(doc.id(), &new_path);
|
self.set_doc_path(doc.id(), &new_path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -937,7 +937,7 @@ indent = { tab-width = 2, unit = " " }
|
||||||
|
|
||||||
[[grammar]]
|
[[grammar]]
|
||||||
name = "html"
|
name = "html"
|
||||||
source = { git = "https://github.com/tree-sitter/tree-sitter-html", rev = "29f53d8f4f2335e61bf6418ab8958dac3282077a" }
|
source = { git = "https://github.com/tree-sitter/tree-sitter-html", rev = "cbb91a0ff3621245e890d1c50cc811bffb77a26b" }
|
||||||
|
|
||||||
[[language]]
|
[[language]]
|
||||||
name = "python"
|
name = "python"
|
||||||
|
|
|
@ -1,3 +1,48 @@
|
||||||
; inherits: html
|
(tag_name) @tag
|
||||||
|
(erroneous_end_tag_name) @error
|
||||||
|
(doctype) @constant
|
||||||
|
(attribute_name) @attribute
|
||||||
|
(comment) @comment
|
||||||
|
|
||||||
|
((attribute
|
||||||
|
(attribute_name) @attribute
|
||||||
|
(quoted_attribute_value (attribute_value) @markup.link.url))
|
||||||
|
(#any-of? @attribute "href" "src"))
|
||||||
|
|
||||||
|
((element
|
||||||
|
(start_tag
|
||||||
|
(tag_name) @tag)
|
||||||
|
(text) @markup.link.label)
|
||||||
|
(#eq? @tag "a"))
|
||||||
|
|
||||||
|
(attribute [(attribute_value) (quoted_attribute_value)] @string)
|
||||||
|
|
||||||
|
((element
|
||||||
|
(start_tag
|
||||||
|
(tag_name) @tag)
|
||||||
|
(text) @markup.bold)
|
||||||
|
(#any-of? @tag "strong" "b"))
|
||||||
|
|
||||||
|
((element
|
||||||
|
(start_tag
|
||||||
|
(tag_name) @tag)
|
||||||
|
(text) @markup.italic)
|
||||||
|
(#any-of? @tag "em" "i"))
|
||||||
|
|
||||||
|
((element
|
||||||
|
(start_tag
|
||||||
|
(tag_name) @tag)
|
||||||
|
(text) @markup.strikethrough)
|
||||||
|
(#any-of? @tag "s" "del"))
|
||||||
|
|
||||||
|
[
|
||||||
|
"<"
|
||||||
|
">"
|
||||||
|
"</"
|
||||||
|
"/>"
|
||||||
|
"<!"
|
||||||
|
] @punctuation.bracket
|
||||||
|
|
||||||
|
"=" @punctuation.delimiter
|
||||||
|
|
||||||
["---"] @punctuation.delimiter
|
["---"] @punctuation.delimiter
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
(namespace_definition name: (namespace_identifier) @namespace)
|
(namespace_definition name: (namespace_identifier) @namespace)
|
||||||
(namespace_identifier) @namespace
|
(namespace_identifier) @namespace
|
||||||
|
|
||||||
(qualified_identifier name: (identifier) @type.enum.variant)
|
|
||||||
|
|
||||||
(auto) @type
|
(auto) @type
|
||||||
"decltype" @type
|
"decltype" @type
|
||||||
|
|
||||||
|
@ -21,12 +19,29 @@
|
||||||
(reference_declarator ["&" "&&"] @type.builtin)
|
(reference_declarator ["&" "&&"] @type.builtin)
|
||||||
(abstract_reference_declarator ["&" "&&"] @type.builtin)
|
(abstract_reference_declarator ["&" "&&"] @type.builtin)
|
||||||
|
|
||||||
|
; -------
|
||||||
; Functions
|
; Functions
|
||||||
|
; -------
|
||||||
|
; Support up to 4 levels of nesting of qualifiers
|
||||||
|
; i.e. a::b::c::d::func();
|
||||||
(call_expression
|
(call_expression
|
||||||
function: (qualified_identifier
|
function: (qualified_identifier
|
||||||
name: (identifier) @function))
|
name: (identifier) @function))
|
||||||
|
(call_expression
|
||||||
|
function: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (identifier) @function)))
|
||||||
|
(call_expression
|
||||||
|
function: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (identifier) @function))))
|
||||||
|
(call_expression
|
||||||
|
function: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (identifier) @function)))))
|
||||||
|
|
||||||
(template_function
|
(template_function
|
||||||
name: (identifier) @function)
|
name: (identifier) @function)
|
||||||
|
@ -34,26 +49,42 @@
|
||||||
(template_method
|
(template_method
|
||||||
name: (field_identifier) @function)
|
name: (field_identifier) @function)
|
||||||
|
|
||||||
; Support up to 3 levels of nesting of qualifiers
|
; Support up to 4 levels of nesting of qualifiers
|
||||||
; i.e. a::b::c::func();
|
; i.e. a::b::c::d::func();
|
||||||
(function_declarator
|
(function_declarator
|
||||||
declarator: (qualified_identifier
|
declarator: (qualified_identifier
|
||||||
name: (identifier) @function))
|
name: (identifier) @function))
|
||||||
|
|
||||||
(function_declarator
|
(function_declarator
|
||||||
declarator: (qualified_identifier
|
declarator: (qualified_identifier
|
||||||
name: (qualified_identifier
|
name: (qualified_identifier
|
||||||
name: (identifier) @function)))
|
name: (identifier) @function)))
|
||||||
|
|
||||||
(function_declarator
|
(function_declarator
|
||||||
declarator: (qualified_identifier
|
declarator: (qualified_identifier
|
||||||
name: (qualified_identifier
|
name: (qualified_identifier
|
||||||
name: (qualified_identifier
|
name: (qualified_identifier
|
||||||
name: (identifier) @function))))
|
name: (identifier) @function))))
|
||||||
|
(function_declarator
|
||||||
|
declarator: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (qualified_identifier
|
||||||
|
name: (identifier) @function)))))
|
||||||
|
|
||||||
(function_declarator
|
(function_declarator
|
||||||
declarator: (field_identifier) @function)
|
declarator: (field_identifier) @function)
|
||||||
|
|
||||||
|
; Constructors
|
||||||
|
|
||||||
|
(class_specifier
|
||||||
|
(type_identifier) @type
|
||||||
|
(field_declaration_list
|
||||||
|
(function_definition
|
||||||
|
(function_declarator
|
||||||
|
(identifier) @constructor)))
|
||||||
|
(#eq? @type @constructor))
|
||||||
|
(destructor_name "~" @constructor
|
||||||
|
(identifier) @constructor)
|
||||||
|
|
||||||
; Parameters
|
; Parameters
|
||||||
|
|
||||||
(parameter_declaration
|
(parameter_declaration
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(erroneous_end_tag_name) @error
|
(erroneous_end_tag_name) @error
|
||||||
(doctype) @constant
|
(doctype) @constant
|
||||||
(attribute_name) @attribute
|
(attribute_name) @attribute
|
||||||
|
(entity) @string.special.symbol
|
||||||
(comment) @comment
|
(comment) @comment
|
||||||
|
|
||||||
((attribute
|
((attribute
|
||||||
|
|
Loading…
Reference in New Issue