neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

javascriptcomplete.vim (28148B)


      1 " Vim completion script
      2 " Language:	Java Script
      3 " Maintainer:	Jay Sitter (jay@jaysitter.com)
      4 " URL: https://github.com/jsit/javascriptcomplete.vim/
      5 " Previous Maintainer:	Mikolaj Machowski ( mikmach AT wp DOT pl )
      6 " Last Change:	2020 Jul 30
      7 
      8 function! javascriptcomplete#CompleteJS(findstart, base)
      9  if a:findstart
     10 " locate the start of the word
     11 let line = getline('.')
     12 let start = col('.') - 1
     13 let curline = line('.')
     14 let compl_begin = col('.') - 2
     15 " Bit risky but JS is rather limited language and local chars shouldn't
     16 " fint way into names
     17 while start >= 0 && line[start - 1] =~ '\k'
     18 	let start -= 1
     19 endwhile
     20 let b:compl_context = getline('.')[0:compl_begin]
     21 return start
     22  else
     23 " Initialize base return lists
     24 let res = []
     25 let res2 = []
     26 " a:base is very short - we need context
     27 " Shortcontext is context without a:base, useful for checking if we are
     28 " looking for objects and for what objects we are looking for
     29 let context = b:compl_context
     30 let shortcontext = substitute(context, a:base.'$', '', '')
     31 unlet! b:compl_context
     32 
     33 if exists("b:jsrange")
     34 	let file = getline(b:jsrange[0],b:jsrange[1])
     35 	unlet! b:jsrange
     36 
     37 	if len(b:js_extfiles) > 0
     38 		let file = b:js_extfiles + file
     39 	endif
     40 
     41 else
     42 	let file = getline(1, '$')
     43 endif
     44 
     45 
     46 " Completion of properties, methods, etc. {{{
     47 if shortcontext =~ '\.$'
     48 	" Complete methods and properties for objects
     49 	" DOM separate
     50 	let doms = ['style.']
     51 	" Arrays
     52 	let arrayprop = ['constructor', 'index', 'input', 'length', 'prototype']
     53 	let arraymeth = ['concat', 'join', 'pop', 'push', 'reverse', 'shift',
     54 				\ 'splice', 'sort', 'toSource', 'toString', 'unshift', 'valueOf',
     55 				\ 'watch', 'unwatch']
     56 	call map(arraymeth, 'v:val."("')
     57 	let arrays = arrayprop + arraymeth
     58 
     59 	" Boolean - complete subset of array values
     60 	" properties - constructor, prototype
     61 	" methods    - toSource, toString, valueOf
     62 
     63 	" Date
     64 	" properties - constructor, prototype
     65 	let datemeth = ['getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds',
     66 				\ 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset',
     67 				\ 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds',
     68 				\ 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds',
     69 				\ 'getYear', 'parse', 'parse',
     70 				\ 'setDate', 'setDay', 'setFullYear', 'setHours', 'setMilliseconds',
     71 				\ 'setMinutes', 'setMonth', 'setSeconds',
     72 				\ 'setUTCDate', 'setUTCDay', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds',
     73 				\ 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'setTime',
     74 				\ 'toGMTString', 'toLocaleString', 'toLocaleDateString', 'toLocaleTimeString',
     75 				\ 'toSource', 'toString', 'toUTCString', 'UTC', 'valueOf', 'watch', 'unwatch']
     76 	call map(datemeth, 'v:val."("')
     77 	let dates = datemeth
     78 
     79 	" Function
     80 	let funcprop = ['arguments', 'arguments.callee', 'arguments.caller', 'arguments.length',
     81 				\ 'arity', 'constructor', 'length', 'prototype']
     82 	let funcmeth = ['apply', 'call', 'toSource', 'toString', 'valueOf']
     83 	call map(funcmeth, 'v:val."("')
     84 	let funcs = funcprop + funcmeth
     85 
     86 	" Math
     87 	let mathprop = ['E', 'LN2', 'LN10', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT']
     88 	let mathmeth = ['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor',
     89 				\ 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan',
     90 				\ 'watch', 'unwatch']
     91 	call map(mathmeth, 'v:val."("')
     92 	let maths = mathprop + mathmeth
     93 
     94 	" Number
     95 	let numbprop = ['MAX_VALUE', 'MIN_VALUE', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY', 
     96 				\ 'constructor', 'prototype']
     97 	let numbmeth = ['toExponential', 'toFixed', 'toPrecision', 'toSource', 'toString', 'valueOf',
     98 				\ 'watch', 'unwatch']
     99 	call map(numbmeth, 'v:val."("')
    100 	let numbs = numbprop + numbmeth
    101 
    102 	" Object
    103 	let objeprop = ['constructor', 'prototype']
    104 	let objemeth = ['eval', 'toSource', 'toString', 'unwatch', 'watch', 'valueOf']
    105 	call map(objemeth, 'v:val."("')
    106 	let objes = objeprop + objemeth
    107 
    108 	" RegExp
    109 	let regeprop = ['constructor', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'prototype']
    110 	let regemeth = ['exec', 'test', 'toSource', 'toString', 'watch', 'unwatch']
    111 	call map(regemeth, 'v:val."("')
    112 	let reges = regeprop + regemeth
    113 
    114 	" String
    115 	let striprop = ['constructor', 'length', 'prototype']
    116 	let strimeth = ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat',
    117 				\ 'fixed', 'fontcolor', 'fontsize', 'fromCharCode', 'indexOf', 'italics',
    118 				\ 'lastIndexOf', 'link', 'match', 'replace', 'search', 'slice', 'small',
    119 				\ 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLowerCase',
    120 				\ 'toSource', 'toString', 'toUpperCase', 'watch', 'unwatch']
    121 	call map(strimeth, 'v:val."("')
    122 	let stris = striprop + strimeth
    123 
    124 	" User created properties
    125 	let user_props1 = filter(copy(file), 'v:val =~ "this\\.\\k"')
    126 	let juser_props1 = join(user_props1, ' ')
    127 	let user_props1 = split(juser_props1, '\zethis\.')
    128 	unlet! juser_props1
    129 	call map(user_props1, 'matchstr(v:val, "this\\.\\zs\\k\\+\\ze")')
    130 
    131 	let user_props2 = filter(copy(file), 'v:val =~ "\\.prototype\\.\\k"')
    132 	let juser_props2 = join(user_props2, ' ')
    133 	let user_props2 = split(juser_props2, '\zeprototype\.')
    134 	unlet! juser_props2
    135 	call map(user_props2, 'matchstr(v:val, "prototype\\.\\zs\\k\\+\\ze")')
    136 	let user_props = user_props1 + user_props2
    137 
    138 	" HTML DOM properties
    139 	" Anchors - anchor.
    140 	let anchprop = ['accessKey', 'charset', 'coords', 'href', 'hreflang', 'id', 'innerHTML',
    141 				\ 'name', 'rel', 'rev', 'shape', 'tabIndex', 'target', 'type', 'onBlur', 'onFocus']
    142 	let anchmeth = ['blur', 'focus']
    143 	call map(anchmeth, 'v:val."("')
    144 	let anths = anchprop + anchmeth
    145 	" Area - area.
    146 	let areaprop = ['accessKey', 'alt', 'coords', 'hash', 'host', 'hostname', 'href', 'id',
    147 				\ 'noHref', 'pathname', 'port', 'protocol', 'search', 'shape', 'tabIndex', 'target']
    148 	let areameth = ['onClick', 'onDblClick', 'onMouseOut', 'onMouseOver']
    149 	call map(areameth, 'v:val."("')
    150 	let areas = areaprop + areameth
    151 	" Base - base.
    152 	let baseprop = ['href', 'id', 'target']
    153 	let bases = baseprop
    154 	" Body - body.
    155 	let bodyprop = ['aLink', 'background', 'gbColor', 'id', 'link', 'scrollLeft', 'scrollTop',
    156 				\ 'text', 'vLink']
    157 	let bodys = bodyprop
    158 	" Document - document.
    159 	let docuprop = ['anchors', 'applets', 'body', 'characterSet', 'childNodes',
    160 				\ 'doctype', 'documentElement', 'documentURI', 'embeds', 'fonts', 'forms',
    161 				\ 'head', 'hidden', 'images', 'implementation', 'lastStyleSheetSet',
    162 				\ 'links', 'plugins', 'preferredStyleSheetSet', 'scripts',
    163 				\ 'scrollingElement', 'selectedStyleSheetSet', 'styleSheetSets',
    164 				\ 'timeline', 'visibilityState', 'cookie', 'defaultView',
    165 				\ 'designMode', 'dir', 'domain', 'lastModified', 'location',
    166 				\ 'readyState', 'referrer', 'title', 'URL', 'activeElement',
    167 				\ 'fullscreenElement', 'styleSheets']
    168 	let documeth = ['adoptNode', 'close', 'createAttribute',
    169 				\ 'createAttributeNS', 'createCDATASection', 'createComment',
    170 				\ 'createDocumentFragment', 'createElement', 'createElementNS',
    171 				\ 'createEvent', 'createExpression', 'createNSResolver',
    172 				\ 'createNodeIterator', 'createProcessingInstruction', 'createRange',
    173 				\ 'createTextNode', 'createTouchList', 'createTreeWalker',
    174 				\ 'enableStyleSheetsForSet', 'evaluate', 'focus', 
    175 				\ 'getElementById', 'getElementsByClassName', 'getElementsByName',
    176 				\ 'getElementsByTagName', 'getElementsByTagNameNS',
    177 				\ 'hasStorageAccess', 'importNode', 'onClick', 'onDblClick',
    178 				\ 'onFocus', 'onKeyDown', 'onKeyPress', 'onKeyUp', 'onMouseDown',
    179 				\ 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp',
    180 				\ 'onResize', 'open', 'querySelector', 'querySelectorAll',
    181 				\ 'requestStorageAccess', 'write', 'writeln']
    182 
    183 	call map(documeth, 'v:val."("')
    184 	let docuxprop = ['attributes', 'childNodes', 'doctype', 'documentElement', 'firstChild',
    185 				\ 'implementation', 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType',
    186 				\ 'nodeValue', 'ownerDocument', 'parentNode', 'previousSibling']
    187 	let docuxmeth = ['createAttribute', 'createCDATASection',
    188 				\ 'createComment', 'createDocument', 'createDocumentFragment',
    189 				\ 'createElement', 'createEntityReference', 'createProcessingInstruction',
    190 				\ 'createTextNode']
    191 	call map(docuxmeth, 'v:val."("')
    192 	let docus = docuprop + docuxprop + documeth + docuxmeth
    193 	" Form - form.
    194 	let formprop = ['elements', 'acceptCharset', 'action', 'encoding', 'enctype', 'id', 'length',
    195 				\ 'method', 'name', 'tabIndex', 'target']
    196 	let formmeth = ['reset', 'submit', 'onReset', 'onSubmit']
    197 	call map(formmeth, 'v:val."("')
    198 	let forms = formprop + formmeth
    199 	" Frame - frame.
    200 	let framprop = ['contentDocument', 'frameBorder', 'id', 'longDesc', 'marginHeight', 'marginWidth',
    201 				\ 'name', 'noResize', 'scrolling', 'src']
    202 	let frammeth = ['blur', 'focus']
    203 	call map(frammeth, 'v:val."("')
    204 	let frams = framprop + frammeth
    205 	" Frameset - frameset.
    206 	let fsetprop = ['cols', 'id', 'rows']
    207 	let fsetmeth = ['blur', 'focus']
    208 	call map(fsetmeth, 'v:val."("')
    209 	let fsets = fsetprop + fsetmeth
    210 	" History - history.
    211 	let histprop = ['length']
    212 	let histmeth = ['back', 'forward', 'go']
    213 	call map(histmeth, 'v:val."("')
    214 	let hists = histprop + histmeth
    215 	" Iframe - iframe.
    216 	let ifraprop = ['align', 'frameBorder', 'height', 'id', 'longDesc', 'marginHeight', 'marginWidth',
    217 				\ 'name', 'scrolling', 'src', 'width']
    218 	let ifras = ifraprop
    219 	" Image - image.
    220 	let imagprop = ['align', 'alt', 'border', 'complete', 'height', 'hspace', 'id', 'isMap', 'longDesc',
    221 				\ 'lowSrc', 'name', 'src', 'useMap', 'vspace', 'width']
    222 	let imagmeth = ['onAbort', 'onError', 'onLoad']
    223 	call map(imagmeth, 'v:val."("')
    224 	let imags = histprop + imagmeth
    225 	" Button - accessible only by other properties
    226 	let buttprop = ['accessKey', 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value']
    227 	let buttmeth = ['blur', 'click', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
    228 	call map(buttmeth, 'v:val."("')
    229 	let butts = buttprop + buttmeth
    230 	" Checkbox - accessible only by other properties
    231 	let checprop = ['accept', 'accessKey', 'align', 'alt', 'checked', 'defaultChecked', 
    232 				\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value'] 
    233 	let checmeth = ['blur', 'click', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
    234 	call map(checmeth, 'v:val."("')
    235 	let checs = checprop + checmeth
    236 	" File upload - accessible only by other properties
    237 	let fileprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue', 
    238 				\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value'] 
    239 	let filemeth = ['blur', 'focus', 'onBlur', 'onClick', 'onFocus', 'onMouseDown', 'onMouseUp']
    240 	call map(filemeth, 'v:val."("')
    241 	let files = fileprop + filemeth
    242 	" Hidden - accessible only by other properties
    243 	let hiddprop = ['defaultValue', 'form', 'id', 'name', 'type', 'value'] 
    244 	let hidds = hiddprop
    245 	" Password - accessible only by other properties
    246 	let passprop = ['accept', 'accessKey', 'defaultValue', 
    247 				\ 'disabled', 'form', 'id', 'maxLength', 'name', 'readOnly', 'size', 'tabIndex', 
    248 				\ 'type', 'value'] 
    249 	let passmeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus', 'onKeyDown', 
    250 				\ 'onKeyPress', 'onKeyUp']
    251 	call map(passmeth, 'v:val."("')
    252 	let passs = passprop + passmeth
    253 	" Radio - accessible only by other properties
    254 	let radiprop = ['accept', 'accessKey', 'align', 'alt', 'checked', 'defaultChecked', 
    255 				\ 'disabled', 'form', 'id', 'name', 'tabIndex', 'type', 'value'] 
    256 	let radimeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus']
    257 	call map(radimeth, 'v:val."("')
    258 	let radis = radiprop + radimeth
    259 	" Reset - accessible only by other properties
    260 	let reseprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue', 
    261 				\ 'disabled', 'form', 'id', 'name', 'size', 'tabIndex', 'type', 'value'] 
    262 	let resemeth = ['blur', 'click', 'focus', 'select', 'onBlur', 'onFocus']
    263 	call map(resemeth, 'v:val."("')
    264 	let reses = reseprop + resemeth
    265 	" Submit - accessible only by other properties
    266 	let submprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue', 
    267 				\ 'disabled', 'form', 'id', 'name', 'size', 'tabIndex', 'type', 'value'] 
    268 	let submmeth = ['blur', 'click', 'focus', 'select', 'onClick', 'onSelectStart']
    269 	call map(submmeth, 'v:val."("')
    270 	let subms = submprop + submmeth
    271 	" Text - accessible only by other properties
    272 	let textprop = ['accept', 'accessKey', 'align', 'alt', 'defaultValue', 
    273 				\ 'disabled', 'form', 'id', 'maxLength', 'name', 'readOnly', 
    274 				\ 'size', 'tabIndex', 'type', 'value'] 
    275 	let textmeth = ['blur', 'focus', 'select', 'onBlur', 'onChange', 'onFocus', 'onKeyDown',
    276 				\ 'onKeyPress', 'onKeyUp', 'onSelect']
    277 	call map(textmeth, 'v:val."("')
    278 	let texts = textprop + textmeth
    279 	" Link - link.
    280 	let linkprop = ['charset', 'disabled', 'href', 'hreflang', 'id', 'media',
    281 				\ 'rel', 'rev', 'target', 'type']
    282 	let linkmeth = ['onLoad']
    283 	call map(linkmeth, 'v:val."("')
    284 	let links = linkprop + linkmeth
    285 	" Location - location.
    286 	let locaprop = ['href', 'hash', 'host', 'hostname', 'pathname', 'port', 'protocol',
    287 				\ 'search']
    288 	let locameth = ['assign', 'reload', 'replace']
    289 	call map(locameth, 'v:val."("')
    290 	let locas = locaprop + locameth
    291 	" Meta - meta.
    292 	let metaprop = ['charset', 'content', 'disabled', 'httpEquiv', 'name', 'scheme']
    293 	let metas = metaprop
    294 	" Navigator - navigator.
    295 	let naviprop = ['plugins', 'appCodeName', 'appName', 'appVersion', 'cookieEnabled',
    296 				\ 'platform', 'userAgent']
    297 	let navimeth = ['javaEnabled', 'taintEnabled']
    298 	call map(navimeth, 'v:val."("')
    299 	let navis = naviprop + navimeth
    300 	" Object - object.
    301 	let objeprop = ['align', 'archive', 'border', 'code', 'codeBase', 'codeType', 'data',
    302 				\ 'declare', 'form', 'height', 'hspace', 'id', 'name', 'standby', 'tabIndex',
    303 				\ 'type', 'useMap', 'vspace', 'width']
    304 	let objes = objeprop
    305 	" Option - accessible only by other properties
    306 	let optiprop = ['defaultSelected', 
    307 				\ 'disabled', 'form', 'id', 'index', 'label', 'selected', 'text', 'value']
    308 	let optis = optiprop
    309 	" Screen - screen.
    310 	let screprop = ['availHeight', 'availWidth', 'colorDepth', 'height', 'width']
    311 	let scres = screprop
    312 	" Select - accessible only by other properties
    313 	let seleprop = ['options', 'disabled', 'form', 'id', 'length', 'multiple', 'name', 
    314 				\ 'selectedIndex', 'size', 'tabIndex', 'type', 'value'] 
    315 	let selemeth = ['blur', 'focus', 'remove', 'onBlur', 'onChange', 'onFocus']
    316 	call map(selemeth, 'v:val."("')
    317 	let seles = seleprop + selemeth
    318 	" Style - style.
    319 	let stylprop = ['background', 'backgroundAttachment', 'backgroundColor', 'backgroundImage',
    320 				\ 'backgroundPosition', 'backgroundRepeat',
    321 				\ 'border', 'borderBottom', 'borderLeft', 'borderRight', 'borderTop',
    322 				\ 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor',
    323 				\ 'borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle',
    324 				\ 'borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth',
    325 				\ 'borderColor', 'borderStyle', 'borderWidth', 'margin', 'marginBottom',
    326 				\ 'marginLeft', 'marginRight', 'marginTop', 'outline', 'outlineStyle', 'outlineWidth',
    327 				\ 'outlineColor', 'outlineStyle', 'outlineWidth', 'padding', 'paddingBottom',
    328 				\ 'paddingLeft', 'paddingRight', 'paddingTop',
    329 				\ 'clear', 'clip', 'clipBottom', 'clipLeft', 'clipRight', 'clipTop', 'content',
    330 				\ 'counterIncrement', 'counterReset', 'cssFloat', 'cursor', 'direction',
    331 				\ 'display', 'markerOffset', 'marks', 'maxHeight', 'maxWidth', 'minHeight',
    332 				\ 'minWidth', 'overflow', 'overflowX', 'overflowY', 'verticalAlign', 'visibility',
    333 				\ 'width',
    334 				\ 'listStyle', 'listStyleImage', 'listStylePosition', 'listStyleType',
    335 				\ 'cssText', 'bottom', 'height', 'left', 'position', 'right', 'top', 'width', 'zindex',
    336 				\ 'orphans', 'widows', 'page', 'pageBreakAfter', 'pageBreakBefore', 'pageBreakInside',
    337 				\ 'borderCollapse', 'borderSpacing', 'captionSide', 'emptyCells', 'tableLayout',
    338 				\ 'color', 'font', 'fontFamily', 'fontSize', 'fontSizeAdjust', 'fontStretch',
    339 				\ 'fontStyle', 'fontVariant', 'fontWeight', 'letterSpacing', 'lineHeight', 'quotes',
    340 				\ 'textAlign', 'textIndent', 'textShadow', 'textTransform', 'textUnderlinePosition',
    341 				\ 'unicodeBidi', 'whiteSpace', 'wordSpacing']
    342 	let styls = stylprop
    343 	" Table - table.
    344 	let tablprop = ['rows', 'tBodies', 'align', 'bgColor', 'border', 'caption', 'cellPadding',
    345 				\ 'cellSpacing', 'frame', 'height', 'rules', 'summary', 'tFoot', 'tHead', 'width']
    346 	let tablmeth = ['createCaption', 'createTFoot', 'createTHead', 'deleteCaption', 'deleteRow',
    347 				\ 'deleteTFoot', 'deleteTHead', 'insertRow']
    348 	call map(tablmeth, 'v:val."("')
    349 	let tabls = tablprop + tablmeth
    350 	" Table data - TableData.
    351 	let tdatprop = ['abbr', 'align', 'axis', 'bgColor', 'cellIndex', 'ch', 'chOff',
    352 				\ 'colSpan', 'headers', 'noWrap', 'rowSpan', 'scope', 'vAlign', 'width']
    353 	let tdats = tdatprop
    354 	" Table row - TableRow.
    355 	let trowprop = ['cells', 'align', 'bgColor', 'ch', 'chOff', 'rowIndex', 'sectionRowIndex',
    356 				\ 'vAlign']
    357 	let trowmeth = ['deleteCell', 'insertCell']
    358 	call map(trowmeth, 'v:val."("')
    359 	let trows = trowprop + trowmeth
    360 	" Textarea - accessible only by other properties
    361 	let tareprop = ['accessKey', 'cols', 'defaultValue', 
    362 				\ 'disabled', 'form', 'id', 'name', 'readOnly', 'rows', 
    363 				\ 'tabIndex', 'type', 'value', 'selectionStart', 'selectionEnd'] 
    364 	let taremeth = ['blur', 'focus', 'select', 'onBlur', 'onChange', 'onFocus']
    365 	call map(taremeth, 'v:val."("')
    366 	let tares = tareprop + taremeth
    367 	" Window - window.
    368 	let windprop = ['frames', 'closed', 'defaultStatus', 'encodeURI', 'event', 'history',
    369 				\ 'length', 'location', 'name', 'onload', 'opener', 'parent', 'screen', 'self',
    370 				\ 'status', 'top', 'XMLHttpRequest', 'ActiveXObject']
    371 	let windmeth = ['alert', 'blur', 'clearInterval', 'clearTimeout', 'close', 'confirm', 'focus',
    372 				\ 'moveBy', 'moveTo', 'open', 'print', 'prompt', 'scrollBy', 'scrollTo', 'setInterval',
    373 				\ 'setTimeout']
    374 	call map(windmeth, 'v:val."("')
    375 	let winds = windprop + windmeth
    376 	" XMLHttpRequest - access by new xxx()
    377 	let xmlhprop = ['onreadystatechange', 'readyState', 'responseText', 'responseXML',
    378 				\ 'status', 'statusText', 'parseError']
    379 	let xmlhmeth = ['abort', 'getAllResponseHeaders', 'getResponseHeaders', 'open',
    380 				\ 'send', 'setRequestHeader']
    381 	call map(xmlhmeth, 'v:val."("')
    382 	let xmlhs = xmlhprop + xmlhmeth
    383 
    384 	" XML DOM
    385 	" Attributes - element.attributes[x].
    386 	let xdomattrprop = ['name', 'specified', 'value']
    387 	" Element - anyelement.
    388 	let xdomelemprop = ['attributes', 'childNodes', 'firstChild', 'lastChild', 
    389 				\ 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue',
    390 				\ 'ownerDocument', 'parentNode', 'prefix', 'previousSibling', 'tagName']
    391 	let xdomelemmeth = ['appendChild', 'addEventListener', 'cloneNode',
    392 				\ 'dispatchEvent', 'getAttribute', 'getAttributeNode',
    393 				\ 'getElementsByTagName', 'hasChildNodes', 'insertBefore',
    394 				\ 'normalize', 'removeAttribute', 'removeAttributeNode',
    395 				\ 'removeChild', 'removeEventListener', 'replaceChild',
    396 				\ 'setAttribute', 'setAttributeNode']
    397 	call map(xdomelemmeth, 'v:val."("')
    398 	let xdomelems = xdomelemprop + xdomelemmeth
    399 	" Node - anynode.
    400 	let xdomnodeprop = ['attributes', 'childNodes', 'firstChild', 'lastChild', 
    401 				\ 'namespaceURI', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue',
    402 				\ 'ownerDocument', 'parentNode', 'prefix', 'previousSibling']
    403 	let xdomnodemeth = ['appendChild', 'cloneNode',
    404 				\ 'hasChildNodes', 'insertBefore', 'removeChild', 'replaceChild']
    405 	call map(xdomnodemeth, 'v:val."("')
    406 	let xdomnodes = xdomnodeprop + xdomnodemeth
    407 	" NodeList 
    408 	let xdomnliss = ['length', 'item(']
    409 	" Error - parseError.
    410 	let xdomerror = ['errorCode', 'reason', 'line', 'linepos', 'srcText', 'url', 'filepos']
    411 
    412 	" Find object type declaration to reduce number of suggestions. {{{
    413 	" 1. Get object name
    414 	" 2. Find object declaration line
    415 	" 3. General declaration follows "= new Type" syntax, additional else
    416 	"    for regexp "= /re/"
    417 	" 4. Make correction for Microsoft.XMLHTTP ActiveXObject
    418 	" 5. Repeat for external files
    419 	let object = matchstr(shortcontext, '\zs\k\+\ze\(\[.\{-}\]\)\?\.$')
    420 	if len(object) > 0
    421 		let decl_line = search(object.'.\{-}=\s*new\s*', 'bn')
    422 		if decl_line > 0
    423 			let object_type = matchstr(getline(decl_line), object.'.\{-}=\s*new\s*\zs\k\+\ze')
    424 			if object_type == 'ActiveXObject' && matchstr(getline(decl_line), object.'.\{-}=\s*new\s*ActiveXObject\s*(.Microsoft\.XMLHTTP.)') != ''
    425 					let object_type = 'XMLHttpRequest'
    426 			endif
    427 		else
    428 			let decl_line = search('var\s*'.object.'\s*=\s*\/', 'bn')
    429 			if decl_line > 0
    430 				let object_type = 'RegExp'
    431 			endif
    432 		endif
    433 		" We didn't find var declaration in current file but we may have
    434 		" something in external files.
    435 		if decl_line == 0 && exists("b:js_extfiles")
    436 			let dext_line = filter(copy(b:js_extfiles), 'v:val =~ "'.object.'.\\{-}=\\s*new\\s*"')
    437 			if len(dext_line) > 0
    438 				let object_type = matchstr(dext_line[-1], object.'.\{-}=\s*new\s*\zs\k\+\ze')
    439 				if object_type == 'ActiveXObject' && matchstr(dext_line[-1], object.'.\{-}=\s*new\s*ActiveXObject\s*(.Microsoft\.XMLHTTP.)') != ''
    440 						let object_type = 'XMLHttpRequest'
    441 				endif
    442 			else
    443 				let dext_line = filter(copy(b:js_extfiles), 'v:val =~ "var\s*'.object.'\\s*=\\s*\\/"')
    444 				if len(dext_line) > 0
    445 					let object_type = 'RegExp'
    446 				endif
    447 			endif
    448 		endif
    449 	endif
    450 	" }}}
    451 
    452 	if !exists('object_type')
    453 		let object_type = ''
    454 	endif
    455 
    456 	if object_type == 'Date'
    457 		let values = dates
    458 	elseif object_type == 'Image'
    459 		let values = imags
    460 	elseif object_type == 'Array'
    461 		let values = arrays
    462 	elseif object_type == 'Boolean'
    463 		" TODO: a bit more than real boolean
    464 		let values = arrays
    465 	elseif object_type == 'XMLHttpRequest'
    466 		let values = xmlhs
    467 	elseif object_type == 'String'
    468 		let values = stris
    469 	elseif object_type == 'RegExp'
    470 		let values = reges
    471 	elseif object_type == 'Math'
    472 		let values = maths
    473 	endif
    474 
    475 	if !exists('values')
    476 	" List of properties
    477 	if shortcontext =~ 'Math\.$'
    478 		let values = maths
    479 	elseif shortcontext =~ 'anchors\(\[.\{-}\]\)\?\.$'
    480 		let values = anths
    481 	elseif shortcontext =~ 'area\.$'
    482 		let values = areas
    483 	elseif shortcontext =~ 'base\.$'
    484 		let values = bases
    485 	elseif shortcontext =~ 'body\.$'
    486 		let values = bodys
    487 	elseif shortcontext =~ 'document\.$'
    488 		let values = docus
    489 	elseif shortcontext =~ 'forms\(\[.\{-}\]\)\?\.$'
    490 		let values = forms
    491 	elseif shortcontext =~ 'frameset\.$'
    492 		let values = fsets
    493 	elseif shortcontext =~ 'history\.$'
    494 		let values = hists
    495 	elseif shortcontext =~ 'iframe\.$'
    496 		let values = ifras
    497 	elseif shortcontext =~ 'images\(\[.\{-}\]\)\?\.$'
    498 		let values = imags
    499 	elseif shortcontext =~ 'links\(\[.\{-}\]\)\?\.$'
    500 		let values = links
    501 	elseif shortcontext =~ 'location\.$'
    502 		let values = locas
    503 	elseif shortcontext =~ 'meta\.$'
    504 		let values = metas
    505 	elseif shortcontext =~ 'navigator\.$'
    506 		let values = navis
    507 	elseif shortcontext =~ 'object\.$'
    508 		let values = objes
    509 	elseif shortcontext =~ 'screen\.$'
    510 		let values = scres
    511 	elseif shortcontext =~ 'style\.$'
    512 		let values = styls
    513 	elseif shortcontext =~ 'table\.$'
    514 		let values = tabls
    515 	elseif shortcontext =~ 'TableData\.$'
    516 		let values = tdats
    517 	elseif shortcontext =~ 'TableRow\.$'
    518 		let values = trows
    519 	elseif shortcontext =~ 'window\.$'
    520 		let values = winds
    521 	elseif shortcontext =~ 'parseError\.$'
    522 		let values = xdomerror
    523 	elseif shortcontext =~ 'attributes\[\d\+\]\.$'
    524 		let values = xdomattrprop
    525 	else
    526 		let values = user_props + arrays + dates + funcs + maths + numbs + objes + reges + stris
    527 		let values += doms + anths + areas + bases + bodys + docus + forms + frams + fsets + hists
    528 		let values += ifras + imags + links + locas + metas + navis + objes + scres
    529 		let values += tabls + trows + tares + winds
    530 		let values += xdomnodes + xdomnliss + xdomelems
    531 	endif
    532 	endif
    533 
    534 	for m in values
    535 		if m =~? '^'.a:base
    536 			call add(res, m)
    537 		elseif m =~? a:base
    538 			call add(res2, m)
    539 		endif
    540 	endfor
    541 
    542 	unlet! values
    543 	return res + res2
    544 
    545 endif
    546 " }}}
    547 
    548 " Get variables data.
    549 let variables = filter(copy(file), 'v:val =~ "var\\s"')
    550 call map(variables, 'matchstr(v:val, ".\\{-}var\\s\\+\\zs.*\\ze")')
    551 call map(variables, 'substitute(v:val, ";\\|$", ",", "g")')
    552 let vars = []
    553 " This loop (and next one) is necessary to get variable names from
    554 " constructs like: var var1, var2, var3 = "something";
    555 for i in range(len(variables))
    556 	let comma_separated = split(variables[i], ',\s*')
    557 	call map(comma_separated, 'matchstr(v:val, "\\k\\+")')
    558 	let vars += comma_separated
    559 endfor
    560 
    561 let variables = sort(vars)
    562 unlet! vars
    563 
    564 " Add "no var" variables.
    565 let undeclared_variables = filter(copy(file), 'v:val =~ "^\\s*\\k\\+\\s*="')
    566 let u_vars = []
    567 for i in range(len(undeclared_variables))
    568 	let  split_equal = split(undeclared_variables[i], '\s*=')
    569 	call map(split_equal, 'matchstr(v:val, "\\k\\+$")')
    570 	let u_vars += split_equal
    571 endfor
    572 
    573 let variables += sort(u_vars)
    574 unlet! u_vars
    575 
    576 " Get functions
    577 let functions = filter(copy(file), 'v:val =~ "^\\s*function\\s"')
    578 let arguments = copy(functions)
    579 call map(functions, 'matchstr(v:val, "^\\s*function\\s\\+\\zs\\k\\+")')
    580 call map(functions, 'v:val."("')
    581 let functions = sort(functions)
    582 
    583 " Create table to keep arguments for additional 'menu' info
    584 let b:js_menuinfo = {}
    585 for i in arguments
    586 	let g:ia = i
    587 	let f_elements = matchlist(i, 'function\s\+\(\k\+\)\s*(\(.\{-}\))')
    588 	if len(f_elements) >= 3
    589 		let b:js_menuinfo[f_elements[1].'('] = f_elements[2]
    590 	endif
    591 endfor
    592 
    593 " Get functions arguments
    594 call map(arguments, 'matchstr(v:val, "function.\\{-}(\\zs.\\{-}\\ze)")')
    595 let jargs = join(arguments, ',')
    596 let jargs = substitute(jargs, '\s', '', 'g')
    597 let arguments = split(jargs, ',')
    598 let arguments = sort(arguments)
    599 
    600 " Built-in functions
    601 let builtin = ['alert(', 'confirm(']
    602 
    603 " Top-level HTML DOM objects
    604 let htmldom = ['document', 'anchor', 'area', 'base', 'body', 'document', 'event', 'form', 'frame', 'frameset', 'history', 'iframe', 'image', 'input', 'link', 'location', 'meta', 'navigator', 'object', 'option', 'screen', 'select', 'table', 'tableData', 'tableHeader', 'tableRow', 'textarea', 'window']
    605 call map(htmldom, 'v:val."."')
    606 
    607 " Top-level properties
    608 let properties = ['decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent',
    609 			\ 'eval', 'Infinity', 'isFinite', 'isNaN', 'NaN', 'Number', 'parseFloat',
    610 			\ 'parseInt', 'String', 'undefined', 'escape', 'unescape']
    611 
    612 " Keywords
    613 let keywords = ["Array", "Boolean", "Date", "Function", "Math", "Number", "Object", "RegExp", "String", "XMLHttpRequest", "ActiveXObject", "abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double ", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in ", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super ", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with"]
    614 
    615 let values = variables + functions + htmldom + arguments + builtin + properties + keywords
    616 
    617 for m in values
    618 	if m =~? '^'.a:base
    619 		call add(res, m)
    620 	elseif m =~? a:base
    621 		call add(res2, m)
    622 	endif
    623 endfor
    624 
    625 let menu = res + res2
    626 let final_menu = []
    627 for i in range(len(menu))
    628 	let item = menu[i]
    629 	if item =~ '($'
    630 		let kind = 'f'
    631 		if has_key(b:js_menuinfo, item)
    632 			let m_info = b:js_menuinfo[item]
    633 		else
    634 			let m_info = ''
    635 		endif
    636 	else
    637 		let kind = 'v'
    638 		let m_info = ''
    639 	endif
    640 	let final_menu += [{'word':item, 'menu':m_info, 'kind':kind}]
    641 endfor
    642 let g:fm = final_menu
    643 return final_menu
    644 
    645 endfunction
    646 
    647 " vim:set foldmethod=marker: