How can one close HTML tags in Vim quickly?

HtmlXmlVimAutocomplete

Html Problem Overview


It's been a while since I've had to do any HTML-like code in Vim, but recently I came across this again. Say I'm writing some simple HTML:

<html><head><title>This is a title</title></head></html>

How do I write those closing tags for title, head and html down quickly? I feel like I'm missing some really simple way here that does not involve me going through writing them all down one by one.

Of course I can use CtrlP to autocomplete the individual tag names but what gets me on my laptop keyboard is actually getting the brackets and slash right.

Html Solutions


Solution 1 - Html

I find using the xmledit plugin pretty useful. it adds two pieces of functionality:

  1. When you open a tag (e.g. type <p>), it expands the tag as soon as you type the closing > into <p></p> and places the cursor inside the tag in insert mode.

  2. If you then immediately type another > (e.g. you type <p>>), it expands that into

    <p>

    </p>

and places the cursor inside the tag, indented once, in insert mode.

The xml vim plugin adds code folding and nested tag matching to these features.

Of course, you don't have to worry about closing tags at all if you write your HTML content in Markdown and use %! to filter your Vim buffer through the Markdown processor of your choice :)

Solution 2 - Html

I like minimal things,

imap ,/ </<C-X><C-O>

Solution 3 - Html

I find it more convinient to make vim write both opening and closing tag for me, instead of just the closing one. You can use excellent http://www.vim.org/scripts/script.php?script_id=1896">ragtag plugin by Tim Pope. Usage looks like this (let | mark cursor position) you type:

span|
press CTRL+x SPACE

and you get

<span>|</span>

You can also use CTRL+x ENTER instead of CTRL+x SPACE, and you get

<span>
|
</span>

Ragtag can do more than just it (eg. insert <%= stuff around this %> or DOCTYPE). You probably want to check out other plugins by http://www.vim.org/account/profile.php?user_id=9012">author of ragtag, especially http://www.vim.org/scripts/script.php?script_id=1697">surround</a>;.

Solution 4 - Html

Check this out..

closetag.vim

Functions and mappings to close open HTML/XML tags

https://www.vim.org/scripts/script.php?script_id=13

I use something similar.

Solution 5 - Html

If you're doing anything elaborate, sparkup is very good.

An example from their site:

ul > li.item-$*3 expands to:

<ul>
    <li class="item-1"></li>
    <li class="item-2"></li>
    <li class="item-3"></li>
</ul>

with a <C-e>.

To do the example given in the question,

html > head > title{This is a title}

yields

<html>
  <head>
    <title>This is a title</title>
  </head>
</html>

Solution 6 - Html

There is also a zencoding vim plugin: https://github.com/mattn/zencoding-vim

tutorial: https://github.com/mattn/zencoding-vim/blob/master/TUTORIAL


Update: this now called Emmet: http://emmet.io/


An excerpt from the tutorial:

1. Expand Abbreviation

  Type abbreviation as 'div>p#foo$*3>a' and type '<c-y>,'.
  ---------------------
  <div>
      <p id="foo1">
          <a href=""></a>
      </p>
      <p id="foo2">
          <a href=""></a>
      </p>
      <p id="foo3">
          <a href=""></a>
      </p>
  </div>
  ---------------------

2. Wrap with Abbreviation

  Write as below.
  ---------------------
  test1
  test2
  test3
  ---------------------
  Then do visual select(line wize) and type '<c-y>,'.
  If you request 'Tag:', then type 'ul>li*'.
  ---------------------
  <ul>
      <li>test1</li>
      <li>test2</li>
      <li>test3</li>
  </ul>
  ---------------------

...

12. Make anchor from URL

  Move cursor to URL
  ---------------------
  http://www.google.com/
  ---------------------
  Type '<c-y>a'
  ---------------------
  <a href="http://www.google.com/">Google</a>
  ---------------------

Solution 7 - Html

Mapping

I like to have my block tags (as opposed to inline) closed immediately and with as simple a shortcut as possible (I like to avoid special keys like CTRL where possible, though I do use closetag.vim to close my inline tags.) I like to use this shortcut when starting blocks of tags (thanks to @kimilhee; this is a take-off of his answer):

