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

Bugfix: Marker data was cleared for every run, hence filemarkers was impossible to...
[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     " 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.s:flake8_builtins.s:flake8_ignore.s:flake8_max_line_length.s:flake8_max_complexity
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     " clear old
165     call s:UnplaceMarkers()
166     let s:matchids = []
167     let s:signids  = []
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