]> 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:

81aedfd3bbc52d882db506ee26ea936465fb9bd3
[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     call s:Warnings()
16 endfunction
17
18 function! flake8#Flake8UnplaceMarkers()
19     call s:UnplaceMarkers()
20     call s:Warnings()
21 endfunction
22
23 "" }}}
24
25 "" ** internal ** {{{
26
27 "" warnings 
28
29 let s:displayed_warnings = 0
30 function s:Warnings()
31   if !s:displayed_warnings
32     let l:show_website_url = 0
33
34     let l:msg = "has been deprecated in favour of flake8 config files"
35     for setting_name in ['g:flake8_ignore', 'g:flake8_builtins', 'g:flake8_max_line_length', 'g:flake8_max_complexity']
36       if exists(setting_name)
37         echohl WarningMsg | echom setting_name l:msg | echohl None
38         let l:show_website_url = 1
39       endif
40     endfor
41
42     if l:show_website_url
43       let l:url = "http://flake8.readthedocs.org/en/latest/config.html"
44       echohl WarningMsg | echom l:url | echohl None
45     endif
46     let s:displayed_warnings = 1
47   endif
48 endfunction
49
50 "" config
51
52 function! s:DeclareOption(name, globalPrefix, default)  " {{{
53     if !exists('g:'.a:name)
54         if a:default != ''
55             execute 'let s:'.a:name.'='.a:default
56         else
57             execute 'let s:'.a:name.'=""'
58         endif
59     else
60         execute 'let l:global="g:".a:name'
61         if l:global != ''
62             execute 'let s:'.a:name.'="'.a:globalPrefix.'".g:'.a:name
63         else
64             execute 'let s:'.a:name.'=""'
65         endif
66     endif
67 endfunction  " }}}
68
69 function! s:Setup()  " {{{
70     "" read options
71
72     " flake8 command
73     call s:DeclareOption('flake8_cmd', '', '"flake8"')
74     " quickfix
75     call s:DeclareOption('flake8_quickfix_location', '', '"belowright"')
76     call s:DeclareOption('flake8_quickfix_height', '', 5)
77     call s:DeclareOption('flake8_show_quickfix', '', 1)
78     " markers to show
79     call s:DeclareOption('flake8_show_in_gutter', '',   0)
80     call s:DeclareOption('flake8_show_in_file', '',   0)
81     call s:DeclareOption('flake8_max_markers', '', 500)
82     " marker signs
83     call s:DeclareOption('flake8_error_marker', '', '"E>"')
84     call s:DeclareOption('flake8_warning_marker', '', '"W>"')
85     call s:DeclareOption('flake8_pyflake_marker', '', '"F>"')
86     call s:DeclareOption('flake8_complexity_marker', '', '"C>"')
87     call s:DeclareOption('flake8_naming_marker', '', '"N>"')
88
89     "" setup markerdata
90
91     if !exists('s:markerdata')
92         let s:markerdata = {}
93         let s:markerdata['E'] = {'name': 'Flake8_Error'}
94         let s:markerdata['W'] = {'name': 'Flake8_Warning'}
95         let s:markerdata['F'] = {'name': 'Flake8_PyFlake'}
96         let s:markerdata['C'] = {'name': 'Flake8_Complexity'}
97         let s:markerdata['N'] = {'name': 'Flake8_Nameing'}
98     endif
99     let s:markerdata['E'].marker = s:flake8_error_marker
100     let s:markerdata['W'].marker = s:flake8_warning_marker
101     let s:markerdata['F'].marker = s:flake8_pyflake_marker
102     let s:markerdata['C'].marker = s:flake8_complexity_marker
103     let s:markerdata['N'].marker = s:flake8_naming_marker
104 endfunction  " }}}
105
106 "" do flake8
107
108 function! s:Flake8()  " {{{
109     " read config
110     call s:Setup()
111
112     let l:executable = split(s:flake8_cmd)[0]
113
114     if !executable(l:executable)
115         echoerr "File " . l:executable . " not found. Please install it first."
116         return
117     endif
118
119     " clear old
120     call s:UnplaceMarkers()
121     let s:matchids = []
122     let s:signids  = []
123
124     " store old grep settings (to restore later)
125     let l:old_gfm=&grepformat
126     let l:old_gp=&grepprg
127     let l:old_shellpipe=&shellpipe
128
129     " write any changes before continuing
130     if &readonly == 0
131         update
132     endif
133
134     set lazyredraw   " delay redrawing
135     cclose           " close any existing cwindows
136
137     " set shellpipe to > instead of tee (suppressing output)
138     set shellpipe=>
139
140     " perform the grep itself
141     let &grepformat="%f:%l:%c: %m\,%f:%l: %m"
142     let &grepprg=s:flake8_cmd
143     silent! grep! "%"
144
145     " restore grep settings
146     let &grepformat=l:old_gfm
147     let &grepprg=l:old_gp
148     let &shellpipe=l:old_shellpipe
149
150     " process results
151     let l:results=getqflist()
152     let l:has_results=results != []
153     if l:has_results
154         " markers
155         if !s:flake8_show_in_gutter == 0 || !s:flake8_show_in_file == 0
156             call s:PlaceMarkers(l:results)
157         endif
158         " quickfix
159         if !s:flake8_show_quickfix == 0
160             " open cwindow
161             execute s:flake8_quickfix_location." copen".s:flake8_quickfix_height
162             setlocal wrap
163             nnoremap <buffer> <silent> c :cclose<CR>
164             nnoremap <buffer> <silent> q :cclose<CR>
165         endif
166     endif
167
168     set nolazyredraw
169     redraw!
170
171     " Show status
172     if l:has_results == 0
173         echon "Flake8 check OK"
174     else
175         echon "Flake8 found issues"
176     endif
177 endfunction  " }}}
178
179 "" markers
180
181 function! s:PlaceMarkers(results)  " {{{
182     " in gutter?
183     if !s:flake8_show_in_gutter == 0
184         " define signs
185         for val in values(s:markerdata)
186             if val.marker != ''
187                 execute "sign define ".val.name." text=".val.marker." texthl=".val.name
188             endif
189         endfor
190     endif
191
192     " place
193     let l:index0 = 100
194     let l:index  = l:index0
195     for result in a:results
196         if l:index >= (s:flake8_max_markers+l:index0)
197             break
198         endif
199         let l:type = strpart(result.text, 0, 1)
200         if has_key(s:markerdata, l:type) && s:markerdata[l:type].marker != ''
201             " file markers
202             if !s:flake8_show_in_file == 0
203                 if !has_key(s:markerdata[l:type], 'matchstr')
204                     let s:markerdata[l:type].matchstr = '\%('
205                 else
206                     let s:markerdata[l:type].matchstr .= '\|'
207                 endif
208                 let s:markerdata[l:type].matchstr .= '\%'.result.lnum.'l\%'.result.col.'c'
209             endif
210             " gutter markers
211             if !s:flake8_show_in_gutter == 0
212                 execute ":sign place ".index." name=".s:markerdata[l:type].name
213                             \ . " line=".result.lnum." file=".expand("%:p")
214                 let s:signids += [l:index]
215             endif
216             let l:index += 1
217         endif
218     endfor
219
220     " in file?
221     if !s:flake8_show_in_file == 0
222         for l:val in values(s:markerdata)
223             if l:val.marker != '' && has_key(l:val, 'matchstr')
224                 let l:val.matchid = matchadd(l:val.name, l:val.matchstr.'\)')
225             endif
226         endfor
227     endif
228 endfunction  " }}}
229
230 function! s:UnplaceMarkers()  " {{{
231     " gutter markers
232     if exists('s:signids')
233         for i in s:signids
234             execute ":sign unplace ".i
235         endfor
236         unlet s:signids
237     endif
238     " file markers
239     for l:val in values(s:markerdata)
240         if has_key(l:val, 'matchid')
241             call matchdelete(l:val.matchid)
242             unlet l:val.matchid
243             unlet l:val.matchstr
244         endif
245     endfor
246 endfunction  " }}}
247
248 "" }}}
249
250 let &cpo = s:save_cpo
251 unlet s:save_cpo
252