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

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