let s:heading_pre_regex = '^\n\d\+\(\.\d\+\)* ' let s:heading_post_regex = '\n\(\*\{3,}\|=\{3,}\|-\{3,}\|\.\{3,}\)$' let s:heading_regex = s:heading_pre_regex.'.*'.s:heading_post_regex let s:navigation_regex = '^\?\n\zsFile: [^,]\+, Node: ' let s:line_ref_regex = '^\* .*::' " let s:inline_ref_regex = '\*note\( \|\n\)\(.\+\n\)*.*::' function! s:dbg(msg) if(exists('g:info_debug')) echom a:msg endif endfunction function! info#HeadingNext() if(search(s:heading_regex)) norm! zt endif endfunction function! info#HeadingPrev() if(search(s:heading_regex, 'b')) norm! zt endif endfunction function! info#GoToRef(name) let l:name = escape(a:name, '$.*') call s:dbg("'".l:name."'") let l:pat = s:navigation_regex . l:name . ', ' let l:line = search(l:pat, 'w') if(l:line) exe l:line norm! zt return endif let l:pat = s:heading_pre_regex . l:name . '.*' . s:heading_post_regex let l:line = search(l:pat, 'w') if(l:line) exe l:line-1 norm! zt return endif endfunction function! info#GoRelative(type) let l:line = search(s:navigation_regex, 'cnb') if(l:line == 0) | return | endif let l:navi = getline(l:line) call s:dbg('navigation|'.l:navi) let l:type = escape(a:type, '$.*') let l:match = matchlist(l:navi, ', '.l:type.': \([^,]\+\)') call s:dbg('match '.string(l:match)) if(empty(l:match)) | return | endif call info#GoToRef(l:match[1]) endfunction function! info#FollowRef() if(search(s:line_ref_regex, 'cnb', line('.'))) let l:line = getline('.') call info#GoToRef(l:line[2:match(l:line, '::')-1]) else let l:endpos = searchpos('::', 'cn', line('.')+1) let l:startpos = searchpos('\*note', 'cnb', line('.')-1) call s:dbg('*note '.string([l:startpos, l:endpos])) if(l:endpos == [0, 0] || l:startpos == [0, 0]) return endif if(l:startpos[0] == l:endpos[0]) let l:line = getline(l:startpos[0])[l:startpos[1]:l:endpos[1]-2] else let l:lines = getline(l:startpos[0], l:endpos[0]) let l:offset = len(join(l:lines[:-2], ' ')) let l:line = join(l:lines, ' ')[l:startpos[1]:l:endpos[1]+l:offset-1] endif " strip 'note ' let l:line = l:line[5:] call info#GoToRef(l:line) endif endfunction function! info#Open(name) if(&filetype != 'info' || &modified) new else set modifiable 0,$d endif execute '0r! info --subnodes '.shellescape(a:name) .,$d set nomodified nomodifiable filetype=info 1 endfunction