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

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