html_autoclosetag.vim 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. if exists('b:mapped_auto_closetag') || &cp | finish | endif
  7. let g:mapped_auto_closetag = 1
  8. ino <buffer> <silent> < <><left>
  9. ino <buffer> <silent> > <c-r>=<SID>CloseTag()<cr>
  10. ino <buffer> <expr> <cr> <SID>Return()
  11. if exists('s:did_auto_closetag') | finish | endif
  12. let g:did_auto_closetag = 1
  13. " Gets the current HTML tag by the cursor.
  14. fun s:GetCurrentTag()
  15. return matchstr(matchstr(getline('.'),
  16. \ '<\zs\(\w\|=\| \|''\|"\)*>\%'.col('.').'c'), '^\a*')
  17. endf
  18. " Cleanly return after autocompleting an html/xml tag.
  19. fun s:Return()
  20. let tag = s:GetCurrentTag()
  21. return tag != '' && match(getline('.'), '</'.tag.'>') > -1 ?
  22. \ "\<cr>\<cr>\<up>" : "\<cr>"
  23. endf
  24. fun s:InComment()
  25. return stridx(synIDattr(synID(line('.'), col('.')-1, 0), 'name'), 'omment') != -1
  26. endf
  27. " Counts occurance of needle in page, when not in a comment.
  28. fun s:CountInPage(needle)
  29. let pos = [line('.'), col('.')]
  30. call cursor(1, 1)
  31. let counter = search(a:needle, 'Wc')
  32. while search(a:needle, 'W')
  33. if !s:InComment() | let counter += 1 | endif
  34. endw
  35. call cursor(pos)
  36. return counter
  37. endf
  38. " Returns whether a closing tag has already been inserted.
  39. fun s:ClosingTag(tag)
  40. return s:CountInPage('\c<'.a:tag.'.\{-}>') <= s:CountInPage('\c</'.a:tag.'>')
  41. endf
  42. " Automatically inserts closing tag after starting tag is typed
  43. fun s:CloseTag()
  44. let line = getline('.')
  45. let col = col('.')
  46. if line[col-1] != '>' | return '>' | endif
  47. let col += 1
  48. call cursor(0, col)
  49. " Don't autocomplete next to a word or another tag or if inside comment
  50. if line[col] !~ '\w\|<\|>' && !s:InComment()
  51. let tag = s:GetCurrentTag()
  52. " Insert closing tag if tag is not self-closing and has not already
  53. " been closed
  54. if tag != '' && tag !~ '\vimg|input|link|meta|br|hr|area|base|param|dd|dt'
  55. \ && !s:ClosingTag(tag)
  56. let line = substitute(line, '\%'.col.'c', '</'.escape(tag, '/').'>', '')
  57. call setline('.', line)
  58. call cursor(0, col)
  59. endif
  60. endif
  61. return ''
  62. endf
  63. " vim:noet:sw=4:ts=4:ft=vim