3

In a file containing tags like these:

<div class="myclass">
Something irrelevant.
</div>
<div class="myclass">
MATCH ME
</div>

I would like to delete all tags not containing a specific pattern, here "MATCH ME" as an example. I can search for the opening of the tag, then do vat, inspect the selection, if it doesn't contain my pattern I hit d to delete it and move on to the next candidate with n, else I will hit n straight, continuing to the end of the file. Now I'd like to automate that, as I have a few files like that. How?

2

Assuming that MATCH ME is always a single line, you can use something like:

:g/^MATCH ME/-1,+1d
  • First, :g/^MATCH ME/ will search for all instances of MATCH ME.
  • We then run the :d (:delete) command on everything that matches with :g, but we also add a range of -1,+1, meaning one line before and one line after the matched line.

If your MATCH ME pattern may consist of multiple lines, we need a slightly more advanced version:

:g/^MATCH ME/call DeleteBetween('<div class="myclass">', '<\/div>')

Instead of adding a whole bunch on the command-line (which quickly becomes unreadable), I created a little helper function:

fun! DeleteBetween(start, end)
    " Reverse search for where we should start deleting
    execute '?' . a:start

    " Remember the line number
    let l:start = line('.')

    " Forward search for when we should stop deleting
    execute '/' . a:end

    " And delete the line range (:4,8d)
    execute ':' . l:start . ',' . line('.') . 'd'
endfun

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.