Vim provides a builtin textobject t that captures a matched pair of HTML tags — so e.g. if you start with this <i>that█ <b>those</b></i>, then typing dat in normal mode leaves you with this█. Very cool.

How might I create similar textobjects for other markup languages with this sort of begin/end syntax? For instance, if I wanted one that captures the a matched pair of Liquid tags, or a matched LaTeX \begin{foo} and \end{foo} tag pair, where might I start?

I'm willing to do some digging and to write my own code, but seeing an example where someone has accomplished something similar would be very helpful.

  • Heh, apparently all I do on this site is ask questions about custom textobjects Aug 27, 2021 at 16:59
  • General thoughts for possible answers: there are plugins that support making custom text objects; there are various web tutorials; probably things I’m missing. (A link does not an answer make—we expect the most relevant information to be contained directly in the answer itself. Include the link as a source and companion, and please attribute material.)
    – D. Ben Knoble
    Aug 27, 2021 at 17:09
  • 1
    So I've done a bit of digging on the plugin front. github.com/kana/vim-textobj-user seems to be the standard recommendation. It does allow for textobjects that are defined by "find beginning" and "find end" functions. But it doesn't allow for the one to pass information to the other — to the "find beginning" function can't say to the other one "The opening tag I found was a foo tag, please look for a /foo in particular." I think that prevents it from handling this. If there's a plugin with that feature, I haven't seen it recommended, though I'll certainly keep googling. Aug 27, 2021 at 17:18
  • Glad youre finding things! My comment was mostly aimed at potential answer writers
    – D. Ben Knoble
    Aug 27, 2021 at 17:22
  • Oh! Sorry! I thought you might be checking if I'd done my homework. :) I appreciate the thoughts in any case. Aug 27, 2021 at 17:25

2 Answers 2


I know a reference to a plugin is not an ideal answer, but this is a tricky thing to accomplish generally and I maintain a plugin which seems to do exactly what you ask for so I'll mention it.

The plugin match-up supports text objects a% and i% corresponding to pairs which were originally defined by matchit's % (matchit is a built-in plugin in vim which supports only visual-mode a% and is a bit inconsistent).

You can customize it with b:match_words like so:

au FileType file let b:match_words = '\begin{\(\w\+\)}:\end{\1},(:)'

It supports LaTeX out of the box (more extensively than VimTeX), and you probably won't need to define your own pairs for many languages.


one of the cool plugins to trait tag is vim surround
let's try out visual mode the that█ then:S<i>.

this <i> that█   <i>

to remove this tag use d s t

OR do manually

  • if you want to delete a tag
    • vat select select by tag
    • at extend select to another outside tag
    • ... you can extend tag also if you want
    • d delete selected text
  • if you want to remove the tag only
    • yit yank text
    • vat select select by tag
    • at extend select to another outside tag
    • ... you can extend tag also if you want
    • p past yanked text
  • Looks like you missed the part of the question where OP want’s text objects for things similar to XML tags (such as LaTeX environment delimiters).
    – D. Ben Knoble
    Aug 28, 2021 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.