mirror of
https://github.com/dense-analysis/ale.git
synced 2026-01-18 00:55:10 +08:00
* Remove virtual text via types-filter This is more robust and has the additional sideeffect that it will make it easier to implement showing virtual text for all warnings simultaneously. We definitely do not want to do a call to prop_remove() for every virtual text as that will cause noticeable lag when many warnings are present, thus we can use this to remove all virtual text lines with one call in the future. Fixes #4294 refs: https://github.com/vim/vim/pull/10945 * Allow virtual text to appear for all warnings of the buffer This can be enabled with: let g:ale_virtualtext_cursor = 2 It is implemented both for neovim and vim 9.0.0297. Note that sometimes it may appear like some warnings are displayed multiple times. This is not a bug in the virtual text implementation, but a sideeffect of multiple linters returning similar results. For example for Rust, the 'cargo' and 'rls' linters appear to be activated at the same time, but they sometimes return identical errors. This causes the virtual text to show the same warning twice. In the future we can mitigate this problem by removing duplicate errors from our internal location list. However users can also achieve cleaner warnings simply by activating only one linter for each language (or multiple unambiguous linters). For example for Rust, the problem could be solved with: let g:ale_linters = {'rust': ['analyzer']} Fixes #2962 Fixes #3666
166 lines
6.6 KiB
VimL
166 lines
6.6 KiB
VimL
" Author: w0rp <devw0rp@gmail.com>
|
|
" Description: ALE functions for autocmd events.
|
|
|
|
" Get the number of milliseconds since some vague, but consistent, point in
|
|
" the past.
|
|
"
|
|
" This function can be used for timing execution, etc.
|
|
"
|
|
" The time will be returned as a Number.
|
|
function! ale#events#ClockMilliseconds() abort
|
|
return float2nr(reltimefloat(reltime()) * 1000)
|
|
endfunction
|
|
|
|
function! ale#events#QuitEvent(buffer) abort
|
|
" Remember when ALE is quitting for BufWrite, etc.
|
|
call setbufvar(a:buffer, 'ale_quitting', ale#events#ClockMilliseconds())
|
|
endfunction
|
|
|
|
function! ale#events#QuitRecently(buffer) abort
|
|
let l:time = getbufvar(a:buffer, 'ale_quitting', 0)
|
|
|
|
return l:time && ale#events#ClockMilliseconds() - l:time < 1000
|
|
endfunction
|
|
|
|
function! ale#events#SaveEvent(buffer) abort
|
|
let l:should_lint = ale#Var(a:buffer, 'enabled') && g:ale_lint_on_save
|
|
|
|
if l:should_lint
|
|
call setbufvar(a:buffer, 'ale_save_event_fired', 1)
|
|
endif
|
|
|
|
if ale#Var(a:buffer, 'fix_on_save') && !ale#events#QuitRecently(a:buffer)
|
|
let l:will_fix = ale#fix#Fix(a:buffer, 'save_file')
|
|
let l:should_lint = l:should_lint && !l:will_fix
|
|
endif
|
|
|
|
if l:should_lint && !ale#events#QuitRecently(a:buffer)
|
|
call ale#Queue(0, 'lint_file', a:buffer)
|
|
endif
|
|
endfunction
|
|
|
|
function! ale#events#LintOnEnter(buffer) abort
|
|
" Unmark a file as being changed outside of Vim after we try to check it.
|
|
call setbufvar(a:buffer, 'ale_file_changed', 0)
|
|
|
|
if ale#Var(a:buffer, 'enabled') && g:ale_lint_on_enter
|
|
call ale#Queue(0, 'lint_file', a:buffer)
|
|
endif
|
|
endfunction
|
|
|
|
function! ale#events#ReadOrEnterEvent(buffer) abort
|
|
" Apply pattern options if the variable is set.
|
|
if get(g:, 'ale_pattern_options_enabled', 1)
|
|
\&& !empty(get(g:, 'ale_pattern_options'))
|
|
call ale#pattern_options#SetOptions(a:buffer)
|
|
endif
|
|
|
|
" When entering a buffer, we are no longer quitting it.
|
|
call setbufvar(a:buffer, 'ale_quitting', 0)
|
|
let l:filetype = getbufvar(a:buffer, '&filetype')
|
|
call setbufvar(a:buffer, 'ale_original_filetype', l:filetype)
|
|
|
|
" If the file changed outside of Vim, check it on BufEnter,BufRead
|
|
if getbufvar(a:buffer, 'ale_file_changed')
|
|
call ale#events#LintOnEnter(a:buffer)
|
|
endif
|
|
endfunction
|
|
|
|
function! ale#events#FileTypeEvent(buffer, new_filetype) abort
|
|
" The old filetype will be set to an empty string by the BuFEnter event,
|
|
" and not linting when the old filetype hasn't been set yet prevents
|
|
" buffers being checked when you enter them when linting on enter is off.
|
|
let l:old_filetype = getbufvar(a:buffer, 'ale_original_filetype', v:null)
|
|
|
|
if l:old_filetype isnot v:null
|
|
\&& !empty(a:new_filetype)
|
|
\&& a:new_filetype isnot# l:old_filetype
|
|
" Remember what the new filetype is.
|
|
call setbufvar(a:buffer, 'ale_original_filetype', a:new_filetype)
|
|
|
|
if g:ale_lint_on_filetype_changed
|
|
call ale#Queue(300, 'lint_file', a:buffer)
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
function! ale#events#FileChangedEvent(buffer) abort
|
|
call setbufvar(a:buffer, 'ale_file_changed', 1)
|
|
|
|
if bufnr('') == a:buffer
|
|
call ale#events#LintOnEnter(a:buffer)
|
|
endif
|
|
endfunction
|
|
|
|
function! ale#events#Init() abort
|
|
" This value used to be a Boolean as a Number, and is now a String.
|
|
let l:text_changed = '' . g:ale_lint_on_text_changed
|
|
|
|
augroup ALEEvents
|
|
autocmd!
|
|
|
|
" These events always need to be set up.
|
|
autocmd BufEnter,BufRead * call ale#events#ReadOrEnterEvent(str2nr(expand('<abuf>')))
|
|
autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
|
|
|
|
if g:ale_enabled
|
|
if l:text_changed is? 'always' || l:text_changed is# '1'
|
|
autocmd TextChanged,TextChangedI * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
|
elseif l:text_changed is? 'normal'
|
|
autocmd TextChanged * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
|
elseif l:text_changed is? 'insert'
|
|
autocmd TextChangedI * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
|
endif
|
|
|
|
if g:ale_lint_on_enter
|
|
autocmd BufWinEnter * call ale#events#LintOnEnter(str2nr(expand('<abuf>')))
|
|
" Track when the file is changed outside of Vim.
|
|
autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('<abuf>')))
|
|
endif
|
|
|
|
if g:ale_lint_on_filetype_changed
|
|
" Only start linting if the FileType actually changes after
|
|
" opening a buffer. The FileType will fire when buffers are opened.
|
|
autocmd FileType * call ale#events#FileTypeEvent(
|
|
\ str2nr(expand('<abuf>')),
|
|
\ expand('<amatch>')
|
|
\)
|
|
endif
|
|
|
|
if g:ale_lint_on_insert_leave
|
|
autocmd InsertLeave * if ale#Var(str2nr(expand('<abuf>')), 'lint_on_insert_leave') | call ale#Queue(0) | endif
|
|
endif
|
|
|
|
if g:ale_echo_cursor || g:ale_cursor_detail
|
|
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif
|
|
" Look for a warning to echo as soon as we leave Insert mode.
|
|
" The script's position variable used when moving the cursor will
|
|
" not be changed here.
|
|
autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarning() | endif
|
|
endif
|
|
|
|
if g:ale_virtualtext_cursor == 1
|
|
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarningWithDelay() | endif
|
|
" Look for a warning to echo as soon as we leave Insert mode.
|
|
" The script's position variable used when moving the cursor will
|
|
" not be changed here.
|
|
autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarning() | endif
|
|
endif
|
|
|
|
if g:ale_hover_cursor
|
|
autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif
|
|
endif
|
|
|
|
if g:ale_close_preview_on_insert
|
|
autocmd InsertEnter * if exists('*ale#preview#CloseIfTypeMatches') | call ale#preview#CloseIfTypeMatches('ale-preview') | endif
|
|
endif
|
|
endif
|
|
augroup END
|
|
|
|
augroup AleURISchemes
|
|
autocmd!
|
|
|
|
autocmd BufNewFile,BufReadPre jdt://** call ale#uri#jdt#ReadJDTLink(expand('<amatch>'))
|
|
augroup END
|
|
endfunction
|