Unnamed repository; edit this file 'description' to name the repository.
Add textobjects for XML, HTML and JSX (#11158)
Björn Ganslandt 7 months ago
parent 9512cb9 · commit 2ee11a0
-rw-r--r--book/src/generated/lang-support.md4
-rw-r--r--book/src/generated/static-cmd.md2
-rw-r--r--book/src/guides/textobject.md2
-rw-r--r--book/src/keymap.md50
-rw-r--r--book/src/textobjects.md1
-rw-r--r--helix-term/src/commands.rs12
-rw-r--r--helix-term/src/keymap/default.rs2
-rw-r--r--runtime/queries/_jsx/textobjects.scm7
-rw-r--r--runtime/queries/html/textobjects.scm9
-rw-r--r--runtime/queries/xml/textobjects.scm5
10 files changed, 68 insertions, 26 deletions
diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md
index b16e9862..5573cc7e 100644
--- a/book/src/generated/lang-support.md
+++ b/book/src/generated/lang-support.md
@@ -104,7 +104,7 @@
| hocon | ✓ | ✓ | ✓ | |
| hoon | ✓ | | | |
| hosts | ✓ | | | |
-| html | ✓ | | | `vscode-html-language-server`, `superhtml` |
+| html | ✓ | ✓ | | `vscode-html-language-server`, `superhtml` |
| htmldjango | ✓ | | | `djlsp`, `vscode-html-language-server`, `superhtml` |
| hurl | ✓ | ✓ | ✓ | |
| hyprlang | ✓ | | ✓ | `hyprls` |
@@ -274,7 +274,7 @@
| wit | ✓ | | ✓ | |
| wren | ✓ | ✓ | ✓ | |
| xit | ✓ | | | |
-| xml | ✓ | | ✓ | |
+| xml | ✓ | ✓ | ✓ | |
| xtc | ✓ | | | |
| yaml | ✓ | ✓ | ✓ | `yaml-language-server`, `ansible-language-server` |
| yara | ✓ | | | `yls` |
diff --git a/book/src/generated/static-cmd.md b/book/src/generated/static-cmd.md
index 7ecb7f4e..0363820e 100644
--- a/book/src/generated/static-cmd.md
+++ b/book/src/generated/static-cmd.md
@@ -267,6 +267,8 @@
| `goto_prev_comment` | Goto previous comment | normal: `` [c ``, select: `` [c `` |
| `goto_next_test` | Goto next test | normal: `` ]T ``, select: `` ]T `` |
| `goto_prev_test` | Goto previous test | normal: `` [T ``, select: `` [T `` |
+| `goto_next_xml_element` | Goto next (X)HTML element | normal: `` ]x ``, select: `` ]x `` |
+| `goto_prev_xml_element` | Goto previous (X)HTML element | normal: `` [x ``, select: `` [x `` |
| `goto_next_entry` | Goto next pairing | normal: `` ]e ``, select: `` ]e `` |
| `goto_prev_entry` | Goto previous pairing | normal: `` [e ``, select: `` [e `` |
| `goto_next_paragraph` | Goto next paragraph | normal: `` ]p ``, select: `` ]p `` |
diff --git a/book/src/guides/textobject.md b/book/src/guides/textobject.md
index b0efb03b..093129d4 100644
--- a/book/src/guides/textobject.md
+++ b/book/src/guides/textobject.md
@@ -28,6 +28,8 @@ The following [captures][tree-sitter-captures] are recognized:
| `comment.around` |
| `entry.inside` |
| `entry.around` |
+| `xml-element.inside` |
+| `xml-element.around` |
[Example query files][textobject-examples] can be found in the helix GitHub repository.
diff --git a/book/src/keymap.md b/book/src/keymap.md
index 10257378..c375c7b3 100644
--- a/book/src/keymap.md
+++ b/book/src/keymap.md
@@ -348,30 +348,32 @@ Displays the signature of the selected completion item. Remapping currently not
These mappings are in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaired).
-| Key | Description | Command |
-| ----- | ----------- | ------- |
-| `]d` | Go to next diagnostic (**LSP**) | `goto_next_diag` |
-| `[d` | Go to previous diagnostic (**LSP**) | `goto_prev_diag` |
-| `]D` | Go to last diagnostic in document (**LSP**) | `goto_last_diag` |
-| `[D` | Go to first diagnostic in document (**LSP**) | `goto_first_diag` |
-| `]f` | Go to next function (**TS**) | `goto_next_function` |
-| `[f` | Go to previous function (**TS**) | `goto_prev_function` |
-| `]t` | Go to next type definition (**TS**) | `goto_next_class` |
-| `[t` | Go to previous type definition (**TS**) | `goto_prev_class` |
-| `]a` | Go to next argument/parameter (**TS**) | `goto_next_parameter` |
-| `[a` | Go to previous argument/parameter (**TS**) | `goto_prev_parameter` |
-| `]c` | Go to next comment (**TS**) | `goto_next_comment` |
-| `[c` | Go to previous comment (**TS**) | `goto_prev_comment` |
-| `]T` | Go to next test (**TS**) | `goto_next_test` |
-| `[T` | Go to previous test (**TS**) | `goto_prev_test` |
-| `]p` | Go to next paragraph | `goto_next_paragraph` |
-| `[p` | Go to previous paragraph | `goto_prev_paragraph` |
-| `]g` | Go to next change | `goto_next_change` |
-| `[g` | Go to previous change | `goto_prev_change` |
-| `]G` | Go to last change | `goto_last_change` |
-| `[G` | Go to first change | `goto_first_change` |
-| `]Space` | Add newline below | `add_newline_below` |
-| `[Space` | Add newline above | `add_newline_above` |
+| Key | Description | Command |
+| ----- | ----------- | ------- |
+| `]d` | Go to next diagnostic (**LSP**) | `goto_next_diag` |
+| `[d` | Go to previous diagnostic (**LSP**) | `goto_prev_diag` |
+| `]D` | Go to last diagnostic in document (**LSP**) | `goto_last_diag` |
+| `[D` | Go to first diagnostic in document (**LSP**) | `goto_first_diag` |
+| `]f` | Go to next function (**TS**) | `goto_next_function` |
+| `[f` | Go to previous function (**TS**) | `goto_prev_function` |
+| `]t` | Go to next type definition (**TS**) | `goto_next_class` |
+| `[t` | Go to previous type definition (**TS**) | `goto_prev_class` |
+| `]a` | Go to next argument/parameter (**TS**) | `goto_next_parameter` |
+| `[a` | Go to previous argument/parameter (**TS**) | `goto_prev_parameter` |
+| `]c` | Go to next comment (**TS**) | `goto_next_comment` |
+| `[c` | Go to previous comment (**TS**) | `goto_prev_comment` |
+| `]T` | Go to next test (**TS**) | `goto_next_test` |
+| `[T` | Go to previous test (**TS**) | `goto_prev_test` |
+| `]p` | Go to next paragraph | `goto_next_paragraph` |
+| `[p` | Go to previous paragraph | `goto_prev_paragraph` |
+| `]g` | Go to next change | `goto_next_change` |
+| `[g` | Go to previous change | `goto_prev_change` |
+| `]G` | Go to last change | `goto_last_change` |
+| `[G` | Go to first change | `goto_first_change` |
+| `[x` | Go to next (X)HTML element | `goto_next_xml_element` |
+| `]x` | Go to previous (X)HTML element | `goto_prev_xml_element` |
+| `]Space` | Add newline below | `add_newline_below` |
+| `[Space` | Add newline above | `add_newline_above` |
## Insert mode
diff --git a/book/src/textobjects.md b/book/src/textobjects.md
index 541acab9..c950167a 100644
--- a/book/src/textobjects.md
+++ b/book/src/textobjects.md
@@ -24,6 +24,7 @@ function or block of code.
| `c` | Comment |
| `T` | Test |
| `g` | Change |
+| `x` | (X)HTML element |
> 💡 `f`, `t`, etc. need a tree-sitter grammar active for the current
document and a special tree-sitter query file to work properly. [Only
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 304dcd88..ee25e8e3 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -565,6 +565,8 @@ impl MappableCommand {
goto_prev_comment, "Goto previous comment",
goto_next_test, "Goto next test",
goto_prev_test, "Goto previous test",
+ goto_next_xml_element, "Goto next (X)HTML element",
+ goto_prev_xml_element, "Goto previous (X)HTML element",
goto_next_entry, "Goto next pairing",
goto_prev_entry, "Goto previous pairing",
goto_next_paragraph, "Goto next paragraph",
@@ -5882,6 +5884,14 @@ fn goto_prev_test(cx: &mut Context) {
goto_ts_object_impl(cx, "test", Direction::Backward)
}
+fn goto_next_xml_element(cx: &mut Context) {
+ goto_ts_object_impl(cx, "xml-element", Direction::Forward)
+}
+
+fn goto_prev_xml_element(cx: &mut Context) {
+ goto_ts_object_impl(cx, "xml-element", Direction::Backward)
+}
+
fn goto_next_entry(cx: &mut Context) {
goto_ts_object_impl(cx, "entry", Direction::Forward)
}
@@ -5949,6 +5959,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
'c' => textobject_treesitter("comment", range),
'T' => textobject_treesitter("test", range),
'e' => textobject_treesitter("entry", range),
+ 'x' => textobject_treesitter("xml-element", range),
'p' => textobject::textobject_paragraph(text, range, objtype, count),
'm' => textobject::textobject_pair_surround_closest(
doc.syntax(),
@@ -5993,6 +6004,7 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
("e", "Data structure entry (tree-sitter)"),
("m", "Closest surrounding pair (tree-sitter)"),
("g", "Change"),
+ ("x", "X(HTML) element (tree-sitter)"),
(" ", "... or any character acting as a pair"),
];
diff --git a/helix-term/src/keymap/default.rs b/helix-term/src/keymap/default.rs
index 82baf336..de005abe 100644
--- a/helix-term/src/keymap/default.rs
+++ b/helix-term/src/keymap/default.rs
@@ -120,6 +120,7 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
"e" => goto_prev_entry,
"T" => goto_prev_test,
"p" => goto_prev_paragraph,
+ "x" => goto_prev_xml_element,
"space" => add_newline_above,
},
"]" => { "Right bracket"
@@ -134,6 +135,7 @@ pub fn default() -> HashMap<Mode, KeyTrie> {
"e" => goto_next_entry,
"T" => goto_next_test,
"p" => goto_next_paragraph,
+ "x" => goto_next_xml_element,
"space" => add_newline_below,
},
diff --git a/runtime/queries/_jsx/textobjects.scm b/runtime/queries/_jsx/textobjects.scm
new file mode 100644
index 00000000..c2b13f0a
--- /dev/null
+++ b/runtime/queries/_jsx/textobjects.scm
@@ -0,0 +1,7 @@
+; See runtime/queries/ecma/README.md for more info.
+
+(jsx_self_closing_element) @xml-element.around @xml-element.inside
+
+(jsx_element (jsx_opening_element) (_)* @xml-element.inside (jsx_closing_element))
+
+(jsx_element) @xml-element.around
diff --git a/runtime/queries/html/textobjects.scm b/runtime/queries/html/textobjects.scm
new file mode 100644
index 00000000..8dd8f2fe
--- /dev/null
+++ b/runtime/queries/html/textobjects.scm
@@ -0,0 +1,9 @@
+(script_element (start_tag) (_) @xml-element.inside (end_tag)) @xml-element.around
+
+(style_element (start_tag) (_) @xml-element.inside (end_tag)) @xml-element.around
+
+(element (start_tag) (_)* @xml-element.inside (end_tag))
+
+(element) @xml-element.around
+
+(comment) @comment.around
diff --git a/runtime/queries/xml/textobjects.scm b/runtime/queries/xml/textobjects.scm
new file mode 100644
index 00000000..e23873e4
--- /dev/null
+++ b/runtime/queries/xml/textobjects.scm
@@ -0,0 +1,5 @@
+(element (start_tag) (_)* @xml-element.inside (end_tag))
+
+(element) @xml-element.around
+
+(comment) @comment.around