]> git.madduck.net Git - etc/vim.git/blob - autoload/flake8.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge pull request #31 from amacfie/patch-1
[etc/vim.git] / autoload / flake8.vim
1 "
2 " Python filetype plugin for running flake8
3 " Language:     Python (ft=python)
4 " Maintainer:   Vincent Driessen <vincent@3rdcloud.com>
5 " Version:      Vim 7 (may work with lower Vim versions, but not tested)
6 " URL:          http://github.com/nvie/vim-flake8
7
8 let s:save_cpo = &cpo
9 set cpo&vim
10
11 "" ** external ** {{{
12
13 function! flake8#Flake8()
14     call s:Flake8()
15 endfunction
16
17 function! flake8#Flake8UnplaceMarkers()
18     call s:UnplaceMarkers()
19 endfunction
20
21 "" }}}
22
23 "" ** internal ** {{{
24
25 "" config
26
27 function! s:DeclareOption(name, globalPrefix, default)  " {{{
28     if !exists('g:'.a:name)
29         if a:default != ''
30             execute 'let s:'.a:name.'='.a:default
31         else
32             execute 'let s:'.a:name.'=""'
33         endif
34     else
35         execute 'let l:global="g:".a:name'
36         if l:global != ''
37             execute 'let s:'.a:name.'="'.a:globalPrefix.'".g:'.a:name
38         else
39             execute 'let s:'.a:name.'=""'
40         endif
41     endif
42 endfunction  " }}}
43
44 function! s:Setup()  " {{{
45     "" read options
46
47     " flake8 command
48     call s:DeclareOption('flake8_cmd', '', '"flake8"')
49     " flake8 stuff
50     call s:DeclareOption('flake8_builtins',        ' --builtins=',        '')
51     call s:DeclareOption('flake8_ignore',          ' --ignore=',          '')
52     call s:DeclareOption('flake8_max_line_length', ' --max-line-length=', '')
53     call s:DeclareOption('flake8_max_complexity',  ' --max-complexity=',  '')
54     " quickfix
55     call s:DeclareOption('flake8_quickfix_location', '', '"belowright"')
56     call s:DeclareOption('flake8_show_quickfix',     '', 1)
57     " markers to show
58     call s:DeclareOption('flake8_show_in_gutter', '',   0)
59     call s:DeclareOption('flake8_show_in_file',   '',   0)
60     call s:DeclareOption('flake8_max_markers',    '', 500)
61     " marker signs
62     call s:DeclareOption('flake8_error_marker',      '', '"E>"')
63     call s:DeclareOption('flake8_warning_marker',    '', '"W>"')
64     call s:DeclareOption('flake8_pyflake_marker',    '', '"F>"')
65     call s:DeclareOption('flake8_complexity_marker', '', '"C>"')
66     call s:DeclareOption('flake8_naming_marker',     '', '"N>"')
67
68     "" setup markerdata
69
70     if !exists('s:markerdata')
71         let s:markerdata = {}
72         let s:markerdata['E'] = { 'name': 'Flake8_Error'      }
73         let s:markerdata['W'] = { 'name': 'Flake8_Warning'    }
74         let s:markerdata['F'] = { 'name': 'Flake8_PyFlake'    }
75         let s:markerdata['C'] = { 'name': 'Flake8_Complexity' }
76         let s:markerdata['N'] = { 'name': 'Flake8_Nameing'    }
77     endif
78     let s:markerdata['E'].marker = s:flake8_error_marker
79     let s:markerdata['W'].marker = s:flake8_warning_marker
80     let s:markerdata['F'].marker = s:flake8_pyflake_marker
81     let s:markerdata['C'].marker = s:flake8_complexity_marker
82     let s:markerdata['N'].marker = s:flake8_naming_marker
83 endfunction  " }}}
84
85 "" do flake8
86
87 function! s:Flake8()  " {{{
88     " read config
89     call s:Setup()
90
91     if !executable(s:flake8_cmd)
92         echoerr "File " . s:flake8_cmd . " not found. Please install it first."
93         return
94     endif
95
96     " clear old
97     call s:UnplaceMarkers()
98     let s:matchids = []
99     let s:signids  = []
100
101     " store old grep settings (to restore later)
102     let l:old_gfm=&grepformat
103     let l:old_gp=&grepprg
104     let l:old_shellpipe=&shellpipe
105
106     " write any changes before continuing
107     if &readonly == 0
108         update
109     endif
110
111     set lazyredraw   " delay redrawing
112     cclose           " close any existing cwindows
113
114     " set shellpipe to > instead of tee (suppressing output)
115     set shellpipe=>
116
117     " perform the grep itself
118     let &grepformat="%f:%l:%c: %m\,%f:%l: %m"
119     let &grepprg=s:flake8_cmd.s:flake8_builtins.s:flake8_ignore.s:flake8_max_line_length.s:flake8_max_complexity
120     silent! grep! "%"
121
122     " restore grep settings
123     let &grepformat=l:old_gfm
124     let &grepprg=l:old_gp
125     let &shellpipe=l:old_shellpipe
126
127     " process results
128     let l:results=getqflist()
129     let l:has_results=results != []
130     if l:has_results
131         " markers
132         if !s:flake8_show_in_gutter == 0 || !s:flake8_show_in_file == 0
133             call s:PlaceMarkers(l:results)
134         endif
135         " quickfix
136         if !s:flake8_show_quickfix == 0
137             " open cwindow
138             execute s:flake8_quickfix_location." copen"
139             setlocal wrap
140             nnoremap <buffer> <silent> c :cclose<CR>
141             nnoremap <buffer> <silent> q :cclose<CR>
142         endif
143     endif
144
145     set nolazyredraw
146     redraw!
147
148     " Show status
149     if l:has_results == 0
150         echon "Flake8 check OK"
151     else
152         echon "Flake8 found issues"
153     endif
154 endfunction  " }}}
155
156 "" markers
157
158 function! s:PlaceMarkers(results)  " {{{
159     " in gutter?
160     if !s:flake8_show_in_gutter == 0
161         " define signs
162         for val in values(s:markerdata)
163             if val.marker != ''
164                 execute "sign define ".val.name." text=".val.marker." texthl=".val.name
165             endif
166         endfor
167     endif
168
169     " place
170     let l:index0 = 100
171     let l:index  = l:index0
172     for result in a:results
173         if l:index >= (s:flake8_max_markers+l:index0)
174             break
175         endif
176         let l:type = strpart(result.text, 0, 1)
177         if has_key(s:markerdata, l:type) && s:markerdata[l:type].marker != ''
178             " file markers
179             if !s:flake8_show_in_file == 0
180                 if !has_key(s:markerdata[l:type], 'matchstr')
181                     let s:markerdata[l:type].matchstr = '\%('
182                 else
183                     let s:markerdata[l:type].matchstr .= '\|'
184                 endif
185                 let s:markerdata[l:type].matchstr .= '\%'.result.lnum.'l\%'.result.col.'c'
186             endif
187             " gutter markers
188             if !s:flake8_show_in_gutter == 0
189                 execute ":sign place ".index." name=".s:markerdata[l:type].name
190                             \ . " line=".result.lnum." file=".expand("%:p")
191                 let s:signids += [l:index]
192             endif
193             let l:index += 1
194         endif
195     endfor
196
197     " in file?
198     if !s:flake8_show_in_file == 0
199         for l:val in values(s:markerdata)
200             if l:val.marker != '' && has_key(l:val, 'matchstr')
201                 let l:val.matchid = matchadd(l:val.name, l:val.matchstr.'\)')
202             endif
203         endfor
204     endif
205 endfunction  " }}}
206
207 function! s:UnplaceMarkers()  " {{{
208     " gutter markers
209     if exists('s:signids')
210         for i in s:signids
211             execute ":sign unplace ".i
212         endfor
213         unlet s:signids
214     endif
215     " file markers
216     for l:val in values(s:markerdata)
217         if has_key(l:val, 'matchid')
218             call matchdelete(l:val.matchid)
219             unlet l:val.matchid
220             unlet l:val.matchstr
221         endif
222     endfor
223 endfunction  " }}}
224
225 "" }}}
226
227 let &cpo = s:save_cpo
228 unlet s:save_cpo
229