function! scope#pair(head, tail)
let obj = {}
let obj.head = a:head
let obj.tail = a:tail
let obj.head_line_number = obj.head[0]
let obj.tail_line_number = obj.tail[0]
if len(obj.head[1]) == 0
let obj.head_string = ''
elseif join(obj.head[1][1:]) == ''
let obj.head_string = obj.head[1][0]
else
let obj.head_string = string#trim(join(obj.head[1][1:], ' '))
endif
if len(obj.tail[1]) == 0
let obj.tail_string = ''
elseif join(obj.tail[1][1:]) == ''
let obj.tail_string = obj.tail[1][0]
else
let obj.tail_string = join(obj.tail[1][1:], ' ')
endif
return obj
endfunction
function! scope#inspect(head_pattern, tail_pattern)
let obj = {}
let obj.head_search_pattern = substitute(a:head_pattern, '\\(', '\\%(', 'g')
let obj.head_collect_pattern = a:head_pattern
let obj.tail_search_pattern = substitute(a:tail_pattern, '\\(', '\\%(', 'g')
if obj.tail_search_pattern !~ '\\z[es]' && obj.tail_search_pattern !~ '\$$'
let obj.tail_search_pattern = obj.tail_search_pattern . '\zs'
endif
let obj.tail_collect_pattern = a:tail_pattern
func obj.init()
let self.stack = []
endfunc
func obj.push(head, tail)
call add(self.stack, scope#pair([a:head, matchlist(getline(a:head), self.head_collect_pattern)], [a:tail, matchlist(getline(a:tail), self.tail_collect_pattern)]))
endfunc
func obj.find_outer_tail()
let self.outer_tail = searchpair(self.head_search_pattern, '', self.tail_search_pattern, 'rcnW')
endfunc
func obj.find_outer_head()
let self.outer_head = searchpair(self.head_search_pattern, '', self.tail_search_pattern, 'rbcnW')
endfunc
func obj.find_current_head()
let self.current_head = searchpair(self.head_search_pattern, '', self.tail_search_pattern, 'bW')
endfunc
func obj.find_current_tail()
let self.current_tail = searchpair(self.head_search_pattern, '', self.tail_search_pattern, 'nW')
endfunc
func obj.scope()
let self.stack = reverse(list#lrotate(self.stack))
return self
endfunc
func obj.get_scope()
call self.init()
call self.find_outer_tail()
if self.outer_tail == 0
return self
endif
let cur_pos = getpos('.')
call self.find_outer_head()
if self.outer_head == 0
return self
endif
call self.push(self.outer_head, self.outer_tail)
call self.find_current_head()
while self.current_head > self.outer_head
call self.find_current_tail()
call self.push(self.current_head, self.current_tail)
call self.find_current_head()
endwhile
call setpos('.', cur_pos)
return self.scope()
endfunction
return obj.get_scope()
endfunction