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.
1 " Author: w0rp <devw0rp@gmail.com>
2 " Description: ALE functions for autocmd events.
4 " Get the number of milliseconds since some vague, but consistent, point in
7 " This function can be used for timing execution, etc.
9 " The time will be returned as a Number.
10 function! ale#events#ClockMilliseconds() abort
11 return float2nr(reltimefloat(reltime()) * 1000)
14 function! ale#events#QuitEvent(buffer) abort
15 " Remember when ALE is quitting for BufWrite, etc.
16 call setbufvar(a:buffer, 'ale_quitting', ale#events#ClockMilliseconds())
19 function! ale#events#QuitRecently(buffer) abort
20 let l:time = getbufvar(a:buffer, 'ale_quitting', 0)
22 return l:time && ale#events#ClockMilliseconds() - l:time < 1000
25 function! ale#events#SaveEvent(buffer) abort
26 let l:should_lint = ale#Var(a:buffer, 'enabled') && g:ale_lint_on_save
29 call setbufvar(a:buffer, 'ale_save_event_fired', 1)
32 if ale#Var(a:buffer, 'fix_on_save') && !ale#events#QuitRecently(a:buffer)
33 let l:will_fix = ale#fix#Fix(a:buffer, 'save_file')
34 let l:should_lint = l:should_lint && !l:will_fix
37 if l:should_lint && !ale#events#QuitRecently(a:buffer)
38 call ale#Queue(0, 'lint_file', a:buffer)
42 function! ale#events#LintOnEnter(buffer) abort
43 " Unmark a file as being changed outside of Vim after we try to check it.
44 call setbufvar(a:buffer, 'ale_file_changed', 0)
46 if ale#Var(a:buffer, 'enabled') && g:ale_lint_on_enter
47 call ale#Queue(0, 'lint_file', a:buffer)
51 function! ale#events#ReadOrEnterEvent(buffer) abort
52 " Apply pattern options if the variable is set.
53 if get(g:, 'ale_pattern_options_enabled', 1)
54 \&& !empty(get(g:, 'ale_pattern_options'))
55 call ale#pattern_options#SetOptions(a:buffer)
58 " When entering a buffer, we are no longer quitting it.
59 call setbufvar(a:buffer, 'ale_quitting', 0)
60 let l:filetype = getbufvar(a:buffer, '&filetype')
61 call setbufvar(a:buffer, 'ale_original_filetype', l:filetype)
63 " If the file changed outside of Vim, check it on BufEnter,BufRead
64 if getbufvar(a:buffer, 'ale_file_changed')
65 call ale#events#LintOnEnter(a:buffer)
69 function! ale#events#FileTypeEvent(buffer, new_filetype) abort
70 " The old filetype will be set to an empty string by the BuFEnter event,
71 " and not linting when the old filetype hasn't been set yet prevents
72 " buffers being checked when you enter them when linting on enter is off.
73 let l:old_filetype = getbufvar(a:buffer, 'ale_original_filetype', v:null)
75 if l:old_filetype isnot v:null
76 \&& !empty(a:new_filetype)
77 \&& a:new_filetype isnot# l:old_filetype
78 " Remember what the new filetype is.
79 call setbufvar(a:buffer, 'ale_original_filetype', a:new_filetype)
81 if g:ale_lint_on_filetype_changed
82 call ale#Queue(300, 'lint_file', a:buffer)
87 function! ale#events#FileChangedEvent(buffer) abort
88 call setbufvar(a:buffer, 'ale_file_changed', 1)
90 if bufnr('') == a:buffer
91 call ale#events#LintOnEnter(a:buffer)
95 " A timer for emulating InsertLeave.
97 " We only need a single timer, and we'll lint the last buffer we entered
99 if !exists('s:insert_leave_timer')
100 let s:insert_leave_timer = -1
103 " True if the ModeChanged event exists.
104 " In this case, ModeChanged will be used instead of InsertLeave emulation.
105 let s:mode_changed_exists = exists('##ModeChanged')
107 function! ale#events#EmulateInsertLeave(buffer) abort
109 call timer_stop(s:insert_leave_timer)
110 call ale#Queue(0, '', a:buffer)
114 function! ale#events#InsertEnterEvent(buffer) abort
115 if g:ale_close_preview_on_insert && exists('*ale#preview#CloseIfTypeMatches')
116 call ale#preview#CloseIfTypeMatches('ale-preview')
119 " Start a repeating timer if the use might not trigger InsertLeave, so we
120 " can emulate its behavior.
121 " If the ModeChanged autocmd exists, it will be used instead of this
122 " timer; as ModeChanged will be sent regardless of how the insert mode is
123 " exited, including <Esc>, <C-c> and <C-]>.
124 if ale#Var(a:buffer, 'lint_on_insert_leave')
125 \&& maparg("\<C-c>", 'i') isnot# '<Esc>'
126 \&& !s:mode_changed_exists
127 call timer_stop(s:insert_leave_timer)
128 let s:insert_leave_timer = timer_start(
130 \ {-> ale#events#EmulateInsertLeave(a:buffer) },
136 function! ale#events#InsertLeaveEvent(buffer) abort
137 " Kill the InsertLeave emulation if the event fired.
138 " If the ModeChanged event is available, it will be used instead of
140 if !s:mode_changed_exists
141 call timer_stop(s:insert_leave_timer)
144 if ale#Var(a:buffer, 'lint_on_insert_leave')
145 call ale#Queue(0, '', a:buffer)
148 " Look for a warning to echo as soon as we leave Insert mode.
149 " The script's position variable used when moving the cursor will
150 " not be changed here.
152 " We don't echo this message in emulated insert leave mode, as the user
153 " may want less work to happen on pressing <C-c> versus <Esc>
154 if exists('*ale#engine#Cleanup')
155 call ale#cursor#EchoCursorWarning()
157 if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1'
158 " Show a virtualtext message if enabled.
159 call ale#virtualtext#ShowCursorWarning()
164 function! ale#events#Init() abort
165 " This value used to be a Boolean as a Number, and is now a String.
166 let l:text_changed = '' . g:ale_lint_on_text_changed
171 " These events always need to be set up.
172 autocmd BufEnter,BufRead * call ale#events#ReadOrEnterEvent(str2nr(expand('<abuf>')))
173 autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
176 if l:text_changed is? 'always'
177 \|| l:text_changed is# '1'
178 \|| g:ale_lint_on_text_changed is v:true
179 autocmd TextChanged,TextChangedI * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
180 elseif l:text_changed is? 'normal'
181 autocmd TextChanged * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
182 elseif l:text_changed is? 'insert'
183 autocmd TextChangedI * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
186 if g:ale_lint_on_enter
187 autocmd BufWinEnter * call ale#events#LintOnEnter(str2nr(expand('<abuf>')))
188 " Track when the file is changed outside of Vim.
189 autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('<abuf>')))
192 if g:ale_lint_on_filetype_changed
193 " Only start linting if the FileType actually changes after
194 " opening a buffer. The FileType will fire when buffers are opened.
195 autocmd FileType * call ale#events#FileTypeEvent(
196 \ str2nr(expand('<abuf>')),
201 " Add an InsertEnter event if we need to close the preview window
202 " on entering insert mode, or if we want to run ALE on leaving
203 " insert mode and <C-c> is not the same as <Esc>.
205 " We will emulate leaving insert mode for users that might not
206 " trigger InsertLeave.
208 " If the ModeChanged event is available, this timer will not
210 if g:ale_close_preview_on_insert
211 \|| (g:ale_lint_on_insert_leave && maparg("\<C-c>", 'i') isnot# '<Esc>' && !s:mode_changed_exists)
212 autocmd InsertEnter * call ale#events#InsertEnterEvent(str2nr(expand('<abuf>')))
215 let l:add_insert_leave_event = g:ale_lint_on_insert_leave
217 if g:ale_echo_cursor || g:ale_cursor_detail
218 " We need to make the message display on InsertLeave
219 let l:add_insert_leave_event = 1
221 autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif
224 if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1'
225 " We need to make the message display on InsertLeave
226 let l:add_insert_leave_event = 1
228 autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarningWithDelay() | endif
231 if l:add_insert_leave_event
232 if s:mode_changed_exists
233 " If the ModeChanged event is available, handle any
234 " transition from the Insert mode to any other mode.
235 autocmd ModeChanged i*:* call ale#events#InsertLeaveEvent(str2nr(expand('<abuf>')))
237 " If ModeChanged is not available, handle InsertLeave events.
238 autocmd InsertLeave * call ale#events#InsertLeaveEvent(str2nr(expand('<abuf>')))
242 if g:ale_hover_cursor
243 autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif
248 augroup AleURISchemes
251 autocmd BufNewFile,BufReadPre jdt://** call ale#uri#jdt#ReadJDTLink(expand('<amatch>'))