vim html5,html5.vim/htmlcomplete.vim at master · othree/html5.vim · GitHub

" Vim completion script

"Language: HTML and XHTML

"Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl )

"Last Change: 2006 Oct 19

"Modified: othree

"Changes: Add HTML5, WAI-ARIA support

"Last Change: 2016 Oct 11

if !exists('g:aria_attributes_complete')

let g:aria_attributes_complete = 1

endif

" Distinguish between HTML versions.

" To use with other HTML versions add another "elseif" condition to match

" proper DOCTYPE.

function! htmlcomplete#DetectOmniFlavor()

if &filetype == 'xhtml'

let b:html_omni_flavor = 'xhtml10s'

else

let b:html_omni_flavor = 'html5'

endif

let i = 1

let line = ""

while i<10 && i

let line = getline(i)

if line =~ '*\

break

endif

let i += 1

endwhile

if line =~ '*\

if line =~ ' HTML 3\.2'

let b:html_omni_flavor = 'html32'

elseif line =~ ' XHTML 1\.1'

let b:html_omni_flavor = 'xhtml11'

else" two-step detection with strict/frameset/transitional

if line =~ ' XHTML 1\.0'

let b:html_omni_flavor = 'xhtml10'

elseif line =~ ' HTML 4\.01'

let b:html_omni_flavor = 'html401'

elseif line =~ ' HTML 4.0\>'

let b:html_omni_flavor = 'html40'

endif

if line =~ '\'

let b:html_omni_flavor .= 't'

elseif line =~ '\

'

let b:html_omni_flavor .= 'f'

else

let b:html_omni_flavor .= 's'

endif

endif

endif

endfunction

function! htmlcomplete#CompleteTags(findstart, base)

if a:findstart

" locate the start of the word

let line = getline('.')

let start = col('.') - 1

let curline = line('.')

let compl_begin = col('.') - 2

while start >= 0 && line[start - 1] =~ '\(\k\|[!:.-]\)'

let start -= 1

endwhile

" Handling of entities {{{

if start >= 0 && line[start - 1] =~ '&'

let b:entitiescompl = 1

let b:compl_context = ''

return start

endif

" }}}

" Handling of

