]> git.madduck.net Git - etc/vim.git/blob - ale_linters/erlang/erlc.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:

Squashed '.vim/bundle/ale/' content from commit 22185c4c
[etc/vim.git] / ale_linters / erlang / erlc.vim
1 " Author: Magnus Ottenklinger - https://github.com/evnu
2
3 let g:ale_erlang_erlc_executable = get(g:, 'ale_erlang_erlc_executable', 'erlc')
4 let g:ale_erlang_erlc_options = get(g:, 'ale_erlang_erlc_options', '')
5
6 function! ale_linters#erlang#erlc#GetExecutable(buffer) abort
7     return ale#Var(a:buffer, 'erlang_erlc_executable')
8 endfunction
9
10 function! ale_linters#erlang#erlc#GetCommand(buffer) abort
11     let l:output_file = ale#util#Tempname()
12     call ale#command#ManageFile(a:buffer, l:output_file)
13
14     let l:command = ale#Escape(ale_linters#erlang#erlc#GetExecutable(a:buffer))
15     \             . ' -o ' . ale#Escape(l:output_file)
16     \             . ' ' . ale#Var(a:buffer, 'erlang_erlc_options')
17     \             . ' %t'
18
19     return l:command
20 endfunction
21
22 function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
23     " Matches patterns like the following:
24     "
25     " error.erl:4: variable 'B' is unbound
26     " error.erl:3: Warning: function main/0 is unused
27     " error.erl:4: Warning: variable 'A' is unused
28     let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+:)? (Warning: )?(.+)$'
29
30     " parse_transforms are a special case. The error message does not indicate a location:
31     " error.erl: undefined parse transform 'some_parse_transform'
32     let l:pattern_parse_transform = '\v(undefined parse transform .*)$'
33     let l:output = []
34
35     let l:pattern_no_module_definition = '\v(no module definition)$'
36     let l:pattern_unused = '\v(.* is unused)$'
37
38     let l:is_hrl = fnamemodify(bufname(a:buffer), ':e') is# 'hrl'
39
40     for l:line in a:lines
41         let l:match = matchlist(l:line, l:pattern)
42
43         " Determine if the output indicates an error. We distinguish between two cases:
44         "
45         " 1) normal errors match l:pattern
46         " 2) parse_transform errors match l:pattern_parse_transform
47         "
48         " If none of the patterns above match, the line can be ignored
49         if len(l:match) == 0 " not a 'normal' warning or error
50             let l:match_parse_transform = matchlist(l:line, l:pattern_parse_transform)
51
52             if len(l:match_parse_transform) == 0 " also not a parse_transform error
53                 continue
54             endif
55
56             call add(l:output, {
57             \   'bufnr': a:buffer,
58             \   'lnum': 0,
59             \   'col': 0,
60             \   'type': 'E',
61             \   'text': l:match_parse_transform[0],
62             \})
63
64             continue
65         endif
66
67         let l:line = l:match[2]
68         let l:warning_or_text = l:match[4]
69         let l:text = l:match[5]
70
71         " If this file is a header .hrl, ignore the following expected messages:
72         " - 'no module definition'
73         " - 'X is unused'
74         if l:is_hrl && (
75         \   match(l:text, l:pattern_no_module_definition) != -1
76         \   || match(l:text, l:pattern_unused) != -1
77         \)
78             continue
79         endif
80
81         if !empty(l:warning_or_text)
82             let l:type = 'W'
83         else
84             let l:type = 'E'
85         endif
86
87         call add(l:output, {
88         \   'bufnr': a:buffer,
89         \   'lnum': l:line,
90         \   'col': 0,
91         \   'type': l:type,
92         \   'text': l:text,
93         \})
94     endfor
95
96     return l:output
97 endfunction
98
99 call ale#linter#Define('erlang', {
100 \   'name': 'erlc',
101 \   'executable': function('ale_linters#erlang#erlc#GetExecutable'),
102 \   'command': function('ale_linters#erlang#erlc#GetCommand'),
103 \   'callback': 'ale_linters#erlang#erlc#Handle',
104 \})