'wrapping sections with HTML tags in vim

I want to be able to quickly wrap entire sections of my HTML with other tags. I run into this a lot when I realize I need an outer div around my other divs, like so:

Original HTML:

<div id='a'>
   <img src='a.png'>
</div>
<div id='b'>
   <img src='b.png'>
</div>

Modified HTML:

<div id='Main'>
   <div id='a'>
      <img src='a.png'>
   </div>
   <div id='b'>
      <img src='b.png'>
   </div>
</div>

I could use matchit.vim and surround.vim but I don't believe surround.vim surrounds with words (ie. <div>), just single characters (ie. <) and it also does not indent.

The closest thing I can think of right now takes 15-20 button presses.



Solution 1:[1]

surround.vim can surround with html tags, but it does not indent indents only when using S from visual mode, not ys and not s in visual, thanks to @RandyMorris. It also putts same-indented div’s on the next and previous lines (without indenting) if the motion to ys or visual selection used was linewise. Does not do even this for yss, so you have to use ysg@<div>j>> if you really want to avoid visual mode.

Update: there are g:surround_indent and b:surround_indent options. If you set any of them surround.vim will use = to indent surrounded text with its surroundings and the above mess with ys not indenting will be false, as well as S (S will use = as well). Requires filetype indent on and proper indenting settings.

If you don’t set these options you will see behavior described in the first paragraph: S indents unconditionally.

Solution 2:[2]

Yes, surround is indeed the way to go. Supposing your cursor is on the first div:

V%j%S<div id="Main"<CR>

or

V5jS<div id="Main"<CR>

do the trick.

Depending on the context, the whole thing could even be shortened to:

Vat<div id="Main"<CR>

The <div id="Main" part seems hard to skip.

There are other ways, of course.

ZenCoding, for example lets you use CSS syntax like that:

V5j<C-y>,div#Main<CR>

I am not aware of any faster way to get what you want.

TextMate's ControlShiftw was nice, that's for sure, but it defaulted to <p> so you'd have to type div id="Main" anyway.

Solution 3:[3]

place cursor at tag you want to surround with,

vatS<div id="Main"><CR>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Fisherman