-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.vim
85 lines (72 loc) · 2.19 KB
/
plugin.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
nnoremap <Leader>vb :ruby Vimbular.match()<CR>
nnoremap <Leader>vc :call InitialiseAndMatch()<CR>
function! InitialiseAndMatch()
let l:current_window = OpenWindow()
ruby Vimbular.match()
let l:back = bufwinnr(l:current_window)
exe l:back . " wincmd w"
endfunction
function! OpenWindow()
let current_win = bufname('%')
let haystack_win = bufwinnr('^_haystack$')
if ( haystack_win == -1)
keepjumps silent new _haystack
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
endif
let results_win = bufwinnr('^_results$')
if ( results_win == -1)
keepjumps silent vnew _results
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
endif
return current_win
endfunction
ruby << EOF
module Vimbular
def self.match()
find_windows
if needle = find_needle
haystack = Vim::Window[@haystack_id].buffer[1]
match_positions = find_matches(needle, haystack)
initialise_results
highlight_matches(match_positions)
end
end
private
def self.find_windows
windows = Range.new(0,VIM::Window.count,true)
for window in windows
if VIM::Window[window].buffer.name =~ /_haystack/
@haystack_id = window
end
if VIM::Window[window].buffer.name =~ /_results/
@results_id = window
end
end
end
def self.find_needle
Vim::Buffer.current.line =~ /\/(.+)\// ? Regexp.new($~[1]) : nil
end
def self.find_matches(needle, haystack)
match_positions = []
haystack_offset = 0
while haystack =~ needle
match_positions << $~.offset(0).map {|pos| pos + haystack_offset}
haystack = haystack.slice(Range.new($~.offset(0).last,-1))
haystack_offset = $~.offset(0).last + haystack_offset
end
match_positions
end
def self.initialise_results
VIM::command("#{@results_id} wincmd w")
VIM::command('normal! dG')
VIM::command('syntax clear')
Vim::Window[@results_id].buffer.line = Vim::Window[@haystack_id].buffer[1]
end
def self.highlight_matches(match_positions)
match_positions.each do |pos|
highlight_string = "syntax region Todo start=/\\%#{pos[0]+1}c/ end=/\\%#{pos[1]+1}c/"
VIM::command(highlight_string)
end
end
end
EOF