]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/ale/ale_linters/prolog/swipl.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:

Merge commit '76265755a1add77121c8f9dabb3e9bb70fe9a972' as '.vim/bundle/ale'
[etc/vim.git] / .vim / bundle / ale / ale_linters / prolog / swipl.vim
1 " Author: Takuya Fujiwara <tyru.exe@gmail.com>
2 " Description: swipl syntax / semantic check for Prolog files
3
4 call ale#Set('prolog_swipl_executable', 'swipl')
5 call ale#Set('prolog_swipl_load', 'current_prolog_flag(argv, [File]), load_files(File, [sandboxed(true)]), halt.')
6 call ale#Set('prolog_swipl_timeout', 3)
7 call ale#Set('prolog_swipl_alarm', 'alarm(%t, (%h), _, [])')
8 call ale#Set('prolog_swipl_alarm_handler', 'writeln(user_error, "ERROR: Exceeded %t seconds, Please change g:prolog_swipl_timeout to modify the limit."), halt(1)')
9
10 function! ale_linters#prolog#swipl#GetCommand(buffer) abort
11     let l:goals = ale#Var(a:buffer, 'prolog_swipl_load')
12     let l:goals = l:goals =~# '^\s*$' ? 'halt' : l:goals
13     let l:timeout = ale#Var(a:buffer, 'prolog_swipl_timeout') + 0
14
15     if l:timeout > 0
16         let l:goals = s:GetAlarm(a:buffer, l:timeout) . ', ' . l:goals
17     endif
18
19     return '%e -g ' . ale#Escape(l:goals) . ' -- %s'
20 endfunction
21
22 function! s:GetAlarm(buffer, timeout) abort
23     let l:handler = ale#Var(a:buffer, 'prolog_swipl_alarm_handler')
24     let l:handler = s:Subst(l:handler, {'t': a:timeout})
25     let l:alarm = ale#Var(a:buffer, 'prolog_swipl_alarm')
26     let l:alarm = s:Subst(l:alarm, {'t': a:timeout, 'h': l:handler})
27
28     return l:alarm
29 endfunction
30
31 function! s:Subst(format, vars) abort
32     let l:vars = extend(copy(a:vars), {'%': '%'})
33
34     return substitute(a:format, '%\(.\)', '\=get(l:vars, submatch(1), "")', 'g')
35 endfunction
36
37 function! ale_linters#prolog#swipl#Handle(buffer, lines) abort
38     let l:output = []
39     let l:i = 0
40
41     let l:pattern = '\v^(ERROR|Warning)+%(:\s*[^:]+:(\d+)%(:(\d+))?)?:\s*(.*)$'
42
43     while l:i < len(a:lines)
44         let l:match = matchlist(a:lines[l:i], l:pattern)
45
46         if empty(l:match)
47             let l:i += 1
48             continue
49         endif
50
51         let [l:i, l:text] = s:GetErrMsg(l:i, a:lines, l:match[4])
52         let l:item = {
53         \   'lnum': (l:match[2] + 0 ? l:match[2] + 0 : 1),
54         \   'col': l:match[3] + 0,
55         \   'text': l:text,
56         \   'type': (l:match[1] is# 'ERROR' ? 'E' : 'W'),
57         \}
58
59         if !s:Ignore(l:item)
60             call add(l:output, l:item)
61         endif
62     endwhile
63
64     return l:output
65 endfunction
66
67 " This returns [<next line number>, <error message string>]
68 function! s:GetErrMsg(i, lines, text) abort
69     if a:text !~# '^\s*$'
70         return [a:i + 1, a:text]
71     endif
72
73     let l:i = a:i + 1
74     let l:text = []
75
76     let l:pattern = '\v^(ERROR|Warning)?:?(.*)$'
77
78     while l:i < len(a:lines)
79         let l:match = matchlist(a:lines[l:i], l:pattern)
80
81         if empty(l:match) || empty(l:match[2])
82             let l:i += 1
83             break
84         endif
85
86         call add(l:text, s:Trim(l:match[2]))
87         let l:i += 1
88     endwhile
89
90     return [l:i, join(l:text, '. ')]
91 endfunction
92
93 function! s:Trim(str) abort
94     return substitute(a:str, '\v^\s+|\s+$', '', 'g')
95 endfunction
96
97 " Skip sandbox error which is caused by directives
98 " because what we want is syntactic or semantic check.
99 function! s:Ignore(item) abort
100     return a:item.type is# 'E'
101     \   && a:item.text =~# '\vNo permission to (call|directive|assert) sandboxed'
102 endfunction
103
104 call ale#linter#Define('prolog', {
105 \   'name': 'swipl',
106 \   'output_stream': 'stderr',
107 \   'executable': {b -> ale#Var(b, 'prolog_swipl_executable')},
108 \   'command': function('ale_linters#prolog#swipl#GetCommand'),
109 \   'callback': 'ale_linters#prolog#swipl#Handle',
110 \})