5

An example HTML, with the cursor where the brackets are:

<foo>
  <bar>
          baz
          quux
          []
  </bar>
</foo>

I would like to outdent the text inside <bar/>. Naturally, I try <it, but it turns out that it is everything inside <bar/> - including the newline after <bar>, and indent before </bar>. Thus, < pulls the entire <bar/> tag, not just the contents.

On the other hand, <i{ does the right thing in pretty much the same circumstance:

if (foo) {
    baz();
    quux();
    []
}

Does anyone have an idea how I can select just the three lines between, without the <bar> and </bar> lines, just like I can do inside the braces? The best I can come up with is vitkoj<; am I missing something obvious?

3

You can use Operator-pending mode to define new text objects by having the mapping invoke Visual mode, and then select the text you want to operate on.

I'm not entirely sure what semantics you want here; the devil is in the details, as usual. But you could try the following:

:onoremap iT :<C-U>normal! vitbowV<CR>

And then <iT to unindent something.

To define the text to operate on it does vit to select the inner tag, backs up a word, moves to the beginning of the selection, then moves on a word, and then makes the selection linewise. This should suffice for most situations.

More details at :help omap-info.

  • So this, together with vnoremap iT itbowV, seems to do pretty much exactly what I want. Should have thought of it before. :) – Amadan May 14 '17 at 18:44
  • 1
    Yep, though I'd recommend xnoremap to avoid Select mode. – Antony May 14 '17 at 18:47
  • Good point. I never ever use select mode, so it's a non-issue for me, but it is a better choice. – Amadan May 14 '17 at 18:50
2

You are right, vim treats tags differently. The plugin vim-indent-object will help you, you can do <ii with it to chance the indent of all lines inside the same indent block.

  • This handles some situations that it doesn't, and vice versa. Looks like a good complementary approach, and I like general purpose solutions like this. A way to do this without a plugin would be to :set foldmethod=indent and operate on the folds. – Antony May 14 '17 at 13:32

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.