]> Sergey Matveev's repositories - dotfiles.git/blob - vim/.vim/autoload/python/importcompl.vim
aa9a1685df669c28aac1952af2ebbc3ecf9b64a3
[dotfiles.git] / vim / .vim / autoload / python / importcompl.vim
1 " Python imports insert completion
2 " Maintainer: Sergey Matveev <stargrave@stargrave.org>
3 " License: GNU General Public License version 3 of the License or later
4 "
5 " This plugin is intended for quick import-line insertion.
6 " For example you have got "from foo.bar import Baz" import somewhere in
7 " your Git-versioned code. In another file you can write "Baz" and then
8 " press <F3> in insert mode. Completion menu will show you suggestions
9 " of all import lines from your code containing Baz import.
10 "
11 " If you have Pylint or Pyflakes output in quickfix window, containing
12 " unfedined variables errors, then you can you :call python#importcompl#all()
13 " function. It will go through the quickfix list and find all possible
14 " imports, sort them and insert under current cursor position.
15 "
16 " It uses external "git grep" call and assumes that "canonical" Python
17 " import format is used (single import per line).
18 " You can use http://www.git.stargrave.org/?p=pyimportcan.git;a=blob;f=pyimportcan.pl
19 " utility to convert existing imports to that format.
20
21 let s:git_grep_cmd = "git grep -H --line-number --ignore-case --no-color "
22
23 function! python#importcompl#sortByLen(s1, s2)
24     if len(a:s1) == len(a:s2) | return a:s1 > a:s2 | endif
25     return 1 ? len(a:s1) > len(a:s2) : -1
26 endfunction
27
28 function! python#importcompl#do() abort
29     normal diw
30     let output = system(s:git_grep_cmd . '"^from .* import .*' . @" . '" -- "*.py" "**/*.py"')
31     let suggestions = []
32     for line in split(output, "\n")
33         if stridx(line, "unused-import") != -1 | continue | endif
34         let m = matchlist(line, '^.*:\d\+:\(.*\)$')
35         if len(m) == 0 | continue | endif
36         call insert(suggestions, m[1])
37     endfor
38     call sort(suggestions, "python#importcompl#sortByLen")
39     call uniq(suggestions)
40     call reverse(suggestions)
41     call complete(col('.'), suggestions)
42     return ''
43 endfunction
44
45 function! python#importcompl#all() abort
46     let output = system(s:git_grep_cmd . '"^from .* import" -- "*.py" "**/*.py"')
47     let imports = {}
48     for line in split(output, "\n")
49         if stridx(line, "unused-import") != -1 | continue | endif
50         for regexp in [
51             \'^.*:\d\+:\(from .* import \(\w\+\).*\)$',
52             \'^.*:\d\+:\(from .* import \w\+ as \(\w\+\).*\)$',
53         \]
54             let m = matchlist(line, regexp)
55             if len(m) == 0 | break | endif
56             let imports[m[2]] = m[1]
57         endfor
58     endfor
59     let result = []
60     for diag in lsp#ui#vim#diagnostics#get_all_buffer_diagnostics()
61         if diag["message"] !~ "^undefined name" | continue | endif
62         let m = diag["message"][strridx(diag["message"][:-2], "'")+1:-2]
63         if len(m) == 0 || !has_key(imports, m) | continue | endif
64         call insert(result, imports[m])
65     endfor
66     call sort(result, "i")
67     call uniq(result)
68     call append(".", result)
69 endfunction