Skip to content

Commit bd6e33e

Browse files
authored
Merge pull request #1157 from fatih/vim-go-tests
Add travis integration and initial test suite
2 parents 7d3e4bc + 1458931 commit bd6e33e

24 files changed

+313
-499
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
doc/tags
22
.DS_Store
3+
4+
messages.log
5+
test.log

.travis.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
language: ruby
2+
3+
sudo: required
4+
5+
env:
6+
global:
7+
- DEPS=$HOME/deps
8+
- PATH=$DEPS/bin:$PATH
9+
- PATCH="v8.0.0134"
10+
11+
install: |
12+
git config --global user.email "[email protected]"
13+
git config --global user.name "Your Name"
14+
15+
# check out if we can pre-compiled Vim releases somehow,
16+
git clone --branch $PATCH --depth 1 https://github.com/vim/vim
17+
cd vim
18+
./configure --prefix=$DEPS --with-features=huge --disable-gui
19+
make
20+
make install
21+
cd -
22+
23+
script: ./scripts/test.sh
24+

Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
all: test
2+
3+
test:
4+
@echo "==> Running tests"
5+
@./scripts/test.sh
6+
7+
.PHONY: all test

README.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# vim-go
1+
# vim-go [![Build Status](http://img.shields.io/travis/fatih/vim-go.svg?style=flat-square)](https://travis-ci.org/fatih/vim-go)
22

