"============================================================================= " File : autoload/unite/sources/outline/defaults/javascript.vim " Author : h1mesuke " Updated : 2012-01-11 " " Contributed by hamaco " " Licensed under the MIT license: " http://www.opensource.org/licenses/mit-license.php " "============================================================================= " Default outline info for JavaScript " Version: 0.1.1 " TODO: Use jsctags for much better heading list! function! unite#sources#outline#defaults#javascript#outline_info() abort return s:outline_info endfunction let s:Util = unite#sources#outline#import('Util') "--------------------------------------- " Sub Patterns let s:pat_indent = '\<\h\w*\>' let s:pat_assign = '\%(\%(var\|let\|const\)\s\+\)\=\(' . s:pat_indent . '\%(\.' . s:pat_indent . '\)*\)\s*=' " NOTE: This sub pattern contains 1 capture; 1:lvalue let s:pat_label = '\(' . s:pat_indent . '\)\s*:' " NOTE: This sub pattern contains 1 capture; 1:label let s:pat_rvalue = '\(function\s*(\([^)]*\))\|(\(.*\))\s*{\|\s*{\|\(\w\+\)\s*(\(.*\))\s*{\)' " NOTE: This sub pattern contains 2 captures; 1:rvalue [, 2:arg_list] let s:pat_def = '\%(\%(export\s\+\%(default\s\+\)\=\)\=function\>\)' let s:pat_es6_class = '^\s*\%(export\s\+\%(default\s\+\)\=\)\=class\s\+\(\S\+\)\s*{$' " NOTE: This sub pattern contains 1 capture; 1:className let s:pat_es6_method = '^\s*\(\%(static\s\+\)\?\w\+\)\s*(\([^)]*\))\s*{$' " NOTE: This sub pattern contains 2 capture; 1:methodName [, 2:arg_list] "----------------------------------------------------------------------------- " Outline Info let s:outline_info = { \ 'heading-1': s:Util.shared_pattern('cpp', 'heading-1'), \ 'heading' : '^\s*\%(' . s:pat_def . '\|' . \ '\%(' . \ '\%(export\s\+\%(default\s\+\)\=\)\=class\s\+\(\S\+\)\s\+\%(extends\s\+\w\+\)\?\|\s*\%(static\s\+\)\?\w\+\s*\|' . s:pat_assign . '\|' . s:pat_label . \ '\)\s*' . s:pat_rvalue . '\)', \ \ 'skip': { \ 'header': s:Util.shared_pattern('cpp', 'header'), \ }, \ \ 'not_match_patterns': [ \ s:Util.shared_pattern('*', 'parameter_list'), \ ], \} function! s:outline_info.create_heading(which, heading_line, matched_line, context) abort let h_lnum = a:context.heading_lnum " Level 1 to 3 are reserved for comment headings. let level = s:Util.get_indent_level(a:context, h_lnum) + 3 let heading = { \ 'word' : a:heading_line, \ 'level': level, \ 'type' : 'generic', \ } if a:which == 'heading-1' && s:Util._cpp_is_in_comment(a:heading_line, a:matched_line) let m_lnum = a:context.matched_lnum let heading.type = 'comment' let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum) elseif a:which ==# 'heading' let matched_list = matchlist(a:heading_line, \ '^\s*' . s:pat_def . '\s\+\(' . s:pat_indent . '\)\s*(\(.*\))') if len(matched_list) > 0 " function Foo(...) -> Foo(...) " function foo(...) -> foo(...) let [func_name, arg_list] = matched_list[1:2] let heading.word = func_name . '(' . arg_list . ')' endif let matched_list = matchlist(a:heading_line, \ '^\s*\%(' . s:pat_assign . '\|' . s:pat_label . '\)\s*' . s:pat_rvalue) if len(matched_list) > 0 let [lvalue, label, rvalue, arg_list] = matched_list[1:4] if lvalue =~ '\S' " Assign if lvalue =~ '\.' " Property let prop_chain = split(lvalue, '\.') let prop_name = prop_chain[-1] if rvalue =~ '^f' if prop_name =~ '^\u' " Foo.Bar = function(...) -> Foo.Bar(...) let heading.word = lvalue . '(' . arg_list . ')' else " Foo.bar = function(...) -> bar(...) "let heading.level += 1 let heading.word = prop_name . '(' . arg_list . ')' endif else if match(prop_chain, '^\u') >= 0 " Foo.Bar = { -> Foo.Bar " Foo.bar = { -> Foo.bar let heading.word = lvalue else " foo.bar = { let heading.level = 0 endif endif elseif lvalue =~ '^\u' " Variale if rvalue =~ '^f' " var Foo = function(...) -> Foo(...) let heading.word = lvalue . '(' . arg_list . ')' else " var Foo = { -> Foo let heading.word = lvalue endif else " var foo = ... let heading.level = 0 endif else " Label if rvalue =~ '^f' " foo: function(...) -> foo(...) let heading.word = label . '(' . arg_list . ')' else " foo: { let heading.level = 0 endif endif else let matched_list = matchlist(a:heading_line, s:pat_es6_class) if len(matched_list) > 0 let heading.level = 1 let heading.word = 'class ' . matched_list[1] else let heading.level = 2 let matched_list = matchlist(a:heading_line, s:pat_es6_method) if len(matched_list) > 0 if match(a:heading_line, '^\s*\%(for\|if\|while\|switch\)\>') != -1 let heading.level = 0 else let [func_name, arg_list] = matched_list[1:2] let heading.word = func_name . '(' . arg_list . ')' endif endif endif endif endif if heading.level > 0 return heading else return {} endif endfunction