tags:

views:

135

answers:

2

I have the following in an XML file:

<TypeDef name="a">
  <ArrayType high="14" low="0">
    <UndefType type="node">
    </UndefType>
  </ArrayType>
</TypeDef>

And I want to copy this entry. Normally I'd go to the first line, enter Line-Visual mode using V, go down to the last line, yank and paste.

How can I copy the entire entry without looking for the end of the entry myself?

+6  A: 

The solution I learned today (thanks to CMS who answered this question) is to use VIM's text object motions.

Put the cursor in the entry to copy, and type the following in command mode: yat:

  • y yanks according to the following movement.
  • at selects the current tag.

Note that if the cursor is inside the "ArrayType" tag, then that's what will be yanked.
Also note that this won't yank the entire lines. Only from the opening brace of the opening tag to the closing brace of the closing tag. This may cause alignment issues if you're not careful.

One way to get around this is by pasting with :put instead of just p, like this: yat:put.
Note that this won't preserve indentation, because the XML entry wasn't yanked as a whole line.

Another way to do it is: vatVy:

  • v enters Visual Mode.
  • at is as above.
  • V switches to Line Visual mode and selects the entire line.
  • y yanks the selection.
Nathan Fellman
Impressive method! I was trying to define a new vim function, but text object seems to be powerful enough.
Jérôme
you can go straight into linewise visual with V... eg Vaty would suffice for the second example
michael
yes, but then doing the 'at' takes me out of Line Visual, and I have to press V again anyway. I figure I'm better off skipping the first shift and just pressing v
Nathan Fellman
'at' takes you out of line visual, as 'a tag' does not necessarily have to span the whole line, so only the matching part is marked visually. Instead of switching back to line visual mode you could also paste linewise with :put
Thanks. I didn't know about :put. I'll add it to the answer.
Nathan Fellman
+2  A: 

In addition to Nathan's answer you might want to check out matchit.vim ... If you have a newer install you probably have it

http://www.vim.org/scripts/script.php?script_id=39

matchit extends vim's % (find matching bracket) to cover xml/html tags and more. So for your solution the action would be from the beginning tag

V%y

matchit is of course very useful for general navigating purposes.

michael