ecd8a32fc6ac0019e57f7b86e0d0411ec55e27df
[dotfiles.git] / vim / .vim / autoload / python / lint.vim
1 " Asynchronous pylint utility call
2 " Maintainer: Sergey Matveev <stargrave@stargrave.org>
3 " License: GNU General Public License version 3 of the License or later
4 "
5 " This plugin allows you to asynchronously call pylint.
6 "
7 " * Press <F6> to start pylint on current file
8 " * Press <S-F6> to open quickfix window with messages from pylint
9 " * All lines with corresponding pylint existing warning will be highlighted
10 " * If no warning and errors occurred, "pylint is clean" message will be shown
11 " * If existing quickfix window is found, then it won't be overwritten.
12 "   Start pylint manually (<F6>) to force its filling
13 " * After Python file is saved, pylint is automatically started
14
15 function! python#lint#status()
16     if exists("b:pylint_job") && job_status(b:pylint_job) == "run" | return "LN" | endif
17     return ""
18 endfunction
19
20 function! s:qffill(ch) abort
21     let msgs = []
22     while ch_status(a:ch) == 'buffered'
23         let msgs = add(msgs, ch_read(a:ch))
24     endwhile
25     cgetexpr msgs
26 endfunction
27
28 sign define LN text=LN texthl=Error
29
30 function! python#lint#finish(ch) abort
31     let l:errorformat_bak = &errorformat
32     set errorformat=%f:%l:\ [%t]%m,%f:%l:%m
33     call s:qffill(a:ch)
34     let &errorformat=l:errorformat_bak
35     sign unplace *
36     let l:id = 2
37     for item in getqflist()
38         if item.lnum == 0 | continue | endif
39         execute(':sign place '.l:id.' name=LN line='.l:item.lnum.' buffer='.l:item.bufnr)
40         let l:id = l:id + 2
41     endfor
42     redraw!
43     if l:id == 2
44         echohl MoreMsg | echomsg "pylint is clean" | echohl None
45         cclose
46     endif
47 endfunction
48
49 function! python#lint#start() abort
50     if exists("g:pylint_disable") ||
51         \ (exists("b:pylint_job") &&
52         \ job_status(b:pylint_job) == "run")
53         return
54     endif
55     let ignores = [
56         \"locally-disabled",
57         \"no-init",
58         \"no-self-use",
59         \"too-few-public-methods",
60         \"missing-docstring",
61         \"too-many-instance-attributes",
62         \"invalid-name",
63         \"too-many-arguments",
64         \"too-many-locals",
65         \"too-many-public-methods",
66         \"no-value-for-parameter",
67     \]
68     let linter = get(g:, "pylint_linter", "flake8")
69     if linter == "flake8"
70         let cmdline = [
71             \"flake8",
72             \"--ignore=E501",
73             \"--format=%(path)s:%(row)d: [%(code)s] %(text)s",
74             \"--max-line-length=90",
75             \expand("%p")
76         \]
77     elseif linter == "pylint"
78         let cmdline = [
79             \"pylint",
80             \"--jobs=4",
81             \"--reports=n",
82             \"--msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}",
83             \"--disable=" . join(ignores, ","),
84             \"--persistent=n",
85             \"--score=no",
86             \expand("%p")
87         \]
88     else
89         echohl WarningMsg | echomsg "Unknown linter specified" | echohl None
90         return
91     endif
92     let b:pylint_job = job_start(cmdline,
93         \ {"in_mode": "nl",  "err_io": "null", "close_cb": "python#lint#finish"})
94 endfunction