2

I have the following piece of HTML:

<div>
  <section>
  </section>
</div>

I would like to wrap the 2 section tags in a single article like so:

<div>
  <article>
    <section>
    </section>
  </article>
</div>

I have vim-surround installed.

If I vitS<article> I get:

<div><article>
  <section>
  </section>
</article></div>

How can I surround the lines inside the tag object?

2

vitVS<article> seems to do what you want.

  • v to start select mode
  • it to select "inner tag"
  • V to start line-wise visual mode
  • S<article> to surround

It would be better to start with line-wise visual mode, and go from there, but it changes it back to 'normal' (non-line wise) visual mode.

  • Unforunately not :( as switching to line-wise visual mode gets the opening <div> tag and you end up with: <article> <div> <section> </section> </article> </div> – Daniel Upton Mar 24 '15 at 16:18
  • 2
    Hmm, the it motion seems to behave different depending on the HTML: I've "discovered" 4 different behaviours :-/ – Martin Tournoij Mar 24 '15 at 16:23
  • 1
    It works if you start on the section tag rather than on the div tag. Selects inside section, then V to just select those 2 lines. As opposed to selecting inside div, which selects part of the first line as well. Or you can go to the section tag and do vatVS to select around the section tag. – Zach Ingbretsen Mar 24 '15 at 21:05
2

Unfortunately, the it text-object starts right after the opening tag with a zero-width match.

The only solution I see is to visually select the lines you want with V{motion} before pressing S. It is less magical than ysit<article> but oh well…

1

Discl.: This is not a Surround answer, just (three into) one that give(s) the result your are expecting -- note: there is a big limitation, Surround can work with any tag, here you'll have to known your tags in advance (well, lh-brackets could ask for the tag to insert, but that wouldn't be very ergonomic) .

With lh-brackets, it'll be solved with:

:Brackets <div> </div> -nl -insert=0 -trigger=µ

Then you select your lines and hit µ. The magic is in the -nl flag.

Otherwise, you have the old way (define your own mapping) ... As I though, I've answered to a very similar question not so long ago, but on SO.

:xnoremap µ S<div><cr><c-r>"</div><esc>
" select your lines, hit µ, and then, you'll need to reindent

" or
xnoremap µ <esc>`>o<div><esc>`<O</div><esc>
0

You can use yS along with at to surround the <section> tags instead of doing a surrounding inside with it on the <div>. So you command will look like so:

<cr>ySat<article><cr>

The <cr> just moves to the start to the next line, a j would do just as well.

The alternative is to use visual mode linewise as other suggested. e.g. vitVS<article><cr>

For more help see:

:h yS

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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