inoremap ><Tab> ><Esc>F<lyt>o</<C-r>"><Esc>O<Space>

Sample usage

Type—

<p>[Tab]

Result—

<p>
 |
</p>

where | indicates cursor position.

Explanation

  • inoremap means create the mapping in insert mode
  • ><Tab> means a closing angle brackets and a tab character; this is what is matched
  • ><Esc> means end the first tag and escape from insert into normal mode
  • F< means find the last opening angle bracket
  • l means move the cursor right one (don't copy the opening angle bracket)
  • yt> means yank from cursor position to up until before the next closing angle bracket (i.e. copy tags contents)
  • o</ means start new line in insert mode and add an opening angle bracket and slash
  • <C-r>" means paste in insert mode from the default register (")
  • ><Esc> means close the closing tag and escape from insert mode
  • O<Space> means start a new line in insert mode above the cursor and insert a space

Solution 8 - Html

Check out vim-closetag

It's a really simple script (also available as a vundle plugin) that closes (X)HTML tags for you. From it's README:

> If this is the current content: > > > Now you press >, the content will be: > >

|
> > And now if you press > again, the content will be: > > > | >


Note: | is the cursor here

Solution 9 - Html

Here is yet another simple solution based on easily foundable Web writing:

  1. Auto closing an HTML tag

    :iabbrev </ </<C-X><C-O>

  2. Turning completion on

    autocmd FileType xml set omnifunc=xmlcomplete#CompleteTags

Solution 10 - Html

allml (now Ragtag ) and Omni-completion ( <C-X><C-O> ) doesn't work in a file like .py or .java.

if you want to close tag automatically in those file, you can map like this.

imap <C-j> <ESC>F<lyt>$a</^R">

( ^R is Contrl+R : you can type like this Control+v and then Control+r )

(| is cursor position ) now if you type..

<p>abcde|

and type ^j

then it close the tag like this..

<p>abcde</p>|

Solution 11 - Html

Building off of the excellent answer by @KeithPinson (sorry, not enough reputation points to comment on your answer yet), this alternative will prevent the autocomplete from copying anything extra that might be inside the html tag (e.g. classes, ids, etc...) but should not be copied to the closing tag.

UPDATE I have updated my response to work with filename.html.erb files.
I noticed my original response didn't work in files commonly used in Rails views, like some_file.html.erb when I was using embedded ruby (e.g. <p>Year: <%= @year %><p>). The code below will work with .html.erb files.

inoremap ><Tab> ><Esc>?<[a-z]<CR>lyiwo</<C-r>"><Esc>O

Sample usage

Type:

<div class="foo">[Tab]

Result:

<div class="foo">
  |
<div>

where | indicates cursor position

And as an example of adding the closing tag inline instead of block style:

inoremap ><Tab> ><Esc>?<[a-z]<CR>lyiwh/[^%]><CR>la</<C-r>"><Esc>F<i

Sample usage

Type:

<div class="foo">[Tab]

Result:

<div class="foo">|<div>

where | indicates cursor position

It's true that both of the above examples rely on >[Tab] to signal a closing tag (meaning you would have to choose either inline or block style). Personally, I use the block-style with >[Tab] and the inline-style with >>.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwdsView Question on Stackoverflow
Solution 1 - HtmlhakamadareView Answer on Stackoverflow
Solution 2 - HtmlsjhView Answer on Stackoverflow
Solution 3 - HtmlKrzysiek GojView Answer on Stackoverflow
Solution 4 - HtmlIan PView Answer on Stackoverflow
Solution 5 - HtmlthantheseView Answer on Stackoverflow
Solution 6 - HtmlPreet KukretiView Answer on Stackoverflow
Solution 7 - HtmlKeith PinsonView Answer on Stackoverflow
Solution 8 - HtmlSheharyarView Answer on Stackoverflow
Solution 9 - HtmlmloskotView Answer on Stackoverflow
Solution 10 - HtmlkimilheeView Answer on Stackoverflow
Solution 11 - HtmlNick ErhardtView Answer on Stackoverflow