helix icon indicating copy to clipboard operation
helix copied to clipboard

Add textobjects for XML, HTML and jsx

Open Ansimorph opened this issue 1 year ago • 5 comments
trafficstars

Building on the work done by @ff2400t this adds text-objects to select xml-like elements in html, jsx and xml files.

Fixes: #6682

The behaviour is consistent with other text-objects in helix. It is however not consistent with vim's tag textobject:

<p>
  <span> inner_span </span>
</p>

If the cursor is on <span> vit would select inner_span in vim. In Helix mix will select <span> inner_span </span> If the cursor is actually inside the tag, both solutions work the same.

I think despite the difference to vim this textobject is very useful and would love to see it in my daily work.

Ansimorph avatar Jul 13 '24 16:07 Ansimorph

Awesome work, thanks!

Can anything be done about HTML tags that don't have closing tags ("void elements" like <img> and <input>) causing the following issue? Try playing about with:

<div class="flex flex-col items-center">
  <input
    placeholder="Enter your email"
    type="email"
    name="EMAIL"
    class="required email mb-4 p-2 border border-gray-300 rounded"
    id="mce-EMAIL"
    required=""
    value=""
  />
  <input
    type="submit"
    name="subscribe"
    id="mc-embedded-subscribe"
    class="button bg-blue-500 hover:bg-blue-600 text-white rounded py-2 px-4"
    value="Subscribe"
  />
</div>

mix anywhere inside the <div>, including inside an <input> selects inside the div, max inside an <input> selects an <input> rather than around the <div> which seems strange compared to mix.

David-Else avatar Aug 27 '24 20:08 David-Else

Thank you so much for doing this, it will make a big difference for me.

Is this intended behavior? I found it surprising that from the same starting point, max would produce a smaller selection than mix. It's related to the example you give but with two children instead of one, which shows mix and max do not have the same behavior when the cursor is inside the tag.

Starting position

mix

The target of "inner" is the <div>.

max

The target of "around" is the <Button>.

david-crespo avatar Aug 28 '24 02:08 david-crespo

@David-Else thanks for the feedback and @david-crespo thanks for your well illustrated point!

The current implementation is consistent with other textobjects. See for example the function textobject with nested functions below, where maf also creates a smaller selection than mif.

I completely agree that the behaviour of the vim tag-textobject is more intuitive, but changing this is not possible in the textobject definition itself AFAIK. We would have to change the way helix handles the textobjects and this is a change that requires more rust knowledge than I currently have and would change this PR from a pretty minimal enhancement into something that requires a lot more discussion with the core team. This is why I tried to keep the PR simple, because a more wide reaching PR for the same problem went nowhere in the past.

Starting Position

Bildschirmfoto 2024-08-28 um 16 01 07

mif

Bildschirmfoto 2024-08-28 um 16 02 13

maf

Bildschirmfoto 2024-08-28 um 16 02 51

Ansimorph avatar Aug 28 '24 14:08 Ansimorph

Wise! Cool with me, it’s a great start.

david-crespo avatar Aug 28 '24 14:08 david-crespo

@Ansimorph OK, if what I described are not bugs then this is fantastic anyway, and I hope it gets merged ASAP.

David-Else avatar Aug 28 '24 17:08 David-Else

What happened to this PR? When will it be merged?

pakhrom avatar Jul 12 '25 08:07 pakhrom

What happened to this PR? When will it be merged?

I don't know – @the-mikedavis is this something you would consider after the release?

Ansimorph avatar Jul 12 '25 09:07 Ansimorph

Yeah this has just been in my review queue for a long time. At a glance it looks good. I'll give it a proper look after the upcoming release

the-mikedavis avatar Jul 12 '25 13:07 the-mikedavis