javascriptcomplete.vim 27 KB

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