--- /dev/null
+ Copyright (c) 2014, Vincent Driessen
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
--- /dev/null
+ vim-flake8
+ ==========
+ `vim-flake8` is a Vim plugin that runs the currently open file through Flake8,
+ a static syntax and style checker for Python source code. It supersedes both
+ [vim-pyflakes](https://github.com/nvie/vim-pyflakes) and
+ [vim-pep8](https://github.com/nvie/vim-pep8).
+
+ [Flake8](https://pypi.python.org/pypi/flake8/) is a wrapper around PyFlakes
+ (static syntax checker), PEP8 (style checker) and Ned's MacCabe script
+ (complexity checker).
+
+
+ Installation
+ ------------
+
+ Make sure you've installed the
+ [flake8](https://pypi.python.org/pypi/flake8/) package.
+
+ If you use vim >= 8, install this plugin with:
+ ```
+ mkdir -p ~/.vim/pack/flake8/start/
+ cd ~/.vim/pack/flake8/start/
+ git clone https://github.com/nvie/vim-flake8.git
+ ```
+
+ Otherwise, install [vim-pathogen](https://github.com/tpope/vim-pathogen)
+ if you're not using it already. Then, simply put the
+ contents of this repository in your `~/.vim/bundle` directory.
+
+ Usage
+ -----
+ 1. Open a Python file
+ 2. Press `<F7>` to run `flake8` on it
+
+ It shows the errors inside a quickfix window, which will allow your to quickly
+ jump to the error locations by simply pressing [Enter].
+
+ If any of `g:flake8_show_in_gutter` or `g:flake8_show_in_file` are set to `1`, call:
+
+ call flake8#Flake8UnplaceMarkers()
+
+ To remove all markers. No default mapping is provided.
+
+ Customization
+ -------------
+ If you don't want to use the `<F7>` key for flake8-checking, simply remap it to
+ another key. It autodetects whether it has been remapped and won't register
+ the `<F7>` key if so. For example, to remap it to `<F3>` instead, use:
+
+ autocmd FileType python map <buffer> <F3> :call flake8#Flake8()<CR>
+
+ For flake8 configuration options please consult the following page:
+
+ http://flake8.pycqa.org/en/latest/user/configuration.html
+
+ To customize the location of your flake8 binary, set `g:flake8_cmd`:
+
+ let g:flake8_cmd="/opt/strangebin/flake8000"
+
+ To customize the location of quick fix window, set `g:flake8_quickfix_location`:
+
+ let g:flake8_quickfix_location="topleft"
+
+ To customize the height of quick fix window, set `g:flake8_quickfix_height`:
+
+ let g:flake8_quickfix_height=7
+
+ To customize whether the quickfix window opens, set `g:flake8_show_quickfix`:
+
+ let g:flake8_show_quickfix=0 " don't show
+ let g:flake8_show_quickfix=1 " show (default)
+
+ To customize whether the show signs in the gutter, set `g:flake8_show_in_gutter`:
+
+ let g:flake8_show_in_gutter=0 " don't show (default)
+ let g:flake8_show_in_gutter=1 " show
+
+ To customize whether the show marks in the file, set `g:flake8_show_in_file`:
+
+ let g:flake8_show_in_file=0 " don't show (default)
+ let g:flake8_show_in_file=1 " show
+
+ To customize the number of marks to show, set `g:flake8_max_markers`:
+
+ let g:flake8_max_markers=500 " (default)
+
+ To customize the gutter markers, set any of `flake8_error_marker`, `flake8_warning_marker`,
+ `flake8_pyflake_marker`, `flake8_complexity_marker`, `flake8_naming_marker`. Setting one to
+ the empty string disables it. Ex.:
+
+ flake8_error_marker='EE' " set error marker to 'EE'
+ flake8_warning_marker='WW' " set warning marker to 'WW'
+ flake8_pyflake_marker='' " disable PyFlakes warnings
+ flake8_complexity_marker='' " disable McCabe complexity warnings
+ flake8_naming_marker='' " disable naming warnings
+
+ To customize the colors used for markers, define the highlight groups, `Flake8_Error`,
+ `Flake8_Warning`, `Flake8_PyFlake`, `Flake8_Complexity`, `Flake8_Naming`:
+
+ " to use colors defined in the colorscheme
+ highlight link Flake8_Error Error
+ highlight link Flake8_Warning WarningMsg
+ highlight link Flake8_Complexity WarningMsg
+ highlight link Flake8_Naming WarningMsg
+ highlight link Flake8_PyFlake WarningMsg
+
+ To show the error message of the current line in the ruler, call `flake8#ShowError()`:
+
+ " add binding to call the function
+ nnoremap <C-K> :call flake8#Flake8ShowError()<cr>
+
+
+ Tips
+ ----
+ A tip might be to run the Flake8 check every time you write a Python file, to
+ enable this, add the following line to your `.vimrc` file (thanks
+ [Godefroid](https://github.com/gotcha)!):
+
+ autocmd BufWritePost *.py call flake8#Flake8()
+
+ This plugin goes well together with the following plugin:
+
+ - [PyUnit](https://github.com/nvie/vim-pyunit) (unit test helper under `<F8>`
+ and `<F9>`)
+
+
+ Max line lengths
+ ----------------
+
+ One particular customization a lot of people like to make is relaxing the
+ maximum line length default. This is a config setting that should be set in
+ flake8 itself. (vim-flake8 "just" invokes it and deals with showing the output
+ in Vim's quickfix window.)
+
+ To do so, put the following into your `~/.config/flake8` file:
+
+ [flake8]
+ max-line-length = 120
+
+
+ History
+ -------
+ 1.6: Deprecated configuring flake8 options through Vim settings. Instead,
+ advise users to use the `~/.config/flake8` config file.
+
+ - Decprecated options:
+ - `g:flake8_builtins`
+ - `g:flake8_ignore`
+ - `g:flake8_max_line_length`
+ - `g:flake8_max_complexity`
+
+ - New options:
+ - `g:flake8_quickfix_height`
+
+ 1.5: Added markers and the option to don't show the quickfix window, also split
+ functions into a autoload file. Added:
+
+ - Options:
+ - `g:flake8_show_quickfix`
+ - `g:flake8_show_in_gutter`
+ - `g:flake8_show_in_file`
+ - `g:flake8_max_markers`
+ - `flake8_error_marker`
+ - `flake8_warning_marker`
+ - `flake8_pyflake_marker`
+ - `flake8_complexity_marker`
+ - `flake8_naming_marker`
+ - Functions:
+ - `flake8#Flake8UnplaceMarkers()`
+ - `flake8#Flake8()`
+ - Highlighting:
+ - `Flake8_Error`
+ - `Flake8_Warning`
+ - `Flake8_Complexity`
+ - `Flake8_Naming`
+ - `Flake8_PyFlake`
+
+ 1.4: Suppress output to stdout.
+
+ 1.3: Added the following options:
+
+ - `g:flake8_builtins="_,apply"`
+ - `g:flake8_max_complexity=10`
+
+ 1.2: Added the following options:
+
+ - `g:flake8_cmd="/opt/strangebin/flake8000"`
+ - `g:flake8_max_line_length=120`
+ - `g:flake8_ignore="E501,W293"`
+
+ 1.1: Added `g:flake8_ignore` option.
+
+ 1.0: Initial version.
+
+
+ License
+ -------
+
+ Liberally licensed under BSD terms.
--- /dev/null
+ "
+ " Python filetype plugin for running flake8
+ " Language: Python (ft=python)
+ " Maintainer: Vincent Driessen <vincent@3rdcloud.com>
+ " Version: Vim 7 (may work with lower Vim versions, but not tested)
+ " URL: http://github.com/nvie/vim-flake8
+
+ let s:save_cpo = &cpo
+ set cpo&vim
+
+ "" ** external ** {{{
+
+ function! flake8#Flake8()
+ call s:Flake8()
+ call s:Warnings()
+ endfunction
+
+ function! flake8#Flake8UnplaceMarkers()
+ call s:UnplaceMarkers()
+ call s:Warnings()
+ endfunction
+
+ function! flake8#Flake8ShowError()
+ call s:ShowErrorMessage()
+ endfunction
+
+ "" }}}
+
+ "" ** internal ** {{{
+
+ "" warnings
+
+ let s:displayed_warnings = 0
+ function s:Warnings()
+ if !s:displayed_warnings
+ let l:show_website_url = 0
+
+ let l:msg = "has been deprecated in favour of flake8 config files"
+ for setting_name in ['g:flake8_ignore', 'g:flake8_builtins', 'g:flake8_max_line_length', 'g:flake8_max_complexity']
+ if exists(setting_name)
+ echohl WarningMsg | echom setting_name l:msg | echohl None
+ let l:show_website_url = 1
+ endif
+ endfor
+
+ if l:show_website_url
+ let l:url = "http://flake8.readthedocs.org/en/latest/config.html"
+ echohl WarningMsg | echom l:url | echohl None
+ endif
+ let s:displayed_warnings = 1
+ endif
+ endfunction
+
+ "" config
+
+ function! s:DeclareOption(name, globalPrefix, default) " {{{
+ if !exists('g:'.a:name)
+ if a:default != ''
+ execute 'let s:'.a:name.'='.a:default
+ else
+ execute 'let s:'.a:name.'=""'
+ endif
+ else
+ execute 'let l:global="g:".a:name'
+ if l:global != ''
+ execute 'let s:'.a:name.'="'.a:globalPrefix.'".g:'.a:name
+ else
+ execute 'let s:'.a:name.'=""'
+ endif
+ endif
+ endfunction " }}}
+
+ function! s:Setup() " {{{
+ "" read options
+
+ " flake8 command
+ call s:DeclareOption('flake8_cmd', '', '"flake8"')
+ " quickfix
+ call s:DeclareOption('flake8_quickfix_location', '', '"belowright"')
+ call s:DeclareOption('flake8_quickfix_height', '', 5)
+ call s:DeclareOption('flake8_show_quickfix', '', 1)
+ " markers to show
+ call s:DeclareOption('flake8_show_in_gutter', '', 0)
+ call s:DeclareOption('flake8_show_in_file', '', 0)
+ call s:DeclareOption('flake8_max_markers', '', 500)
+ " marker signs
+ call s:DeclareOption('flake8_error_marker', '', '"E>"')
+ call s:DeclareOption('flake8_warning_marker', '', '"W>"')
+ call s:DeclareOption('flake8_pyflake_marker', '', '"F>"')
+ call s:DeclareOption('flake8_complexity_marker', '', '"C>"')
+ call s:DeclareOption('flake8_naming_marker', '', '"N>"')
+
+ "" setup markerdata
+
+ if !exists('s:markerdata')
+ let s:markerdata = {}
+ let s:markerdata['E'] = {'name': 'Flake8_Error'}
+ let s:markerdata['W'] = {'name': 'Flake8_Warning'}
+ let s:markerdata['F'] = {'name': 'Flake8_PyFlake'}
+ let s:markerdata['C'] = {'name': 'Flake8_Complexity'}
+ let s:markerdata['N'] = {'name': 'Flake8_Nameing'}
+ endif
+ let s:markerdata['E'].marker = s:flake8_error_marker
+ let s:markerdata['W'].marker = s:flake8_warning_marker
+ let s:markerdata['F'].marker = s:flake8_pyflake_marker
+ let s:markerdata['C'].marker = s:flake8_complexity_marker
+ let s:markerdata['N'].marker = s:flake8_naming_marker
+
+ endfunction " }}}
+
+ "" do flake8
+
+ function! s:Flake8() " {{{
+ " read config
+ call s:Setup()
+
+ let l:executable = split(s:flake8_cmd)[0]
+
+ if !executable(l:executable)
+ echoerr "File " . l:executable . " not found. Please install it first."
+ return
+ endif
+
+ " clear old
+ call s:UnplaceMarkers()
+ let s:matchids = []
+ let s:signids = []
+
+ " store old grep settings (to restore later)
+ let l:old_gfm=&grepformat
+ let l:old_gp=&grepprg
+ let l:old_shellpipe=&shellpipe
+ let l:old_t_ti=&t_ti
+ let l:old_t_te=&t_te
+
+ " write any changes before continuing
+ if &readonly == 0
+ update
+ endif
+
+ set lazyredraw " delay redrawing
+
+ " prevent terminal from blinking
+ set shellpipe=>
+ set t_ti=
+ set t_te=
+
+ " perform the grep itself
+ let &grepformat="%f:%l:%c: %m\,%f:%l: %m,%-G%\\d"
+ let &grepprg=s:flake8_cmd
+ silent! grep! "%"
+ " close any existing cwindows,
+ " placed after 'grep' in case quickfix is open on autocmd QuickFixCmdPost
+ cclose
+
+ " restore grep settings
+ let &grepformat=l:old_gfm
+ let &grepprg=l:old_gp
+ let &shellpipe=l:old_shellpipe
+ let &t_ti=l:old_t_ti
+ let &t_te=l:old_t_te
+ " store mapping of line number to error string
+
+ " process results
+ let s:resultDict = {}
+
+ let l:results=getqflist()
+ let l:has_results=results != []
+ if l:has_results
+ " save line number of each error message
+ for result in l:results
+ let linenum = result.lnum
+ let s:resultDict[linenum] = result.text
+ endfor
+
+ " markers
+ if !s:flake8_show_in_gutter == 0 || !s:flake8_show_in_file == 0
+ call s:PlaceMarkers(l:results)
+ endif
+ " quickfix
+ if !s:flake8_show_quickfix == 0
+ " open cwindow
+ execute s:flake8_quickfix_location." copen".s:flake8_quickfix_height
+ setlocal wrap
+ nnoremap <buffer> <silent> c :cclose<CR>
+ nnoremap <buffer> <silent> q :cclose<CR>
+ endif
+ endif
+
+ set nolazyredraw
+ redraw!
+
+ " Show status
+ if l:has_results == 0
+ echon "Flake8 check OK"
+ else
+ echon "Flake8 found issues"
+ endif
+ endfunction " }}}
+
+
+
+ "" markers
+ function! s:PlaceMarkers(results) " {{{
+ " in gutter?
+ if !s:flake8_show_in_gutter == 0
+ " define signs
+ for val in values(s:markerdata)
+ if val.marker != ''
+ execute "sign define ".val.name." text=".val.marker." texthl=".val.name
+ endif
+ endfor
+ endif
+
+ " place
+ let l:index0 = 100
+ let l:index = l:index0
+ for result in a:results
+ if l:index >= (s:flake8_max_markers+l:index0)
+ break
+ endif
+ let l:type = strpart(result.text, 0, 1)
+ if has_key(s:markerdata, l:type) && s:markerdata[l:type].marker != ''
+ " file markers
+ if !s:flake8_show_in_file == 0
+ if !has_key(s:markerdata[l:type], 'matchstr')
+ let s:markerdata[l:type].matchstr = '\%('
+ else
+ let s:markerdata[l:type].matchstr .= '\|'
+ endif
+ let s:markerdata[l:type].matchstr .= '\%'.result.lnum.'l\%'.result.col.'c'
+ endif
+ " gutter markers
+ if !s:flake8_show_in_gutter == 0
+ execute ":sign place ".index." name=".s:markerdata[l:type].name
+ \ . " line=".result.lnum." file=".expand("%:p")
+ let s:signids += [l:index]
+ endif
+ let l:index += 1
+ endif
+ endfor
+
+ " in file?
+ if !s:flake8_show_in_file == 0
+ for l:val in values(s:markerdata)
+ if l:val.marker != '' && has_key(l:val, 'matchstr')
+ let l:val.matchid = matchadd(l:val.name, l:val.matchstr.'\)')
+ endif
+ endfor
+ endif
+ endfunction " }}}
+
+ function! s:UnplaceMarkers() " {{{
+ " gutter markers
+ if exists('s:signids')
+ for i in s:signids
+ execute ":sign unplace ".i
+ endfor
+ unlet s:signids
+ endif
+ " file markers
+ for l:val in values(s:markerdata)
+ if has_key(l:val, 'matchid')
+ call matchdelete(l:val.matchid)
+ unlet l:val.matchid
+ unlet l:val.matchstr
+ endif
+ endfor
+ endfunction " }}}
+
+ function! s:ShowErrorMessage() " {{{
+ let l:cursorPos = getpos(".")
+ if !exists('s:resultDict')
+ return
+ endif
+ if !exists('b:showing_message')
+ " ensure showing msg is always defined
+ let b:showing_message = ' '
+ endif
+
+ " if there is a message on the current line,
+ " then echo it
+ if has_key(s:resultDict, l:cursorPos[1])
+ let l:errorText = get(s:resultDict, l:cursorPos[1])
+ echo strpart(l:errorText, 0, &columns-1)
+ let b:showing_message = 1
+ endif
+
+ " if a message is already being shown,
+ " then clear it
+ if !b:showing_message == 0
+ echo
+ let b:showing_message = 0
+ endif
+
+ endfunction " }}}
+
+ "" }}}
+
+ let &cpo = s:save_cpo
+ unlet s:save_cpo
--- /dev/null
+ "
+ " Python filetype plugin for running flake8
+ " Language: Python (ft=python)
+ " Maintainer: Vincent Driessen <vincent@3rdcloud.com>
+ " Version: Vim 7 (may work with lower Vim versions, but not tested)
+ " URL: http://github.com/nvie/vim-flake8
+ "
+ " Only do this when not done yet for this buffer
+ if exists("b:loaded_flake8_ftplugin")
+ finish
+ endif
+ let b:loaded_flake8_ftplugin=1
+
+ let s:save_cpo = &cpo
+ set cpo&vim
+
+ "" Highlight groups for errors
+ " pep8 errors
+ highlight default Flake8_Error
+ \ ctermbg=DarkRed ctermfg=Red cterm=bold
+ \ guibg=DarkRed guifg=Red gui=bold
+ " pep8 warnings
+ highlight default Flake8_Warning
+ \ ctermbg=Yellow ctermfg=DarkYellow cterm=bold
+ \ guibg=Yellow guifg=DarkYellow gui=bold
+ " PyFlakes codes
+ highlight default Flake8_PyFlake
+ \ ctermbg=DarkBlue ctermfg=Blue cterm=bold
+ \ guibg=DarkBlue guifg=Blue gui=bold
+ " McCabe complexity warnings
+ highlight default Flake8_Complexity
+ \ ctermbg=DarkBlue ctermfg=Blue cterm=bold
+ \ guibg=DarkBlue guifg=Blue gui=bold
+ " naming conventions
+ highlight default Flake8_Naming
+ \ ctermbg=DarkBlue ctermfg=Blue cterm=bold
+ \ guibg=DarkBlue guifg=Blue gui=bold
+
+ " to not break with old versions
+ function! Flake8()
+ call flake8#Flake8()
+ endfunction
+
+ " Add mappings, unless the user didn't want this.
+ " The default mapping is registered under to <F7> by default, unless the user
+ " remapped it already (or a mapping exists already for <F7>)
+ if !exists("no_plugin_maps") && !exists("no_flake8_maps")
+ if !hasmapto('Flake8(') && !hasmapto('flake8#Flake8(')
+ noremap <buffer> <F7> :call flake8#Flake8()<CR>
+ endif
+ endif
+
+ let &cpo = s:save_cpo
+ unlet s:save_cpo
+