diff --git a/autoload/ale.vim b/autoload/ale.vim index 766ed6fa..9defbd82 100644 --- a/autoload/ale.vim +++ b/autoload/ale.vim @@ -5,15 +5,31 @@ let s:lint_timer = -1 let s:queued_buffer_number = -1 let s:should_lint_file_for_buffer = {} -let s:queue_error_delay_ms = 1000 * 60 * 2 +let s:error_delay_ms = 1000 * 60 * 2 -if !exists('s:dont_queue_until') - let s:dont_queue_until = -1 -endif +let s:timestamp_map = {} -if !exists('s:dont_lint_until') - let s:dont_lint_until = -1 -endif +" Given a key for a script variable for tracking the time to wait until +" a given function should be called, a funcref for a function to call, and +" a List of arguments, call the function and return whatever value it returns. +" +" If the function throws an exception, then the function will not be called +" for a while, and 0 will be returned instead. +function! ale#CallWithCooldown(timestamp_key, func, arglist) abort + let l:now = ale#util#ClockMilliseconds() + + if l:now < get(s:timestamp_map, a:timestamp_key, -1) + return 0 + endif + + let s:timestamp_map[a:timestamp_key] = l:now + s:error_delay_ms + + let l:return_value = call(a:func, a:arglist) + + let s:timestamp_map[a:timestamp_key] = -1 + + return l:return_value +endfunction " Return 1 if a file is too large for ALE to handle. function! ale#FileTooLarge() abort @@ -40,21 +56,15 @@ function! ale#Queue(delay, ...) abort throw 'too many arguments!' endif - let l:now = ale#util#ClockMilliseconds() - - if l:now < s:dont_queue_until - return - endif - - let s:dont_queue_until = l:now + s:queue_error_delay_ms - " Default linting_flag to '' let l:linting_flag = get(a:000, 0, '') let l:buffer = get(a:000, 1, bufnr('')) - call s:ALEQueueImpl(a:delay, l:linting_flag, l:buffer) - - let s:dont_queue_until = -1 + return ale#CallWithCooldown( + \ 'dont_queue_until', + \ function('s:ALEQueueImpl'), + \ [a:delay, l:linting_flag, l:buffer], + \) endfunction function! s:ALEQueueImpl(delay, linting_flag, buffer) abort @@ -114,17 +124,11 @@ function! ale#Lint(...) abort let l:buffer = bufnr('') endif - let l:now = ale#util#ClockMilliseconds() - - if l:now < s:dont_lint_until - return - endif - - let s:dont_lint_until = l:now + s:queue_error_delay_ms - - call s:ALELintImpl(l:buffer) - - let s:dont_lint_until = -1 + return ale#CallWithCooldown( + \ 'dont_lint_until', + \ function('s:ALELintImpl'), + \ [l:buffer], + \) endfunction function! s:ALELintImpl(buffer) abort @@ -152,8 +156,7 @@ function! ale#ResetLintFileMarkers() abort endfunction function! ale#ResetErrorDelays() abort - let s:dont_queue_until = -1 - let s:dont_lint_until = -1 + let s:timestamp_map = {} endfunction let g:ale_has_override = get(g:, 'ale_has_override', {}) diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim index 693d1642..72351c5f 100644 --- a/autoload/ale/cursor.vim +++ b/autoload/ale/cursor.vim @@ -1,6 +1,18 @@ " Author: w0rp " Description: Echoes lint message for the current line, if any +let s:cursor_timer = -1 +let s:last_pos = [0, 0, 0] +let s:error_delay_ms = 1000 * 60 * 2 + +if !exists('s:dont_queue_until') + let s:dont_queue_until = -1 +endif + +if !exists('s:dont_echo_until') + let s:dont_echo_until = -1 +endif + " Return a formatted message according to g:ale_echo_msg_format variable function! s:GetMessage(linter, type, text) abort let l:msg = g:ale_echo_msg_format @@ -67,6 +79,10 @@ function! s:StopCursorTimer() abort endfunction function! ale#cursor#EchoCursorWarning(...) abort + return ale#CallWithCooldown('dont_echo_until', function('s:EchoImpl'), []) +endfunction + +function! s:EchoImpl() abort if ale#ShouldDoNothing(bufnr('')) return endif @@ -90,10 +106,15 @@ function! ale#cursor#EchoCursorWarning(...) abort endif endfunction -let s:cursor_timer = -1 -let s:last_pos = [0, 0, 0] - function! ale#cursor#EchoCursorWarningWithDelay() abort + return ale#CallWithCooldown( + \ 'dont_echo_with_delay_until', + \ function('s:EchoWithDelayImpl'), + \ [], + \) +endfunction + +function! s:EchoWithDelayImpl() abort if ale#ShouldDoNothing(bufnr('')) return endif diff --git a/test/test_lint_error_delay.vader b/test/test_lint_error_delay.vader index 32d82715..4c7f0947 100644 --- a/test/test_lint_error_delay.vader +++ b/test/test_lint_error_delay.vader @@ -16,3 +16,11 @@ Execute(ALE should stop queuing for a while after exceptions are thrown): Execute(ALE should stop linting for a while after exceptions are thrown): AssertThrows call ale#Lint() call ale#Lint() + +Execute(ALE should stop queuing echo messages for a while after exceptions are thrown): + AssertThrows call ale#cursor#EchoCursorWarningWithDelay() + call ale#cursor#EchoCursorWarningWithDelay() + +Execute(ALE should stop echoing messages for a while after exceptions are thrown): + AssertThrows call ale#cursor#EchoCursorWarning() + call ale#cursor#EchoCursorWarning()