17

How can I configure Vim so that when I change one member of a matching pair of HTML tags, the other is automatically changed to match?

For example: given <span>content</span>, I want to change <span> to <div>, and then the closing </span> automatically changes to </div>. Optimally this would happen upon returning from insert mode to normal mode, but it would be OK if I had to hit a special keybinding to make this happen.

hjkml
  • 325
  • 1
  • 2
  • 5

4 Answers4

28

The excellent surround.vim makes this simple — with the cursor anywhere within the tag you want to change, in normal mode, type cst<div> (change surrounding tag to <div>). The tag name will be changed to "div" in both the opening and closing tag, and you'll be back in normal mode.

sj26
  • 471
  • 4
  • 5
3

Here are few steps:

  1. Place your cursor on the first tag.
  2. Select outer html code by pressing: vat.
  3. Press Esc to exit visual mode and type:

    :'<,'<s/span/div/
    :'>,'>s/span/div/
    

    Note that :'>,'>s/span/div/ won't work correctly if there are two occurrences of the same closing tag in the same line, as it'll always change the first one. To fix it, use: :'>,'>s/.*\zsspan/div/ instead. See: How to change last occurrence of the string in the line?

Related:

kenorb
  • 20,250
  • 14
  • 140
  • 164
  • Does entering visual mode do anything, once you've exited it? – AncientSwordRage Jan 25 '17 at 11:43
  • I'm not sure if I get the question. In the visual mode you're selecting the outer html for the given HTML tags, so substitution will only affect the selected region. – kenorb Jan 25 '17 at 11:46
  • When I tried this, it looked like pressing Esc exited visual mode *entirely*, so that the substitution would have effected any other region; nothing remained highlighted after pressing Esc . – AncientSwordRage Jan 25 '17 at 13:10
  • @Pureferret The ranges from the 3. step should use the last selected region. – kenorb Jan 25 '17 at 13:29
  • This is a terrible thing! It must change a closing tag on the fly during editting matching tag – Alex Shwarc Sep 15 '17 at 17:55
  • Does not seem ergonomic. So much keystrokes (time) for such a simple operation. – Dzintars Apr 30 '20 at 11:42
2

The Vim tagalong plugin can do this:

Vim tagalong

Flux
  • 2,516
  • 4
  • 20
  • 45
0

With the SwapIt - Extensible keyword swapper, you can define tag groups that can then be toggled via <C-a> / <C-x>. For example, in ~/.vim/ftplugin/html_swapit.vim:

SwapList layout p div span

If you have both start and end tag on the same line (and there's only one of that type), you can edit both via my ChangeGlobally plugin.


There are also several "multicursor" plugins, which allow you to mark certain words and edit them all at once.

Ingo Karkat
  • 11,664
  • 1
  • 34
  • 48