let stylestart = searchpair('

let styleend = searchpair('

if stylestart != 0 && styleend != 0

if stylestart <= curline && styleend >= curline

let start = col('.') - 1

let b:csscompl = 1

while start >= 0 && line[start - 1] =~ '\(\k\|-\)'

let start -= 1

endwhile

endif

endif

" }}}

" Handling of

let scriptstart = searchpair('

let scriptend = searchpair('

if scriptstart != 0 && scriptend != 0

if scriptstart <= curline && scriptend >= curline

let start = col('.') - 1

let b:jscompl = 1

let b:jsrange = [scriptstart, scriptend]

while start >= 0 && line[start - 1] =~ '\k'

let start -= 1

endwhile

" We are inside of

" of all linked external files and (secondary, less probably) other

" This logic could possible be done in separate function - may be

" reused in events scripting (also with option could be reused for

" CSS

let b:js_extfiles = []

let l = line('.')

let c = col('.')

call cursor(1,1)

while search('<\@<=script\>', 'W') && line('.') <= l

if synIDattr(synID(line('.'),col('.')-1,0),"name") !~? 'comment'

let sname = matchstr(getline('.'), '

if filereadable(sname)

let b:js_extfiles += readfile(sname)

endif

endif

endwhile

call cursor(1,1)

let js_scripttags = []

while search('

if matchstr(getline('.'), '

let js_scripttag = getline(line('.'), search('', 'W'))

let js_scripttags += js_scripttag

endif

endwhile

let b:js_extfiles += js_scripttags

call cursor(l,c)

unlet! l c

endif

endif

" }}}

if !exists("b:csscompl") && !exists("b:jscompl")

let b:compl_context = getline('.')[0:(compl_begin)]

if b:compl_context !~ '<[^>]*$'

" Look like we may have broken tag. Check previous lines.

let i = 1

while 1

let context_line = getline(curline-i)

if context_line =~ '<[^>]*$'

" Yep, this is this line

let context_lines = getline(curline-i, curline-1) + [b:compl_context]

let b:compl_context = join(context_lines, ' ')

break

elseif context_line =~ '>[^<]*$' || i == curline

" We are in normal tag line, no need for completion at all

" OR reached first line without tag at all

let b:compl_context = ''

break

endif

let i += 1

endwhile

" Make sure we don't have counter

unlet! i

endif

let b:compl_context = matchstr(b:compl_context, '.*\zs<.*')

" Return proper start for on-events. Without that beginning of

" completion will be badly reported

if b:compl_context =~? 'on[a-z]*\s*=\s*\(''[^'']*\|"[^"]*\)$'

let start = col('.') - 1

while start >= 0 && line[start - 1] =~ '\k'

let start -= 1

endwhile

endif

" If b:compl_context begins with <? we are inside of PHP code. It

" wasn't closed so PHP completion passed it to HTML

if &filetype =~? 'php' && b:compl_context =~ '^<?'

let b:phpcompl = 1

let start = col('.') - 1

while start >= 0 && line[start - 1] =~ '[a-zA-Z_0-9\x7f-\xff$]'

let start -= 1

endwhile

endif

else

let b:compl_context = getline('.')[0:compl_begin]

endif

return start

else

" Initialize base return lists

let res = []

let res2 = []

" a:base is very short - we need context

let context = b:compl_context

" Check if we should do CSS completion inside of

" or JS completion inside of

" tag AND &ft==php

if exists("b:csscompl")

unlet! b:csscompl

let context = b:compl_context

unlet! b:compl_context

return csscomplete#CompleteCSS(0, context)

elseif exists("b:jscompl")

unlet! b:jscompl

return javascriptcomplete#CompleteJS(0, a:base)

elseif exists("b:phpcompl")

unlet! b:phpcompl

let context = b:compl_context

return phpcomplete#CompletePHP(0, a:base)

else

if len(b:compl_context) == 0 && !exists("b:entitiescompl")

return []

endif

let context = matchstr(b:compl_context, '.\zs.*')

endif

unlet! b:compl_context

" Entities completion {{{

if exists("b:entitiescompl")

unlet! b:entitiescompl

if !exists("b:html_omni")

call htmlcomplete#CheckDoctype()

call htmlcomplete#LoadData()

endif

if g:aria_attributes_complete == 1 && !exists("b:aria_omni")

call htmlcomplete#LoadAria()

endif

let entities = b:html_omni['vimxmlentities']

if len(a:base) == 1

for m in entities

if m =~ '^'.a:base

call add(res, m.';')

endif

endfor

return res

else

for m in entities

if m =~? '^'.a:base

call add(res, m.';')

elseif m =~? a:base

call add(res2, m.';')

endif

endfor

return res + res2

endif

endif

" }}}

if context =~ '>'

" Generally if context contains > it means we are outside of tag and

" should abandon action - with one exception:

if context =~ 'style[^>]\{-}>[^<]\{-}$'

return csscomplete#CompleteCSS(0, context)

elseif context =~ 'script[^>]\{-}>[^<]\{-}$'

let b:jsrange = [line('.'), search('<\/script\>', 'nW')]

return javascriptcomplete#CompleteJS(0, context)

else

return []

endif

endif

" If context contains > it means we are already outside of tag and we

" should abandon action

" If context contains white space it is attribute.

" It can be also value of attribute.

" We have to get first word to offer proper completions

if context == ''

let tag = ''

else

let tag = split(context)[0]

" Detect if tag is uppercase to return in proper case,

" we need to make it lowercase for processing

if tag =~ '^\u*$'

let uppercase_tag = 1

let tag = tolower(tag)

else

let uppercase_tag = 0

endif

endif

" Get last word, it should be attr name

let attr = matchstr(context, '\S\+="[^"]*$')

if attr == ''

let attr = matchstr(context, '.*\s\zs.*')

endif

" Possible situations where any prediction would be difficult:

" 1. Events attributes

if context =~ '\s'

" Sort out style, class, and on* cases

if context =~? "\\(id\\|class\\)\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"

\|| context =~? "style\\s*=\\s*[\"'][^\"']*$"

\|| context =~? 'on[a-z]*\s*=\s*\(''[^'']*\|"[^"]*\)$'

" Id, class completion {{{

if context =~? "\\(id\\|class\\)\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"

if context =~? "class\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"

let search_for = "class"

elseif context =~? "id\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"

let search_for = "id"

endif

" Handle class name completion

" 1. Find lines of

" 1a. Check file for @import

" 2. Extract filename(s?) of stylesheet,

call cursor(1,1)

let head = getline(search('

'), search('<\/head>'))

let headjoined = join(copy(head), ' ')

if headjoined =~ '

let stylehead = substitute(headjoined, '+>\*[,', ' ', 'g')

if search_for == 'class'

let styleheadlines = split(stylehead)

let headclasslines = filter(copy(styleheadlines), "v:val =~ '\\([a-zA-Z0-9:]\\+\\)\\?\\.[a-zA-Z0-9_-]\\+'")

else

let stylesheet = split(headjoined, '[{}]')

" Get all lines which fit id syntax

let classlines = filter(copy(stylesheet), "v:val =~ '#[a-zA-Z0-9_-]\\+'")

" Filter out possible color definitions

call filter(classlines, "v:val !~ ':\\s*#[a-zA-Z0-9_-]\\+'")

" Filter out complex border definitions

call filter(classlines, "v:val !~ '\\(none\\|hidden\\|dotted\\|dashed\\|solid\\|double\\|groove\\|ridge\\|inset\\|outset\\)\\s*#[a-zA-Z0-9_-]\\+'")

let templines = join(classlines, ' ')

let headclasslines = split(templines)

call filter(headclasslines, "v:val =~ '#[a-zA-Z0-9_-]\\+'")

endif

let internal = 1

else

let internal = 0

endif

let styletable = []

let secimportfiles = []

let filestable = filter(copy(head), "v:val =~ '\\(@import\\|link.*stylesheet\\)'")

for line in filestable

if line =~ "@import"

let styletable += [matchstr(line, "import\\s\\+\\(url(\\)\\?[\"']\\?\\zs\\f\\+\\ze")]

elseif line =~ "

let styletable += [matchstr(line, "href\\s*=\\s*[\"']\\zs\\f\\+\\ze")]

endif

endfor

for file in styletable

if filereadable(file)

let stylesheet = readfile(file)

let secimport = filter(copy(stylesheet), "v:val =~ '@import'")

if len(secimport)>0

for line in secimport

let secfile = matchstr(line, "import\\s\\+\\(url(\\)\\?[\"']\\?\\zs\\f\\+\\ze")

let secfile = fnamemodify(file, ":p:h").'/'.secfile

let secimportfiles += [secfile]

endfor

endif

endif

endfor

let cssfiles = styletable + secimportfiles

let classes = []

for file in cssfiles

if filereadable(file)

let stylesheet = readfile(file)

let stylefile = join(stylesheet, ' ')

let stylefile = substitute(stylefile, '+>\*[,', ' ', 'g')

if search_for == 'class'

let stylesheet = split(stylefile)

let classlines = filter(copy(stylesheet), "v:val =~ '\\([a-zA-Z0-9:]\\+\\)\\?\\.[a-zA-Z0-9_-]\\+'")

else

let stylesheet = split(stylefile, '[{}]')

" Get all lines which fit id syntax

let classlines = filter(copy(stylesheet), "v:val =~ '#[a-zA-Z0-9_-]\\+'")

" Filter out possible color definitions

call filter(classlines, "v:val !~ ':\\s*#[a-zA-Z0-9_-]\\+'")

" Filter out complex border definitions

call filter(classlines, "v:val !~ '\\(none\\|hidden\\|dotted\\|dashed\\|solid\\|double\\|groove\\|ridge\\|inset\\|outset\\)\\s*#[a-zA-Z0-9_-]\\+'")

let templines = join(classlines, ' ')

let stylelines = split(templines)

let classlines = filter(stylelines, "v:val =~ '#[a-zA-Z0-9_-]\\+'")

endif

" We gathered classes definitions from all external files

let classes += classlines

endif

endfor

if internal == 1

let classes += headclasslines

endif

if search_for == 'class'

let elements = {}

for element in classes

if element =~ '^\.'

let class = matchstr(element, '^\.\zs[a-zA-Z][a-zA-Z0-9_-]*\ze')

let class = substitute(class, ':.*', '', '')

if has_key(elements, 'common')

let elements['common'] .= ' '.class

else

let elements['common'] = class

endif

else

let class = matchstr(element, '[a-zA-Z1-6]*\.\zs[a-zA-Z][a-zA-Z0-9_-]*\ze')

let tagname = tolower(matchstr(element, '[a-zA-Z1-6]*\ze.'))

if tagname != ''

if has_key(elements, tagname)

let elements[tagname] .= ' '.class

else

let elements[tagname] = class

endif

endif

endif

endfor

if has_key(elements, tag) && has_key(elements, 'common')

let values = split(elements[tag]." ".elements['common'])

elseif has_key(elements, tag) && !has_key(elements, 'common')

let values = split(elements[tag])

elseif !has_key(elements, tag) && has_key(elements, 'common')

let values = split(elements['common'])

else

return []

endif

elseif search_for == 'id'

" Find used IDs

" 1. Catch whole file

let filelines = getline(1, line('$'))

" 2. Find lines with possible id

let used_id_lines = filter(filelines, 'v:val =~ "id\\s*=\\s*[\"''][a-zA-Z0-9_-]\\+"')

" 3a. Join all filtered lines

let id_string = join(used_id_lines, ' ')

" 3b. And split them to be sure each id is in separate item

let id_list = split(id_string, 'id\s*=\s*')

" 4. Extract id values

let used_id = map(id_list, 'matchstr(v:val, "[\"'']\\zs[a-zA-Z0-9_-]\\+\\ze")')

let joined_used_id = ','.join(used_id, ',').','

let allvalues = map(classes, 'matchstr(v:val, ".*#\\zs[a-zA-Z0-9_-]\\+")')

let values = []

for element in classes

if joined_used_id !~ ','.element.','

let values += [element]

endif

endfor

endif

" We need special version of sbase

let classbase = matchstr(context, ".*[\"']")

let classquote = matchstr(classbase, '.$')

let entered_class = matchstr(attr, ".*=\\s*[\"']\\zs.*")

for m in sort(values)

if m =~? '^'.entered_class

call add(res, m . classquote)

elseif m =~? entered_class

call add(res2, m . classquote)

endif

endfor

return res + res2

elseif context =~? "style\\s*=\\s*[\"'][^\"']*$"

return csscomplete#CompleteCSS(0, context)

endif

" }}}

" Complete on-events {{{

if context =~? 'on[a-z]*\s*=\s*\(''[^'']*\|"[^"]*\)$'

" We have to:

" 1. Find external files

let b:js_extfiles = []

let l = line('.')

let c = col('.')

call cursor(1,1)

while search('<\@<=script\>', 'W') && line('.') <= l

if synIDattr(synID(line('.'),col('.')-1,0),"name") !~? 'comment'

let sname = matchstr(getline('.'), '

if filereadable(sname)

let b:js_extfiles += readfile(sname)

endif

endif

endwhile

" 2. Find at least one

call cursor(1,1)

let js_scripttags = []

while search('

if matchstr(getline('.'), '

let js_scripttag = getline(line('.'), search('', 'W'))

let js_scripttags += js_scripttag

endif

endwhile

let b:js_extfiles += js_scripttags

" 3. Proper call for javascriptcomplete#CompleteJS

call cursor(l,c)

let js_context = matchstr(a:base, '\k\+$')

let js_shortcontext = substitute(a:base, js_context.'$', '', '')

let b:compl_context = context

let b:jsrange = [l, l]

unlet! l c

return javascriptcomplete#CompleteJS(0, js_context)

endif

" }}}

let stripbase = matchstr(context, ".*\\(on[a-zA-Z]*\\|style\\|class\\)\\s*=\\s*[\"']\\zs.*")

" Now we have context stripped from all chars up to style/class.

" It may fail with some strange style value combinations.

if stripbase !~ "[\"']"

return []

endif

endif

" Value of attribute completion {{{

" If attr contains =\s*[\"'] we catched value of attribute

if attr =~ "=\s*[\"']" || attr =~ "=\s*$"

" Let do attribute specific completion

let attrname = matchstr(attr, '.*\ze\s*=')

let entered_value = matchstr(attr, ".*=\\s*[\"']\\?\\zs.*")

let values = []

" Load data {{{

if !exists("b:html_omni")

call htmlcomplete#CheckDoctype()

call htmlcomplete#LoadData()

endif

if g:aria_attributes_complete == 1 && !exists("b:aria_omni")

call htmlcomplete#LoadAria()

endif

" }}}

if attrname == 'href'

" Now we are looking for local anchors defined by name or id

if entered_value =~ '^#'

let file = join(getline(1, line('$')), ' ')

" Split it be sure there will be one id/name element in

" item, it will be also first word [a-zA-Z0-9_-] in element

let oneelement = split(file, "\\(meta \\)\\@

for i in oneelement

let values += ['#'.matchstr(i, "^[a-zA-Z][a-zA-Z0-9%_-]*")]

endfor

endif

else

if has_key(b:html_omni, tag) && has_key(b:html_omni[tag][1], attrname)

let values = b:html_omni[tag][1][attrname]

elseif attrname =~ '^aria-' && exists("b:aria_omni") && has_key(b:aria_omni['aria_attributes'], attrname)

let values = b:aria_omni['aria_attributes'][attrname]

else

return []

endif

endif

if len(values) == 0

return []

endif

" We need special version of sbase

let attrbase = matchstr(context, ".*[\"']")

let attrquote = matchstr(attrbase, '.$')

if attrquote !~ "['\"]"

let attrquoteopen = '"'

let attrquote = '"'

else

let attrquoteopen = ''

endif

" Multi value attributes don't need ending quote

let info = ''

if has_key(b:html_omni['vimxmlattrinfo'], attrname)

let info = b:html_omni['vimxmlattrinfo'][attrname][0]

elseif exists("b:aria_omni") && has_key(b:aria_omni['vimariaattrinfo'], attrname)

let info = b:aria_omni['vimariaattrinfo'][attrname][0]

endif

if info =~ "^\\*"

let attrquote = ''

endif

if len(entered_value)>0

if entered_value =~ "\\s$"

let entered_value = ''

else

let entered_value = split(entered_value)[-1]

endif

endif

for m in values

" This if is needed to not offer all completions as-is

" alphabetically but sort them. Those beginning with entered

" part will be as first choices

if m =~ '^'.entered_value

call add(res, attrquoteopen . m . attrquote)

elseif m =~ entered_value

call add(res2, attrquoteopen . m . attrquote)

endif

endfor

return res + res2

endif

" }}}

" Attribute completion {{{

" Shorten context to not include last word

let sbase = matchstr(context, '.*\ze\s.*')

" Load data {{{

if !exists("b:html_omni")

call htmlcomplete#CheckDoctype()

call htmlcomplete#LoadData()

endif

if g:aria_attributes_complete == 1 && !exists("b:aria_omni")

call htmlcomplete#LoadAria()

endif

" }}}

if has_key(b:html_omni, tag)

let attrs = keys(b:html_omni[tag][1])

else

return []

endif

if exists("b:aria_omni")

let roles = []

if has_key(b:aria_omni['default_role'], tag)

let roles = [b:aria_omni['default_role'][tag]]

endif

if context =~ 'role='

let start = matchend(context, "role=['\"]")

let end = matchend(context, "[a-z ]\\+['\"]", start)

if start != -1 && end != -1

let roles = split(strpart(context, start, end-start-1), " ")

endif

endif

for i in range(len(roles))

let role = roles[i]

if has_key(b:aria_omni['role_attributes'], role)

let attrs = extend(attrs, b:aria_omni['role_attributes'][role])

endif

endfor

endif

for m in sort(attrs)

if m =~ '^'.attr

call add(res, m)

elseif m =~ attr

call add(res2, m)

endif

endfor

"let menu = res + res2

let menu = res

if has_key(b:html_omni, 'vimxmlattrinfo') || (exists("b:aria_omni") && has_key(b:aria_omni, 'vimariaattrinfo'))

let final_menu = []

for i in range(len(menu))

let item = menu[i]

if has_key(b:html_omni['vimxmlattrinfo'], item)

let m_menu = b:html_omni['vimxmlattrinfo'][item][0]

let m_info = b:html_omni['vimxmlattrinfo'][item][1]

elseif exists("b:aria_omni") && has_key(b:aria_omni['vimariaattrinfo'], item)

let m_menu = b:aria_omni['vimariaattrinfo'][item][0]

let m_info = b:aria_omni['vimariaattrinfo'][item][1]

else

let m_menu = ''

let m_info = ''

endif

if item =~ '^aria-' && exists("b:aria_omni")

if len(b:aria_omni['aria_attributes'][item])>0 && b:aria_omni['aria_attributes'][item][0] =~ '^\(BOOL\|'.item.'\)$'

let item = item

let m_menu = 'Bool'

else

let item .= '="'

endif

else

if len(b:html_omni[tag][1][item])>0 && b:html_omni[tag][1][item][0] =~ '^\(BOOL\|'.item.'\)$'

let item = item

let m_menu = 'Bool'

else

let item .= '="'

endif

endif

let final_menu += [{'word':item, 'menu':m_menu, 'info':m_info}]

endfor

else

let final_menu = []

for i in range(len(menu))

let item = menu[i]

if len(b:html_omni[tag][1][item])>0 && b:html_omni[tag][1][item][0] =~ '^\(BOOL\|'.item.'\)$'

let item = item

else

let item .= '="'

endif

let final_menu += [item]

endfor

return final_menu

endif

return final_menu

endif

" }}}

" Close tag {{{

let b:unaryTagsStack = "area base br col command embed hr img input keygen link meta param source track wbr"

if context =~ '^\/'

if context =~ '^\/.'

return []

else

let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")

return [opentag.">"]

endif

endif

" }}}

" Load data {{{

if !exists("b:html_omni")

call htmlcomplete#CheckDoctype()

call htmlcomplete#LoadData()

endif

if g:aria_attributes_complete == 1 && !exists("b:aria_omni")

call htmlcomplete#LoadAria()

endif

" }}}

" Tag completion {{{

" Deal with tag completion.

let opentag = tolower(xmlcomplete#GetLastOpenTag("b:unaryTagsStack"))

"MM: TODO: GLOT works always the same but with some weird situation it

" behaves as intended in HTML but screws in PHP

if opentag == '' || &filetype == 'php' && !has_key(b:html_omni, opentag)

" Hack for sometimes failing GetLastOpenTag.

" As far as I tested fail isn't GLOT fault but problem

" of invalid document - not properly closed tags and other mish-mash.

" Also when document is empty. Return list of *all* tags.

let tags = keys(b:html_omni)

call filter(tags, 'v:val !~ "^vimxml"')

else

if has_key(b:html_omni, opentag)

let tags = b:html_omni[opentag][0]

else

return []

endif

endif

" }}}

if exists("uppercase_tag") && uppercase_tag == 1

let context = tolower(context)

endif

" Handle XML keywords: DOCTYPE

if opentag == ''

let tags = [

\'!DOCTYPE html>',

\'!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',

\'!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/1999/xhtml">'

\] + sort(tags)

endif

"for m in sort(tags)

for m in tags

if m =~ '^'.context

call add(res, m)

elseif m =~ context

call add(res2, m)

endif

endfor

let menu = res + res2

if has_key(b:html_omni, 'vimxmltaginfo')

let final_menu = []

for i in range(len(menu))

let item = menu[i]

if has_key(b:html_omni['vimxmltaginfo'], item)

let m_menu = b:html_omni['vimxmltaginfo'][item][0]

let m_info = b:html_omni['vimxmltaginfo'][item][1]

else

let m_menu = ''

let m_info = ''

endif

if &filetype == 'html' && exists("uppercase_tag") && uppercase_tag == 1 && item !~ 'DOCTYPE'

let item = toupper(item)

endif

if item =~ 'DOCTYPE'

if item =~ 'DTD'

let abbr = 'DOCTYPE '.matchstr(item, 'DTD \zsX\?HTML .\{-}\ze\/\/')

else

let abbr = 'DOCTYPE HTML 5'

endif

else

let abbr = item

endif

let final_menu += [{'abbr':abbr, 'word':item, 'menu':m_menu, 'info':m_info}]

endfor

else

let final_menu = menu

endif

return final_menu

" }}}

endif

endfunction

function! htmlcomplete#LoadAria()" {{{

runtime! autoload/xml/aria.vim

if exists("g:xmldata_aria")

\&& has_key(g:xmldata_aria, 'default_role')

\&& has_key(g:xmldata_aria, 'role_attributes')

\&& has_key(g:xmldata_aria, 'vimariaattrinfo')

\&& has_key(g:xmldata_aria, 'aria_attributes')

let b:aria_omni = g:xmldata_aria

else

let g:aria_attributes_complete = 0

endif

endfunction

" }}}

function! htmlcomplete#LoadData()" {{{

if !exists("b:html_omni_flavor")

if &filetype == 'html'

let b:html_omni_flavor = 'html5'

else

let b:html_omni_flavor = 'html5'

endif

endif

" With that if we still have bloated memory but create new buffer

" variables only by linking to existing g:variable, not sourcing whole

" file.

if exists('g:xmldata_'.b:html_omni_flavor)

exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor

else

exe 'runtime! autoload/xml/'.b:html_omni_flavor.'.vim'

exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor

endif

endfunction

" }}}

function! htmlcomplete#CheckDoctype()" {{{

if exists('b:html_omni_flavor')

let old_flavor = b:html_omni_flavor

else

let old_flavor = ''

endif

call htmlcomplete#DetectOmniFlavor()

if !exists('b:html_omni_flavor')

return

else

" Tie g:xmldata with b:html_omni this way we need to sourca data file only

" once, not every time per buffer.

if old_flavor == b:html_omni_flavor

return

else

if exists('g:xmldata_'.b:html_omni_flavor)

exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor

else

exe 'runtime! autoload/xml/'.b:html_omni_flavor.'.vim'

exe 'let b:html_omni = g:xmldata_'.b:html_omni_flavor

endif

return

endif

endif

endfunction

" }}}

"vim:set foldmethod=marker:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值