This repository was archived by the owner on Apr 7, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathphpspec.vim
More file actions
201 lines (174 loc) · 4.9 KB
/
phpspec.vim
File metadata and controls
201 lines (174 loc) · 4.9 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
if exists('g:loaded_phpspec') && g:loaded_phpspec
finish
endif
let g:loaded_phpspec = 1
if ! exists('g:phpspec_executable')
if filereadable('./bin/phpspec')
let g:phpspec_executable = './bin/phpspec'
elseif filereadable('./vendor/bin/phpspec')
let g:phpspec_executable = './vendor/bin/phpspec'
elseif filereadable('./vendor/phpspec/phpspec/bin/phpspec')
let g:phpspec_executable = './vendor/phpspec/phpspec/bin/phpspec'
else
let g:phpspec_executable = 'phpspec'
endif
endif
if ! exists('g:phpspec')
let g:phpspec = {}
endif
if (!exists('g:phpspec_default_mapping') || g:phpspec_default_mapping)
map <leader>spr :PhpSpecRun<CR>
map <leader>spc :PhpSpecRunCurrent<CR>
map <leader>sps :PhpSpecSwitch<CR>
endif
command! -nargs=0 PhpSpecRun call phpspec#run()
command! -nargs=0 PhpSpecRunCurrent call phpspec#run_current()
command! -nargs=1 PhpSpecDesc call phpspec#describe(<f-args>)
command! -nargs=0 PhpSpecSwitch call phpspec#switch()
function s:load_phpspec_yml(yml_path)
python << EOF
import yaml, os, vim
yml_path = vim.eval('a:yml_path')
f = open(yml_path);
phpspec = yaml.load(f);
vim.command('let g:phpspec["%s"] = %s' %(yml_path, repr(phpspec)));
f.close();
EOF
endfunction
function s:run(cmd)
if exists('*vimproc#pgroup_open')
let proc = vimproc#pgroup_open(a:cmd, 0, 2)
call proc.stdin.close()
let lines = []
while ! proc.stdout.eof || ! proc.stderr.eof
try
if ! proc.stdout.eof
call add(lines, proc.stdout.read_line())
endif
if ! proc.stderr.eof
call add(lines, proc.stderr.read_line())
endif
catch
echom v:throwpoint
endtry
endwhile
call proc.stdout.close()
call proc.stderr.close()
call proc.kill(9)
call proc.waitpid()
else
let lines = split(system(a:cmd), '\n')
endif
botright new
setlocal winheight=15
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
call append(line('$'), lines)
endfunction
function phpspec#switch()
let file_class = substitute(phpspec#get_class_name(), '\\', '/', 'g')
let file_match = phpspec#match(getcwd(), file_class)
if strlen(file_match) == 0
if file_class =~ 'Spec$'
echoerr 'Unable to find matching class for '.file_class
else
if 1 == confirm('No spec yet, would you like to create it?', "&Yes\n&No")
call phpspec#describe(file_class)
endif
endif
else
if bufexists(file_match)
execute(printf('buffer %s', file_match))
elseif filereadable(file_match)
execute(printf('edit %s', file_match))
endif
endif
endfunction
function phpspec#describe(file_class)
let cmd = g:phpspec_executable.' desc '.file_class.' -q'
if exists('*vimproc#system')
call vimproc#system(cmd)
else
call system(cmd)
endif
call phpspec#switch()
endfunction
function phpspec#run(...)
let cmd = g:phpspec_executable.' run --no-ansi'
if a:0 > 0
let cmd .= ' '.a:1
endif
call s:run(cmd)
endfunction
function phpspec#run_current()
let cmd = g:phpspec_executable.' run --no-ansi '.expand('%')
call s:run(cmd)
endfunction
function phpspec#match(directory, file_class)
" Load phpspec's config, and use cache if available
let phpspec_yml = a:directory.'/phpspec.yml'
if ! has_key(g:phpspec, phpspec_yml)
if filereadable(phpspec_yml)
call s:load_phpspec_yml(phpspec_yml)
else
echoerr 'Cannot find phpspec.yml'
return
endif
endif
let is_spec = a:file_class =~ 'Spec$'
let file_class = substitute(a:file_class, 'Spec$', '', '')
let file_match = ''
let suites = items(g:phpspec[phpspec_yml]['suites'])
for [suite, settings] in suites
if type(settings) == 1
let src_path = 'src'
let spec_path = 'spec'
let namespace = settings
else
let src_path = get(settings, 'src_path', 'src')
let spec_path = get(settings, 'spec_path', 'spec').'/spec'
let namespace = get(settings, 'namespace', '')
endif
let namespace = substitute(namespace, '\\', '/', '')
if is_spec
if stridx(file_class, 'spec/'.namespace.'/') == 0
let candidate = src_path.'/'
\.substitute(file_class, escape('spec/'.namespace.'/', '\/'), '', 'g')
\.'.php'
if filereadable(candidate)
let file_match = candidate
break
endif
endif
else
if stridx(file_class, namespace.'/') == 0
let candidate = spec_path.'/'.file_class.'Spec.php'
if filereadable(candidate)
let file_match = candidate
break
endif
endif
endif
unlet suite settings
endfor
unlet suites
return file_match
endfunction
function! phpspec#get_class_name()
let name_pattern = '[a-zA-Z_\x7f-\xff\\][a-zA-Z_0-9\x7f-\xff\\]*'
let total_lines = line('$') - 1
let namespace = '\'
let class = ''
let i = 0
while i < total_lines
let line = getline(i)
if line =~? '^\s*namespace\s*'.name_pattern
let namespace = matchstr(line, '^\s*namespace\s*\zs'.name_pattern.'\ze')
endif
if line =~? '^\s*class\s*'.name_pattern
let class = matchstr(line, '^\s*class\s*\zs'.name_pattern.'\ze')
break
endif
let i += 1
endwhile
return namespace.'\'.class
endfunction