├── README └── ftplugin └── html_autoclosetag.vim /README: -------------------------------------------------------------------------------- 1 | This is a mirror of http://www.vim.org/scripts/script.php?script_id=2591 2 | 3 | Automatically closes HTML tag once you finish typing it with >. It is also smart enough to not autoclose tags when in a comment, when they are self-closing, or when they have already been closed. 4 | 5 | So, , upon typing >, will become |, where | is the cursor. 6 | But, if you type , the script knows to keep it the same. 7 | -------------------------------------------------------------------------------- /ftplugin/html_autoclosetag.vim: -------------------------------------------------------------------------------- 1 | " File: HTML AutoCloseTag.vim 2 | " Author: Michael Sanders (msanders42 [at] gmail [dot] com) 3 | " Last Updated: April 7 2009 4 | " Version: 0.3 5 | " Description: Automatically closes HTML tag once you finish typing it with > 6 | 7 | if exists('b:mapped_auto_closetag') || &cp | finish | endif 8 | let b:mapped_auto_closetag = 1 9 | 10 | ino < <> 11 | ino > =CloseTag() 12 | ino Return() 13 | 14 | if exists('s:did_auto_closetag') | finish | endif 15 | let s:did_auto_closetag = 1 16 | 17 | " Gets the current HTML tag by the cursor. 18 | fun s:GetCurrentTag() 19 | return matchstr(matchstr(getline('.'), 20 | \ '<\zs\(\w\|=\| \|''\|"\)*>\%'.col('.').'c'), '^\a*') 21 | endf 22 | 23 | " Cleanly return after autocompleting an html/xml tag. 24 | fun s:Return() 25 | let tag = s:GetCurrentTag() 26 | return tag != '' && match(getline('.'), '') > -1 ? 27 | \ "\\\" : "\" 28 | endf 29 | 30 | fun s:InComment() 31 | return stridx(synIDattr(synID(line('.'), col('.')-1, 0), 'name'), 'omment') != -1 32 | endf 33 | 34 | " Counts occurance of needle in page, when not in a comment. 35 | fun s:CountInPage(needle) 36 | let pos = [line('.'), col('.')] 37 | call cursor(1, 1) 38 | let counter = search(a:needle, 'Wc') 39 | while search(a:needle, 'W') 40 | if !s:InComment() | let counter += 1 | endif 41 | endw 42 | call cursor(pos) 43 | return counter 44 | endf 45 | 46 | " Returns whether a closing tag has already been inserted. 47 | fun s:ClosingTag(tag) 48 | return s:CountInPage('\c<'.a:tag.'.\{-}>') <= s:CountInPage('\c') 49 | endf 50 | 51 | " Automatically inserts closing tag after starting tag is typed 52 | fun s:CloseTag() 53 | let line = getline('.') 54 | let col = col('.') 55 | if line[col-1] != '>' | return '>' | endif 56 | let col += 1 57 | call cursor(0, col) 58 | " Don't autocomplete next to a word or another tag or if inside comment 59 | if line[col] !~ '\w\|<\|>' && !s:InComment() 60 | let tag = s:GetCurrentTag() 61 | " Insert closing tag if tag is not self-closing and has not already 62 | " been closed 63 | if tag != '' && tag !~ '\vimg|input|link|meta|br|hr|area|base|param|dd|dt' 64 | \ && !s:ClosingTag(tag) 65 | let line = substitute(line, '\%'.col.'c', '', '') 66 | call setline('.', line) 67 | call cursor(0, col) 68 | endif 69 | endif 70 | return '' 71 | endf 72 | " vim:noet:sw=4:ts=4:ft=vim 73 | --------------------------------------------------------------------------------