33
<p align="center">
44
<img style="float: right;" src="assets/vim-go.png" alt="Vim-go logo"/>
@@ -288,6 +288,18 @@ information. It includes
288288
section](https://github.com/fatih/vim-go/wiki/FAQ-Troubleshooting), and many
289289
other [various pieces](https://github.com/fatih/vim-go/wiki) of information.
290290

291+
## Development & Testing
292+
293+
vim-go supports now test files. Please check `autoload` folder for examples. If
294+
you add a new feature be sure you also include the `_test.vim` file next to the
295+
script. You can locally test it by running:
296+
297+
```
298+
make
299+
```
300+
301+
Additionally, each new pull request will trigger a new Travis-ci job.
302+
291303
## Donation
292304

293305
People have asked for this for a long time, now you can be a fully supporter by

Rakefile

-13
This file was deleted.

autoload/go/fmt.vim

+136-121
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,8 @@
22
" Use of this source code is governed by a BSD-style
33
" license that can be found in the LICENSE file.
44
"
5-
" fmt.vim: Vim command to format Go files with gofmt.
6-
"
7-
" This filetype plugin add a new commands for go buffers:
8-
"
9-
" :Fmt
10-
"
11-
" Filter the current Go buffer through gofmt.
12-
" It tries to preserve cursor position and avoids
13-
" replacing the buffer with stderr output.
14-
"
15-
" Options:
16-
"
17-
" g:go_fmt_command [default="gofmt"]
18-
"
19-
" Flag naming the gofmt executable to use.
20-
"
21-
" g:go_fmt_autosave [default=1]
22-
"
23-
" Flag to auto call :Fmt when saved file
24-
"
5+
" fmt.vim: Vim command to format Go files with gofmt (and gofmt compatible
6+
" toorls, such as goimports).
257

268
if !exists("g:go_fmt_command")
279
let g:go_fmt_command = "gofmt"
@@ -67,6 +49,13 @@ function! go#fmt#Format(withGoimport) abort
6749
catch
6850
let l:curw = winsaveview()
6951
endtry
52+
53+
" save our undo file to be restored after we are done. This is needed to
54+
" prevent an additional undo jump due to BufWritePre auto command and also
55+
" restore 'redo' history because it's getting being destroyed every
56+
" BufWritePre
57+
let tmpundofile = tempname()
58+
exe 'wundo! ' . tmpundofile
7059
else
7160
" Save cursor position and many other things.
7261
let l:curw = winsaveview()
@@ -75,43 +64,116 @@ function! go#fmt#Format(withGoimport) abort
7564
" Write current unsaved buffer to a temp file
7665
let l:tmpname = tempname()
7766
call writefile(getline(1, '$'), l:tmpname)
67+
if go#util#IsWin()
68+
let l:tmpname = tr(l:tmpname, '\', '/')
69+
endif
70+
71+
let bin_name = g:go_fmt_command
72+
if a:withGoimport == 1
73+
let bin_name = g:go_goimports_bin
74+
endif
75+
76+
let out = go#fmt#run(bin_name, l:tmpname, expand('%'))
77+
if go#util#ShellError() == 0
78+
call s:update_file(l:tmpname, expand('%'))
79+
elseif g:go_fmt_fail_silently == 0
80+
let errors = s:parse_errors(out)
81+
call s:show_errors(errors)
82+
endif
83+
84+
" We didn't use the temp file, so clean up
85+
call delete(l:tmpname)
7886

7987
if g:go_fmt_experimental == 1
80-
" save our undo file to be restored after we are done. This is needed to
81-
" prevent an additional undo jump due to BufWritePre auto command and also
82-
" restore 'redo' history because it's getting being destroyed every
83-
" BufWritePre
84-
let tmpundofile = tempname()
85-
exe 'wundo! ' . tmpundofile
88+
" restore our undo history
89+
silent! exe 'rundo ' . tmpundofile
90+
call delete(tmpundofile)
91+
92+
" Restore our cursor/windows positions, folds, etc.
93+
if empty(l:curw)
94+
silent! loadview
95+
else
96+
call winrestview(l:curw)
97+
endif
98+
else
99+
" Restore our cursor/windows positions.
100+
call winrestview(l:curw)
86101
endif
102+
endfunction
87103

88-
" get the command first so we can test it
89-
let bin_name = g:go_fmt_command
90-
if a:withGoimport == 1
91-
let bin_name = g:go_goimports_bin
104+
" update_file updates the target file with the given formatted source
105+
function! s:update_file(source, target)
106+
" remove undo point caused via BufWritePre
107+
try | silent undojoin | catch | endtry
108+
109+
let old_fileformat = &fileformat
110+
if exists("*getfperm")
111+
" save file permissions
112+
let original_fperm = getfperm(a:target)
92113
endif
93114

94-
" check if the user has installed command binary.
95-
" For example if it's goimports, let us check if it's installed,
96-
" if not the user get's a warning via go#path#CheckBinPath()
97-
let bin_path = go#path#CheckBinPath(bin_name)
98-
if empty(bin_path)
99-
return
115+
call rename(a:source, a:target)
116+
117+
" restore file permissions
118+
if exists("*setfperm") && original_fperm != ''
119+
call setfperm(a:target , original_fperm)
100120
endif
101121

102-
if bin_name != "gofmt"
122+
" reload buffer to reflect latest changes
123+
silent edit!
124+
125+
let &fileformat = old_fileformat
126+
let &syntax = &syntax
127+
128+
" clean up previous location list
129+
let l:listtype = "locationlist"
130+
call go#list#Clean(l:listtype)
131+
call go#list#Window(l:listtype)
132+
endfunction
133+
134+
" run runs the gofmt/goimport command for the given source file and returns
135+
" the the output of the executed command. Target is the real file to be
136+
" formated.
137+
function! go#fmt#run(bin_name, source, target)
138+
let cmd = s:fmt_cmd(a:bin_name, a:source, a:target)
139+
if cmd[0] == "goimports"
103140
" change GOPATH too, so goimports can pick up the correct library
104141
let old_gopath = $GOPATH
105142
let $GOPATH = go#path#Detect()
106143
endif
107144

108-
" populate the final command with user based fmt options
109-
let command = bin_path . ' -w '
110-
if a:withGoimport != 1
111-
let command = command . g:go_fmt_options
145+
let command = join(cmd, " ")
146+
147+
" execute our command...
148+
let out = go#util#System(command)
149+
150+
if cmd[0] == "goimports"
151+
let $GOPATH = old_gopath
152+
endif
153+
154+
return out
155+
endfunction
156+
157+
" fmt_cmd returns a dict that contains the command to execute gofmt (or
158+
" goimports). args is dict with
159+
function! s:fmt_cmd(bin_name, source, target)
160+
" check if the user has installed command binary.
161+
" For example if it's goimports, let us check if it's installed,
162+
" if not the user get's a warning via go#path#CheckBinPath()
163+
let bin_path = go#path#CheckBinPath(a:bin_name)
164+
if empty(bin_path)
165+
return
112166
endif
113167

114-
if bin_name == "goimports"
168+
" start constructing the command
169+
let cmd = [bin_path]
170+
call add(cmd, "-w")
171+
172+
if a:bin_name != "goimports"
173+
call extend(cmd, split(g:go_fmt_options, " "))
174+
else
175+
" lazy check if goimports support `-srcdir`. We should eventually remove
176+
" this in the future
115177
if !exists('b:goimports_vendor_compatible')
116178
let out = go#util#System(bin_path . " --help")
117179
if out !~ "-srcdir"
@@ -124,95 +186,47 @@ function! go#fmt#Format(withGoimport) abort
124186
if exists('b:goimports_vendor_compatible') && b:goimports_vendor_compatible
125187
let ssl_save = &shellslash
126188
set noshellslash
127-
let command = command . '-srcdir ' . shellescape(expand("%:p"))
189+
call extend(cmd, ["-srcdir", shellescape(fnamemodify(a:target, ":p"))])
128190
let &shellslash = ssl_save
129191
endif
130192
endif
131193

132-
" execute our command...
133-
if go#util#IsWin()
134-
let l:tmpname = tr(l:tmpname, '\', '/')
135-
endif
136-
let out = go#util#System(command . " " . l:tmpname)
137-
138-
if bin_name != "gofmt"
139-
let $GOPATH = old_gopath
140-
endif
194+
call add(cmd, a:source)
195+
return cmd
196+
endfunction
141197

142-
let l:listtype = "locationlist"
143-
"if there is no error on the temp file replace the output with the current
144-
"file (if this fails, we can always check the outputs first line with:
145-
"splitted =~ 'package \w\+')
146-
if go#util#ShellError() == 0
147-
" remove undo point caused via BufWritePre
148-
try | silent undojoin | catch | endtry
149-
150-
" Replace current file with temp file, then reload buffer
151-
let old_fileformat = &fileformat
152-
if exists("*getfperm")
153-
" save old file permissions
154-
let original_fperm = getfperm(expand('%'))
155-
endif
156-
call rename(l:tmpname, expand('%'))
157-
" restore old file permissions
158-
if exists("*setfperm") && original_fperm != ''
159-
call setfperm(expand('%'), original_fperm)
160-
endif
161-
silent edit!
162-
let &fileformat = old_fileformat
163-
let &syntax = &syntax
164-
165-
" clean up previous location list, but only if it's due to fmt
166-
if exists('b:got_fmt_error') && b:got_fmt_error
167-
let b:got_fmt_error = 0
168-
call go#list#Clean(l:listtype)
169-
call go#list#Window(l:listtype)
170-
endif
171-
elseif g:go_fmt_fail_silently == 0
172-
let splitted = split(out, '\n')
173-
"otherwise get the errors and put them to location list
174-
let errors = []
175-
for line in splitted
176-
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
177-
if !empty(tokens)
178-
call add(errors, {"filename": @%,
179-
\"lnum": tokens[2],
180-
\"col": tokens[3],
181-
\"text": tokens[4]})
182-
endif
183-
endfor
184-
if empty(errors)
185-
% | " Couldn't detect gofmt error format, output errors
186-
endif
187-
if !empty(errors)
188-
call go#list#Populate(l:listtype, errors, 'Format')
189-
echohl Error | echomsg "Gofmt returned error" | echohl None
198+
" parse_errors parses the given errors and returns a list of parsed errors
199+
function! s:parse_errors(content) abort
200+
let splitted = split(a:content, '\n')
201+
202+
" list of errors to be put into location list
203+
let errors = []
204+
for line in splitted
205+
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
206+
if !empty(tokens)
207+
call add(errors,{
208+
\"lnum": tokens[2],
209+
\"col": tokens[3],
210+
\"text": tokens[4],
211+
\ })
190212
endif
213+
endfor
191214

192-
let b:got_fmt_error = 1
193-
call go#list#Window(l:listtype, len(errors))
215+
return errors
216+
endfunction
194217

195-
" We didn't use the temp file, so clean up
196-
call delete(l:tmpname)
218+
" show_errors opens a location list and shows the given errors. If the given
219+
" errors is empty, it closes the the location list
220+
function! s:show_errors(errors) abort
221+
let l:listtype = "locationlist"
222+
if !empty(a:errors)
223+
call go#list#Populate(l:listtype, a:errors, 'Format')
224+
echohl Error | echomsg "Gofmt returned error" | echohl None
197225
endif
198226

199-
if g:go_fmt_experimental == 1
200-
" restore our undo history
201-
silent! exe 'rundo ' . tmpundofile
202-
call delete(tmpundofile)
203-
endif
204-
205-
if g:go_fmt_experimental == 1
206-
" Restore our cursor/windows positions, folds, etc.
207-
if empty(l:curw)
208-
silent! loadview
209-
else
210-
call winrestview(l:curw)
211-
endif
212-
else
213-
" Restore our cursor/windows positions.
214-
call winrestview(l:curw)
215-
endif
227+
" this closes the window if there are no errors or it opens
228+
" it if there is any
229+
call go#list#Window(l:listtype, len(a:errors))
216230
endfunction
217231

218232
function! go#fmt#ToggleFmtAutoSave() abort
@@ -225,4 +239,5 @@ function! go#fmt#ToggleFmtAutoSave() abort
225239
let g:go_fmt_autosave = 1
226240
call go#util#EchoProgress("auto fmt enabled")
227241
endfunction
242+
228243
" vim: sw=2 ts=2 et

0 commit comments

Comments
 (0)