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 8function! 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', 'body', 'characterSet', 'doctype', 160 \ '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', 'getElementById', 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 645endfunction 646 647" vim:set foldmethod=marker: 648