├── .gitignore ├── README.mkd ├── autoload └── unite │ ├── filters │ ├── outline_formatter.vim │ └── outline_matcher_glob.vim │ └── sources │ ├── outline.vim │ └── outline │ ├── defaults │ ├── changelog.vim │ ├── conf.vim │ ├── cpp.vim │ ├── css.vim │ ├── dosini.vim │ ├── help.vim │ ├── html.vim │ ├── java.vim │ ├── javascript.vim │ ├── markdown.vim │ ├── perl.vim │ ├── php.vim │ ├── pir.vim │ ├── python.vim │ ├── review.vim │ ├── rst.vim │ ├── ruby.vim │ ├── ruby │ │ └── rspec.vim │ ├── scala.vim │ ├── scheme.vim │ ├── sh.vim │ ├── tex.vim │ ├── textile.vim │ ├── unittest.vim │ └── vim.vim │ ├── misc │ └── wzmemo_text.vim │ ├── modules │ ├── base.vim │ ├── ctags.vim │ ├── file_cache.vim │ ├── tree.vim │ └── util.vim │ └── util.vim └── doc ├── .gitignore ├── unite-outline.jax └── unite-outline.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /README.mkd: -------------------------------------------------------------------------------- 1 | # unite-outline 2 | 3 | ## Introduction 4 | 5 | unite-outline is a [unite.vim](https://github.com/Shougo/unite.vim)'s source 6 | which provides your Vim's buffer with the outline view. It parses the current 7 | buffer's content and extracts headings from the buffer. And then it shows the 8 | list of the headings using unite.vim's interface. When you select a heading 9 | from the list, you can jump to the corresponding location in the buffer. 10 | 11 | The methods for extracting headings can be implemented for each individual 12 | filetypes. You can customize them as you like with Vim script and can also 13 | create new ones for unsupported filetypes. 14 | 15 | ## Install 16 | 17 | Install the distributed files into your Vim script directory which is usually 18 | $HOME/.vim, or $HOME/vimfiles on Windows. 19 | 20 | You can show the heading list of the current buffer with ":Unite outline" 21 | command if you succeeded the installation (and unite-outline supports the 22 | filetype of the buffer). 23 | 24 | ## Usage 25 | 26 | To show the heading list of the current buffer, execute |:Unite| command with 27 | "outline" as a source parameter. 28 | 29 | :Unite outline 30 | 31 | unite-outline parses the current buffer's content and extracts headings from 32 | the buffer. And then it shows the list of the headings with unite.vim's 33 | interface. When you select a heading from the list, you can jump to the 34 | corresponding location of the buffer. 35 | 36 | See :help unite-outline for more details. 37 | 38 | ## Screenshots 39 | 40 | See [unite-outline's wiki](https://github.com/h1mesuke/unite-outline/wiki). 41 | 42 | -------------------------------------------------------------------------------- /autoload/unite/filters/outline_formatter.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/filters/outline_formatter.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " Version : 0.5.1 6 | " License : MIT license {{{ 7 | " 8 | " Permission is hereby granted, free of charge, to any person obtaining 9 | " a copy of this software and associated documentation files (the 10 | " "Software"), to deal in the Software without restriction, including 11 | " without limitation the rights to use, copy, modify, merge, publish, 12 | " distribute, sublicense, and/or sell copies of the Software, and to 13 | " permit persons to whom the Software is furnished to do so, subject to 14 | " the following conditions: 15 | " 16 | " The above copyright notice and this permission notice shall be included 17 | " in all copies or substantial portions of the Software. 18 | " 19 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | " }}} 27 | "============================================================================= 28 | 29 | let s:save_cpo = &cpo 30 | set cpo&vim 31 | 32 | function! unite#filters#outline_formatter#define() 33 | return s:formatter 34 | endfunction 35 | 36 | let s:Util = unite#sources#outline#import('Util') 37 | 38 | let s:BLANK = { 39 | \ 'word': '', 40 | \ 'source': 'outline', 41 | \ 'kind' : 'common', 42 | \ 'is_dummy': 1, 43 | \ } 44 | 45 | let s:formatter = { 46 | \ 'name' : 'outline_formatter', 47 | \ 'description': 'view formatter for outline tree', 48 | \ } 49 | 50 | function! s:formatter.filter(candidates, unite_context) 51 | if empty(a:candidates) | return a:candidates | endif 52 | 53 | let bufnr = a:unite_context.source__outline_source_bufnr 54 | let context = unite#sources#outline#get_outline_data(bufnr, 'context') 55 | 56 | " Insert blanks for readability. 57 | let candidates = s:insert_blanks(a:candidates, context) 58 | 59 | " Turbo Jump 60 | if len(a:candidates) < 10 61 | let matches = filter(copy(a:candidates), 'v:val.is_matched') 62 | if len(matches) == 1 " Bingo! 63 | let bingo = copy(matches[0]) 64 | if bingo != a:candidates[0] 65 | " Prepend a copy of the only one matched heading to the narrowing 66 | " results for jumping to its position with one . 67 | let bingo.abbr = substitute(bingo.abbr, '^ \=', '!', '') 68 | let candidates = [bingo, s:BLANK] + candidates 69 | endif 70 | endif 71 | endif 72 | return candidates 73 | endfunction 74 | 75 | function! s:insert_blanks(candidates, context) 76 | let oinfo = a:context.outline_info 77 | if a:context.extracted_by !=# 'filetype' || 78 | \ (empty(oinfo.heading_groups) && !has_key(oinfo, 'need_blank_between')) 79 | return a:candidates 80 | endif 81 | 82 | if !has_key(oinfo, 'need_blank_between') 83 | " Use the default implementation. 84 | let oinfo.need_blank_between = function('s:need_blank_between') 85 | endif 86 | let candidates = [] 87 | let prev_sibling = {} | let prev_level = 0 88 | let memo = {} | " for memoization 89 | for cand in a:candidates 90 | if cand.source__heading_level <= prev_level && 91 | \ oinfo.need_blank_between(prev_sibling[cand.source__heading_level], cand, memo) 92 | call add(candidates, s:BLANK) 93 | endif 94 | call add(candidates, cand) 95 | let prev_sibling[cand.source__heading_level] = cand 96 | let prev_level = cand.source__heading_level 97 | endfor 98 | return candidates 99 | endfunction 100 | 101 | function! s:need_blank_between(cand1, cand2, memo) dict 102 | return (a:cand1.source__heading_group != a:cand2.source__heading_group || 103 | \ a:cand1.source__has_marked_child || a:cand2.source__has_marked_child) 104 | endfunction 105 | 106 | let &cpo = s:save_cpo 107 | unlet s:save_cpo 108 | -------------------------------------------------------------------------------- /autoload/unite/filters/outline_matcher_glob.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/filters/outline_matcher_glob.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " Version : 0.5.1 6 | " License : MIT license {{{ 7 | " 8 | " Permission is hereby granted, free of charge, to any person obtaining 9 | " a copy of this software and associated documentation files (the 10 | " "Software"), to deal in the Software without restriction, including 11 | " without limitation the rights to use, copy, modify, merge, publish, 12 | " distribute, sublicense, and/or sell copies of the Software, and to 13 | " permit persons to whom the Software is furnished to do so, subject to 14 | " the following conditions: 15 | " 16 | " The above copyright notice and this permission notice shall be included 17 | " in all copies or substantial portions of the Software. 18 | " 19 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | " }}} 27 | "============================================================================= 28 | 29 | let s:save_cpo = &cpo 30 | set cpo&vim 31 | 32 | function! unite#filters#outline_matcher_glob#define() 33 | return s:matcher 34 | endfunction 35 | 36 | let s:Tree = unite#sources#outline#import('Tree') 37 | 38 | let s:matcher = { 39 | \ 'name' : 'outline_matcher_glob', 40 | \ 'description': 'glob matcher for outline tree', 41 | \ } 42 | 43 | " Derived from: 44 | " unite/autoload/filters/matcher_glob.vim 45 | " 46 | function! s:matcher.filter(candidates, unite_context) 47 | if empty(a:candidates) | return a:candidates | endif 48 | 49 | call s:Tree.List.reset_marks(a:candidates) 50 | 51 | if a:unite_context.input == '' 52 | return a:candidates 53 | endif 54 | 55 | for input in split(a:unite_context.input, '\\\@ 5 | " Updated : 2012-01-11 6 | " 7 | " Licensed under the MIT license: 8 | " http://www.opensource.org/licenses/mit-license.php 9 | " 10 | "============================================================================= 11 | 12 | " Default outline info for ChangeLog 13 | " Version: 0.0.2 14 | 15 | function! unite#sources#outline#defaults#changelog#outline_info() 16 | return s:outline_info 17 | endfunction 18 | 19 | "--------------------------------------- 20 | " Sub Patterns 21 | 22 | let s:pat_date = '\(\S.*\)\=\d\+[-:]\d\+[-:]\d\+' 23 | let s:pat_item = '\s\+\*\s\+' 24 | 25 | "----------------------------------------------------------------------------- 26 | " Outline Info 27 | 28 | let s:outline_info = { 29 | \ 'heading': '^\(' . s:pat_date . '\|' . s:pat_item . '\)', 30 | \ 31 | \ 'highlight_rules': [ 32 | \ { 'name' : 'level_1', 33 | \ 'pattern' : '/' . s:pat_date . '.*/' }, 34 | \ ], 35 | \} 36 | 37 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 38 | let heading = { 39 | \ 'word' : a:heading_line, 40 | \ 'level': 0, 41 | \ 'type' : 'generic', 42 | \ } 43 | 44 | if a:heading_line =~ '^' . s:pat_date 45 | let heading.level = 1 46 | elseif a:heading_line =~ '^' . s:pat_item 47 | let heading.level = 2 48 | endif 49 | 50 | if heading.level > 0 51 | return heading 52 | else 53 | return {} 54 | endif 55 | endfunction 56 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/conf.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/conf.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Conf files 12 | " Version: 0.0.5 13 | 14 | function! unite#sources#outline#defaults#conf#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading-1': s:Util.shared_pattern('sh', 'heading-1'), 25 | \ 26 | \ 'skip': { 27 | \ 'header': s:Util.shared_pattern('sh', 'header'), 28 | \ }, 29 | \} 30 | 31 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 32 | let heading = { 33 | \ 'word' : a:heading_line, 34 | \ 'level': 0, 35 | \ 'type' : 'generic', 36 | \ } 37 | 38 | if a:which ==# 'heading-1' 39 | let m_lnum = a:context.matched_lnum 40 | let heading.type = 'comment' 41 | let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum, 4) 42 | endif 43 | 44 | if heading.level > 0 45 | return heading 46 | else 47 | return {} 48 | endif 49 | endfunction 50 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/cpp.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/cpp.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for C++ 12 | " Version: 0.2.0 13 | 14 | function! unite#sources#outline#defaults#cpp#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Ctags = unite#sources#outline#import('Ctags') 19 | let s:Util = unite#sources#outline#import('Util') 20 | 21 | "----------------------------------------------------------------------------- 22 | " Outline Info 23 | 24 | let s:outline_info = { 25 | \ 'heading_groups': { 26 | \ 'namespace': ['namespace'], 27 | \ 'type' : ['class', 'enum', 'struct', 'typedef'], 28 | \ 'function' : ['function', 'macro'], 29 | \ }, 30 | \ 31 | \ 'not_match_patterns': [ 32 | \ s:Util.shared_pattern('*', 'parameter_list'), 33 | \ ' => .*', 34 | \ ], 35 | \ 36 | \ 'highlight_rules': [ 37 | \ { 'name' : 'parameter_list', 38 | \ 'pattern': '/\%(=> .*\)\@ .*\)\@.*\|\h\w*\)\ze\s*(/' }, 43 | \ { 'name' : 'macro', 44 | \ 'pattern': '/\h\w*\ze .*=> /' }, 45 | \ { 'name' : 'expanded', 46 | \ 'pattern': '/ => \zs.*/' }, 47 | \ { 'name' : 'id', 48 | \ 'pattern': '/ \zs#\d\+/' }, 49 | \ ], 50 | \} 51 | 52 | function! s:outline_info.extract_headings(context) 53 | return s:Ctags.extract_headings(a:context) 54 | endfunction 55 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/css.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/css.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for CSS 12 | " Version: 0.0.3 13 | 14 | function! unite#sources#outline#defaults#css#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading-1': s:Util.shared_pattern('c', 'heading-1'), 25 | \ 26 | \ 'skip': { 27 | \ 'header': { 28 | \ 'leading': '^@charset', 29 | \ 'block' : s:Util.shared_pattern('c', 'header'), 30 | \ }, 31 | \ }, 32 | \} 33 | 34 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 35 | let heading = { 36 | \ 'word' : a:heading_line, 37 | \ 'level': 0, 38 | \ 'type' : 'generic', 39 | \ } 40 | 41 | if a:which ==# 'heading-1' 42 | let m_lnum = a:context.matched_lnum 43 | let heading.type = 'comment' 44 | let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum, 4) 45 | endif 46 | 47 | if heading.level > 0 48 | return heading 49 | else 50 | return {} 51 | endif 52 | endfunction 53 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/dosini.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/dosini.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Windows INI files 12 | " Version: 0.0.2 13 | 14 | function! unite#sources#outline#defaults#dosini#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | "----------------------------------------------------------------------------- 19 | " Outline Info 20 | 21 | let s:outline_info = { 22 | \ 'heading': '^\s*\[[^\]]\+\]', 23 | \ } 24 | 25 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 26 | let heading = { 27 | \ 'word' : a:heading_line, 28 | \ 'level': 1, 29 | \ 'type' : 'generic', 30 | \ } 31 | return heading 32 | endfunction 33 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/help.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/help.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Vim Help 12 | " Version: 0.1.2 13 | 14 | function! unite#sources#outline#defaults#help#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | " HEADING SAMPLES: 21 | " 22 | "== Level 1 23 | " 24 | " ========================================================================== 25 | " Heading 26 | " 27 | "== Level 2 28 | " 29 | " -------------------------------------------------------------------------- 30 | " Heading 31 | " 32 | "== Level 3 33 | " 34 | " 1.1 Heading 35 | " 36 | "== Level 4-1 37 | " 38 | " HEADING *tag* 39 | " 40 | "== Level 4-2 41 | " 42 | " HEADING ~ 43 | " *tag* 44 | 45 | "--------------------------------------- 46 | " Sub Patterns 47 | 48 | let s:pat_section_nr = '\d\+\.\d\+\s\+\S' 49 | let s:pat_upper_word = '\u[[:upper:][:digit:]_]\+\>' 50 | let s:pat_helptag = '\*[^*]\+\*' 51 | 52 | "----------------------------------------------------------------------------- 53 | " Outline Info 54 | 55 | let s:outline_info = { 56 | \ 'heading-1': '^[-=]\{10,}\s*$', 57 | \ 'heading' : '^\%(' . s:pat_section_nr . '\|' . 58 | \ s:pat_upper_word . '.*\%(' . s:pat_helptag . '\|\~\)\)', 59 | \ } 60 | 61 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 62 | let heading = { 63 | \ 'word' : a:heading_line, 64 | \ 'level': 0, 65 | \ 'type' : 'generic', 66 | \ } 67 | 68 | let lines = a:context.lines 69 | 70 | if a:which ==# 'heading-1' 71 | let m_lnum = a:context.matched_lnum 72 | if a:matched_line =~ '^=' 73 | let heading.level = 1 74 | elseif a:matched_line =~ '^-' && lines[m_lnum-1] !~ '\S' 75 | let heading.level = 2 76 | endif 77 | elseif a:which ==# 'heading' 78 | let h_lnum = a:context.heading_lnum 79 | if a:heading_line =~ '^' . s:pat_section_nr 80 | if a:heading_line =~ '\~\s*$' 81 | let heading.level = 3 82 | endif 83 | elseif a:heading_line =~ s:pat_helptag || 84 | \ s:Util.neighbor_match(a:context, h_lnum, s:pat_helptag) 85 | let heading.level = 4 86 | endif 87 | endif 88 | 89 | if heading.level > 0 90 | let heading.word = s:normalize_heading_word(heading.word) 91 | if heading.word =~? '^Contents\s*$' 92 | let heading.level = 1 93 | endif 94 | return heading 95 | else 96 | return {} 97 | endif 98 | endfunction 99 | 100 | function! s:normalize_heading_word(word) 101 | let word = substitute(a:word, '\%(\~\|{{{\d\=\)\s*$', '', '') 102 | let word = substitute(word, s:pat_helptag, '', 'g') 103 | if word !~ '\l' 104 | let word = s:Util.String.capitalize(word, 'g') 105 | endif 106 | return word 107 | endfunction 108 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/html.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/html.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for HTML 12 | " Version: 0.0.8 13 | 14 | function! unite#sources#outline#defaults#html#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "--------------------------------------- 21 | " Patterns 22 | 23 | let s:heading_tags = ['head', 'body', 'h\([1-6]\)'] 24 | let s:heading_pattern = '\c<\(' . join(s:heading_tags, '\|') . '\)\>[^>]*>' 25 | 26 | "----------------------------------------------------------------------------- 27 | " Outline Info 28 | 29 | let s:outline_info = { 30 | \ 'heading': s:heading_pattern, 31 | \ 32 | \ 'highlight_rules': [ 33 | \ { 'name' : 'level_1', 34 | \ 'pattern': '/H1\. .*/' }, 35 | \ { 'name' : 'level_2', 36 | \ 'pattern': '/H2\. .*/' }, 37 | \ { 'name' : 'level_3', 38 | \ 'pattern': '/H3\. .*/' }, 39 | \ { 'name' : 'level_4', 40 | \ 'pattern': '/H4\. .*/' }, 41 | \ { 'name' : 'level_5', 42 | \ 'pattern': '/H5\. .*/' }, 43 | \ { 'name' : 'level_6', 44 | \ 'pattern': '/H6\. .*/' }, 45 | \ ], 46 | \} 47 | 48 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 49 | let heading = { 50 | \ 'word' : a:heading_line, 51 | \ 'level': 0, 52 | \ 'type' : 'generic', 53 | \ } 54 | 55 | let matches = matchlist(a:heading_line, s:heading_pattern) 56 | let tag = matches[1] 57 | if tag =~? '^\%(head\|body\)$' 58 | let heading.level = 1 59 | let heading.word = substitute(tag, '^\(.\)', '\u\1', '') 60 | else 61 | let level = str2nr(matches[2]) 62 | let heading.level = level + 1 63 | let heading.word = 'H' . level . '. ' . s:get_text_content(level, a:context) 64 | endif 65 | 66 | if heading.level > 0 67 | return heading 68 | else 69 | return {} 70 | endif 71 | endfunction 72 | 73 | function! s:get_text_content(level, context) 74 | let h_lnum = a:context.heading_lnum 75 | let text = s:Util.join_to(a:context, h_lnum, ']*>') 76 | let text = substitute(text, '\n', '', 'g') 77 | let text = substitute(text, '<[[:alpha:]/][^>]*>', '', 'g') 78 | return text 79 | endfunction 80 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/java.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/java.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Java 12 | " Version: 0.1.6 13 | 14 | function! unite#sources#outline#defaults#java#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Ctags = unite#sources#outline#import('Ctags') 19 | let s:Util = unite#sources#outline#import('Util') 20 | 21 | "----------------------------------------------------------------------------- 22 | " Outline Info 23 | 24 | let s:outline_info = { 25 | \ 'heading_groups': { 26 | \ 'package': ['package'], 27 | \ 'type' : ['interface', 'class', 'enum'], 28 | \ 'method' : ['method'], 29 | \ }, 30 | \ 31 | \ 'not_match_patterns': [ 32 | \ s:Util.shared_pattern('*', 'parameter_list'), 33 | \ ], 34 | \ 35 | \ 'highlight_rules': [ 36 | \ { 'name' : 'package', 37 | \ 'pattern': '/\S\+\ze : package/' }, 38 | \ { 'name' : 'type', 39 | \ 'pattern': '/\S\+\ze : \%(interface\|class\|enum\)/' }, 40 | \ { 'name' : 'method', 41 | \ 'pattern': '/\h\w*\ze\s*(/' }, 42 | \ { 'name' : 'parameter_list', 43 | \ 'pattern': '/(.*)/' }, 44 | \ ], 45 | \} 46 | 47 | function! s:outline_info.extract_headings(context) 48 | return s:Ctags.extract_headings(a:context) 49 | endfunction 50 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/javascript.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/javascript.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Contributed by hamaco 7 | " 8 | " Licensed under the MIT license: 9 | " http://www.opensource.org/licenses/mit-license.php 10 | " 11 | "============================================================================= 12 | 13 | " Default outline info for JavaScript 14 | " Version: 0.1.1 15 | 16 | " TODO: Use jsctags for much better heading list! 17 | 18 | function! unite#sources#outline#defaults#javascript#outline_info() 19 | return s:outline_info 20 | endfunction 21 | 22 | let s:Util = unite#sources#outline#import('Util') 23 | 24 | "--------------------------------------- 25 | " Sub Patterns 26 | 27 | let s:pat_indent = '\<\h\w*\>' 28 | 29 | let s:pat_assign = '\%(var\s\+\)\=\(' . s:pat_indent . '\%(\.' . s:pat_indent . '\)*\)\s*=' 30 | " NOTE: This sub pattern contains 1 capture; 1:lvalue 31 | 32 | let s:pat_label = '\(' . s:pat_indent . '\)\s*:' 33 | " NOTE: This sub pattern contains 1 capture; 1:label 34 | 35 | let s:pat_rvalue = '\(function\s*(\([^)]*\))\|{\)' 36 | " NOTE: This sub pattern contains 2 captures; 1:rvalue [, 2:arg_list] 37 | 38 | "----------------------------------------------------------------------------- 39 | " Outline Info 40 | 41 | let s:outline_info = { 42 | \ 'heading-1': s:Util.shared_pattern('cpp', 'heading-1'), 43 | \ 'heading' : '^\s*\%(function\>\|' . 44 | \ '\%(' . s:pat_assign . '\|' . s:pat_label . '\)\s*' . s:pat_rvalue . '\)', 45 | \ 46 | \ 'skip': { 47 | \ 'header': s:Util.shared_pattern('cpp', 'header'), 48 | \ }, 49 | \ 50 | \ 'not_match_patterns': [ 51 | \ s:Util.shared_pattern('*', 'parameter_list'), 52 | \ ], 53 | \} 54 | 55 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 56 | let h_lnum = a:context.heading_lnum 57 | " Level 1 to 3 are reserved for comment headings. 58 | let level = s:Util.get_indent_level(a:context, h_lnum) + 3 59 | let heading = { 60 | \ 'word' : a:heading_line, 61 | \ 'level': level, 62 | \ 'type' : 'generic', 63 | \ } 64 | 65 | if a:which == 'heading-1' && s:Util._cpp_is_in_comment(a:heading_line, a:matched_line) 66 | let m_lnum = a:context.matched_lnum 67 | let heading.type = 'comment' 68 | let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum) 69 | 70 | elseif a:which ==# 'heading' 71 | 72 | let matched_list = matchlist(a:heading_line, 73 | \ '^\s*function\s\+\(' . s:pat_indent . '\)\s*(\(.*\))') 74 | if len(matched_list) > 0 75 | " function Foo(...) -> Foo(...) 76 | " function foo(...) -> foo(...) 77 | let [func_name, arg_list] = matched_list[1:2] 78 | let heading.word = func_name . '(' . arg_list . ')' 79 | endif 80 | 81 | let matched_list = matchlist(a:heading_line, 82 | \ '^\s*\%(' . s:pat_assign . '\|' . s:pat_label . '\)\s*' . s:pat_rvalue) 83 | if len(matched_list) > 0 84 | let [lvalue, label, rvalue, arg_list] = matched_list[1:4] 85 | if lvalue =~ '\S' 86 | " Assign 87 | if lvalue =~ '\.' 88 | " Property 89 | let prop_chain = split(lvalue, '\.') 90 | let prop_name = prop_chain[-1] 91 | if rvalue =~ '^f' 92 | if prop_name =~ '^\u' 93 | " Foo.Bar = function(...) -> Foo.Bar(...) 94 | let heading.word = lvalue . '(' . arg_list . ')' 95 | else 96 | " Foo.bar = function(...) -> bar(...) 97 | let heading.level += 1 98 | let heading.word = prop_name . '(' . arg_list . ')' 99 | endif 100 | else 101 | if match(prop_chain, '^\u') >= 0 102 | " Foo.Bar = { -> Foo.Bar 103 | " Foo.bar = { -> Foo.bar 104 | let heading.word = lvalue 105 | else 106 | " foo.bar = { 107 | let heading.level = 0 108 | endif 109 | endif 110 | elseif lvalue =~ '^\u' 111 | " Variale 112 | if rvalue =~ '^f' 113 | " var Foo = function(...) -> Foo(...) 114 | let heading.word = lvalue . '(' . arg_list . ')' 115 | else 116 | " var Foo = { -> Foo 117 | let heading.word = lvalue 118 | endif 119 | else 120 | " var foo = ... 121 | let heading.level = 0 122 | endif 123 | else 124 | " Label 125 | if rvalue =~ '^f' 126 | " foo: function(...) -> foo(...) 127 | let heading.word = label . '(' . arg_list . ')' 128 | else 129 | " foo: { 130 | let heading.level = 0 131 | endif 132 | endif 133 | endif 134 | endif 135 | 136 | if heading.level > 0 137 | return heading 138 | else 139 | return {} 140 | endif 141 | endfunction 142 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/markdown.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/markdown.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Markdown 12 | " Version: 0.0.5 13 | 14 | function! unite#sources#outline#defaults#markdown#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | "----------------------------------------------------------------------------- 19 | " Outline Info 20 | 21 | let s:outline_info = { 22 | \ 'heading' : '^#\+', 23 | \ 'heading+1': '^[-=]\+$', 24 | \ } 25 | 26 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 27 | let heading = { 28 | \ 'word' : a:heading_line, 29 | \ 'level': 0, 30 | \ 'type' : 'generic', 31 | \ } 32 | 33 | if a:which ==# 'heading' 34 | let heading.level = strlen(matchstr(a:heading_line, '^#\+')) 35 | let heading.word = substitute(heading.word, '^#\+\s*', '', '') 36 | let heading.word = substitute(heading.word, '\s*#\+\s*$', '', '') 37 | elseif a:which ==# 'heading+1' 38 | if a:matched_line =~ '^=' 39 | let heading.level = 1 40 | else 41 | let heading.level = 2 42 | endif 43 | endif 44 | 45 | if heading.level > 0 46 | let heading.word = substitute(heading.word, '\s*]*>\s*\%(\s*\)\=$', '', '') 47 | return heading 48 | else 49 | return {} 50 | endif 51 | endfunction 52 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/perl.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/perl.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Perl 12 | " Version: 0.1.0 13 | 14 | function! unite#sources#outline#defaults#perl#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading-1': s:Util.shared_pattern('sh', 'heading-1'), 25 | \ 'heading' : '^\%(\s*\%(sub\s\+\h\|\%(package\|BEGIN\|CHECK\|INIT\|END\)\>\)\|__\%(DATA\|END\)__$\)', 26 | \ 27 | \ 'skip': { 28 | \ 'header': s:Util.shared_pattern('sh', 'header'), 29 | \ 'block' : ['^=\%(cut\)\@!\w\+', '^=cut'], 30 | \ }, 31 | \ 32 | \ 'highlight_rules': [ 33 | \ { 'name' : 'comment', 34 | \ 'pattern' : '/#.*/' }, 35 | \ { 'name' : 'sub', 36 | \ 'pattern' : '/\h\w*/', 37 | \ 'highlight': unite#sources#outline#get_highlight('function') }, 38 | \ { 'name' : 'block', 39 | \ 'pattern' : '/\<\%(BEGIN\|CHECK\|INIT\|END\|__\%(DATA\|END\)__\)\>/', 40 | \ 'highlight': unite#sources#outline#get_highlight('special') }, 41 | \ { 'name' : 'package', 42 | \ 'pattern' : '/\S\+\ze : package/', 43 | \ 'highlight': unite#sources#outline#get_highlight('type') }, 44 | \ { 'name' : '_after_colon', 45 | \ 'pattern' : '/ : \h\w*/', 46 | \ 'highlight': unite#sources#outline#get_highlight('normal') }, 47 | \ ], 48 | \} 49 | 50 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 51 | let h_lnum = a:context.heading_lnum 52 | " Level 1 to 3 are reserved for comment headings. 53 | let level = s:Util.get_indent_level(a:context, h_lnum) + 3 54 | let heading = { 55 | \ 'word' : a:heading_line, 56 | \ 'level': level, 57 | \ 'type' : 'generic', 58 | \ } 59 | 60 | if a:which == 'heading-1' && a:heading_line =~ '^\s*#' 61 | let m_lnum = a:context.matched_lnum 62 | let heading.type = 'comment' 63 | let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum) 64 | elseif a:which == 'heading' 65 | if a:heading_line =~ '^\s*package\>' 66 | let heading.word = substitute(heading.word, ';\s*$', '', '') 67 | let heading.word = substitute(heading.word, '^\s*\zspackage\s\+', '', '') . ' : package' 68 | else 69 | let heading.word = substitute(heading.word, '\', '', '') 70 | let heading.word = substitute(heading.word, '\s*{.*$', '', '') 71 | let heading.level += 1 72 | endif 73 | endif 74 | return heading 75 | endfunction 76 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/php.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/php.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Contributed by hamaco 7 | " 8 | " Licensed under the MIT license: 9 | " http://www.opensource.org/licenses/mit-license.php 10 | " 11 | "============================================================================= 12 | 13 | " Default outline info for PHP 14 | " Version: 0.1.2 15 | 16 | function! unite#sources#outline#defaults#php#outline_info() 17 | return s:outline_info 18 | endfunction 19 | 20 | let s:Util = unite#sources#outline#import('Util') 21 | 22 | "--------------------------------------- 23 | " Sub Pattern 24 | 25 | let s:pat_type = '\%(interface\|class\|function\)\>' 26 | 27 | "----------------------------------------------------------------------------- 28 | " Outline Info 29 | 30 | let s:outline_info = { 31 | \ 'heading-1': s:Util.shared_pattern('cpp', 'heading-1'), 32 | \ 'heading' : '^\s*\%(\h\w*\s\+\)*' . s:pat_type, 33 | \ 34 | \ 'skip': { 35 | \ 'header': { 36 | \ 'leading': '^\%(' 80 | " Interface 81 | let heading.type = 'interface' 82 | let heading.word = matchstr(heading.word, '\zs\' 84 | " Class 85 | let heading.type = 'class' 86 | let heading.word = matchstr(heading.word, '\zs\' 92 | let heading.word = '+ ' . heading.word 93 | elseif modifiers =~ '\' 94 | let heading.word = '# ' . heading.word 95 | elseif modifiers =~ '\' 96 | let heading.word = '- ' . heading.word 97 | elseif heading.level > 3 98 | let heading.word = substitute(heading.word, '\%(&\|\h\)\@=', '+ ', '') 99 | endif 100 | let heading.word = substitute(heading.word, '\S\zs(', ' (', '') 101 | endif 102 | " Append modifiers. 103 | let modifiers = substitute(modifiers, '\%(public\|protected\|private\)', '', 'g') 104 | if modifiers !~ '^\s*$' 105 | let heading.word .= ' <' . join(split(modifiers, '\s\+'), ',') . '>' 106 | endif 107 | endif 108 | return heading 109 | endfunction 110 | 111 | function! s:outline_info.need_blank_between(cand1, cand2, memo) 112 | if a:cand1.source__heading_group == 'function' && a:cand2.source__heading_group == 'function' 113 | " Don't insert a blank between two sibling functions. 114 | return 0 115 | else 116 | return (a:cand1.source__heading_group != a:cand2.source__heading_group || 117 | \ a:cand1.source__has_marked_child || a:cand2.source__has_marked_child) 118 | endif 119 | endfunction 120 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/pir.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/pir.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for PIR 12 | " Version: 0.0.3 (draft) 13 | 14 | function! unite#sources#outline#defaults#pir#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading-1': s:Util.shared_pattern('sh', 'heading-1'), 25 | \ 'heading' : '^\.sub\>', 26 | \ 27 | \ 'skip': { 28 | \ 'header': s:Util.shared_pattern('sh', 'header'), 29 | \ 'block' : ['^=\%(cut\)\@!\w\+', '^=cut'], 30 | \ }, 31 | \} 32 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/python.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/python.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Python 12 | " Version: 0.2.0 13 | 14 | function! unite#sources#outline#defaults#python#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading' : '^\s*\%(class\|def\)\>', 25 | \ 26 | \ 'skip': { 27 | \ 'header': s:Util.shared_pattern('sh', 'header'), 28 | \ 'block' : ['r\="""', '\\\@' 60 | " Class 61 | let heading.type = 'class' 62 | let heading.word = matchstr(heading.word, '^\s*class\s\+\zs\h\w*') . ' : class' 63 | elseif heading.word =~ '^\s*def\>' 64 | " Function 65 | let heading.type = 'function' 66 | let heading.word = substitute(heading.word, '\ 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for ReVIEW 12 | " Version: 0.0.2 13 | 14 | function! unite#sources#outline#defaults#review#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | "----------------------------------------------------------------------------- 19 | " Outline Info 20 | 21 | let s:outline_info = { 22 | \ 'heading': '^=\+', 23 | \ } 24 | 25 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 26 | let heading = { 27 | \ 'word' : substitute(a:heading_line, '^=\+\s*', '', ''), 28 | \ 'level': strlen(matchstr(a:heading_line, '^=\+')), 29 | \ 'type' : 'generic', 30 | \ } 31 | if heading.word !~ '^\[/' 32 | return heading 33 | else 34 | return {} 35 | endif 36 | endfunction 37 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/rst.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/rst.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for reStructuredText 12 | " Version: 0.0.3 13 | 14 | function! unite#sources#outline#defaults#rst#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | "----------------------------------------------------------------------------- 19 | " Outline Info 20 | 21 | let s:outline_info = { 22 | \ 'heading+1': '^[[:punct:]]\{4,}$', 23 | \ } 24 | 25 | function! s:outline_info.before(context) 26 | let s:adornment_levels = {} 27 | let s:adornment_id = 2 28 | endfunction 29 | 30 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 31 | let heading = { 32 | \ 'word' : a:heading_line, 33 | \ 'level': 0, 34 | \ 'type' : 'generic', 35 | \ } 36 | 37 | let lines = a:context.lines 38 | let h_lnum = a:context.heading_lnum 39 | 40 | " Check the matching strictly. 41 | if a:matched_line =~ '^\([[:punct:]]\)\1\{3,}$' 42 | if h_lnum > 1 && lines[h_lnum - 1] == a:matched_line 43 | " Title 44 | let heading.level = 1 45 | else 46 | " Sections 47 | let adchar = a:matched_line[0] 48 | if !has_key(s:adornment_levels, adchar) 49 | let s:adornment_levels[adchar] = s:adornment_id 50 | let s:adornment_id += 1 51 | endif 52 | let heading.level = s:adornment_levels[adchar] 53 | endif 54 | endif 55 | 56 | if heading.level > 0 57 | return heading 58 | else 59 | return {} 60 | endif 61 | endfunction 62 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/ruby.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/ruby.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Ruby 12 | " Version: 0.1.5 13 | 14 | function! unite#sources#outline#defaults#ruby#outline_info(...) 15 | if a:0 16 | " Redirect to DSL's outline info. 17 | let context = a:1 18 | let path = context.buffer.path 19 | if path =~ '_spec\.rb$' 20 | " RSpec 21 | return 'ruby/rspec' 22 | endif 23 | endif 24 | return s:outline_info 25 | endfunction 26 | 27 | let s:Util = unite#sources#outline#import('Util') 28 | 29 | "----------------------------------------------------------------------------- 30 | " Outline Info 31 | 32 | let s:outline_info = { 33 | \ 'heading-1': s:Util.shared_pattern('sh', 'heading-1'), 34 | \ 'heading_keywords': [ 35 | \ 'module', 'class', 'protected', 'private', 36 | \ 'def', '[mc]\=attr_\(accessor\|reader\|writer\)', 'alias', 37 | \ 'BEGIN', 'END', '__END__', 38 | \ ], 39 | \ 40 | \ 'skip': { 41 | \ 'header': s:Util.shared_pattern('sh', 'header'), 42 | \ 'block' : ['^=begin', '^=end'], 43 | \ }, 44 | \ 45 | \ 'heading_groups': { 46 | \ 'type' : ['module', 'class'], 47 | \ 'method': ['method'], 48 | \ }, 49 | \ 50 | \ 'not_match_patterns': [ 51 | \ s:Util.shared_pattern('*', 'parameter_list'), 52 | \ ], 53 | \ 54 | \ 'highlight_rules': [ 55 | \ { 'name' : 'comment', 56 | \ 'pattern' : '/#.*/' }, 57 | \ { 'name' : 'method', 58 | \ 'pattern' : '/:\@\)\@![_[:alnum:]=\[\]<>!?.]\+/' }, 59 | \ { 'name' : 'type', 60 | \ 'pattern' : '/\S\+\ze : \%(module\|class\)/' }, 61 | \ { 'name' : 'eigen_class', 62 | \ 'pattern' : '/\/', 66 | \ 'highlight': unite#sources#outline#get_highlight('special') }, 67 | \ { 'name' : 'meta_method', 68 | \ 'pattern' : '/\' 77 | endfunction 78 | 79 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 80 | let word = a:heading_line 81 | let type = 'generic' 82 | let level = 0 83 | 84 | if a:which == 'heading-1' && a:heading_line =~ '^\s*#' 85 | let m_lnum = a:context.matched_lnum 86 | let type = 'comment' 87 | let level = s:Util.get_comment_heading_level(a:context, m_lnum) 88 | 89 | elseif a:which == 'heading' 90 | let h_lnum = a:context.heading_lnum 91 | let level = s:Util.get_indent_level(a:context, h_lnum) + 3 92 | " NOTE: Level 1 to 3 are reserved for toplevel comment headings. 93 | 94 | let matches = matchlist(a:heading_line, self.heading) 95 | let keyword = matches[1] 96 | let type = keyword 97 | 98 | if keyword == 'module' || keyword == 'class' 99 | if word =~ '\s\+<<\s\+' 100 | " Eigen-class 101 | else 102 | " Module, Class 103 | let word = matchstr(word, '^\s*\%(module\|class\)\s\+\zs\h\w*') . ' : ' . keyword 104 | endif 105 | elseif keyword == 'protected' || keyword == 'private' 106 | " Accessibility 107 | let indented = 0 108 | for idx in range(1, 5) 109 | let line = get(a:context.lines, h_lnum + idx, '') 110 | if line =~ '\S' 111 | let indented = level < s:Util.get_indent_level(a:context, h_lnum + idx) + 3 112 | break 113 | endif 114 | endfor 115 | if !indented 116 | let level = 0 117 | endif 118 | elseif keyword == 'def' 119 | if word =~ '#{' 120 | " Meta-method 121 | else 122 | " Method 123 | let type = 'method' 124 | let word = substitute(word, '\.*', '', '') 133 | let word = substitute(word, '\s*:', ' ', 'g') . ' : ' . access 134 | elseif keyword == 'alias' 135 | " Alias 136 | let type = 'method' 137 | let word = substitute(word, '\ \2', '') 139 | elseif keyword =~ '^\%(BEGIN\|END\)$' 140 | " BEGIN, END 141 | let word = substitute(word, '\s*{.*$', '', '') 142 | else 143 | " __END__ 144 | endif 145 | let word = substitute(word, '\%(;\|#{\@!\).*$', '', '') 146 | endif 147 | 148 | if level > 0 149 | let heading = { 150 | \ 'word' : word, 151 | \ 'level': level, 152 | \ 'type' : type, 153 | \ } 154 | else 155 | let heading = {} 156 | endif 157 | return heading 158 | endfunction 159 | 160 | function! s:outline_info.fold_ruby_block(context, lnum) 161 | let line = a:context.lines[a:lnum] 162 | let indent = matchlist(line, '^\(\s*\)')[1] 163 | let line = s:Util.join_to(a:context, a:lnum, indent . '%\(end\>\|}\)') 164 | let line = substitute(line, '\s*\n\s*', '; ', 'g') 165 | let line = substitute(substitute(line, 'do;', '{', ''), '; end', ' }', '') 166 | return line 167 | endfunction 168 | 169 | function! s:outline_info.need_blank_between(cand1, cand2, memo) 170 | if a:cand1.source__heading_group == 'method' && a:cand2.source__heading_group == 'method' 171 | " Don't insert a blank between two sibling methods. 172 | return 0 173 | else 174 | return (a:cand1.source__heading_group != a:cand2.source__heading_group || 175 | \ a:cand1.source__has_marked_child || a:cand2.source__has_marked_child) 176 | endif 177 | endfunction 178 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/ruby/rspec.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/ruby/rspec.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Contributed by kenchan 7 | " 8 | " Licensed under the MIT license: 9 | " http://www.opensource.org/licenses/mit-license.php 10 | " 11 | "============================================================================= 12 | 13 | " Default outline info for Ruby/RSpec 14 | " Version: 0.1.2 15 | 16 | function! unite#sources#outline#defaults#ruby#rspec#outline_info() 17 | return s:outline_info 18 | endfunction 19 | 20 | let s:Util = unite#sources#outline#import('Util') 21 | 22 | "----------------------------------------------------------------------------- 23 | " Outline Info 24 | 25 | " Inherit Ruby's outline info. 26 | let s:super = unite#sources#outline#get_outline_info('ruby', 1, 1) 27 | 28 | let s:outline_info = deepcopy(s:super) 29 | call extend(s:outline_info, { 30 | \ 'super': s:super, 31 | \ 32 | \ 'rspec_heading_keywords': [ 33 | \ 'shared\=_\%(as\|context\|examples\%(_for\)\=\)', 34 | \ 'describe', 'context', 'before', 'after', 'let!\=', 35 | \ 'subject\%(\s*\%(do\|{\)\)\@=', 'it\%(_\w\+\|s\)\=', 'specify', 36 | \ ], 37 | \ 38 | \ 'not_match_patterns': [ 39 | \ '^\s*\%(let!\=\)\@!\S\+\s*\zs([^)]*)', 40 | \ ], 41 | \ 42 | \ 'rspec_highlight_rules': [ 43 | \ { 'name' : 'shared_context', 44 | \ 'pattern' : '/\.*/', 45 | \ 'highlight': unite#sources#outline#get_highlight('rspec_shared_context', 'level_1') }, 46 | \ { 'name' : 'behavior', 47 | \ 'pattern' : '/\<\%(describe\|context\)\>.*/', 48 | \ 'highlight': unite#sources#outline#get_highlight('rspec_behaviour', 'level_1') }, 49 | \ { 'name' : 'hook', 50 | \ 'pattern' : '/\<\%(before\|after\)\>.*/', 51 | \ 'highlight': unite#sources#outline#get_highlight('rspec_hook', 'level_3') }, 52 | \ { 'name' : 'let', 53 | \ 'pattern' : '/\.*/', 54 | \ 'highlight': unite#sources#outline#get_highlight('rspec_let', 'level_3') }, 55 | \ { 'name' : 'subject', 56 | \ 'pattern' : '/\.*/', 57 | \ 'highlight': unite#sources#outline#get_highlight('rspec_subject', 'level_2') }, 58 | \ { 'name' : 'example', 59 | \ 'pattern' : '/\<\%(it\%(_\w\+\|s\)\=\|specify\)\>.*/', 60 | \ 'highlight': unite#sources#outline#get_highlight('rspec_example', 'level_2') }, 61 | \ ], 62 | \}) 63 | 64 | function! s:outline_info.initialize() 65 | let self.rspec_heading = '^\s*\(' . join(self.rspec_heading_keywords, '\|') . '\)\>' 66 | let self.heading_keywords += self.rspec_heading_keywords 67 | let self.highlight_rules += self.rspec_highlight_rules 68 | call call(self.super.initialize, [], self) 69 | endfunction 70 | 71 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 72 | let word = a:heading_line 73 | let type = 'generic' 74 | let level = 0 75 | 76 | if a:which == 'heading' && a:heading_line =~ self.rspec_heading 77 | let h_lnum = a:context.heading_lnum 78 | let level = s:Util.get_indent_level(a:context, h_lnum) + 3 79 | " NOTE: Level 1 to 3 are reserved for toplevel comment headings. 80 | 81 | let type = 'rspec' 82 | let word = substitute(word, '\s*\%(do\|{\)\%(\s*|[^|]*|\)\=\s*$', '', '') 83 | "let word = substitute(word, '\%(;\|#{\@!\).*$', '', '') 84 | 85 | if word =~ '^\s*\%(subject\|it\)\s*$' 86 | let word = self.fold_ruby_block(a:context, h_lnum) 87 | endif 88 | endif 89 | 90 | if level > 0 91 | let heading = { 92 | \ 'word' : word, 93 | \ 'level': level, 94 | \ 'type' : type, 95 | \ } 96 | else 97 | let heading = call(self.super.create_heading, 98 | \ [a:which, a:heading_line, a:matched_line, a:context], self.super) 99 | endif 100 | return heading 101 | endfunction 102 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/scala.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/scala.vim 3 | " Author : thinca 4 | " Updated : 2012-01-11 5 | " 6 | " License : Creative Commons Attribution 2.1 Japan License 7 | " 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Scala 12 | " Version: 0.1.3 13 | 14 | function! unite#sources#outline#defaults#scala#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "--------------------------------------- 21 | " Sub Pattern 22 | 23 | let s:pat_heading = '^\s*\%(\h\w*\s\+\)*\zs\<\%(class\|object\|trait\|def\)\>' 24 | 25 | "----------------------------------------------------------------------------- 26 | " Outline Info 27 | 28 | let s:outline_info = { 29 | \ 'heading-1': s:Util.shared_pattern('cpp', 'heading-1'), 30 | \ 'heading' : s:pat_heading, 31 | \ 32 | \ 'skip': { 33 | \ 'header': s:Util.shared_pattern('cpp', 'header'), 34 | \ }, 35 | \ 36 | \ 'not_match_patterns': [ 37 | \ s:Util.shared_pattern('*', 'after_lbracket'), 38 | \ s:Util.shared_pattern('*', 'after_lparen'), 39 | \ s:Util.shared_pattern('*', 'after_colon'), 40 | \ ], 41 | \} 42 | 43 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 44 | let h_lnum = a:context.heading_lnum 45 | " Level 1 to 3 are reserved for comment headings. 46 | let level = s:Util.get_indent_level(a:context, h_lnum) + 3 47 | let heading = { 48 | \ 'word' : a:heading_line, 49 | \ 'level': level, 50 | \ 'type' : 'generic', 51 | \ } 52 | 53 | if a:which == 'heading-1' && s:Util._cpp_is_in_comment(a:heading_line, a:matched_line) 54 | let m_lnum = a:context.matched_lnum 55 | let heading.type = 'comment' 56 | let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum) 57 | elseif a:which == 'heading' 58 | let heading.type = matchstr(a:matched_line, s:pat_heading) 59 | let heading.word = matchstr(a:heading_line, '^.\{-}\ze\%(\s\+=\%(\s.*\)\?\|\s*{\s*\)\?$') 60 | endif 61 | return heading 62 | endfunction 63 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/scheme.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/scheme.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Scheme 12 | " Version: 0.0.6 (draft) 13 | 14 | function! unite#sources#outline#defaults#scheme#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading-1': '^\s*;\+\s*[-=]\{10,}\s*$', 25 | \ 'heading' : '^\s*(define\>', 26 | \ 27 | \ 'skip': { 'header': '^;' }, 28 | \} 29 | 30 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 31 | let heading = { 32 | \ 'word' : a:heading_line, 33 | \ 'level': 0, 34 | \ 'type' : 'generic', 35 | \ } 36 | 37 | if a:which ==# 'heading-1' && a:heading_line =~ '^\s*;' 38 | let m_lnum = a:context.matched_lnum 39 | let heading.type = 'comment' 40 | let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum, 5) 41 | elseif a:which ==# 'heading' 42 | let heading.level = 4 43 | endif 44 | 45 | if heading.level > 0 46 | return heading 47 | else 48 | return {} 49 | endif 50 | endfunction 51 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/sh.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/sh.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Shell script 12 | " Version: 0.1.0 13 | 14 | function! unite#sources#outline#defaults#sh#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading-1': s:Util.shared_pattern('sh', 'heading-1'), 25 | \ 'heading' : '^\s*\%(\w\+\s*()\|function\>\)', 26 | \ 27 | \ 'skip': { 28 | \ 'header': s:Util.shared_pattern('sh', 'header'), 29 | \ }, 30 | \ 31 | \ 'highlight_rules': [ 32 | \ { 'name' : 'comment', 33 | \ 'pattern' : '/#.*/' }, 34 | \ { 'name' : 'function', 35 | \ 'pattern' : '/\h\w*/' }, 36 | \ ], 37 | \} 38 | 39 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 40 | let heading = { 41 | \ 'word' : a:heading_line, 42 | \ 'level': 0, 43 | \ 'type' : 'generic', 44 | \ } 45 | 46 | if a:which ==# 'heading-1' && a:heading_line =~ '^\s*#' 47 | let m_lnum = a:context.matched_lnum 48 | let heading.type = 'comment' 49 | let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum, 5) 50 | elseif a:which ==# 'heading' 51 | let heading.level = 4 52 | let heading.type = 'function' 53 | let heading.word = substitute(heading.word, '\s*\((.*)\s*\)\={.*$', '', '') 54 | endif 55 | 56 | if heading.level > 0 57 | return heading 58 | else 59 | return {} 60 | endif 61 | endfunction 62 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/tex.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/tex.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for TeX 12 | " Version: 0.1.0 13 | 14 | function! unite#sources#outline#defaults#tex#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading': '^\s*\\\%(title\|part\|chapter\|\%(sub\)\{,2}section\|begin{thebibliography}\){', 25 | \} 26 | 27 | let s:unit_level_map = { 28 | \ 'title' : 1, 29 | \ 'part' : 2, 30 | \ 'chapter' : 3, 31 | \ 'section' : 4, 32 | \ 'subsection' : 5, 33 | \ 'subsubsection': 6, 34 | \ } 35 | 36 | function! s:outline_info.before(context) 37 | let s:unit_count = map(copy(s:unit_level_map), '0') 38 | let s:bib_level = 6 39 | endfunction 40 | 41 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 42 | let heading = { 43 | \ 'word' : a:heading_line, 44 | \ 'level': 0, 45 | \ 'type' : 'generic', 46 | \ } 47 | 48 | let h_lnum = a:context.heading_lnum 49 | if a:heading_line =~ '^\s*\\begin{thebibliography}{' 50 | " Bibliography 51 | let heading.level = s:bib_level 52 | let bib_label = s:Util.neighbor_matchstr(a:context, h_lnum, 53 | \ '\\renewcommand{\\bibname}{\zs.*\ze}\s*$', 3) 54 | let heading.word = (empty(bib_label) ? "Bibliography" : bib_label) 55 | else 56 | " Parts, Chapters, Sections, etc 57 | let unit = matchstr(a:heading_line, '^\s*\\\zs\w\+\ze{') 58 | let s:unit_count[unit] += 1 59 | let heading.level = s:unit_level_map[unit] 60 | if 1 < heading.level && heading.level < s:bib_level 61 | let s:bib_level = heading.level 62 | endif 63 | let heading.word = s:normalize_heading_word( 64 | \ s:Util.join_to(a:context, h_lnum, '}\s*$'), unit) 65 | endif 66 | 67 | if heading.level > 0 68 | return heading 69 | else 70 | return {} 71 | endif 72 | endfunction 73 | 74 | function! s:normalize_heading_word(word, unit) 75 | let word = substitute(a:word, '\\\\\n', '', 'g') 76 | let word = matchstr(word, '^\s*\\\w\+{\zs.*\ze}\s*$') 77 | let word = s:unit_seqnr_prefix(a:unit) . word 78 | return word 79 | endfunction 80 | 81 | function! s:unit_seqnr_prefix(unit) 82 | if a:unit ==# 'title' 83 | let seqnr = [] 84 | elseif a:unit ==# 'part' 85 | let seqnr = [s:Util.String.nr2roman(s:unit_count.part)] 86 | elseif a:unit ==# 'chapter' 87 | let seqnr = [s:unit_count.chapter] 88 | elseif a:unit ==# 'section' 89 | if s:unit_count.chapter > 0 90 | let seqnr = [s:unit_count.chapter, s:unit_count.section] 91 | elseif a:unit ==# 'section' 92 | let seqnr = [s:unit_count.section] 93 | else 94 | endif 95 | elseif a:unit ==# 'subsection' 96 | if s:unit_count.chapter > 0 97 | let seqnr = [s:unit_count.chapter, s:unit_count.section, s:unit_count.subsection] 98 | else 99 | let seqnr = [s:unit_count.section, s:unit_count.subsection] 100 | endif 101 | elseif a:unit ==# 'subsubsection' 102 | if s:unit_count.chapter > 0 103 | let seqnr = [s:unit_count.section, s:unit_count.subsection, s:unit_count.subsubsection] 104 | else 105 | let seqnr = [] 106 | endif 107 | endif 108 | let prefix = join(seqnr, '.') 109 | let prefix .= (!empty(prefix) ? " " : "") 110 | return prefix 111 | endfunction 112 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/textile.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/textile.vim 3 | " Author : basyura 4 | " Maintainer : h1mesuke 5 | " Updated : 2012-01-11 6 | " 7 | " Licensed under the MIT license: 8 | " http://www.opensource.org/licenses/mit-license.php 9 | " 10 | "============================================================================= 11 | 12 | " Default outline info for Textile 13 | " Version: 0.0.2 14 | 15 | function! unite#sources#outline#defaults#textile#outline_info() 16 | return s:outline_info 17 | endfunction 18 | 19 | "----------------------------------------------------------------------------- 20 | " Outline Info 21 | 22 | let s:outline_info = { 23 | \ 'heading': '^h[1-6]\.\s', 24 | \ } 25 | 26 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 27 | let heading = { 28 | \ 'word' : substitute(a:heading_line, '^h[1-6]\.\s\+', '', ''), 29 | \ 'level': str2nr(matchstr(a:heading_line, '^h\zs[1-6]\ze\.\s')), 30 | \ 'type' : 'generic', 31 | \ } 32 | return heading 33 | endfunction 34 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/unittest.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/unittest.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for UnitTest results 12 | " Version: 0.0.5 13 | 14 | " h1mesuke/vim-unittest - GitHub 15 | " https://github.com/h1mesuke/vim-unittest 16 | 17 | function! unite#sources#outline#defaults#unittest#outline_info() 18 | return s:outline_info 19 | endfunction 20 | 21 | "----------------------------------------------------------------------------- 22 | " Outline Info 23 | 24 | let s:outline_info = { 25 | \ 'is_volatile': 1, 26 | \ 27 | \ 'heading-1': '^[-=]\{10,}', 28 | \ 'heading' : '^\s*\d\+) \%(Failure\|Error\): ', 29 | \} 30 | 31 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 32 | let heading = { 33 | \ 'word' : a:heading_line, 34 | \ 'level': 0, 35 | \ 'type' : 'generic', 36 | \ } 37 | 38 | if a:which ==# 'heading-1' 39 | if a:matched_line =~ '^=' || a:heading_line =~ '^\d\+ tests,' 40 | let heading.level = 1 41 | elseif a:matched_line =~ '^-' 42 | let heading.level = 2 43 | endif 44 | elseif a:which ==# 'heading' 45 | let heading.level = 3 46 | endif 47 | 48 | if heading.level > 0 49 | return heading 50 | else 51 | return {} 52 | endif 53 | endfunction 54 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/defaults/vim.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/defaults/vim.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Vim script 12 | " Version: 0.1.5 13 | 14 | function! unite#sources#outline#defaults#vim#outline_info() 15 | return s:outline_info 16 | endfunction 17 | 18 | let s:Util = unite#sources#outline#import('Util') 19 | 20 | "----------------------------------------------------------------------------- 21 | " Outline Info 22 | 23 | let s:outline_info = { 24 | \ 'heading-1': '^\s*"\s*[-=]\{10,}\s*$', 25 | \ 'heading' : '^\%(augroup\s\+\%(END\>\)\@!\|\s*fu\%[nction]!\= \)', 26 | \ 27 | \ 'skip': { 'header': '^"' }, 28 | \ 29 | \ 'not_match_patterns': [ 30 | \ s:Util.shared_pattern('*', 'parameter_list'), 31 | \ ], 32 | \ 33 | \ 'highlight_rules': [ 34 | \ { 'name' : 'comment', 35 | \ 'pattern' : '/".*/' }, 36 | \ { 'name' : 'augroup', 37 | \ 'pattern' : '/\S\+\ze : augroup/', 38 | \ 'highlight': unite#sources#outline#get_highlight('type') }, 39 | \ { 'name' : 'function', 40 | \ 'pattern' : '/\S\+\ze\s*(/' }, 41 | \ { 'name' : 'parameter_list', 42 | \ 'pattern' : '/(.*)/' }, 43 | \ ], 44 | \} 45 | 46 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 47 | let heading = { 48 | \ 'word' : a:heading_line, 49 | \ 'level': 0, 50 | \ 'type' : 'generic', 51 | \ } 52 | 53 | if a:which ==# 'heading-1' && a:heading_line =~ '^\s*"' 54 | let m_lnum = a:context.matched_lnum 55 | let heading.type = 'comment' 56 | let heading.level = s:Util.get_comment_heading_level(a:context, m_lnum, 5) 57 | elseif a:which ==# 'heading' 58 | let heading.level = 4 59 | if heading.word =~ '^augroup ' 60 | let heading.type = 'augroup' 61 | let heading.word = substitute(heading.word, '^augroup\s\+', '', '') . ' : augroup' 62 | else 63 | let heading.type = 'function' 64 | let heading.word = substitute(heading.word, '^\s*fu\%[nction]!\=', '', '') 65 | let heading.word = substitute(heading.word, '\S\zs(', ' (', '') 66 | endif 67 | endif 68 | 69 | if heading.level > 0 70 | let heading.word = substitute(heading.word, '"\=\s*{{{\d\=\s*$', '', '') 71 | return heading 72 | else 73 | return {} 74 | endif 75 | endfunction 76 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/misc/wzmemo_text.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/sources/outline/text.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " 6 | " Licensed under the MIT license: 7 | " http://www.opensource.org/licenses/mit-license.php 8 | " 9 | "============================================================================= 10 | 11 | " Default outline info for Text (WzMemo style) 12 | " Version: 0.0.2 13 | 14 | " USAGE: 15 | " 1. Copy this file to '~/.vim/autoload/unite/sources/outline' 16 | " 2. Rename this file to 'text.vim' 17 | " 18 | " If needed: 19 | " 3. Make a ftdetect file for text filetype at '~/.vim/ftdetect/text.vim' 20 | " and write this: 21 | " 22 | " autocmd BufRead,BufNewFile *.txt set filetype=text 23 | 24 | function! unite#sources#outline#defaults#text#outline_info() 25 | return s:outline_info 26 | endfunction 27 | 28 | let s:outline_info = { 29 | \ 'heading' : '^\.\+', 30 | \ } 31 | 32 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 33 | let level = strlen(matchstr(a:heading_line, '^\.\+')) 34 | let heading = { 35 | \ 'word' : substitute(a:heading_line, '^\.\+\s*', '', ''), 36 | \ 'level': level, 37 | \ 'type' : 'generic', 38 | \ } 39 | return heading 40 | endfunction 41 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/modules/base.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/source/outline/modules/base.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " Version : 0.5.1 6 | " License : MIT license {{{ 7 | " 8 | " Permission is hereby granted, free of charge, to any person obtaining 9 | " a copy of this software and associated documentation files (the 10 | " "Software"), to deal in the Software without restriction, including 11 | " without limitation the rights to use, copy, modify, merge, publish, 12 | " distribute, sublicense, and/or sell copies of the Software, and to 13 | " permit persons to whom the Software is furnished to do so, subject to 14 | " the following conditions: 15 | " 16 | " The above copyright notice and this permission notice shall be included 17 | " in all copies or substantial portions of the Software. 18 | " 19 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | " }}} 27 | "============================================================================= 28 | 29 | let s:save_cpo = &cpo 30 | set cpo&vim 31 | 32 | function! unite#sources#outline#modules#base#new(name, sid) 33 | let module = copy(s:Module) 34 | let module.__name__ = a:name 35 | let module.__prefix__ = a:sid . a:name . '_' 36 | " => 10_Fizz_ 37 | return module 38 | endfunction 39 | 40 | "----------------------------------------------------------------------------- 41 | 42 | function! s:get_SID() 43 | return matchstr(expand(''), '\d\+_') 44 | endfunction 45 | let s:SID = s:get_SID() 46 | delfunction s:get_SID 47 | 48 | let s:Module = {} 49 | 50 | function! s:Module_bind(func_name) dict 51 | let self[a:func_name] = function(self.__prefix__ . a:func_name) 52 | endfunction 53 | let s:Module.__bind__ = function(s:SID . 'Module_bind') 54 | let s:Module.function = s:Module.__bind__ | " syntax sugar 55 | 56 | let &cpo = s:save_cpo 57 | unlet s:save_cpo 58 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/modules/ctags.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/source/outline/lib/ctags.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " Version : 0.5.1 6 | " License : MIT license {{{ 7 | " 8 | " Permission is hereby granted, free of charge, to any person obtaining 9 | " a copy of this software and associated documentation files (the 10 | " "Software"), to deal in the Software without restriction, including 11 | " without limitation the rights to use, copy, modify, merge, publish, 12 | " distribute, sublicense, and/or sell copies of the Software, and to 13 | " permit persons to whom the Software is furnished to do so, subject to 14 | " the following conditions: 15 | " 16 | " The above copyright notice and this permission notice shall be included 17 | " in all copies or substantial portions of the Software. 18 | " 19 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | " }}} 27 | "============================================================================= 28 | 29 | let s:save_cpo = &cpo 30 | set cpo&vim 31 | 32 | function! unite#sources#outline#modules#ctags#import() 33 | return s:Ctags 34 | endfunction 35 | 36 | "----------------------------------------------------------------------------- 37 | 38 | let s:Tree = unite#sources#outline#import('Tree') 39 | let s:Util = unite#sources#outline#import('Util') 40 | let s:Vital = vital#of('unite') 41 | 42 | function! s:get_SID() 43 | return matchstr(expand(''), '\d\+_') 44 | endfunction 45 | let s:SID = s:get_SID() 46 | delfunction s:get_SID 47 | 48 | " Ctags module provides a function to extract headings from a file using the Exuberant 49 | " Ctags. It executes the Ctags and parses its output and build a tree of 50 | " headings. 51 | " 52 | let s:Ctags = unite#sources#outline#modules#base#new('Ctags', s:SID) 53 | 54 | " Find the Exuberant Ctags and identify its binary name. If not found, returns 55 | " empty String. 56 | " 57 | function! s:find_exuberant_ctags() 58 | let ctags_exe_names = [ 59 | \ 'ctags-exuberant', 60 | \ 'exctags', 61 | \ 'ctags', 62 | \ 'tags', 63 | \ ] 64 | if exists('g:neocomplcache_ctags_program') && !empty(g:neocomplcache_ctags_program) 65 | let ctags_exe_names = [g:neocomplcache_ctags_program] + ctags_exe_names 66 | endif 67 | for ctags in ctags_exe_names 68 | if executable(ctags) 69 | " Make sure it is Exuberant. 70 | let ctags_out = unite#util#system(ctags . ' --version') 71 | if split(ctags_out, "\")[0] =~? '\' 72 | return ctags 73 | endif 74 | endif 75 | endfor 76 | return '' 77 | endfunction 78 | 79 | let s:Ctags.exe = s:find_exuberant_ctags() 80 | let s:Ctags.lang_info = {} 81 | 82 | " Returns True if the Exuberant Ctags is available. 83 | " 84 | function! s:Ctags_exists() 85 | return !empty(s:Ctags.exe) 86 | endfunction 87 | call s:Ctags.function('exists') 88 | 89 | " Returns True if the Exuberant Ctags supports {filetype}. 90 | " 91 | function! s:Ctags_supports(filetype) 92 | if !has_key(s:Ctags.lang_info, a:filetype) 93 | return 0 94 | else 95 | let lang_info = s:Ctags.lang_info[a:filetype] 96 | let ctags_out = unite#util#system(s:Ctags.exe . ' --list-languages') 97 | return index(split(ctags_out, "\"), lang_info.name, 1) >= 0 98 | endif 99 | endfunction 100 | call s:Ctags.function('supports') 101 | 102 | " Executes the Ctags and returns a List of tag objects. 103 | " 104 | function! s:execute_ctags(context) 105 | " Write the current content of the buffer to a temporary file. 106 | let input = join(a:context.lines[1:], "\") 107 | let input = s:Vital.iconv(input, &encoding, &termencoding) 108 | let temp_file = tempname() 109 | if writefile(split(input, "\"), temp_file) == -1 110 | call unite#util#print_message( 111 | \ "[unite-outline] Couldn't make a temporary file at " . temp_file) 112 | return [] 113 | endif 114 | " NOTE: If the auto-update is enabled, the buffer may have been changed 115 | " since the last write. Because the user expects the headings to be 116 | " extracted from the buffer which he/she is watching now, we need to process 117 | " the buffer's content not its file's content. 118 | 119 | let filetype = a:context.buffer.filetype 120 | " Assemble the command-line. 121 | let lang_info = s:Ctags.lang_info[filetype] 122 | let opts = ' -f - --excmd=number --fields=afiKmsSzt --sort=no ' 123 | let opts .= ' --language-force=' . lang_info.name . ' ' 124 | let opts .= lang_info.ctags_options 125 | 126 | let path = s:Util.Path.normalize(temp_file) 127 | let path = s:Util.String.shellescape(path) 128 | 129 | let cmdline = s:Ctags.exe . opts . path 130 | 131 | " Execute the Ctags. 132 | let ctags_out = unite#util#system(cmdline) 133 | let status = unite#util#get_last_status() 134 | if status != 0 135 | call unite#util#print_message( 136 | \ "[unite-outline] ctags failed with status " . status . ".") 137 | return [] 138 | endif 139 | 140 | " Delete the used temporary file. 141 | if delete(temp_file) != 0 142 | call unite#util#print_error( 143 | \ "unite-outline: Couldn't delete a temporary file: " . temp_file) 144 | endif 145 | 146 | let tag_lines = split(ctags_out, "\") 147 | try 148 | " Convert tag lines into tag objects. 149 | let tags = map(tag_lines, 's:create_tag(v:val, lang_info)') 150 | call filter(tags, '!empty(v:val)') 151 | return tags 152 | catch 153 | " The first line of the output often contains a hint of an error. 154 | throw tag_lines[0] 155 | endtry 156 | endfunction 157 | 158 | " Creates a tag object from a tag line. If the line is not a tag line, for 159 | " example, a warning message from the standard error, returns an empty 160 | " Dictionary. 161 | " 162 | " TAG FILE FORMAT: 163 | " 164 | " tag_line 165 | " := tag_namefile_nameex_cmd;"{extension_fields} 166 | " 167 | " extension_fields 168 | " := key:valuekey:value... 169 | " 170 | function! s:create_tag(tag_line, lang_info) 171 | let fields = split(a:tag_line, "\") 172 | if len(fields) < 3 173 | " The line doesn't seem a tag line, so ignore it. 174 | " Example: ctags: Warning: {message} 175 | return {} 176 | endif 177 | let tag = {} 178 | let tag.name = fields[0] 179 | let tag.lnum = str2nr(fields[2]) 180 | for ext_fld in fields[3:-1] 181 | let [key, value] = matchlist(ext_fld, '^\([^:]\+\):\(.*\)$')[1:2] 182 | let tag[key] = value 183 | endfor 184 | for scope_kind in a:lang_info.scope_kinds 185 | if has_key(tag, scope_kind) 186 | let tag.scope_kind = scope_kind 187 | let tag.scope = tag[scope_kind] 188 | endif 189 | endfor 190 | if has_key(tag, 'scope') 191 | let tag.qualified_name = tag.scope . a:lang_info.scope_delim . tag.name 192 | else 193 | let tag.qualified_name = tag.name 194 | endif 195 | return tag 196 | endfunction 197 | 198 | " Extract headings from the context buffer's file using the Ctags and then 199 | " returns a tree of the headings. 200 | " 201 | function! s:Ctags_extract_headings(context) 202 | let filetype = a:context.buffer.filetype 203 | if !s:Ctags_exists() 204 | call unite#print_message("[unite-outline] Sorry, Exuberant Ctags required.") 205 | return [] 206 | elseif !s:Ctags_supports(filetype) 207 | call unite#print_message("[unite-outline] " . 208 | \ "Sorry, your ctags doesn't support " . toupper(filetype)) 209 | return [] 210 | endif 211 | 212 | " Execute the Ctags and get a List of tag objects. 213 | let tags = s:execute_ctags(a:context) 214 | 215 | let lang_info = s:Ctags.lang_info[filetype] 216 | let scope_kinds_pattern = '^\%(' . join(lang_info.scope_kinds, '\|') . '\)$' 217 | let scope_table = {} 218 | 219 | " Tag name counter 220 | let s:counter = {} 221 | 222 | " Build a heading tree processing a List of tag objects. 223 | let root = s:Tree.new() 224 | for tag in tags 225 | " Create a heading from the tag object. 226 | if has_key(lang_info, 'create_heading') 227 | let heading = lang_info.create_heading(tag, a:context) 228 | else 229 | let heading = s:create_heading(tag, a:context) 230 | endif 231 | if empty(heading) | continue | endif 232 | 233 | " Remove extra spaces to normalize the parameter list. 234 | let heading.word = substitute(substitute(heading.word, '(\s*', '(', ''), '\s*)', ')', '') 235 | 236 | if tag.kind =~# scope_kinds_pattern 237 | " The heading has its scope, in other words, it is able to have child 238 | " headings. To append its children that come after to it, register it to 239 | " the table. 240 | " Example: a class, a module, etc 241 | if !has_key(scope_table, tag.qualified_name) 242 | let scope_table[tag.qualified_name] = heading 243 | elseif has_key(scope_table[tag.qualified_name], '__pseudo__') 244 | " Replace the pseudo heading with the actual one. 245 | let heading.children = scope_table[tag.qualified_name].children 246 | let scope_table[tag.qualified_name] = heading 247 | endif 248 | endif 249 | 250 | if has_key(tag, 'scope') 251 | " Group_A: The heading belongs to a scope, in other words, it has 252 | " a parent heading. 253 | " Example: a method in class, an inner class, etc 254 | if !has_key(scope_table, tag.scope) 255 | " If the parent heading hasn't registered to the table yet, create 256 | " a pseudo heading as a place holder. 257 | let pseudo_heading = s:create_pseudo_heading(tag) 258 | let scope_table[tag.scope] = pseudo_heading 259 | endif 260 | " Prepend a symbol character (+, #, -) to show the accessibility to the 261 | " heading word. 262 | let heading.word = s:get_tag_access_mark(tag) . heading.word 263 | call s:Tree.append_child(scope_table[tag.scope], heading) 264 | else 265 | " Group_B: The heading belongs to the toplevel. 266 | call s:Tree.append_child(root, heading) 267 | endif 268 | endfor 269 | unlet! s:counter 270 | 271 | " Merge orphaned pseudo headings. 272 | let pseudo_headings = filter(values(scope_table), 'has_key(v:val, "__pseudo__")') 273 | if len(pseudo_headings) > 0 274 | for heading in pseudo_headings 275 | call s:Tree.append_child(root, heading) 276 | endfor 277 | call s:Util.List.sort_by_lnum(root.children) 278 | endif 279 | return root 280 | endfunction 281 | call s:Ctags.function('extract_headings') 282 | 283 | " Creates a heading from {tag}. 284 | " 285 | function! s:create_heading(tag, context) 286 | let line = a:context.lines[a:tag.lnum] 287 | let heading = { 288 | \ 'word' : a:tag.name, 289 | \ 'type' : a:tag.kind, 290 | \ "lnum" : a:tag.lnum, 291 | \ } 292 | if has_key(a:tag, 'signature') 293 | let heading.word .= ' ' . a:tag.signature 294 | else 295 | let heading.word .= ' : ' . a:tag.kind 296 | endif 297 | if has_key(a:tag, 'implementation') 298 | let heading.word .= ' <' . a:tag.implementation . '>' 299 | endif 300 | return heading 301 | endfunction 302 | 303 | " Creates a pseudo heading from {tag}. 304 | " Pseudo headings are the headings whose tags don't exists actually because 305 | " maybe they belong to the other files. 306 | " 307 | function! s:create_pseudo_heading(tag) 308 | let heading = { 309 | \ 'word' : '(' . a:tag.scope . ') : ' . a:tag.scope_kind, 310 | \ 'type' : a:tag.scope_kind, 311 | \ 'lnum' : a:tag.lnum, 312 | \ '__pseudo__': 1, 313 | \ } 314 | return heading 315 | endfunction 316 | 317 | " Gets a full parameter list from the context buffer's line. 318 | " 319 | function! s:get_param_list(context, lnum) 320 | let line = s:Util.join_to_rparen(a:context, a:lnum) 321 | return matchstr(line, '([^)]*)') 322 | endfunction 323 | 324 | " Returns a symbol character (+, #, -) to show the accessibility of {tag}. 325 | " 326 | let s:OOP_ACCESS_MARKS = { 327 | \ 'public' : '+', 328 | \ 'protected': '#', 329 | \ 'private' : '-' 330 | \ } 331 | function! s:get_tag_access_mark(tag) 332 | let access = has_key(a:tag, 'access') ? a:tag.access : 'unknown' 333 | return get(s:OOP_ACCESS_MARKS, access, '_') . ' ' 334 | endfunction 335 | 336 | " Count up {tag}'s name and returns an ID suffix (#2, #3, ...) for {tag}. 337 | " If the {tag} is the first one that has the name, returns empty String. 338 | " 339 | function! s:get_tag_id(tag) 340 | let name = a:tag.qualified_name 341 | if has_key(a:tag, 'signature') 342 | let name .= a:tag.signature 343 | endif 344 | if has_key(s:counter, name) 345 | let s:counter[name] += 1 346 | return ' #' . s:counter[name] 347 | else 348 | let s:counter[name] = 1 349 | return '' 350 | endif 351 | endfunction 352 | 353 | " TODO: Specifying ctags's -I option from some variable. 354 | "----------------------------------------------------------------------------- 355 | " C/C++ 356 | " 357 | " [c] classes 358 | " [d] macro definitions 359 | " e enumerators (values inside an enumeration) 360 | " [f] function definitions 361 | " [g] enumeration names 362 | " l local variables 363 | " m class, struct, and union members 364 | " [n] namespaces 365 | " p function prototypes 366 | " [s] structure names 367 | " [t] typedefs 368 | " [u] union names 369 | " v variable definitions 370 | " x external and forward variable declarations 371 | " 372 | let s:Ctags.lang_info.cpp = { 373 | \ 'name': 'C++', 374 | \ 'ctags_options': ' --c++-kinds=cdfgnstu ', 375 | \ 'scope_kinds' : ['namespace', 'class', 'struct'], 376 | \ 'scope_delim' : '::', 377 | \ } 378 | function! s:Ctags.lang_info.cpp.create_heading(tag, context) 379 | let line = a:context.lines[a:tag.lnum] 380 | let heading = { 381 | \ 'word' : a:tag.name, 382 | \ 'type' : a:tag.kind, 383 | \ 'lnum' : a:tag.lnum, 384 | \ } 385 | let ignore = 0 386 | if heading.type ==# 'function' 387 | " Function 388 | if a:tag.name =~# '^[[:upper:]_]\{3,}$' 389 | " Application of a macro was incorrectly parsed as a function 390 | " definition. 391 | let ignore = 1 392 | elseif has_key(a:tag, 'signature') 393 | let heading.word .= ' ' . a:tag.signature 394 | else 395 | let heading.word .= ' ' . s:get_param_list(a:context, a:tag.lnum) 396 | endif 397 | let heading.word .= s:get_tag_id(a:tag) 398 | elseif heading.type ==# 'macro' 399 | " Macro 400 | if line =~# '#undef\>' 401 | let ignore = 1 402 | else 403 | " Append its parameter list if exists. 404 | if line =~# a:tag.name . '(' 405 | let heading.word .= ' ' . s:get_param_list(a:context, a:tag.lnum) 406 | endif 407 | " Append what the macro will be expanded to. 408 | let heading.word .= s:get_tag_id(a:tag) . 409 | \ ' => ' . s:get_expanded(a:context, a:tag.lnum, a:tag.name) 410 | endif 411 | else 412 | " Otehrs 413 | let heading.word .= s:get_tag_id(a:tag) . ' : ' . a:tag.kind 414 | endif 415 | if has_key(a:tag, 'implementation') 416 | let heading.word .= ' <' . a:tag.implementation . '>' 417 | endif 418 | return ignore ? {} : heading 419 | endfunction 420 | 421 | function! s:get_expanded(context, lnum, macro) 422 | let line = a:context.lines[a:lnum] 423 | let expanded = matchstr(line, a:macro . '\%(([^)]*)\)\=\s\+\zs.*') 424 | let lnum = a:lnum + 1 425 | while strlen(expanded) < 10 && expanded =~ '\\\s*$' 426 | let expanded .= substitute(a:context.lines[lnum], '^\s*', ' ', '') 427 | let lnum += 1 428 | endwhile 429 | let expanded = substitute(expanded, '\\\s*$', ' ...', '') 430 | let expanded = substitute(expanded, '\s*\\\s*', ' ', 'g') 431 | return expanded 432 | endfunction 433 | 434 | let s:Ctags.lang_info.c = copy(s:Ctags.lang_info.cpp) 435 | call extend(s:Ctags.lang_info.c, { 436 | \ 'name': 'C', 437 | \ 'ctags_options': ' --c-kinds=cdfgnstu ' 438 | \ }, 'force') 439 | 440 | "----------------------------------------------------------------------------- 441 | " Java 442 | " 443 | " [c] classes 444 | " e enum constants 445 | " f fields 446 | " [g] enum types 447 | " [i] interfaces 448 | " l local variables 449 | " [m] methods 450 | " [p] packages 451 | " 452 | let s:Ctags.lang_info.java = { 453 | \ 'name': 'Java', 454 | \ 'ctags_options': ' --java-kinds=cgimp ', 455 | \ 'scope_kinds' : ['interface', 'class', 'enum'], 456 | \ 'scope_delim' : '.', 457 | \ } 458 | 459 | let &cpo = s:save_cpo 460 | unlet s:save_cpo 461 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/modules/file_cache.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/source/outline/_cache.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " Version : 0.5.1 6 | " License : MIT license {{{ 7 | " 8 | " Permission is hereby granted, free of charge, to any person obtaining 9 | " a copy of this software and associated documentation files (the 10 | " "Software"), to deal in the Software without restriction, including 11 | " without limitation the rights to use, copy, modify, merge, publish, 12 | " distribute, sublicense, and/or sell copies of the Software, and to 13 | " permit persons to whom the Software is furnished to do so, subject to 14 | " the following conditions: 15 | " 16 | " The above copyright notice and this permission notice shall be included 17 | " in all copies or substantial portions of the Software. 18 | " 19 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | " }}} 27 | "============================================================================= 28 | 29 | let s:save_cpo = &cpo 30 | set cpo&vim 31 | 32 | function! unite#sources#outline#modules#file_cache#import(dir) 33 | let s:FileCache.DIR = a:dir 34 | return s:FileCache 35 | endfunction 36 | 37 | "----------------------------------------------------------------------------- 38 | 39 | let s:Util = unite#sources#outline#import('Util') 40 | 41 | function! s:get_SID() 42 | return matchstr(expand(''), '\d\+_') 43 | endfunction 44 | let s:SID = s:get_SID() 45 | delfunction s:get_SID 46 | 47 | " FileCache module provides functions to access and manage the cache data 48 | " stored in files on the local filesystem. 49 | " 50 | let s:FileCache = unite#sources#outline#modules#base#new('FileCache', s:SID) 51 | 52 | if get(g:, 'unite_source_outline_debug', 0) 53 | let s:FileCache.CLEANUP_FILE_COUNT = 10 54 | let s:FileCache.CLEANUP_RATE = 1 55 | let s:FileCache.EXPIRES = 60 56 | else 57 | let s:FileCache.CLEANUP_FILE_COUNT = 300 58 | let s:FileCache.CLEANUP_RATE = 10 59 | let s:FileCache.EXPIRES = 60 * 60 * 24 * 30 60 | endif 61 | 62 | " Returns True if the cached data associated with buffer {bufnr} is available. 63 | " 64 | function! s:FileCache_has(bufnr) dict 65 | let path = s:get_buffer_path(a:bufnr) 66 | return s:cache_file_exists(path) 67 | endfunction 68 | call s:FileCache.function('has') 69 | 70 | " Returns True if the cache file associated with file {path} exists. 71 | " 72 | function! s:cache_file_exists(path) 73 | return (s:cache_dir_exists() && filereadable(s:get_cache_file_path(a:path))) 74 | endfunction 75 | 76 | " Returns True if the cache directory exists. 77 | " 78 | function! s:cache_dir_exists() 79 | if isdirectory(s:FileCache.DIR) 80 | return 1 81 | else 82 | try 83 | call mkdir(iconv(s:FileCache.DIR, &encoding, &termencoding), 'p') 84 | catch 85 | call unite#util#print_error("unite-outline: Couldn't create the cache directory.") 86 | endtry 87 | return isdirectory(s:FileCache.DIR) 88 | endif 89 | endfunction 90 | 91 | " Returns a full pathname of the file opened at the buffer {bufnr}. 92 | " 93 | function! s:get_buffer_path(bufnr) 94 | return fnamemodify(bufname(a:bufnr), ':p') 95 | endfunction 96 | 97 | " Returns a full pathname of the cache file for the file {path}. 98 | " 99 | function! s:get_cache_file_path(path) 100 | return s:FileCache.DIR . '/' . s:encode_file_path(a:path) 101 | endfunction 102 | 103 | " Encodes a full pathname to a basename. 104 | " 105 | " Original source from Shougo's neocomplcache 106 | " https://github.com/Shougo/neocomplcache 107 | " 108 | function! s:encode_file_path(path) 109 | if len(s:FileCache.DIR) + len(a:path) < 150 110 | " Encode {path} to a basename. 111 | return substitute(substitute(a:path, ':', '=-', 'g'), '[/\\]', '=+', 'g') 112 | else 113 | " Calculate a simple hash. 114 | let sum = 0 115 | for idx in range(len(a:path)) 116 | let sum += char2nr(a:path[idx]) * (idx + 1) 117 | endfor 118 | return printf('%X', sum) 119 | endif 120 | endfunction 121 | 122 | " Returns the cached data associated with buffer {bufnr}. 123 | " 124 | function! s:FileCache_get(bufnr) dict 125 | let path = s:get_buffer_path(a:bufnr) 126 | let data = s:load_cache_file(path) 127 | return data 128 | endfunction 129 | call s:FileCache.function('get') 130 | 131 | function! s:load_cache_file(path) 132 | let cache_file = s:get_cache_file_path(a:path) 133 | let lines = readfile(cache_file) 134 | if !empty(lines) 135 | let dumped_data = lines[0] 136 | call s:print_debug("[LOADED] cache file: " . cache_file) 137 | else 138 | throw "unite-outline: Couldn't load the cache file: " . cache_file 139 | endif 140 | " Touch; Update the timestamp. 141 | if writefile([dumped_data], cache_file) == 0 142 | call s:print_debug("[TOUCHED] cache file: " . cache_file) 143 | endif 144 | sandbox let data = eval(dumped_data) 145 | return data 146 | endfunction 147 | 148 | " Saves {data} to the cache file. 149 | " 150 | function! s:FileCache_set(bufnr, data) dict 151 | let path = s:get_buffer_path(a:bufnr) 152 | try 153 | if s:cache_dir_exists() 154 | call s:save_cache_file(path, a:data) 155 | elseif s:cache_file_exists(path) 156 | call s:remove_file(s:get_cache_file_path(path)) 157 | endif 158 | catch /^unite-outline:/ 159 | call unite#util#print_error(v:exception) 160 | endtry 161 | call s:cleanup_cache_files() 162 | endfunction 163 | call s:FileCache.function('set') 164 | 165 | function! s:save_cache_file(path, data) 166 | let cache_file = s:get_cache_file_path(a:path) 167 | let dumped_data = string(a:data) 168 | if writefile([dumped_data], cache_file) == 0 169 | call s:print_debug("[SAVED] cache file: " . cache_file) 170 | else 171 | throw "unite-outline: Couldn't save the cache to: " . cache_file 172 | endif 173 | endfunction 174 | 175 | " Remove the cached data associated with buffer {bufnr}. 176 | " 177 | function! s:FileCache_remove(bufnr) dict 178 | let path = s:get_buffer_path(a:bufnr) 179 | if s:cache_file_exists(path) 180 | try 181 | call s:remove_file(s:get_cache_file_path(path)) 182 | catch /^unite-outline:/ 183 | call unite#util#print_error(v:exception) 184 | endtry 185 | endif 186 | endfunction 187 | call s:FileCache.function('remove') 188 | 189 | function! s:remove_file(path) 190 | if delete(a:path) == 0 191 | call s:print_debug("[DELETED] cache file: " . a:path) 192 | else 193 | throw "unite-outline: Couldn't delete the cache file: " . a:path 194 | endif 195 | endfunction 196 | 197 | " Remove all cache files. 198 | " 199 | function! s:FileCache_clear() 200 | if s:cache_dir_exists() 201 | call s:cleanup_all_cache_files() 202 | echomsg "unite-outline: Deleted all cache files." 203 | else 204 | call unite#util#print_error("unite-outline: Cache directory doesn't exist.") 205 | endif 206 | endfunction 207 | call s:FileCache.function('clear') 208 | 209 | function! s:cleanup_all_cache_files() 210 | call s:cleanup_cache_files(1) 211 | endfunction 212 | 213 | " Remove old cache files. 214 | " 215 | function! s:cleanup_cache_files(...) 216 | let delete_all = (a:0 ? a:1 : 0) 217 | let cache_files = split(globpath(s:FileCache.DIR, '*'), "\") 218 | let dlt_files = [] 219 | 220 | if delete_all 221 | let dlt_files = cache_files 222 | elseif len(cache_files) > s:FileCache.CLEANUP_FILE_COUNT 223 | let now = localtime() 224 | if now % s:FileCache.CLEANUP_RATE == 0 225 | for path in cache_files 226 | if now - getftime(path) > s:FileCache.EXPIRES 227 | call add(dlt_files, path) 228 | endif 229 | endfor 230 | endif 231 | endif 232 | for path in dlt_files 233 | try 234 | call s:remove_file(path) 235 | catch /^unite-outline:/ 236 | call unite#util#print_error(v:exception) 237 | endtry 238 | endfor 239 | endfunction 240 | 241 | function! s:print_debug(msg) 242 | call s:Util.print_debug('cache', a:msg) 243 | endfunction 244 | 245 | let &cpo = s:save_cpo 246 | unlet s:save_cpo 247 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/modules/tree.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/source/outline/modules/tree.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " Version : 0.5.1 6 | " License : MIT license {{{ 7 | " 8 | " Permission is hereby granted, free of charge, to any person obtaining 9 | " a copy of this software and associated documentation files (the 10 | " "Software"), to deal in the Software without restriction, including 11 | " without limitation the rights to use, copy, modify, merge, publish, 12 | " distribute, sublicense, and/or sell copies of the Software, and to 13 | " permit persons to whom the Software is furnished to do so, subject to 14 | " the following conditions: 15 | " 16 | " The above copyright notice and this permission notice shall be included 17 | " in all copies or substantial portions of the Software. 18 | " 19 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | " }}} 27 | "============================================================================= 28 | 29 | let s:save_cpo = &cpo 30 | set cpo&vim 31 | 32 | function! unite#sources#outline#modules#tree#import() 33 | return s:Tree 34 | endfunction 35 | 36 | "----------------------------------------------------------------------------- 37 | 38 | function! s:get_SID() 39 | return matchstr(expand(''), '\d\+_') 40 | endfunction 41 | let s:SID = s:get_SID() 42 | delfunction s:get_SID 43 | 44 | " Tree module provides functions to build a tree structure. 45 | " There are two ways to build a Tree: 46 | " 47 | " A. Build a Tree from a List of objects with the level attribute using 48 | " Tree.build(). 49 | " 50 | " B. Build a Tree one node by one node manually using Tree.new() and 51 | " Tree.append_child(). 52 | " 53 | " The following example shows how to build a Tree in the latter way. 54 | " 55 | " == Example 56 | " 57 | " let s:Tree = unite#sources#outline#import('Tree') 58 | " 59 | " let root = s:Tree.new() 60 | " call s:Tree.append_child(root, heading_A) 61 | " call s:Tree.append_child(root, heading_B) 62 | " call s:Tree.append_child(heading_A, heading_1) 63 | " call s:Tree.append_child(heading_A, heading_2) 64 | " call s:Tree.append_child(heading_B, heading_3) 65 | " 66 | " |/ 67 | " 68 | " root 69 | " | 70 | " +--heading_A 71 | " | +--heading_1 72 | " | +--heading_2 73 | " | 74 | " +--heading_B 75 | " +--heading_3 76 | " 77 | let s:Tree = unite#sources#outline#modules#base#new('Tree', s:SID) 78 | let s:Tree.MAX_DEPTH = 20 79 | 80 | " Creates a new root node. 81 | " 82 | function! s:Tree_new() 83 | return { '__root__': 1, 'id': 0, 'level': 0, 'children': [] } 84 | endfunction 85 | call s:Tree.function('new') 86 | 87 | " Append {child} to a List of children of {node}. 88 | " 89 | function! s:Tree_append_child(node, child) 90 | if !has_key(a:node, 'children') 91 | let a:node.children = [] 92 | endif 93 | call add(a:node.children, a:child) 94 | " Ensure that all nodes have `children'. 95 | if !has_key(a:child, 'children') 96 | let a:child.children = [] 97 | " NOTE: While building a Tree, all nodes of the Tree pass through this 98 | " function as a:child. 99 | endif 100 | endfunction 101 | call s:Tree.function('append_child') 102 | 103 | " Builds a tree structure from a List of elements, which are Dictionaries with 104 | " `level' attribute, and then returns the root node of the built Tree. 105 | " 106 | " NOTE: This function allows discontinuous levels and can build a Tree from such 107 | " a sequence of levels well. 108 | " 109 | " root root 110 | " | | 111 | " +--1 +--1 112 | " [1, 3, 5, 5, 2, ...] => | +--3 => | +--2 113 | " | | +--5 | | +--3 114 | " | | +--5 | | +--3 115 | " | | | | 116 | " : +--2 : +--2 117 | " 118 | function! s:Tree_build(elems) 119 | let root = s:Tree_new() 120 | if empty(a:elems) | return root | endif 121 | " Build a Tree. 122 | let stack = [root] 123 | for elem in a:elems 124 | " Forget about the current children... 125 | let elem.children = [] 126 | " Make the top of the stack point to the parent. 127 | while elem.level <= stack[-1].level 128 | call remove(stack, -1) 129 | endwhile 130 | call s:Tree_append_child(stack[-1], elem) 131 | call add(stack, elem) 132 | endfor 133 | call s:normalize_levels(root) 134 | return root 135 | endfunction 136 | call s:Tree.function('build') 137 | 138 | " Normalize the level of nodes in accordance with the given Tree's structure. 139 | " 140 | " root root 141 | " | | 142 | " +--1 +--1 143 | " | +--3 | +--2 144 | " | | +--5 => | | +--3 145 | " | | +--5 | | +--3 146 | " | | | | 147 | " : +--2 : +--2 148 | " 149 | function! s:normalize_levels(node) 150 | for child in a:node.children 151 | let child.level = a:node.level + 1 152 | call s:normalize_levels(child) 153 | endfor 154 | endfunction 155 | 156 | " Flattens a Tree into a List with setting the levels of nodes. 157 | " 158 | function! s:Tree_flatten(node) 159 | let elems = [] 160 | for child in a:node.children 161 | let child.level = a:node.level + 1 162 | call add(elems, child) 163 | let elems += s:Tree_flatten(child) 164 | endfor 165 | return elems 166 | endfunction 167 | call s:Tree.function('flatten') 168 | 169 | "----------------------------------------------------------------------------- 170 | " Tree.List 171 | 172 | " Tree.List module provides functions to process a List of objects with the 173 | " level attribute in tree-aware way. 174 | " 175 | let s:List = unite#sources#outline#modules#base#new('List', s:SID) 176 | let s:Tree.List = s:List 177 | 178 | " Normalize the levels of {objs}. 179 | " 180 | function! s:List_normalize_levels(objs) 181 | let tree = s:Tree_build(a:objs) 182 | let objs = s:fast_flatten(tree) 183 | return objs 184 | endfunction 185 | call s:List.function('normalize_levels') 186 | 187 | " Flattens a Tree into a List without setting the levels of nodes. 188 | " 189 | function! s:fast_flatten(node) 190 | let objs = [] 191 | " Push toplevel nodes. 192 | let stack = reverse(copy(a:node.children)) 193 | while !empty(stack) 194 | " Pop a node. 195 | let node = remove(stack, -1) 196 | call add(objs, node) 197 | " Push the node's children. 198 | let stack += reverse(copy(node.children)) 199 | endwhile 200 | return objs 201 | endfunction 202 | 203 | " Resets the matched-marks of the candidates. 204 | " 205 | function! s:List_reset_marks(candidates) 206 | if empty(a:candidates) | return a:candidates | endif 207 | let prev_cand = { 208 | \ 'is_matched': 1, 'source__is_marked': 1, 209 | \ 'source__heading_level': 0, 210 | \ } 211 | for cand in a:candidates 212 | let cand.is_matched = 1 213 | let cand.source__is_marked = 1 214 | let prev_cand.source__has_marked_child = 215 | \ prev_cand.source__heading_level < cand.source__heading_level 216 | let prev_cand = cand 217 | endfor 218 | let cand.source__has_marked_child = 0 219 | endfunction 220 | call s:List.function('reset_marks') 221 | 222 | " Marks the matched candidates and their ancestors. 223 | " 224 | " * A candidate is MATCHED for which eval({pred}) returns True. 225 | " * A candidate is MARKED when any its child has been marked. 226 | " 227 | " NOTE: unite-outline's matcher and formatter see these flags to accomplish 228 | " their tree-aware filtering and formatting tasks. 229 | " 230 | function! s:List_mark(candidates, pred, ...) 231 | let pred = substitute(a:pred, '\', 'cand', 'g') 232 | let mark_reserved = map(range(0, s:Tree.MAX_DEPTH), 0) 233 | for cand in reverse(copy(a:candidates)) 234 | if !cand.source__is_marked 235 | continue 236 | endif 237 | let cand.is_matched = cand.is_matched && eval(pred) 238 | if cand.is_matched 239 | let matched_level = cand.source__heading_level 240 | if 1 < matched_level 241 | let mark_reserved[1 : matched_level - 1] = map(range(matched_level - 1), 1) 242 | endif 243 | endif 244 | let cand.source__is_marked = cand.is_matched 245 | if mark_reserved[cand.source__heading_level] 246 | let cand.source__is_marked = 1 247 | let cand.source__has_marked_child = 1 248 | let mark_reserved[cand.source__heading_level] = 0 249 | else 250 | let cand.source__has_marked_child = 0 251 | endif 252 | endfor 253 | endfunction 254 | call s:List.function('mark') 255 | 256 | " Remove the matched headings and their descendants. 257 | " 258 | function! s:List_remove(headings, pred) 259 | let pred = substitute(a:pred, '\', 'head', 'g') 260 | let matched_level = s:Tree.MAX_DEPTH + 1 261 | let headings = [] 262 | for head in a:headings 263 | if head.level <= matched_level 264 | if eval(pred) 265 | let matched_level = head.level 266 | else 267 | let matched_level = s:Tree.MAX_DEPTH + 1 268 | call add(headings, head) 269 | endif 270 | endif 271 | endfor 272 | return headings 273 | endfunction 274 | call s:List.function('remove') 275 | 276 | unlet s:List 277 | 278 | let &cpo = s:save_cpo 279 | unlet s:save_cpo 280 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/modules/util.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/source/outline/modules/util.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " Version : 0.5.1 6 | " License : MIT license {{{ 7 | " 8 | " Permission is hereby granted, free of charge, to any person obtaining 9 | " a copy of this software and associated documentation files (the 10 | " "Software"), to deal in the Software without restriction, including 11 | " without limitation the rights to use, copy, modify, merge, publish, 12 | " distribute, sublicense, and/or sell copies of the Software, and to 13 | " permit persons to whom the Software is furnished to do so, subject to 14 | " the following conditions: 15 | " 16 | " The above copyright notice and this permission notice shall be included 17 | " in all copies or substantial portions of the Software. 18 | " 19 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | " }}} 27 | "============================================================================= 28 | 29 | let s:save_cpo = &cpo 30 | set cpo&vim 31 | 32 | function! unite#sources#outline#modules#util#import() 33 | return s:Util 34 | endfunction 35 | 36 | "----------------------------------------------------------------------------- 37 | 38 | function! s:get_SID() 39 | return matchstr(expand(''), '\d\+_') 40 | endfunction 41 | let s:SID = s:get_SID() 42 | delfunction s:get_SID 43 | 44 | let s:Util = unite#sources#outline#modules#base#new('Util', s:SID) 45 | 46 | "----------------------------------------------------------------------------- 47 | " Heading 48 | 49 | function! s:Util_get_indent_level(context, lnum) 50 | let line = a:context.lines[a:lnum] 51 | let sw = a:context.buffer.sw 52 | let ts = a:context.buffer.ts 53 | let indent = substitute(matchstr(line, '^\s*'), '\t', repeat(' ', ts), 'g') 54 | return strlen(indent) / sw + 1 55 | endfunction 56 | call s:Util.function('get_indent_level') 57 | 58 | function! s:Util_get_comment_heading_level(context, lnum, ...) 59 | let line = a:context.lines[a:lnum] 60 | if line =~ '^\s' 61 | let level = (a:0 ? a:1 : s:Util_get_indent_level(a:context, a:lnum) + 3) 62 | else 63 | let level = (strlen(substitute(line, '\s*', '', 'g')) > 40 ? 2 : 3) 64 | let level -= (line =~ '=') 65 | endif 66 | return level 67 | endfunction 68 | call s:Util.function('get_comment_heading_level') 69 | 70 | "----------------------------------------------------------------------------- 71 | " Matching 72 | 73 | " join_to( {context}, {lnum}, {pattern} [, {limit}]) 74 | function! s:Util_join_to(context, lnum, pattern, ...) 75 | let lines = a:context.lines 76 | let limit = (a:0 ? a:1 : 3) 77 | if limit < 0 78 | return s:join_to_backward(lines, a:lnum, a:pattern, limit * -1) 79 | endif 80 | let lnum = a:lnum 81 | let limit = min([a:lnum + limit, len(lines) - 1]) 82 | while lnum <= limit 83 | let line = lines[lnum] 84 | if line =~# a:pattern 85 | break 86 | endif 87 | let lnum += 1 88 | endwhile 89 | return join(lines[a:lnum : lnum], "\n") 90 | endfunction 91 | call s:Util.function('join_to') 92 | 93 | function! s:join_to_backward(context, lnum, pattern, limit) 94 | let lines = a:context.lines 95 | let limit = max(1, a:lnum - a:limit]) 96 | while lnum > 0 97 | let line = lines[lnum] 98 | if line =~# a:pattern 99 | break 100 | endif 101 | let lnum -= 1 102 | endwhile 103 | return join(lines[lnum : a:lnum], "\n") 104 | endfunction 105 | 106 | function! s:Util_join_to_rparen(context, lnum, ...) 107 | let limit = (a:0 ? a:1 : 3) 108 | let line = s:Util_join_to(a:context, a:lnum, ')', limit) 109 | let line = substitute(line, "\\s*\n\\s*", ' ', 'g') 110 | let line = substitute(line, ')\zs.*$', '', '') 111 | return line 112 | endfunction 113 | call s:Util.function('join_to_rparen') 114 | 115 | " neighbor_match( {context}, {lnum}, {pattern} [, {range} [, {exclusive}]) 116 | function! s:Util_neighbor_match(context, lnum, pattern, ...) 117 | let lines = a:context.lines 118 | let range = get(a:000, 0, 1) 119 | let exclusive = !!get(a:000, 1, 0) 120 | if type(range) == type([]) 121 | let [prev, next] = range 122 | else 123 | let [prev, next] = [range, range] 124 | endif 125 | let [bwd_range, fwd_range] = s:neighbor_ranges(a:context, a:lnum, prev, next, exclusive) 126 | for lnum in bwd_range 127 | if lines[lnum] =~# a:pattern 128 | return 1 129 | endif 130 | endfor 131 | for lnum in fwd_range 132 | if lines[lnum] =~# a:pattern 133 | return 1 134 | endif 135 | endfor 136 | return 0 137 | endfunction 138 | call s:Util.function('neighbor_match') 139 | 140 | function! s:neighbor_ranges(context, lnum, prev, next, exclusive) 141 | let max_lnum = len(a:context.lines) - 1 142 | let bwd_range = range(max([1, a:lnum - a:prev]), max([1, a:lnum - a:exclusive])) 143 | let fwd_range = range(min([a:lnum + a:exclusive, max_lnum]), min([a:lnum + a:next, max_lnum])) 144 | return [bwd_range, fwd_range] 145 | endfunction 146 | 147 | " neighbor_matchstr( {context}, {lnum}, {pattern} [, {range} [, {exclusive}]) 148 | function! s:Util_neighbor_matchstr(context, lnum, pattern, ...) 149 | let lines = a:context.lines 150 | let range = get(a:000, 0, 1) 151 | let exclusive = !!get(a:000, 1, 0) 152 | if type(range) == type([]) 153 | let [prev, next] = range 154 | else 155 | let [prev, next] = [range, range] 156 | endif 157 | let [bwd_range, fwd_range] = s:neighbor_ranges(a:context, a:lnum, prev, next, exclusive) 158 | for lnum in bwd_range 159 | let matched = matchstr(lines[lnum], a:pattern) 160 | if !empty(matched) 161 | return matched 162 | endif 163 | endfor 164 | for lnum in fwd_range 165 | let matched = matchstr(lines[lnum], a:pattern) 166 | if !empty(matched) 167 | return matched 168 | endif 169 | endfor 170 | return "" 171 | endfunction 172 | call s:Util.function('neighbor_matchstr') 173 | 174 | let s:SHARED_PATTERNS = { 175 | \ '*': { 176 | \ 'parameter_list': '\S\s*\zs([^)]*)', 177 | \ 'parameter_list_and_after': '\S\s*\zs([^)]*).*$', 178 | \ 'after_lbrace' : '{.*$', 179 | \ 'after_lbracket': '[.*$', 180 | \ 'after_lparen' : '(.*$', 181 | \ 'after_colon' : ':.*$', 182 | \ }, 183 | \ 'c': { 184 | \ 'heading-1': '^\s*\/\*\s*[-=*]\{10,}\s*$', 185 | \ 'header' : ['^/\*', '\*/\s*$'], 186 | \ }, 187 | \ 'cpp': { 188 | \ 'heading-1': '^\s*/[/*]\s*[-=/*]\{10,}\s*$', 189 | \ 'header' : { 190 | \ 'leading': '^//', 191 | \ 'block' : ['^/\*', '\*/\s*$'], 192 | \ }, 193 | \ }, 194 | \ 'sh': { 195 | \ 'heading-1': '^\s*#\s*[-=#]\{10,}\s*$', 196 | \ 'header' : '^#', 197 | \ }, 198 | \} 199 | 200 | function! s:Util_shared_pattern(filetype, which) 201 | return s:SHARED_PATTERNS[a:filetype][a:which] 202 | endfunction 203 | call s:Util.function('shared_pattern') 204 | 205 | "----------------------------------------------------------------------------- 206 | " List 207 | 208 | let s:List = unite#sources#outline#modules#base#new('List', s:SID) 209 | let s:Util.List = s:List 210 | 211 | function! s:List_sort_by_lnum(dicts) 212 | return sort(a:dicts, 's:compare_by_lnum') 213 | endfunction 214 | function! s:compare_by_lnum(d1, d2) 215 | let n1 = a:d1.lnum 216 | let n2 = a:d2.lnum 217 | return n1 == n2 ? 0 : n1 > n2 ? 1 : -1 218 | endfunction 219 | call s:List.function('sort_by_lnum') 220 | 221 | unlet s:List 222 | 223 | "----------------------------------------------------------------------------- 224 | " Path 225 | 226 | let Path = unite#sources#outline#modules#base#new('Path', s:SID) 227 | let s:Util.Path = Path 228 | 229 | " Path.normalize( {path} [, {mods}]) 230 | function! s:Path_normalize(path, ...) 231 | let path = a:path 232 | if a:0 233 | let mods = a:0 234 | let path = fnamemodify(path, mods) 235 | endif 236 | let path = substitute(path, '[/\\]', '/', 'g') 237 | return path 238 | endfunction 239 | call Path.function('normalize') 240 | 241 | unlet Path 242 | 243 | "----------------------------------------------------------------------------- 244 | " String 245 | 246 | let String = unite#sources#outline#modules#base#new('String', s:SID) 247 | let s:Util.String = String 248 | 249 | " String.capitalize( {str} [, {flag}]) 250 | function! s:String_capitalize(str, ...) 251 | let flag = (a:0 ? a:1 : '') 252 | return substitute(a:str, '\<\(\h\)\(\w\+\)\>', '\u\1\L\2', flag) 253 | endfunction 254 | call String.function('capitalize') 255 | 256 | " Ported from: 257 | " Sample code from Programing Ruby, page 145 258 | " 259 | function! s:String_nr2roman(nr) 260 | if a:nr <= 0 || 4999 < a:nr 261 | return string(a:nr) 262 | endif 263 | let factors = [ 264 | \ ["M", 1000], ["CM", 900], ["D", 500], ["CD", 400], 265 | \ ["C", 100], ["XC", 90], ["L", 50], ["XL", 40], 266 | \ ["X", 10], ["IX", 9], ["V", 5], ["IV", 4], 267 | \ ["I", 1], 268 | \] 269 | let nr = a:nr 270 | let roman = "" 271 | for [code, factor] in factors 272 | let cnt = nr / factor 273 | let nr = nr % factor 274 | if cnt > 0 275 | let roman .= repeat(code, cnt) 276 | endif 277 | endfor 278 | return roman 279 | endfunction 280 | call String.function('nr2roman') 281 | 282 | function! s:String_shellescape(str) 283 | if &shell =~? '^\%(cmd\%(\.exe\)\=\|command\.com\)\%(\s\|$\)' 284 | return '"' . substitute(a:str, '"', '""', 'g') . '"' 285 | else 286 | return "'" . substitute(a:str, "'", "'\\\\''", 'g') . "'" 287 | endif 288 | endfunction 289 | call String.function('shellescape') 290 | 291 | unlet String 292 | 293 | "----------------------------------------------------------------------------- 294 | " Misc 295 | 296 | function! s:Util_print_debug(which, msg) 297 | if get(g:, 'unite_source_outline_' . a:which . '_debug', 0) 298 | echomsg "unite-outline: " . a:msg 299 | endif 300 | endfunction 301 | call s:Util.function('print_debug') 302 | 303 | function! s:Util_print_progress(msg) 304 | echon a:msg 305 | redraw 306 | endfunction 307 | call s:Util.function('print_progress') 308 | 309 | function! s:Util__cpp_is_in_comment(heading_line, matched_line) 310 | return ((a:matched_line =~ '^\s*//' && a:heading_line =~ '^\s*//') || 311 | \ (a:matched_line =~ '^\s*/\*' && a:matched_line !~ '\*/\s*$')) 312 | endfunction 313 | call s:Util.function('_cpp_is_in_comment') 314 | 315 | let &cpo = s:save_cpo 316 | unlet s:save_cpo 317 | -------------------------------------------------------------------------------- /autoload/unite/sources/outline/util.vim: -------------------------------------------------------------------------------- 1 | "============================================================================= 2 | " File : autoload/unite/source/outline/util.vim 3 | " Author : h1mesuke 4 | " Updated : 2012-01-11 5 | " Version : 0.5.1 6 | " License : MIT license {{{ 7 | " 8 | " Permission is hereby granted, free of charge, to any person obtaining 9 | " a copy of this software and associated documentation files (the 10 | " "Software"), to deal in the Software without restriction, including 11 | " without limitation the rights to use, copy, modify, merge, publish, 12 | " distribute, sublicense, and/or sell copies of the Software, and to 13 | " permit persons to whom the Software is furnished to do so, subject to 14 | " the following conditions: 15 | " 16 | " The above copyright notice and this permission notice shall be included 17 | " in all copies or substantial portions of the Software. 18 | " 19 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 | " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 | " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 | " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | " }}} 27 | "============================================================================= 28 | 29 | let s:save_cpo = &cpo 30 | set cpo&vim 31 | 32 | let s:Util = unite#sources#outline#import('Util') 33 | 34 | " NOTE: All of the functions in this file are obsolete now. If you need any of 35 | " them, please import Util module and call them as Dictionary functions. 36 | 37 | "----------------------------------------------------------------------------- 38 | " Heading 39 | 40 | function! unite#sources#outline#util#get_indent_level(...) 41 | return call(s:Util.get_indent_level, a:000) 42 | endfunction 43 | 44 | function! unite#sources#outline#util#get_comment_heading_level(...) 45 | return call(s:Util.get_comment_heading_level, a:000) 46 | endfunction 47 | 48 | "----------------------------------------------------------------------------- 49 | " Matching 50 | 51 | function! unite#sources#outline#util#join_to(...) 52 | return call(s:Util.join_to, a:000) 53 | endfunction 54 | 55 | function! unite#sources#outline#util#join_to_rparen(...) 56 | return call(s:Util.join_to_rparen, a:000) 57 | endfunction 58 | 59 | function! unite#sources#outline#util#neighbor_match(...) 60 | return call(s:Util.neighbor_match, a:000) 61 | endfunction 62 | 63 | function! unite#sources#outline#util#neighbor_matchstr(...) 64 | return call(s:Util.neighbor_matchstr, a:000) 65 | endfunction 66 | 67 | function! unite#sources#outline#util#shared_pattern(...) 68 | return call(s:Util.shared_pattern, a:000) 69 | endfunction 70 | 71 | "----------------------------------------------------------------------------- 72 | " Path 73 | 74 | function! unite#sources#outline#util#normalize_path(...) 75 | return call(s:Util.Path.normalize, a:000) 76 | endfunction 77 | 78 | "----------------------------------------------------------------------------- 79 | " String 80 | 81 | function! unite#sources#outline#util#capitalize(...) 82 | return call(s:Util.String.capitalize, a:000) 83 | endfunction 84 | 85 | function! unite#sources#outline#util#nr2roman(...) 86 | return call(s:Util.String.nr2roman, a:000) 87 | endfunction 88 | 89 | function! unite#sources#outline#util#shellescape(...) 90 | return call(s:Util.String.shellescape, a:000) 91 | endfunction 92 | 93 | "----------------------------------------------------------------------------- 94 | " Misc 95 | 96 | function! unite#sources#outline#util#print_debug(...) 97 | return call(s:Util.print_debug, a:000) 98 | endfunction 99 | 100 | function! unite#sources#outline#util#print_progress(...) 101 | return call(s:Util.print_progress, a:000) 102 | endfunction 103 | 104 | function! unite#sources#outline#util#sort_by_lnum(...) 105 | return call(s:Util.List.sort_by_lnum, a:000) 106 | endfunction 107 | 108 | function! unite#sources#outline#util#_cpp_is_in_comment(...) 109 | return call(s:Util._cpp_is_in_comment, a:000) 110 | endfunction 111 | 112 | let &cpo = s:save_cpo 113 | unlet s:save_cpo 114 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | tags-* 3 | -------------------------------------------------------------------------------- /doc/unite-outline.jax: -------------------------------------------------------------------------------- 1 | *unite-outline.txt* バッファの見出し一覧を表示し、ジャンプ機能を提供する。 2 | 3 | Author : h1mesuke 4 | Updated : 2012-01-11 5 | Version : 0.5.1 6 | License : MIT license {{{ 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | "Software"), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | }}} 26 | 27 | 目次 *unite-outline-contents* 28 | 29 | 概要 |unite-outline-introduction| 30 | インストール |unite-outline-install| 31 | 使い方 |unite-outline-usage| 32 | 設定 |unite-outline-settings| 33 | 変数 |unite-outline-variables| 34 | 設定例 |unite-outline-settings-example| 35 | Outline Info |unite-outline-info| 36 | outline info の作成 |unite-outline-info-create| 37 | outline info の属性 |unite-outline-info-attributes| 38 | 外部プログラム |unite-outline-info-external-programs| 39 | 関数 |unite-outline-functions| 40 | ユーティリティ関数 |unite-outline-utility-functions| 41 | ToDo |unite-outline-todo| 42 | 既知の問題 |unite-outline-known-issues| 43 | 更新履歴 |unite-outline-changelog| 44 | 45 | ============================================================================== 46 | 概要 *unite-outline-introduction* 47 | 48 | *unite-outline* は、バッファの見出しを抽出し、|unite|のインターフェー 49 | スを使ってそれらを一覧表示、各見出しへのジャンプ機能を提供する source 50 | です。見出しを抽出するためのパターンおよび見出しレベルの決定ロジックを 51 | ファイルタイプごとに設定することができ、ユーザーによる高度なカスタマイ 52 | ズが可能です。 53 | 54 | ============================================================================== 55 | インストール *unite-outline-install* 56 | 57 | 配布アーカイブに含まれるファイル群を、そのフォルダごと Vim の 58 | 'runtimepath' にコピーします。 $HOME/.vim(Windows の場合は 59 | $HOME/vimfiles)へのインストールがもっとも一般的でしょう。 60 | インストール後の配置は 61 | 62 | $HOME/.vim/autoload/unite/sources/outline.vim 63 | $HOME/.vim/autoload/unite/sources/outline/ 64 | $HOME/.vim/autoload/unite/filters/*.vim 65 | $HOME/.vim/doc/unite-outline.* 66 | 67 | になります。 68 | 69 | インストールに成功すると :Unite outline でバッファの見出し一覧を表示で 70 | きます。(そのファイルタイプ用の outline info が存在する場合) 71 | 72 | ============================================================================== 73 | 使い方 *unite-outline-usage* 74 | 75 | |unite|の使い方については、unite.vim のヘルプを参照して下さい。ここで 76 | は、unite.vim の source である unite-outline の使い方を説明します。 77 | 78 | 見出し一覧を表示する ~ 79 | 80 | バッファの見出し一覧を表示するには、source として outline を指定し、 81 | :Unite を実行します。 82 | > 83 | :Unite outline 84 | < 85 | これにより、ファイルタイプごとに定義された outline info にもとづく見出 86 | しの抽出が行われ、unite のインターフェースを使って見出しの一覧が表示さ 87 | れます。表示された一覧から見出しを選択すると、該当箇所へジャンプできま 88 | す。 89 | 90 | 抽出された見出しはキャッシュされ、2回目以降は見出し一覧の表示が高速に 91 | なります。 92 | 93 | 見出しを絞り込む ~ 94 | 95 | |unite-usage|を参照 96 | 97 | 見出し一覧を更新する ~ 98 | 99 | キャッシュの内容を破棄し、見出しの抽出をやり直したい場合は、outline の 100 | 引数に "!" を指定して :Unite を実行します。 101 | > 102 | :Unite outline:! 103 | < 104 | もしくは、見出し一覧が表示されている状態(ノーマルモード)で 105 | |(unite_redraw)|(デフォルトのキーマッピングでは )を実行し 106 | ます。 107 | 108 | NOTE: バージョン 0.5.0 から見出しの自動更新が可能になりました。 109 | 詳細は|unite-outline-filetype-option-auto-update|を参照 110 | 111 | ============================================================================== 112 | 設定 *unite-outline-settings* 113 | 114 | ------------------------------------------------------------------------------ 115 | 変数 *unite-outline-variables* 116 | 117 | g:unite_source_outline_info *g:unite_source_outline_info* 118 | 119 | ファイルタイプごとの outline info を格納する辞書 120 | オートロード関数を使わず、vimrc にて直に outline info を定義す 121 | る場合にのみ、作成した outline info をこの辞書に登録します。 122 | 123 | outline info ついては 124 | |unite-outline-info|, |unite-outline-info-create|を参照 125 | 126 | 初期値は {} 127 | 128 | unite-outline に同梱されている outline info はオートロード関数 129 | によって遅延ロードされるため、この辞書の初期値は空になっていま 130 | す。 131 | *g:unite_source_outline_indent_width* 132 | g:unite_source_outline_indent_width 133 | 134 | 見出しレベルに応じて設定されるインデントの幅 135 | unite-outline はこの値にもとづいて見出し一覧のインデントを生成 136 | します。 137 | 138 | 初期値は 2 139 | *g:unite_source_outline_filetype_options* 140 | g:unite_source_outline_filetype_options 141 | 142 | ファイルタイプごとのオプション設定を行うための辞書 143 | ファイルタイプごとに、オプション名をキー、オプション値を値とす 144 | る辞書を設定します。 145 | 146 | 「すべてのファイルタイプ」を意味する特殊なファイルタイプ名とし 147 | て "*" が使用できます。個別の設定がなされていないファイルタイ 148 | プにはその設定が適用されます。 149 | 150 | 初期値は {} 151 | 152 | 設定例: > 153 | let g:unite_source_outline_filetype_options = { 154 | \ '*': { 155 | \ 'auto_update': 1, 156 | \ 'auto_update_event': 'write', 157 | \ }, 158 | \ 'cpp': { 159 | \ 'auto_update': 0, 160 | \ }, 161 | \ 'javascript': { 162 | \ 'ignore_types': ['comment'], 163 | \ }, 164 | \ 'markdown': { 165 | \ 'auto_update_event': 'hold', 166 | \ }, 167 | \} 168 | < 169 | 設定可能なオプション ~ 170 | 171 | auto_update *unite-outline-filetype-option-auto-update* 172 | 173 | 見出しの自動更新を行うかどうか。 174 | デフォルト値は 1 175 | 176 | *unite-outline-filetype-option-auto-update-event* 177 | auto_update_event 178 | 179 | 見出しの自動更新を行うタイミング 180 | 以下のいずれか。 181 | 182 | 値 見出しの更新契機 183 | -------------------------------------------- 184 | "write" |BufWritePost| 185 | "hold" |BufWritePost|, |CursorHold| 186 | 187 | デフォルト値は "write" 188 | 189 | NOTE: 見出しの更新は、前回の更新時からバッファの内容が 190 | 変更されていた場合にのみ行われます。また、"hold" を使 191 | 用する場合、'updatetime' が見出しの更新間隔になります 192 | ので、適切な値に設定して下さい。 193 | 194 | ignore_types *unite-outline-filetype-option-ignore-types* 195 | 196 | 非表示にしたい見出しの種類のリスト 197 | 指定可能な見出しの種類については outline info の定義を 198 | 参照 199 | 200 | デフォルト値は [] 201 | 202 | *g:unite_source_outline_max_headings* 203 | g:unite_source_outline_max_headings 204 | 205 | 抽出する見出し数の上限 206 | 見出しの数がこの値に達すると見出しの抽出を打ち切ります。 207 | 208 | 初期値は 1000 209 | *g:unite_source_outline_cache_limit* 210 | g:unite_source_outline_cache_limit 211 | 212 | キャッシュ永続化の行数しきい値 213 | 214 | 見出しのキャッシュは通常バッファローカル変数に保存されますが、 215 | 見出し抽出の対象バッファの行数がこの値より大きい場合、キャッ 216 | シュをファイルにも保存します。 217 | 218 | キャッシュがファイルに保存されると、Vim の再起動後もそのファイ 219 | ルから見出しを読み込むため、大きなバッファの見出し一覧の表示が 220 | 初回から高速になります。 221 | 222 | 初期値は 1000 223 | *g:unite_source_outline_highlight* 224 | g:unite_source_outline_highlight 225 | 226 | 見出し一覧のハイライトを指定するための辞書 227 | 見出しのグループごとに適用するハイライトを変更できます。 228 | 229 | 初期値は {} 230 | 231 | 設定例: > 232 | let g:unite_source_outline_highlight = { 233 | \ 'comment' : 'Comment', 234 | \ 'expanded': 'Constant', 235 | \ 'function': 'Function', 236 | \ 'id' : 'Special', 237 | \ 'macro' : 'Macro', 238 | \ 'method' : 'Function', 239 | \ 'normal' : g:unite_abbr_highlight, 240 | \ 'package' : g:unite_abbr_highlight, 241 | \ 'special' : 'Macro', 242 | \ 'type' : 'Type', 243 | \ 'level_1' : 'Type', 244 | \ 'level_2' : 'PreProc', 245 | \ 'level_3' : 'Identifier', 246 | \ 'level_4' : 'Constant', 247 | \ 'level_5' : 'Special', 248 | \ 'level_6' : g:unite_abbr_highlight, 249 | \ 'parameter_list': g:unite_abbr_highlight, 250 | \ } 251 | < 252 | ハイライトを適用する部分を指定するためのパターンは、個々のファ 253 | イルタイプ用の outline info で定義します。 254 | 255 | 詳細は|unite-outline-info-highlight_rules|を参照 256 | 257 | ------------------------------------------------------------------------------ 258 | 設定例 *unite-outline-settings-example* 259 | > 260 | nnoremap [unite] 261 | nmap f [unite] 262 | 263 | nnoremap [unite]o :Unite -buffer-name=outline outline 264 | 265 | call unite#set_buffer_name_option('outline', 'ignorecase', 1) 266 | call unite#set_buffer_name_option('outline', 'smartcase', 1) 267 | < 268 | ============================================================================== 269 | Outline Info *unite-outline-info* 270 | 271 | unite-outline では、ファイルタイプごとの見出しの抽出パターンと、見出し 272 | レベルの決定ロジック(関数)などを outline info と呼ばれる辞書によって 273 | 定義します。これを vimrc にて、あるいは所定の位置に配置した Vim script 274 | によって記述することで、ファイルタイプごとの見出し抽出と見出し一覧の作 275 | 成を自在にカスタマイズできます。 276 | 277 | 見出し一覧の表示を実行した際、対象バッファのファイルタイプにもとづき 278 | outline info の探索が実行されます。探索の順序は以下の通りです。 279 | 280 | 1. g:unite_source_outline_info.{filetype} 281 | 2. outline#{filetype}#outline_info() 282 | 3. unite#sources#outline#{filetype}#outline_info() 283 | 4. unite#sources#outline#defaults#{filetype}#outline_info() 284 | 285 | ------------------------------------------------------------------------------ 286 | outline info の作成 *unite-outline-info-create* 287 | 288 | unite-outline に同梱されている outline info ではなく、ユーザー独自の 289 | outline info を作成/使用したい場合、その方法は以下の2つです。 290 | 291 | A. オートロード関数を定義する。 [推奨] 292 | 293 | * $HOME/.vim/autoload/unite/sources/outline/ に 294 | {filetype}.vim を作成し、そこにオートロード関数 295 | unite#sources#outline#{filetype}#outline_info() を定義する。 296 | 297 | または 298 | 299 | $HOME/.vim/autoload/outline/ に 300 | {filetype}.vim を作成し、そこにオートロード関数 301 | outline#{filetype}#outline_info() を定義する。 302 | 303 | * 関数の返値として、outline info(辞書)を返す。 304 | 305 | この方法で定義した outline info は必要になるまでロードされませ 306 | ん。 vimrc を肥大化させることもないので、outline info を作り込 307 | むのであればこちらの方法がおすすめです。 308 | 309 | $HOME/.vim/autoload/unite/sources/outline/defaults/ にあるデフ 310 | ォルトの outline info はすべてこの方法で定義されています。 311 | 312 | B. vimrc にてグローバル変数に設定する。 [非推奨] 313 | 314 | * vimrc にて g:unite_source_outline_info.{filetype} に直接 315 | outline info を設定する。 316 | 317 | 定義例(Ruby用): > 318 | let g:unite_source_outline_info.ruby = { 319 | \ 'heading': '^\s*\(module\|class\|def\)\>', 320 | \ 'skip': { 321 | \ 'header': '^#', 322 | \ 'block' : ['^=begin', '^=end'], 323 | \ }, 324 | \} 325 | < 326 | ------------------------------------------------------------------------------ 327 | outline info の属性 *unite-outline-info-attributes* 328 | 329 | outline info の属性は以下の通りです。unite-outline はそれぞれの属性に 330 | 設定された値にもとづき、ファイルタイプ固有の見出し抽出を行います。 331 | 332 | EXTRACTING HEADINGS BY CALLBACK ~ 333 | *unite-outline-info-heading-1* 334 | heading-1 文字列(任意) 335 | 336 | 「次の行が」見出しであるような行にマッチするパターン 337 | これを設定することで、例えば 338 | > 339 | ========================================= 340 | 見出し1 341 | < 342 | や 343 | > 344 | ----------------------------------------- 345 | 見出し2 346 | < 347 | のような、飾りの枠線の下にくるタイプの見出しを抽出できます。 348 | また、 349 | > 350 | /**************************************** 351 | * 352 | * 見出し3 353 | * 354 | ****************************************/ 355 | < 356 | こういうタイプの見出しにも対応できるよう、次の行が実質上の空行 357 | とみなせる場合は、もうひとつ次の行も見るにようになっています。 358 | 359 | 定義例: > 360 | let s:outline_info = { 361 | \ 'heading-1': '^[-=]\{10,}\s*$', 362 | \ } 363 | < 364 | *unite-outline-info-heading* 365 | heading 文字列(任意) 366 | 367 | 「その行が」見出しであるような行にマッチするパターン 368 | 369 | 定義例(HTML用): > 370 | let s:outline_info = { 371 | \ 'heading': '<[hH][1-6][^>]*>', 372 | \ } 373 | < 374 | *unite-outline-info-heading-pattern-restrictions* 375 | 重要:使用できる正規表現の制約 ~ 376 | 377 | heading-1, heaging, heading+1 のパターンとして使用できる正規表 378 | 現には以下の制約があります。 379 | 380 | 1. 'magic'オプションがオンである場合の書法を用いること 381 | 2. 後方参照(\1..\9)を使用しないこと |/magic|, |/\1| 382 | 383 | これらは、見出し抽出時のパターンマッチングの速度を最大限に上げ 384 | るためにもうけられている制約です。見出しの抽出に後方参照が必要 385 | な場合は、 heading-1, heading, heading+1 には後方参照のない緩 386 | めのパターンを設定し、マッチ後の create_heading()関数にて再度、 387 | 後方参照を用いた厳密なマッチングを行うといった方法で対処して下 388 | さい。 389 | *unite-outline-info-heading+1* 390 | heading+1 文字列(任意) 391 | 392 | 「前の行が」見出しであるような行にマッチするパターン 393 | これを設定することで、例えば Markdown の 394 | > 395 | 見出し 396 | ------ 397 | < 398 | のような、下線をともなうタイプの見出しを抽出できます。 399 | 400 | 定義例(Markdown用): > 401 | let s:outline_info = { 402 | \ 'heading' : '^#\+', 403 | \ 'heading+1': '^[-=]\+$', 404 | \ } 405 | < 406 | *unite-outline-info-create_heading()* 407 | create_heading 関数(任意) 408 | 409 | create_heading( 410 | {which}, {heading-line}, {matched-line}, {context}) 411 | 412 | 設定されていると、heading-1, heading, heading+1 によるマッチが 413 | 成功するたびに呼び出されます。 414 | 返値として見出しオブジェクト(辞書)を返します。 415 | 416 | この関数を定義することで、見出し一覧に設定する文字列の整形、お 417 | よび見出しレベル(インデント)の設定が行えます。 418 | 419 | create_heading()関数に渡される引数は以下の通りです。 420 | 421 | * {which} 文字列 422 | マッチの種類 423 | "heading-1", "heading", "heading+1" の 424 | いずれか 425 | 426 | * {heading-line} 文字列 427 | 見出しとなる行 428 | 429 | * {matched-line} 文字列 430 | マッチした行 431 | 432 | *unite-outline-context-object* 433 | * {context} 辞書 434 | その他の情報、以下の属性を含む 435 | 436 | * heading_lnum 整数 437 | {heading-line} の行番号 438 | 439 | * matched_lnum 整数 440 | {matched-line} の行番号 441 | 442 | * lines リスト 443 | バッファの全行 444 | リストの添字と行番号が一致するよう、ダ 445 | ミーの空行が先頭に付加されている。イテ 446 | レートの際は注意。 447 | 448 | * buffer 辞書 449 | バッファ情報 450 | 451 | * nr 整数 452 | バッファ番号 453 | 454 | * path 文字列 455 | バッファで編集中のファイルのパス 456 | 457 | * filetype 文字列 458 | バッファのファイルタイプ 459 | 460 | 参照可能なすべての属性については 461 | autoload/unite/source/outline.vim を参 462 | 照 463 | 464 | * outline_info 辞書 465 | outline info 466 | 467 | {context} に渡される辞書は見出し抽出の間同じものが使い回されま 468 | すので、既存の属性を書き換えないで下さい。 469 | 470 | *unite-outline-heading-object* 471 | HEADING OBJECT ~ 472 | 473 | 返値となる辞書には以下の属性を設定します。 474 | 475 | * word 文字列(必須) 476 | 見出し一覧に表示される文字列 477 | 478 | * level 整数 (任意) 479 | 見出しレベル 480 | 設定しておくと、見出し一覧に表示される際、レベ 481 | ルに応じたインデントが付加されます。 482 | 省略した場合は 1 になります。 483 | 484 | 参照:|g:unite_source_outline_indent_width| 485 | 486 | * type 文字列(任意) 487 | 見出しの種類 488 | 省略した場合は "generic" になります。 489 | 490 | 空の辞書を返すと、見出しではないとみなされ、無視されます。 491 | 492 | 定義例(HTML用): > 493 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 494 | let level = str2nr(matchstr(a:heading_line, '<[hH]\zs[1-6]\ze[^>]*>')) 495 | let heading = { 496 | \ 'word' : "h" . level. ". " . s:get_text_content(level, a:context) 497 | \ 'level': level, 498 | \ 'type' : 'generic', 499 | \ } 500 | return heading 501 | endfunction 502 | < 503 | *unite-outline-info-skip* 504 | skip 辞書(任意) 505 | 506 | 見出し抽出の対象としない領域を指定するための辞書 507 | 以下の属性を設定することで、指定の領域を見出し抽出の対象外にで 508 | きます。 509 | 510 | *unite-outline-info-skip-header* 511 | header 文字列、リスト、辞書のいずれか(任意) 512 | バッファの先頭にあるヘッダ部分(作者や著作権の表示があ 513 | る部分)から見出しが抽出されるのを防ぐために設定します。 514 | 515 | (a) 文字列が設定された場合は、それをパターンとみなし、 516 | バッファの先頭からそのパターンにマッチする行が続く 517 | 間をスキップします。 518 | > 519 | \ 'skip': { 520 | \ 'header': '^#', 521 | \ }, 522 | < 523 | (b) リストが設定された場合は、それをパターンのペアと見 524 | なし、ファイルの先頭が skip.header[0] にマッチする 525 | 場合に、 skip.header[1] にマッチする行までをスキッ 526 | プします。 527 | > 528 | \ 'skip': { 529 | \ 'header': ['^/\*', '\*/\s*$'], 530 | \ }, 531 | < 532 | (c) 辞書が設定された場合は、leading属性に (a) のパター 533 | ン、 block属性に (b) のリストが設定されているもの 534 | とし、バッファの先頭からそれぞれにマッチする部分を 535 | スキップします。 536 | > 537 | \ 'skip': { 538 | \ 'header': { 539 | \ 'leading': '^//', 540 | \ 'block' : ['^/\*', '\*/\s*$'], 541 | \ }, 542 | \ }, 543 | < 544 | block リスト(任意) *unite-outline-info-skip-block* 545 | 設定されていると、値をパターンのペアと見なし、バッファ 546 | 中の、 skip.block[0] にマッチする行から skip.block[1] 547 | にマッチする行までをスキップします。 548 | > 549 | \ 'skip': { 550 | \ 'block': ['^=begin', '^=end'], 551 | \ }, 552 | < 553 | EXTRACTING HEADINGS BY YOURSELF ~ 554 | *unite-outline-info-extract_headings()* 555 | extract_headings 関数(任意) 556 | 557 | extract_headings( {context}) 558 | 559 | 設定されていると、見出しを抽出するために呼ばれます。 560 | 返値として見出し(辞書)のリストまたはツリーを返します。 561 | 562 | この関数を定義することで、outline info独自の見出し抽出を実装で 563 | きます。これにより、従来の正規表現を使ったパターンマッチによる 564 | 方法では見出しの抽出が困難な場合でも、外部の構文解析プログラム 565 | を利用するなどの方法が可能になります。 566 | 567 | extract_headings() に渡される引数は以下の通りです。 568 | 569 | * {context} 辞書 570 | 詳細は|unite-outline-context-object|を参照 571 | 572 | 返値は見出し(辞書)のリストまたはツリーであり、個々の見出しに 573 | は |unite-outline-heading-object|の属性に加え、以下の属性も設 574 | 定する必要があります。 575 | 576 | * lnum 整数 (必須) 577 | 見出し行の行番号 578 | 579 | 見出しのツリーを返す ~ 580 | 581 | アウトラインを解析する過程で outline info が見出しのツリー構造 582 | を把握できる場合、extract_headings() にて見出しのツリーを構築 583 | し、それを返値とすることができます。 584 | 585 | 見出しのツリーは以下のように作成します。 586 | 587 | 例: > 588 | let s:Tree = unite#sources#outline#import('Tree') 589 | 590 | let root = s:Tree.new() 591 | call s:Tree.append_child(root, heading_A) 592 | call s:Tree.append_child(root, heading_B) 593 | call s:Tree.append_child(heading_A, heading_1) 594 | call s:Tree.append_child(heading_A, heading_2) 595 | call s:Tree.append_child(heading_B, heading_3) 596 | < 597 | トップレベルの見出しは Tree.new() で生成した root の子となるよ 598 | うにし、以下、見出し間の親子関係を Tree.append_child() にて設 599 | 定します。 600 | 601 | これにより、下図のような構造のツリーができます。 602 | extract_headings() からは root を返します。(見出し一覧には 603 | root は表示されません) 604 | > 605 | root 606 | | 607 | +--heading_A 608 | | +--heading_1 609 | | +--heading_2 610 | | 611 | +--heading_B 612 | +--heading_3 613 | < 614 | 見出しのツリーを返す場合、見出しの親子関係から見出しレベルを決 615 | 定できるため、個々の見出しに level属性を設定する必要はありませ 616 | ん。 617 | 618 | FORMATTING ~ 619 | *unite-outline-info-heading_groups* 620 | heading_groups 辞書(任意) 621 | 622 | 見出しのグループ分けを行うための辞書 623 | 設定されていると、見出し一覧を表示する際、互いに異なるグループ 624 | に属する見出しの間に空行が挿入されるようになります。 625 | 626 | 個々のグループは見出しの type のリストです。 627 | 628 | 見出しの抽出に際しては、この属性に設定された辞書を元に、所属す 629 | るグループの名前が見出しの group属性に設定されます。 630 | 631 | 定義例(C++用): > 632 | let s:outline_info = { 633 | \ 'heading_groups': { 634 | \ 'namespace': ['namespace'], 635 | \ 'type' : ['class', 'enum', 'struct', 'typedef'], 636 | \ 'function' : ['function'], 637 | \ 'macro' : ['macro'], 638 | \ }, 639 | \} 640 | < 641 | NARROWING ~ 642 | *unite-outline-info-not_match_patterns* 643 | not_match_patterns リスト(任意) 644 | 645 | 絞り込みの対象にしない部分を指定するパターンのリスト 646 | 見出しの word のうち、このリストに指定したパターンにマッチする 647 | 部分は絞り込みの対象にならなくなります。 648 | 649 | SYNTAX HIGHLIGHTING ~ 650 | *unite-outline-info-highlight_rules* 651 | highlight_rules 辞書(任意) 652 | 653 | 見出し一覧のシンタックスハイライトの定義(辞書)のリスト 654 | シンタックスは、見出し一覧が表示される直前に、リストの添字の順 655 | に定義されます。マッチするパターンが複数ある場合は 656 | |:syn-priority|にあるルールにもとづき適用されるシンタックスが 657 | 決定されます。 658 | 659 | パターンは正規表現で記述できますが、両端を '/' などの記号で囲 660 | む必要があります。(詳細は|:syn-pattern|を参照) 661 | 662 | 定義例(Vim script用): > 663 | let s:outline_info = { 664 | \ 'highlight_rules': [ 665 | \ { 'name' : 'comment', 666 | \ 'pattern' : '/".*/' }, 667 | \ { 'name' : 'augroup', 668 | \ 'pattern' : '/\S\+\ze : augroup/', 669 | \ 'highlight': g:unite_source_outline_highlight.type }, 670 | \ { 'name' : 'function', 671 | \ 'pattern' : '/\S\+\ze\s*(/' }, 672 | \ { 'name' : 'parameter_list', 673 | \ 'pattern' : '/(.*)/' }, 674 | \} 675 | < 676 | highlight属性は省略でき、その場合は 677 | |g:unite_source_outline_highlight| 変数に設定されているハイラ 678 | イトが使われます。 679 | 680 | CACHING ~ 681 | *unite-outline-info-is_volatile* 682 | is_volatile 数値(任意) 683 | 684 | 抽出した見出しをキャッシュするかどうか。 685 | 1 を設定すると、見出しはキャッシュされません。 686 | 687 | *unite-outline-info-hooks* 688 | HOOKS ~ 689 | *unite-outline-info-initialize()* 690 | initialize 関数(任意) 691 | 692 | initialize() 693 | 694 | 設定されていると、outline info がロードした後に呼び出されます。 695 | outline info の初期化のために実行すべき処理があればここに記述 696 | します。 697 | *unite-outline-info-before()* 698 | before 関数(任意) 699 | 700 | before( {context}) 701 | 702 | 設定されていると、見出しの抽出が始まる前に呼び出されます。 703 | 見出し抽出前に実行すべき処理があればここに記述します。 704 | 705 | {context} については、|unite-outline-context-object|を参照 706 | 707 | *unite-outline-info-after()* 708 | after 関数(任意) 709 | 710 | after( {context}) 711 | 712 | 設定されていると、見出しの抽出が完了した後に呼び出されます。 713 | 見出し抽出後に実行すべき処理があればここに記述します。 714 | 715 | {context} については、|unite-outline-context-object|を参照 716 | 717 | ------------------------------------------------------------------------------ 718 | 外部プログラム *unite-outline-info-external-programs* 719 | 720 | 同梱されている outline info のうち、一部のファイルタイプ用のものは、見 721 | 出しの抽出に特定の外部プログラムを使用します。 722 | 723 | これらのファイルタイプでの見出し抽出を行うためには、指定された外部プロ 724 | グラムが実行可能である(PATH が通っており、|system()|から呼び出せる) 725 | 必要があります。 726 | 727 | C, C++, Java ~ 728 | 729 | * Exuberant Ctags(必須) 730 | http://ctags.sourceforge.net/ 731 | 732 | ============================================================================== 733 | 関数 *unite-outline-functions* 734 | 735 | *unite#sources#outline#alias()* 736 | unite#sources#outline#alias( {alias}, {source}) 737 | 738 | ファイルタイプの別名を設定します。{source} の outline info を 739 | 別のファイルタイプでも利用したい場合に使用します。 740 | 741 | 用例: > 742 | call unite#sources#outline#alias('xhtml', 'html') 743 | call unite#sources#outline#alias('zsh', 'sh') 744 | < 745 | *unite#sources#outline#get_outline_info()* 746 | unite#sources#outline#get_outline_info( 747 | {filetype} [, {reload} [, {nouser}]]) 748 | 749 | {filetype} の outline info を返します。 750 | {reload} が non-zero の場合、outline info を取得する前にスクリ 751 | プトを source し直します。(outline info がオートロード関数を 752 | 使ってファイルに定義されている場合にのみ有効) 753 | {nouser} が non-zero の場合、ユーザー定義の outline info の探 754 | 索をスキップします。 755 | outline info が見つからない場合は空の辞書 {} を返します。 756 | 757 | *unite#sources#outline#get_filetype_option()* 758 | unite#sources#outline#get_filetype_option( 759 | {filetype}, {key} [, {default}]) 760 | 761 | {filetype} のオプション {key} の値を返します。 762 | 設定値が見つからない場合、{default} が指定されていれば 763 | {default} を、そうでないなら 0 を返します。 764 | 765 | *unite#sources#outline#get_highlight()* 766 | unite#sources#outline#get_highlight( {name} ...) 767 | 768 | {name} に関連付けられたハイライトグループ名を返します。 769 | 関連付けがない場合は、引数を順次調べ関連付けを探します。関連付 770 | けが最後まで見つからなかった場合は |g:unite_abbr_highlight| の 771 | 値を返します。 772 | 773 | ハイライトグループ名への関連付けについては 774 | |g:unite_source_outline_highlight| を参照 775 | 776 | *unite#sources#outline#import()* 777 | unite#sources#outline#import( {module}) 778 | 779 | 組み込みモジュールをインポートします。 780 | > 781 | let s:Util = unite#sources#outline#import('Util') 782 | < 783 | *unite#sources#outline#remove_cache_files()* 784 | unite#sources#outline#remove_cache_files() 785 | 786 | ファイルに保存した見出しのキャッシュを削除します。 787 | 788 | UTILITY FUNCTIONS *unite-outline-utility-functions* 789 | 790 | 以下は、outline info を作成するにあたり、create_heading() や 791 | extract_headings() で使用すると便利なユーティリティ関数です。 792 | 793 | 使用する場合は以下のようにモジュールをインポートし、辞書関数として呼び 794 | 出して下さい。 795 | > 796 | let s:Util = unite#sources#outline#import('Util') 797 | call s:Util.get_indent_level(a:context, h_lnum) 798 | < 799 | {context} には、create_heading() や extract_headings() が引数として 800 | 受け取った辞書|unite-outline-context-object|を渡します。 801 | 802 | HEADINGS ~ 803 | *unite-outline-Util.get_indent_level()* 804 | Util.get_indent_level( {context}, {lnum}) 805 | 806 | 行番号が {lnum} である行のインデントレベルを返します。 807 | 808 | MATCHING ~ 809 | *unite-outline-Util.join_to()* 810 | Util.join_to( {context}, {lnum}, {pattern} [, {limit}]) 811 | 812 | 行番号が {lnum} の行から {pattern} にマッチする行までを連結し 813 | た文字列を返します。連結される行と行の間には "\n" が挿入されま 814 | す。{limit} には最大何行先までマッチを試行/連結するかを指定で 815 | き、省略した場合は 3 になります。{limit} に負の値を指定すると、 816 | 行番号が {lnum} の行から前の行に対してマッチの試行と連結を行い 817 | ます。 818 | *unite-outline-Util.neighbor_match()* 819 | Util.neighbor_match( 820 | {context}, {lnum}, {pattern} [, {range} [, {exclusive}]]) 821 | 822 | 行番号が {lnum} の行およびその前後の行が {pattern} にマッチす 823 | るならば真、そうでないなら偽を返します。{range} には前後の何 824 | 行分に対しマッチを試行するかを指定でき、省略した場合は 1 にな 825 | ります。{range} にリストを指定すると、マッチを試行する行数を前 826 | と後ろ、別々に設定できます。 827 | {exclusive} に 1 を指定すると、行番号が {lnum} の行をマッチの 828 | 試行対象から除外します。 829 | 830 | *unite-outline-Util.neighbor_matchstr()* 831 | Util.neighbor_matchstr( 832 | {context}, {lnum}, {pattern} [, {range} [, {exclusive}]]) 833 | 834 | |unite-outline-Util.neighbor_match()|の派生形。真偽値ではなく、 835 | マッチした部分文字列を返します。マッチしない場合は "" を返しま 836 | す。 837 | 838 | ============================================================================== 839 | TODO *unite-outline-todo* 840 | 841 | * D, Erlang, Go, Haskell などの outline info 842 | 843 | * 対応ファイルタイプの充実 844 | 845 | * Issues - h1mesuke/unite-outline - GitHub 846 | https://github.com/h1mesuke/unite-outline/issues 847 | 848 | ------------------------------------------------------------------------------ 849 | outline info 募集! 850 | 851 | outline info が同梱されていないファイルタイプ用の outline info を作成 852 | された方がおられたら、ぜひとも作者までお寄せ下さい。参考に(もしくは配 853 | 布アーカイブにそのまま同梱)させていただきます。 854 | 855 | * Issues - h1mesuke/unite-outline - GitHub 856 | https://github.com/h1mesuke/unite-outline/issues 857 | 858 | * Send a pull request - GitHub 859 | https://github.com/h1mesuke/unite-outline/pull/new/master 860 | 861 | ============================================================================== 862 | 既知の問題 *unite-outline-issues* 863 | 864 | 親子関係の誤認識 ~ 865 | 866 | unite-outline では、見出しの親子関係をツリー構造で把握しています。 867 | 絞り込みの際には、このツリー構造にもとづき、見出しの親子関係に配慮した 868 | 絞り込みを行います。(小見出しがマッチした見出しも残すなど) 869 | 870 | 現在、一部のファイルタイプでは、ソースコードのインデントの深さから見出 871 | しレベルを決定しています。この場合、作成される見出しのツリーが、必ずし 872 | も論理的に正しい親子関係を反映しないことがあります。結果、絞り込みの結 873 | 果に、実際には親子関係にないはずの見出しが残ることがあります。 874 | 875 | ============================================================================== 876 | 更新履歴 *unite-outline-changelog* 877 | 878 | 0.5.1 2011-11-01 879 | 880 | * unite#sources#outline#get_outline_info() のインターフェースを変更 881 | - ファイルタイプリダイレクトに対応 882 | |unite#sources#outline#get_outline_info()| 883 | 884 | * unite#sources#outline#get_default_outline_info() を削除 885 | 886 | * フックを追加 887 | - initialize |unite-outline-info-initialize| 888 | 889 | * フックの名前を変更 890 | - initialize -> before |unite-outline-info-before| 891 | - finalize -> after |unite-outline-info-after| 892 | 893 | * 内部データの管理を改善 894 | 895 | * 見出しの絞り込みを高速化 896 | - 再帰呼び出しをなくし、反復的に処理するように改善 897 | 898 | 0.5.0 2011-09-06 899 | 900 | * 見出しの自動更新を実装し、以下のファイルタイプオプションを追加 901 | - auto_update |unite-outline-filetype-option-auto-update| 902 | - auto_update_event 903 | 904 | 0.3.8 2011-08-25 905 | 906 | * 見出しの抽出を高速化 907 | これにともない、outline info の heading-1, heading, heading+1 に使用 908 | できる正規表現にいくつかの制約を導入 909 | |unite-outline-info-heading-pattern-restrictions| 910 | 911 | * ファイルタイプごとのオプション設定をまとめるため、以下の変数を追加 912 | -|g:unite_source_outline_filetype_options| 913 | - g:unite_source_outline_ignore_heading_types は上記の変数に統合 914 | 915 | * 以下のキーマッピングを deprecated とした 916 | - (unite_outline_loop_cursor_down) 917 | - (unite_outline_loop_cursor_up) 918 | 919 | 0.3.7 2011-08-14 920 | 921 | * 見出しが1つまで絞り込まれたら、絞り込み結果の最上段にその見出しを複 922 | 製する機能を追加。見出し選択のためのカーソル移動を不要とした。 923 | 924 | * 折り畳みの見出し抽出を実装 |unite-outline-usage| 925 | 926 | 0.3.6 2011-08-08 927 | 928 | * 見出し一覧のシンタックスハイライトに対応し、以下の変数を追加 929 | -|g:unite_source_outline_highlight| 930 | 931 | * outline info の仕様に以下の属性を追加 932 | - highlight_rules |unite-outline-info-highlight_rules| 933 | 934 | 0.3.5 2011-05-14 935 | 936 | * outline info の仕様に以下の属性を追加 937 | - heading_groups |unite-outline-info-heading_groups| 938 | - need_blank_between() 939 | 940 | 0.3.4 2011-04-26 941 | 942 | * キャッシュの管理ロジックを改善し、以下の変数を削除 943 | - g:unite_source_outline_cache_buffers 944 | 945 | * outline info の仕様に以下の属性を追加 946 | - not_match_patterns |unite-outline-info-not_match_patterns| 947 | 948 | * 親子関係に配慮した matcher を実装 949 | 950 | 0.3.3 2011-03-19 951 | 952 | * outline info の仕様から以下の属性を削除 953 | - skip_header() 954 | 955 | * キャッシュの保存ディレクトリを g:unite_data_directory以下に固定し、 956 | 以下の変数を削除 957 | - g:unite_source_outline_cache_dir 958 | 959 | * キャッシュに関するオプション変数を整理 960 | - g:unite_source_outline_cache_serialize_limit を 961 | |g:unite_source_outline_cache_limit|に変更 962 | - 従来の g:unite_source_outline_cache_limit は削除 963 | 964 | 0.3.2 2011-03-01 965 | 966 | * outline info の探索パスに "autoload/outline" を追加 967 | 968 | * outline_info.extract_headings() による、outline info独自の見出し 969 | 抽出に対応 970 | 971 | * {context} の仕様を変更 972 | context.lines の先頭にダミーの空行を付加し、リストの添字と行番号が 973 | 一致するように修正し、以下の属性名を変更 974 | - heading_index -> heading_lnum 975 | - matched_index -> matched_lnum 976 | 977 | * ユーティリティ関数のインターフェースを変更 978 | 引数として、{lines} ではなく {context} を、{idx} ではなく {lnum} を 979 | 受け取るように修正 980 | 981 | 0.3.1 2011-01-29 982 | 983 | * 特定の種類の見出しを非表示にする機能を追加し、以下の変数を追加 984 | -|g:unite_source_outline_ignore_heading_types| 985 | 986 | 0.3.0 2011-01-10 987 | 988 | * create_heading() から見出しのメタ情報をもった辞書を返せるように 989 | outline info の仕様を拡張 990 | 991 | 0.2.1 2011-01-04 992 | 993 | * キャッシュの一部永続化を実装し、以下の変数を追加 994 | -|g:unite_source_outline_cache_dir| 995 | -|g:unite_source_outline_cache_serialize_limit| 996 | 997 | vim:tw=78:ts=8:ft=help:norl:noet:fen:fdl=0:fdm=marker: 998 | -------------------------------------------------------------------------------- /doc/unite-outline.txt: -------------------------------------------------------------------------------- 1 | *unite-outline.txt* outline source for unite.vim 2 | 3 | Author : h1mesuke 4 | Updated : 2012-01-11 5 | Version : 0.5.1 6 | License : MIT license {{{ 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining 9 | a copy of this software and associated documentation files (the 10 | "Software"), to deal in the Software without restriction, including 11 | without limitation the rights to use, copy, modify, merge, publish, 12 | distribute, sublicense, and/or sell copies of the Software, and to 13 | permit persons to whom the Software is furnished to do so, subject to 14 | the following conditions: 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | }}} 26 | 27 | CONTENTS *unite-outline-contents* 28 | 29 | Introduction |unite-outline-introduction| 30 | Install |unite-outline-install| 31 | Usage |unite-outline-usage| 32 | Settings |unite-outline-settings| 33 | Variables |unite-outline-variables| 34 | Example |unite-outline-settings-example| 35 | Outline Info |unite-outline-info| 36 | Create Outline Info |unite-outline-info-create| 37 | Attributes |unite-outline-info-attributes| 38 | External Programs |unite-outline-info-external-programs| 39 | Functions |unite-outline-functions| 40 | Utility Functions |unite-outline-utility-functions| 41 | ToDo |unite-outline-todo| 42 | Known Issues |unite-outline-known-issues| 43 | ChanheLog |unite-outline-changelog| 44 | 45 | ============================================================================== 46 | INTRODUCTION *unite-outline-introduction* 47 | 48 | *unite-outline* is a |unite|'s source which provides your Vim's buffer 49 | with the outline view. It parses the current buffer's content and 50 | extracts headings from the buffer. And then it shows the list of the 51 | headings using unite.vim's interface. When you select a heading from 52 | the list, you can jump to the corresponding location in the buffer. 53 | 54 | The methods for extracting headings can be implemented for each 55 | individual filetypes. You can customize them as you like with Vim 56 | script and can also create new ones for unsupported filetypes. 57 | 58 | ============================================================================== 59 | INSTALL *unite-outline-install* 60 | 61 | Install the distributed files into your Vim script directory which is 62 | usually $HOME/.vim, or $HOME/vimfiles on Windows. 63 | 64 | You can show the heading list of the current buffer with ":Unite 65 | outline" command if you succeeded the installation (and unite-outline 66 | supports the filetype of the buffer). 67 | 68 | ============================================================================== 69 | USAGE *unite-outline-usage* 70 | 71 | SHOW HEADINGS ~ 72 | 73 | To show the heading list of the current buffer, execute |:Unite| 74 | command with "outline" as a source parameter. 75 | > 76 | :Unite outline 77 | < 78 | unite-outline parses the current buffer's content and extracts 79 | headings from the buffer. And then it shows the list of the headings 80 | using unite.vim's interface. When you select a heading from the list, 81 | you can jump to the corresponding location in the buffer. 82 | 83 | In most cases, extracted headings are cached. Because unite-outline 84 | reuses the cached data as possible, subsequent extraction for the 85 | buffer will get much faster than the first time. 86 | 87 | FILTER HEADINGS ~ 88 | 89 | See |unite-usage|. 90 | 91 | UPDATE HEADINGS ~ 92 | 93 | If you want to forcefully update the heading list discarding the 94 | cached data, execute ":Unite outline" command with "!" as an outline 95 | source's parameter. 96 | > 97 | :Unite outline:! 98 | < 99 | Or, execute |(unite_redraw)|, which is mapped to by 100 | default, at the heading list in Normal mode. 101 | 102 | NOTE: From version 0.5.0, unite-outline updates headings automatically. 103 | See |unite-outline-filetype-option-auto-update| . 104 | 105 | ============================================================================== 106 | SETTINGS *unite-outline-settings* 107 | 108 | ------------------------------------------------------------------------------ 109 | VARIABLES *unite-outline-variables* 110 | 111 | g:unite_source_outline_info *g:unite_source_outline_info* 112 | 113 | Dictionary of outline infos. 114 | If you define an outline info on your vimrc, register the 115 | outline info to this Dictionary. Otherwise, you don't need to 116 | use it at all. 117 | 118 | See |unite-outline-info|, |unite-outline-info-create|. 119 | 120 | Default value is {}. 121 | 122 | Because all of the default outline infos, which have been 123 | included in the distributed archive, will be loaded by 124 | autoload functions later on demand, the initial value of this 125 | dictionary is empty. 126 | 127 | *g:unite_source_outline_indent_width* 128 | g:unite_source_outline_indent_width 129 | 130 | Indent width used in heading lists. 131 | 132 | Default value is 2. 133 | 134 | *g:unite_source_outline_filetype_options* 135 | g:unite_source_outline_filetype_options 136 | 137 | Dictionary of filetype specific options. 138 | 139 | You can configure filetype specific options for a filetype by 140 | giving a Dictionary, that consists of option-value pairs, to 141 | this variable with the filetype as a key. 142 | 143 | The generic filetype "*", that means all filetypes, is 144 | available. If a filetype has no value for an option, the value 145 | of "*" for the option is applied. 146 | 147 | Default value is {} 148 | 149 | Example: > 150 | let g:unite_source_outline_filetype_options = { 151 | \ '*': { 152 | \ 'auto_update': 1, 153 | \ 'auto_update_event': 'write', 154 | \ }, 155 | \ 'cpp': { 156 | \ 'auto_update': 0, 157 | \ }, 158 | \ 'javascript': { 159 | \ 'ignore_types': ['comment'], 160 | \ }, 161 | \ 'markdown': { 162 | \ 'auto_update_event': 'hold', 163 | \ }, 164 | \} 165 | < 166 | FILETYPE OPTIONS ~ 167 | 168 | auto_update *unite-outline-filetype-option-auto-update* 169 | 170 | Whether unite-outline update headings automatically or 171 | not. 172 | 173 | Default value is 1. 174 | 175 | *unite-outline-filetype-option-auto-update-event* 176 | auto_update_event 177 | 178 | Event that triggers the auto-update of headings. 179 | One of the followings. 180 | 181 | Value Trigger(s) 182 | -------------------------------------------- 183 | "write" |BufWritePost| 184 | "hold" |BufWritePost|, |CursorHold| 185 | 186 | Default value is "write". 187 | 188 | NOTE: Headings are updated only when the buffer has 189 | been changed since the last update. If you choice 190 | "hold" as "auto_update_event", the interval of updates 191 | is specified by 'updatetime'. 192 | 193 | ignore_types *unite-outline-filetype-option-ignore-types* 194 | 195 | List of heading types to be ignored. 196 | 197 | See the definition of the outline info to know about 198 | available heading types. 199 | 200 | Default value is [] 201 | 202 | *g:unite_source_outline_max_headings* 203 | g:unite_source_outline_max_headings 204 | 205 | Maximum number of headings. 206 | unite-outline aborts the extraction if the number of extracted 207 | headings reaches the value of this variable. 208 | 209 | Default value is 1000. 210 | *g:unite_source_outline_cache_limit* 211 | g:unite_source_outline_cache_limit 212 | 213 | Threshold for persistent/on-memory caching. 214 | 215 | If the number of lines of the buffer is greater than the value 216 | of this variable, the cache of the extracted headings is 217 | stored in a file. 218 | 219 | Once the cache is stored in a file, unite-outline loads the 220 | headings from the file even at the first time of its execution 221 | after a reboot of Vim. 222 | 223 | Default value is 1000. 224 | *g:unite_source_outline_highlight* 225 | g:unite_source_outline_highlight 226 | 227 | Dictionary of highlight settings. 228 | You can change the highlight for each heading groups. 229 | 230 | Default value is {} 231 | 232 | Example: > 233 | let g:unite_source_outline_highlight = { 234 | \ 'comment' : 'Comment', 235 | \ 'expanded': 'Constant', 236 | \ 'function': 'Function', 237 | \ 'id' : 'Special', 238 | \ 'macro' : 'Macro', 239 | \ 'method' : 'Function', 240 | \ 'normal' : g:unite_abbr_highlight, 241 | \ 'package' : g:unite_abbr_highlight, 242 | \ 'special' : 'Macro', 243 | \ 'type' : 'Type', 244 | \ 'level_1' : 'Type', 245 | \ 'level_2' : 'PreProc', 246 | \ 'level_3' : 'Identifier', 247 | \ 'level_4' : 'Constant', 248 | \ 'level_5' : 'Special', 249 | \ 'level_6' : g:unite_abbr_highlight, 250 | \ 'parameter_list': g:unite_abbr_highlight, 251 | \ } 252 | < 253 | The patterns to specify the regions to be highlighted are 254 | defined in each filetypes' outline infos. 255 | 256 | See |unite-outline-info-highlight_rules|. 257 | 258 | ------------------------------------------------------------------------------ 259 | SETTINGS EXAMPLE *unite-outline-settings-example* 260 | > 261 | nnoremap [unite] 262 | nmap f [unite] 263 | 264 | nnoremap [unite]o :Unite -buffer-name=outline outline 265 | 266 | call unite#set_buffer_name_option('outline', 'ignorecase', 1) 267 | call unite#set_buffer_name_option('outline', 'smartcase', 1) 268 | < 269 | ============================================================================== 270 | OUTLINE INFO *unite-outline-info* 271 | 272 | Outline info is a Dictionary that implements the filetype specific way 273 | of extracting headings. Usually, it has some regexp patterns of 274 | headings and a callback function to create a heading from a line of 275 | the buffer. 276 | 277 | You can customize the creation of a heading list as you like by 278 | creating your own outline infos or modifying the default ones. 279 | 280 | When you try to show the heading list, the outline info for the 281 | current buffer's filetype is searched for. 282 | 283 | The search order is as follows: 284 | 285 | 1. g:unite_source_outline_info.{filetype} 286 | 2. outline#{filetype}#outline_info() 287 | 3. unite#sources#outline#{filetype}#outline_info() 288 | 4. unite#sources#outline#defaults#{filetype}#outline_info() 289 | 290 | ------------------------------------------------------------------------------ 291 | CREATE OUTLINE INFO *unite-outline-info-create* 292 | 293 | There are two ways to create and use your own outline infos. 294 | 295 | [RECOMMENDED] 296 | A. Define an autoload function to return the outline info. 297 | 298 | * Create a file {filetype}.vim at 299 | $HOME/.vim/autoload/unite/sources/outline/ 300 | 301 | * Define unite#sources#outline#{filetype}#outline_info() in 302 | the file. 303 | 304 | or 305 | 306 | * Create {filetype}.vim at 307 | $HOME/.vim/autoload/outline/ 308 | 309 | * Define outline#{filetype}#outline_info() in the 310 | file. 311 | 312 | * Returns the outline info from the autoload function as its 313 | return value. 314 | 315 | I recommend you to define an outline info in this manner 316 | because loading of the outline info is delayed until it is 317 | actually needed and it doesn't enlarge your vimrc. 318 | 319 | The default outline infos at 320 | $HOME/.vim/autoload/unite/sources/outline/defaults/ have been 321 | defined in this manner. 322 | 323 | B. Register the outline info to the global variable. 324 | 325 | * Define a Dictionary as the outline info and set it to 326 | g:unite_source_outline_info.{filetype} at your vimrc. 327 | 328 | Example (for Ruby): > 329 | let g:unite_source_outline_info.ruby = { 330 | \ 'heading': '^\s*\(module\|class\|def\)\>', 331 | \ 'skip': { 332 | \ 'header': '^#', 333 | \ 'block' : ['^=begin', '^=end'], 334 | \ }, 335 | \} 336 | < 337 | ------------------------------------------------------------------------------ 338 | ATTRIBUTES *unite-outline-info-attributes* 339 | 340 | The attributes of outline info are as follows: 341 | 342 | EXTRACTING HEADINGS BY CALLBACK ~ 343 | *unite-outline-info-heading-1* 344 | heading-1 String (Optional) 345 | 346 | Pattern that matches to the PREVIOUS line of a heading line. 347 | By setting this attribute, the outline info can extract the 348 | headings that follow a decoration line. For example, 349 | > 350 | ========================================= 351 | Heading 1 352 | < 353 | or 354 | > 355 | ----------------------------------------- 356 | Heading 2 357 | < 358 | or 359 | > 360 | /**************************************** 361 | * 362 | * Heading 3 363 | * 364 | ****************************************/ 365 | < 366 | Because unite-outline see one more next line if the next line 367 | of a decoration line seems to be a blank line, the headings 368 | like the third example are extracted well. 369 | 370 | Example: > 371 | let s:outline_info = { 372 | \ 'heading-1': '^[-=]\{10,}\s*$', 373 | \ } 374 | < 375 | *unite-outline-info-heading* 376 | heading String (Optional) 377 | 378 | Pattern that matches to a heading line itself. 379 | 380 | Example (for HTML): > 381 | let s:outline_info = { 382 | \ 'heading': '<[hH][1-6][^>]*>', 383 | \ } 384 | < 385 | *unite-outline-info-heading-pattern-restrictions* 386 | RESTRICTIONS ON HEADING PATTERNS ~ 387 | 388 | There are the following restrictions on the regular 389 | expressions used in heading-1, heading or heading+1. 390 | 391 | 1. Use 'magic' notation. |/magic| 392 | 2. Don't use any back references (\1..\9). |/\1| 393 | 394 | These restrictions exist to maximize the speed of pattern 395 | matching. If you need any back references to extract headings, 396 | please use a pattern that has no back references and matches 397 | loosely and then filter the matched lines strictly again at 398 | create_heading() callback function. 399 | 400 | *unite-outline-info-heading+1* 401 | heading+1 String (Optional) 402 | 403 | Pattern that matches to the NEXT line of a heading line. 404 | By setting this attribute, the outline info can extract the 405 | headings that are followed by a decoration line like 406 | Markdown's headings. For example, 407 | > 408 | Heading 409 | ------- 410 | < 411 | Example (for Markdown): > 412 | let s:outline_info = { 413 | \ 'heading' : '^#\+', 414 | \ 'heading+1': '^[-=]\+$', 415 | \ } 416 | < *unite-outline-info-create_heading()* 417 | create_heading Funcref (Optional) 418 | 419 | create_heading( 420 | {which}, {heading-line}, {matched-line}, {context}) 421 | 422 | If defined, called whenever a heading is matched. 423 | It should return a heading object, that is a Dictionary. 424 | 425 | By defining this callback function, you can format the words 426 | of headings and decide the heading level (indent) of them. 427 | 428 | The arguments passed to create_heading() are as follows: 429 | 430 | * {which} String 431 | Kind of the match. 432 | One of "heading-1", "heading" or 433 | "heading+1" 434 | 435 | * {heading-line} String 436 | Line that is a heading. 437 | 438 | * {matched-line} String 439 | Line that was matched. 440 | 441 | *unite-outline-context-object* 442 | * {context} Dictionary 443 | Extra information about the current 444 | context. It contains the following 445 | attributes. 446 | 447 | * heading_lnum Number 448 | Line number of {heading-line}. 449 | 450 | * matched_lnum Number 451 | Line number of {matched-line}. 452 | 453 | * lines List 454 | List of all lines of the current 455 | buffer. 456 | 457 | An empty line has been prepended to 458 | the List to enable to use lnum as List 459 | index. Please beware it when you 460 | iterate the lines. 461 | 462 | * buffer Dictionary 463 | Buffer's information. It contains the 464 | following attributes. 465 | 466 | * nr Number 467 | Buffer number. 468 | 469 | * path String 470 | Path of the file edited on the buffer. 471 | 472 | * filetype String 473 | Filetype of the buffer. 474 | 475 | See autoload/unite/source/outline.vim 476 | for more available attributes. 477 | 478 | * outline_info Dictionary 479 | outline info 480 | 481 | You shouldn't rewrite any existing attributes of {context} 482 | because the Dictionary assigned to {context} is the same 483 | instance while the extraction. 484 | 485 | *unite-outline-heading-object* 486 | HEADING OBJECT ~ 487 | 488 | create_heading() should return a heading object that is 489 | a Dictionary with the following attributes. 490 | 491 | * word String (Required) 492 | Words of the heading displayed on the heading 493 | list window. 494 | 495 | * level Number (Optional) 496 | Heading level. 497 | The heading will be indented according to the 498 | level. If omitted, set to 1. 499 | 500 | See |g:unite_source_outline_indent_width|. 501 | 502 | * type String (Optional) 503 | Type of the heading. 504 | If omitted, set to "generic". 505 | 506 | If returns an empty Dictionary, it isn't considered as 507 | a heading and ignored. 508 | 509 | Example (for HTML): > 510 | function! s:outline_info.create_heading(which, heading_line, matched_line, context) 511 | let level = str2nr(matchstr(a:heading_line, '<[hH]\zs[1-6]\ze[^>]*>')) 512 | let heading = { 513 | \ 'word' : "h" . level . ". " . s:get_text_content(level, a:context) 514 | \ 'level': level, 515 | \ 'type' : 'generic', 516 | \ } 517 | return heading 518 | endfunction 519 | < 520 | *unite-outline-info-skip* 521 | skip Dictionary (Optional) 522 | 523 | Dictionary to specify the ranges to be skipped while the 524 | extraction. There are the following sub attributes. 525 | 526 | *unite-outline-info-skip-header* 527 | header String or List or Dictionary (Optional) 528 | It is set to prevent headings being extracted from the 529 | header part at the head of the buffer, in which the 530 | information about the author and/or the copyright 531 | notice exist. 532 | 533 | (a) If a String is set, it is considered as a pattern. 534 | 535 | If line 1 of the buffer is matched by the 536 | pattern, unite-outline skips to the line which 537 | isn't matched by the pattern. 538 | > 539 | \ 'skip': { 540 | \ 'header': '^#', 541 | \ }, 542 | < 543 | (b) If a List is set, it is considered as a pair of 544 | patterns, the first one of which matches the 545 | beginning of the header and the second one matches 546 | the end. 547 | 548 | If line 1 of the buffer is matched by 549 | skip.header[0], unite-outline skips to the 550 | line which is matched by skip.header[1]. 551 | > 552 | \ 'skip': { 553 | \ 'header': ['^/\*', '\*/\s*$'], 554 | \ }, 555 | < 556 | (c) If a Dictionary is set, it is assumed that 557 | "leading" attribute is set to (a)'s pattern and/or 558 | "block" attribute is set to (b)'s List. 559 | unite-outline skips the header in the manner of 560 | (a) and/or (b). 561 | > 562 | \ 'skip': { 563 | \ 'header': { 564 | \ 'leading': '^//', 565 | \ 'block' : ['^/\*', '\*/\s*$'], 566 | \ }, 567 | \ }, 568 | < 569 | block List (Optional) *unite-outline-info-skip-block* 570 | It is considered as a pair of patterns, the first one 571 | of which matches the beginning of a range to be 572 | skipped and the second one matches the end of the 573 | range. 574 | 575 | unite-outline skips all ranges that starts from the 576 | line matched by skip.block[0] to the line matched by 577 | skip.block[1]. 578 | > 579 | \ 'skip': { 580 | \ 'block': ['^=begin', '^=end'], 581 | \ }, 582 | < 583 | EXTRACTING HEADINGS BY YOURSELF ~ 584 | *unite-outline-info-extract_headings()* 585 | extract_headings Funcref (Optional) 586 | 587 | extract_headings( {context}) 588 | 589 | If defined, called to extract headings. 590 | It should return a List of headings or a Tree of headings. 591 | 592 | By defining this callback function, you can implement your 593 | original logic to extract headings. Even if it is so difficult 594 | to extract headings by the pattern matching and callback 595 | strategy by create_heading(), you can use any external 596 | programs like ctags in extract_headings() to accomplish the 597 | extraction. 598 | 599 | The argument passed to extract_headings() is: 600 | 601 | * {context} Dictionary 602 | Information about the current context. 603 | See |unite-outline-context-object|. 604 | 605 | extract_headings() should return a List of headings or a Tree 606 | of headings. Each of the headings must have "lnum" attribute 607 | in addition to the attributes described in 608 | |unite-outline-heading-object|. 609 | 610 | * lnum Number (Required) 611 | Line number of a heading line. 612 | 613 | RETURNING A TREE OF HEADINGS ~ 614 | 615 | If the outline info can know the tree structure of extracted 616 | headings in its extracting process, extract_headings() can 617 | return the headings as a Tree. 618 | 619 | You can build a Tree of headings in the manner shown in the 620 | following example. 621 | 622 | Example: > 623 | let s:Tree = unite#sources#outline#import('Tree') 624 | 625 | let root = s:Tree.new() 626 | call s:Tree.append_child(root, heading_A) 627 | call s:Tree.append_child(root, heading_B) 628 | call s:Tree.append_child(heading_A, heading_1) 629 | call s:Tree.append_child(heading_A, heading_2) 630 | call s:Tree.append_child(heading_B, heading_3) 631 | < 632 | The headings at the top level must be children of the root 633 | node created by Tree.new(). The relations between each 634 | headings and its children can be made by Tree.append_child(). 635 | 636 | As a result of the example code, a tree that has a structure 637 | shown in the following figure is built. extract_headings() 638 | must returns the root node, that never be displayed on the 639 | heading list window. 640 | > 641 | root 642 | | 643 | +--heading_A 644 | | +--heading_1 645 | | +--heading_2 646 | | 647 | +--heading_B 648 | +--heading_3 649 | < 650 | Because the heading level can be decided from the depth of the 651 | node, each headings isn't required to have "level" attribute 652 | in this case. 653 | 654 | FORMATTING ~ 655 | *unite-outline-info-heading_groups* 656 | heading_groups Dictionary (Optional) 657 | 658 | Dictionary used for categorizing headings to heading groups. 659 | unite-outline automatically adds "group" attribute to each 660 | headings using this Dictionary, that defines heading groups 661 | and their member types. Each groups is a List of heading 662 | types. 663 | 664 | unite-outline inserts a blank line between two headings that 665 | belong to different groups when the heading list is displayed. 666 | 667 | Example (for C++): > 668 | let s:outline_info = { 669 | \ 'heading_groups': { 670 | \ 'namespace': ['namespace'], 671 | \ 'type' : ['class', 'enum', 'struct', 'typedef'], 672 | \ 'function' : ['function'], 673 | \ 'macro' : ['macro'], 674 | \ }, 675 | \} 676 | < 677 | NARROWING ~ 678 | *unite-outline-info-not_match_patterns* 679 | not_match_patterns List (Optional) 680 | 681 | List of patterns to specify the parts of heading words that 682 | never match on narrowing. 683 | The parts of heading words that match to any of the patterns 684 | in the List are excluded from the words for which the matcher 685 | searches keywords. 686 | 687 | SYNTAX HIGHLIGHTING ~ 688 | *unite-outline-info-highlight_rules* 689 | highlight_rules Dictionary (Optional) 690 | 691 | List of highlight rules, that are Dictionaries. 692 | Syntax highlights are defined in the order in the List before 693 | displaying a heading list. When two or more patterns match at 694 | the same position, |:syn-priority| rule is applied. 695 | 696 | Patterns must be surrounded by two identical characters. 697 | See |:syn-pattern| for details. 698 | 699 | Example (for Vim script): > 700 | let s:outline_info = { 701 | \ 'highlight_rules': [ 702 | \ { 'name' : 'comment', 703 | \ 'pattern' : '/".*/' }, 704 | \ { 'name' : 'augroup', 705 | \ 'pattern' : '/\S\+\ze : augroup/', 706 | \ 'highlight': g:unite_source_outline_highlight.type }, 707 | \ { 'name' : 'function', 708 | \ 'pattern' : '/\S\+\ze\s*(/' }, 709 | \ { 'name' : 'parameter_list', 710 | \ 'pattern' : '/(.*)/' }, 711 | \} 712 | < 713 | If "highlight" attribute is omitted, the highlight specified 714 | by |g:unite_source_outline_highlight| variable is used. 715 | 716 | CACHING ~ 717 | *unite-outline-info-is_volatile* 718 | is_volatile Number (Optional) 719 | 720 | Whether extracted headings is cached or not. 721 | If set to none-zero, headings are not cached. 722 | 723 | *unite-outline-info-hooks* 724 | HOOKS ~ 725 | *unite-outline-info-initialize()* 726 | initialize Funcref (Optional) 727 | 728 | initialize() 729 | 730 | If defined, called after loading the outline info. 731 | 732 | See |unite-outline-context-object| for {context} 733 | 734 | *unite-outline-info-before()* 735 | before Funcref (Optional) 736 | 737 | before( {context}) 738 | 739 | If defined, called before extracting headings. 740 | 741 | See |unite-outline-context-object| for {context} 742 | 743 | *unite-outline-info-after()* 744 | after Funcref (Optional) 745 | 746 | after( {context}) 747 | 748 | If defined, called after extracting headings. 749 | 750 | See |unite-outline-context-object| for {context} 751 | 752 | ------------------------------------------------------------------------------ 753 | EXTERNAL PROGRAMS *unite-outline-info-external-programs* 754 | 755 | Some of the default outline infos use external program(s) to 756 | accomplish their extracting tasks. 757 | 758 | The external programs must be executable for Vim, in other words, they 759 | must be able to be executed by |system()| with the proper setting of 760 | PATH environment variable. 761 | 762 | C, C++, Java ~ 763 | 764 | * Exuberant Ctags (Required) 765 | http://ctags.sourceforge.net/ 766 | 767 | ============================================================================== 768 | FUNCTIONS *unite-outline-functions* 769 | 770 | *unite#sources#outline#alias()* 771 | unite#sources#outline#alias( {alias}, {filetype}) 772 | 773 | Defines an alias of {filetype}. By defining an alias, you can 774 | use the outline info for {filetype} in another filetype. 775 | 776 | Example: > 777 | call unite#sources#outline#alias('xhtml', 'html') 778 | call unite#sources#outline#alias('zsh', 'sh') 779 | < 780 | *unite#sources#outline#get_outline_info()* 781 | unite#sources#outline#get_outline_info( 782 | {filetype} [, {reload} [, {nouser}]]) 783 | 784 | Returns the outline info of {filetype}. 785 | When {reload} is non-zero, sources the script where the 786 | outline info is defined before getting it. 787 | When {nouser} is non-zero, skips searching user defined 788 | outline infos and returns one of the bundled. 789 | If the outline info is not found, returns an empty Dictionary. 790 | 791 | *unite#sources#outline#get_filetype_option()* 792 | unite#sources#outline#get_filetype_option( 793 | {filetype}, {key} [, {default}]) 794 | 795 | Returns a value of option {key} for {filetype}. 796 | If the value of option {key} is not available, returns 797 | {default} if given otherwise returns 0. 798 | 799 | *unite#sources#outline#get_highlight()* 800 | unite#sources#outline#get_highlight( {name} ...) 801 | 802 | Returns a highlight group name associated with {name}. 803 | If {name} has no association, tries following arguments until 804 | the association is found. If not found finally, returns the 805 | value of |g:unite_abbr_highlight|. 806 | 807 | See |g:unite_source_outline_highlight|. 808 | 809 | *unite#sources#outline#import()* 810 | unite#sources#outline#import( {module}) 811 | 812 | Imports a built-in module. 813 | > 814 | let s:Util = unite#sources#outline#import('Util') 815 | < 816 | *unite#sources#outline#remove_cache_files()* 817 | unite#sources#outline#remove_cache_files() 818 | 819 | Remove all cache files. 820 | 821 | UTILITY FUNCTIONS *unite-outline-utility-functions* 822 | 823 | The followings are utility functions that are convenient when used in 824 | create_heading() or extract_headings(). 825 | 826 | If you want to use them, please import Util module using 827 | unite#sources#outline#import() function. 828 | > 829 | let s:Util = unite#sources#outline#import('Util') 830 | call s:Util.get_indent_level(a:context, h_lnum) 831 | < 832 | If an utility function requires {context}, you need to pass the 833 | Dictionary received as {context} argument of create_heading() or 834 | extract_headings(). See |unite-outline-context-object|. 835 | 836 | HEADINGS ~ 837 | *unite-outline-Util.get_indent_level()* 838 | Util.get_indent_level( {context}, {lnum}) 839 | 840 | Returns the level of the indentation of line {lnum}. 841 | 842 | MATCHING ~ 843 | *unite-outline-Util.join_to()* 844 | Util.join_to( {context}, {lnum}, {pattern} [, {limit}]) 845 | 846 | Joins from line {lnum} to the line that matches to {pattern} into one 847 | String and then returns it. "\n" is put in between the joined lines. 848 | 849 | {limit} specifies the maximum number of lines to be joined. 850 | When {limit} is omitted, the default value 3 is used. 851 | When {limit} is negative, searches the matched line backward. 852 | 853 | *unite-outline-Util.neighbor_match()* 854 | Util.neighbor_match( 855 | {context}, {lnum}, {pattern} [, {range} [, {exclusive}]]) 856 | 857 | Returns True if line {lnum} or one of its neighbor lines 858 | matches to {pattern}, otherwise returns False. {range} 859 | specifies the range of the neighbors to be tried to match. 860 | When {range} is omitted, the default value 1 is used. It means 861 | the neighbors are only the previous line and the next line. 862 | When {range} is a List, for example [m, n], it specifies that 863 | the neighbors are the previous m lines and the next n lines. 864 | 865 | When {exclusive} is given and non-zero, line {lnum} itself 866 | isn't be tried to match. 867 | 868 | *unite-outline-Util.neighbor_matchstr()* 869 | Util.neighbor_matchstr( 870 | {context}, {lnum}, {pattern} [, {range} [, {exclusive}]]) 871 | 872 | Variety of |unite-outline-Util.neighbor_match()|. 873 | Returns the matched string not a boolean value. 874 | If there's no match, returns an empty String. 875 | 876 | ============================================================================== 877 | TODO *unite-outline-todo* 878 | 879 | * Add outline infos for D, Erlang, Go, Haskell, etc... 880 | 881 | * Issues - h1mesuke/unite-outline - GitHub 882 | https://github.com/h1mesuke/unite-outline/issues 883 | 884 | ------------------------------------------------------------------------------ 885 | MESSAGE FROM THE AUTHOR 886 | 887 | Please send your nice outline info! 888 | 889 | I want unite-outline to support more and more filetypes. But, creating 890 | an outline info worth of using is not easy because it requires deep 891 | knowledge of the target filetype. So, it is virtually impossible for 892 | me to create outline infos for all filetypes around the world. 893 | 894 | If you have written an outline info for some filetype and think it is 895 | nice, please send it to me. I will bundle it to the distribution as 896 | the default outline info of the filetype. 897 | 898 | * Issues - h1mesuke/unite-outline - GitHub 899 | https://github.com/h1mesuke/unite-outline/issues 900 | 901 | * Send a pull request - GitHub 902 | https://github.com/h1mesuke/unite-outline/pull/new/master 903 | 904 | ============================================================================== 905 | KNOWN ISSUES *unite-outline-issues* 906 | 907 | INCORRECT STRUCTURED TREE ~ 908 | 909 | unite-outline internally builds a tree structure of headings to know 910 | the relationship among headings and traces the tree structure to 911 | accomplish its tree-aware narrowing task. Therefore, not only the 912 | matched headings but also their ancestors are displayed as the results 913 | of the narrowing. 914 | 915 | Outline infos for some filetypes decide the level of headings from 916 | their indentation depth at the buffer. In this case, the built tree 917 | may be structured incorrectly. As a result, the results of narrowing 918 | may contain headings that are neither matched nor ancestors of matched 919 | ones. 920 | 921 | ============================================================================== 922 | CHANHELOG *unite-outline-changelog* 923 | 924 | 0.5.1 2011-11-01 925 | 926 | * Changed unite#sources#outline#get_outline_info()'s interface. 927 | - And supported filetype redirection. 928 | |unite#sources#outline#get_outline_info()| 929 | 930 | * Deleted unite#sources#outline#get_default_outline_info() 931 | 932 | * Added a new hook. 933 | - initialize |unite-outline-info-initialize| 934 | 935 | * Changed hook names. 936 | - initialize -> before |unite-outline-info-before| 937 | - finalize -> after |unite-outline-info-after| 938 | 939 | * Refactoring the internal data management. 940 | 941 | * Improved the speed of tree-aware matching. 942 | - No recursive calls. The matcher does its task iteratively. 943 | 944 | 0.5.0 2011-9-06 945 | 946 | * Implemented the auto-update feature and added the following 947 | filetype specific options. 948 | - auto_update |unite-outline-filetype-option-auto-update| 949 | - auto_update_event 950 | 951 | 0.3.8 2011-08-25 952 | 953 | * Improved the speed of heading extraction. 954 | Some restrictions on the regular expressions used in heading-1, 955 | heading or heading+1 were introduced along with this change. 956 | |unite-outline-info-heading-pattern-restrictions| 957 | 958 | * Added |g:unite_source_outline_filetype_options| variable. 959 | g:unite_source_outline_ignore_heading_types variable was integrated 960 | into this new variable as one filetype option. 961 | 962 | * Deprecated the following keymappings. 963 | - (unite_outline_loop_cursor_down) 964 | - (unite_outline_loop_cursor_up) 965 | 966 | vim:tw=78:ts=8:ft=help:norl:noet:fen:fdl=0:fdm=marker: 967 | --------------------------------------------------------------------------------