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

Fix dead link
[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     if !executable(s:flake8_cmd)
113         echoerr "File " . s:flake8_cmd . " not found. Please install it first."
114         return
115     endif
116
117     " clear old
118     call s:UnplaceMarkers()
119     let s:matchids = []
120     let s:signids  = []
121
122     " store old grep settings (to restore later)
123     let l:old_gfm=&grepformat
124     let l:old_gp=&grepprg
125     let l:old_shellpipe=&shellpipe
126
127     " write any changes before continuing
128     if &readonly == 0
129         update
130     endif
131
132     set lazyredraw   " delay redrawing
133     cclose           " close any existing cwindows
134
135     " set shellpipe to > instead of tee (suppressing output)
136     set shellpipe=>
137
138     " perform the grep itself
139     let &grepformat="%f:%l:%c: %m\,%f:%l: %m"
140     let &grepprg=s:flake8_cmd
141     silent! grep! "%"
142
143     " restore grep settings
144     let &grepformat=l:old_gfm
145     let &grepprg=l:old_gp
146     let &shellpipe=l:old_shellpipe
147
148     " process results
149     let l:results=getqflist()
150     let l:has_results=results != []
151     if l:has_results
152         " markers
153         if !s:flake8_show_in_gutter == 0 || !s:flake8_show_in_file == 0
154             call s:PlaceMarkers(l:results)
155         endif
156         " quickfix
157         if !s:flake8_show_quickfix == 0
158             " open cwindow
159             execute s:flake8_quickfix_location." copen".s:flake8_quickfix_height
160             setlocal wrap
161             nnoremap <buffer> <silent> c :cclose<CR>
162             nnoremap <buffer> <silent> q :cclose<CR>
163         endif
164     endif
165
166     set nolazyredraw
167     redraw!
168
169     " Show status
170     if l:has_results == 0
171         echon "Flake8 check OK"
172     else
173         echon "Flake8 found issues"
174     endif
175 endfunction  " }}}
176
177 "" markers
178
179 function! s:PlaceMarkers(results)  " {{{
180     " in gutter?
181     if !s:flake8_show_in_gutter == 0
182         " define signs
183         for val in values(s:markerdata)
184             if val.marker != ''
185                 execute "sign define ".val.name." text=".val.marker." texthl=".val.name
186             endif
187         endfor
188     endif
189
190     " place
191     let l:index0 = 100
192     let l:index  = l:index0
193     for result in a:results
194         if l:index >= (s:flake8_max_markers+l:index0)
195             break
196         endif
197         let l:type = strpart(result.text, 0, 1)
198         if has_key(s:markerdata, l:type) && s:markerdata[l:type].marker != ''
199             " file markers
200             if !s:flake8_show_in_file == 0
201                 if !has_key(s:markerdata[l:type], 'matchstr')
202                     let s:markerdata[l:type].matchstr = '\%('
203                 else
204                     let s:markerdata[l:type].matchstr .= '\|'
205                 endif
206                 let s:markerdata[l:type].matchstr .= '\%'.result.lnum.'l\%'.result.col.'c'
207             endif
208             " gutter markers
209             if !s:flake8_show_in_gutter == 0
210                 execute ":sign place ".index." name=".s:markerdata[l:type].name
211                             \ . " line=".result.lnum." file=".expand("%:p")
212                 let s:signids += [l:index]
213             endif
214             let l:index += 1
215         endif
216     endfor
217
218     " in file?
219     if !s:flake8_show_in_file == 0
220         for l:val in values(s:markerdata)
221             if l:val.marker != '' && has_key(l:val, 'matchstr')
222                 let l:val.matchid = matchadd(l:val.name, l:val.matchstr.'\)')
223             endif
224         endfor
225     endif
226 endfunction  " }}}
227
228 function! s:UnplaceMarkers()  " {{{
229     " gutter markers
230     if exists('s:signids')
231         for i in s:signids
232             execute ":sign unplace ".i
233         endfor
234         unlet s:signids
235     endif
236     " file markers
237     for l:val in values(s:markerdata)
238         if has_key(l:val, 'matchid')
239             call matchdelete(l:val.matchid)
240             unlet l:val.matchid
241             unlet l:val.matchstr
242         endif
243     endfor
244 endfunction  " }}}
245
246 "" }}}
247
248 let &cpo = s:save_cpo
249 unlet s:save_cpo
250