vim/ftplugin/python/flake8.vim

189 lines
4.8 KiB
VimL
Executable File

" Check python support
if !has('python')
echo "Error: PyFlake.vim required vim compiled with +python."
finish
endif
if !exists('g:PyFlakeRangeCommand')
let g:PyFlakeRangeCommand = 'Q'
endif
if !exists('b:PyFlake_initialized')
let b:PyFlake_initialized = 1
au BufWritePost <buffer> call flake8#on_write()
au CursorHold <buffer> call flake8#get_message()
au CursorMoved <buffer> call flake8#get_message()
" Commands
command! -buffer PyFlakeToggle :let b:PyFlake_disabled = exists('b:PyFlake_disabled') ? b:PyFlake_disabled ? 0 : 1 : 1
command! -buffer PyFlake :call flake8#run()
command! -buffer -range=% PyFlakeAuto :call flake8#auto(<line1>,<line2>)
" Keymaps
if g:PyFlakeRangeCommand != ''
exec 'vnoremap <buffer> <silent> ' . g:PyFlakeRangeCommand . ' :PyFlakeAuto<CR>'
endif
let b:showing_message = 0
" Signs definition
sign define W text=WW texthl=Todo
sign define C text=CC texthl=Comment
sign define R text=RR texthl=Visual
sign define E text=EE texthl=Error
endif
"Check for flake8 plugin is loaded
if exists("g:PyFlakeDirectory")
finish
endif
if !exists('g:PyFlakeOnWrite')
let g:PyFlakeOnWrite = 1
endif
" Init variables
let g:PyFlakeDirectory = expand('<sfile>:p:h')
if !exists('g:PyFlakeCheckers')
let g:PyFlakeCheckers = 'pep8,mccabe,pyflakes'
endif
if !exists('g:PyFlakeDefaultComplexity')
let g:PyFlakeDefaultComplexity=10
endif
if !exists('g:PyFlakeDisabledMessages')
let g:PyFlakeDisabledMessages = 'E501'
endif
if !exists('g:PyFlakeCWindow')
let g:PyFlakeCWindow = 6
endif
if !exists('g:PyFlakeSigns')
let g:PyFlakeSigns = 1
endif
if !exists('g:PyFlakeMaxLineLength')
let g:PyFlakeMaxLineLength = 100
endif
python << EOF
import sys
import json
import vim
sys.path.insert(0, vim.eval("g:PyFlakeDirectory"))
from flake8 import run_checkers, fix_lines, Pep8Options, MccabeOptions
def flake8_check():
checkers=vim.eval('g:PyFlakeCheckers').split(',')
ignore=vim.eval('g:PyFlakeDisabledMessages').split(',')
MccabeOptions.complexity=int(vim.eval('g:PyFlakeDefaultComplexity'))
Pep8Options.max_line_length=int(vim.eval('g:PyFlakeMaxLineLength'))
filename=vim.current.buffer.name
parse_result(run_checkers(filename, checkers, ignore))
def parse_result(result):
vim.command('let g:qf_list = {}'.format(json.dumps(result, ensure_ascii=False)))
EOF
function! flake8#on_write()
if !g:PyFlakeOnWrite || exists("b:PyFlake_disabled") && b:PyFlake_disabled
return
endif
call flake8#check()
endfunction
function! flake8#run()
if &modifiable && &modified
write
endif
call flake8#check()
endfun
function! flake8#check()
py flake8_check()
let s:matchDict = {}
for err in g:qf_list
let s:matchDict[err.lnum] = err.text
endfor
call setqflist(g:qf_list, 'r')
" Place signs
if g:PyFlakeSigns
call flake8#place_signs()
endif
" Open cwindow
if g:PyFlakeCWindow
cclose
if len(g:qf_list)
let l:winsize = len(g:qf_list) > g:PyFlakeCWindow ? g:PyFlakeCWindow : len(g:qf_list)
exec l:winsize . 'cwindow'
endif
endif
endfunction
function! flake8#auto(l1, l2) "{{{
cclose
sign unplace *
let s:matchDict = {}
call setqflist([])
python << EOF
start, end = int(vim.eval('a:l1'))-1, int(vim.eval('a:l2'))
enc = vim.eval('&enc')
lines = fix_lines(vim.current.buffer[start:end]).splitlines()
res = [ln.encode(enc, 'replace') for ln in lines]
vim.current.buffer[start:end] = res
EOF
endfunction "}}}
function! flake8#place_signs()
"first remove all sings
sign unplace *
"now we place one sign for every quickfix line
let l:id = 1
for item in getqflist()
execute(':sign place '.l:id.' name='.l:item.type.' line='.l:item.lnum.' buffer='.l:item.bufnr)
let l:id = l:id + 1
endfor
endfunction
" keep track of whether or not we are showing a message
" WideMsg() prints [long] message up to (&columns-1) length
" guaranteed without "Press Enter" prompt.
function! flake8#wide_msg(msg)
let x=&ruler | let y=&showcmd
set noruler noshowcmd
redraw
echo strpart(a:msg, 0, &columns-1)
let &ruler=x | let &showcmd=y
endfun
function! flake8#get_message()
let s:cursorPos = getpos(".")
" Bail if RunPyflakes hasn't been called yet.
if !exists('s:matchDict')
return
endif
" if there's a message for the line the cursor is currently on, echo
" it to the console
if has_key(s:matchDict, s:cursorPos[1])
let s:pyflakesMatch = get(s:matchDict, s:cursorPos[1])
call flake8#wide_msg(s:pyflakesMatch)
let b:showing_message = 1
return
endif
" otherwise, if we're showing a message, clear it
if b:showing_message == 1
echo
let b:showing_message = 0
endif
endfunction