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

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