#1889 Add support for automatically previewing messages based on the cursor position
This commit is contained in:
parent
f380d8508e
commit
43d7e8fde9
5 changed files with 116 additions and 39 deletions
|
@ -1,4 +1,6 @@
|
|||
scriptencoding utf-8
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Author: João Paulo S. de Souza <joao.paulo.silvasouza@hotmail.com>
|
||||
" Description: Echoes lint message for the current line, if any
|
||||
|
||||
" Controls the milliseconds delay before echoing a message.
|
||||
|
@ -37,12 +39,11 @@ function! ale#cursor#TruncatedEcho(original_message) abort
|
|||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:FindItemAtCursor() abort
|
||||
let l:buf = bufnr('')
|
||||
let l:info = get(g:ale_buffer_info, l:buf, {})
|
||||
function! s:FindItemAtCursor(buffer) abort
|
||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
let l:loclist = get(l:info, 'loclist', [])
|
||||
let l:pos = getcurpos()
|
||||
let l:index = ale#util#BinarySearch(l:loclist, l:buf, l:pos[1], l:pos[2])
|
||||
let l:index = ale#util#BinarySearch(l:loclist, a:buffer, l:pos[1], l:pos[2])
|
||||
let l:loc = l:index >= 0 ? l:loclist[l:index] : {}
|
||||
|
||||
return [l:info, l:loc]
|
||||
|
@ -56,7 +57,9 @@ function! s:StopCursorTimer() abort
|
|||
endfunction
|
||||
|
||||
function! ale#cursor#EchoCursorWarning(...) abort
|
||||
if !g:ale_echo_cursor
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
if !g:ale_echo_cursor && !g:ale_cursor_detail
|
||||
return
|
||||
endif
|
||||
|
||||
|
@ -65,28 +68,39 @@ function! ale#cursor#EchoCursorWarning(...) abort
|
|||
return
|
||||
endif
|
||||
|
||||
if ale#ShouldDoNothing(bufnr(''))
|
||||
if ale#ShouldDoNothing(l:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let [l:info, l:loc] = s:FindItemAtCursor()
|
||||
let [l:info, l:loc] = s:FindItemAtCursor(l:buffer)
|
||||
|
||||
if !empty(l:loc)
|
||||
let l:format = ale#Var(l:buffer, 'echo_msg_format')
|
||||
let l:msg = ale#GetLocItemMessage(l:loc, l:format)
|
||||
call ale#cursor#TruncatedEcho(l:msg)
|
||||
let l:info.echoed = 1
|
||||
elseif get(l:info, 'echoed')
|
||||
" We'll only clear the echoed message when moving off errors once,
|
||||
" so we don't continually clear the echo line.
|
||||
execute 'echo'
|
||||
let l:info.echoed = 0
|
||||
if g:ale_echo_cursor
|
||||
if !empty(l:loc)
|
||||
let l:format = ale#Var(l:buffer, 'echo_msg_format')
|
||||
let l:msg = ale#GetLocItemMessage(l:loc, l:format)
|
||||
call ale#cursor#TruncatedEcho(l:msg)
|
||||
let l:info.echoed = 1
|
||||
elseif get(l:info, 'echoed')
|
||||
" We'll only clear the echoed message when moving off errors once,
|
||||
" so we don't continually clear the echo line.
|
||||
execute 'echo'
|
||||
let l:info.echoed = 0
|
||||
endif
|
||||
endif
|
||||
|
||||
if g:ale_cursor_detail
|
||||
if !empty(l:loc)
|
||||
call s:ShowCursorDetailForItem(l:loc, {'stay_here': 1})
|
||||
else
|
||||
call ale#preview#CloseIfTypeMatches('ale-preview')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#cursor#EchoCursorWarningWithDelay() abort
|
||||
if !g:ale_echo_cursor
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
if !g:ale_echo_cursor && !g:ale_cursor_detail
|
||||
return
|
||||
endif
|
||||
|
||||
|
@ -104,7 +118,7 @@ function! ale#cursor#EchoCursorWarningWithDelay() abort
|
|||
" we should echo something. Otherwise we can end up doing processing
|
||||
" the echo message far too frequently.
|
||||
if l:pos != s:last_pos
|
||||
let l:delay = ale#Var(bufnr(''), 'echo_delay')
|
||||
let l:delay = ale#Var(l:buffer, 'echo_delay')
|
||||
|
||||
let s:last_pos = l:pos
|
||||
let s:cursor_timer = timer_start(
|
||||
|
@ -114,24 +128,37 @@ function! ale#cursor#EchoCursorWarningWithDelay() abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ShowCursorDetailForItem(loc, options) abort
|
||||
let l:stay_here = get(a:options, 'stay_here', 0)
|
||||
|
||||
let s:last_detailed_line = line('.')
|
||||
let l:message = get(a:loc, 'detail', a:loc.text)
|
||||
let l:lines = split(l:message, "\n")
|
||||
call ale#preview#Show(l:lines, {'stay_here': l:stay_here})
|
||||
|
||||
" Clear the echo message if we manually displayed details.
|
||||
if !l:stay_here
|
||||
execute 'echo'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#cursor#ShowCursorDetail() abort
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
" Only echo the warnings in normal mode, otherwise we will get problems.
|
||||
if mode() isnot# 'n'
|
||||
return
|
||||
endif
|
||||
|
||||
if ale#ShouldDoNothing(bufnr(''))
|
||||
if ale#ShouldDoNothing(l:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:StopCursorTimer()
|
||||
|
||||
let [l:info, l:loc] = s:FindItemAtCursor()
|
||||
let [l:info, l:loc] = s:FindItemAtCursor(l:buffer)
|
||||
|
||||
if !empty(l:loc)
|
||||
let l:message = get(l:loc, 'detail', l:loc.text)
|
||||
|
||||
call ale#preview#Show(split(l:message, "\n"))
|
||||
execute 'echo'
|
||||
call s:ShowCursorDetailForItem(l:loc, {'stay_here': 0})
|
||||
endif
|
||||
endfunction
|
||||
|
|
|
@ -131,13 +131,17 @@ function! ale#events#Init() abort
|
|||
autocmd InsertLeave * call ale#Queue(0)
|
||||
endif
|
||||
|
||||
if g:ale_echo_cursor
|
||||
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_close_preview_on_insert
|
||||
autocmd InsertEnter * if exists('*ale#preview#CloseIfTypeMatches') | call ale#preview#CloseIfTypeMatches('ale-preview') | endif
|
||||
endif
|
||||
endif
|
||||
augroup END
|
||||
endfunction
|
||||
|
|
|
@ -15,13 +15,13 @@ function! ale#preview#Show(lines, ...) abort
|
|||
setlocal modifiable
|
||||
setlocal noreadonly
|
||||
setlocal nobuflisted
|
||||
let &l:filetype = get(l:options, 'filetype', 'ale-preview')
|
||||
setlocal buftype=nofile
|
||||
setlocal bufhidden=wipe
|
||||
:%d
|
||||
call setline(1, a:lines)
|
||||
setlocal nomodifiable
|
||||
setlocal readonly
|
||||
let &l:filetype = get(l:options, 'filetype', 'ale-preview')
|
||||
|
||||
if get(l:options, 'stay_here')
|
||||
wincmd p
|
||||
|
|
61
doc/ale.txt
61
doc/ale.txt
|
@ -527,12 +527,13 @@ circumstances.
|
|||
ALE will report problems with your code in the following ways, listed with
|
||||
their relevant options.
|
||||
|
||||
* By updating loclist. (On by default) - |g:ale_set_loclist|
|
||||
* By updating quickfix. (Off by default) - |g:ale_set_quickfix|
|
||||
* By setting error highlights. - |g:ale_set_highlights|
|
||||
* By creating signs in the sign column. - |g:ale_set_signs|
|
||||
* By echoing messages based on your cursor. - |g:ale_echo_cursor|
|
||||
* By showing balloons for your mouse cursor - |g:ale_set_balloons|
|
||||
* By updating loclist. (On by default) - |g:ale_set_loclist|
|
||||
* By updating quickfix. (Off by default) - |g:ale_set_quickfix|
|
||||
* By setting error highlights. - |g:ale_set_highlights|
|
||||
* By creating signs in the sign column. - |g:ale_set_signs|
|
||||
* By echoing messages based on your cursor. - |g:ale_echo_cursor|
|
||||
* By displaying the preview based on your cursor. - |g:ale_cursor_detail|
|
||||
* By showing balloons for your mouse cursor - |g:ale_set_balloons|
|
||||
|
||||
Please consult the documentation for each option, which can reveal some other
|
||||
ways of tweaking the behaviour of each way of displaying problems. You can
|
||||
|
@ -805,6 +806,20 @@ g:ale_change_sign_column_color *g:ale_change_sign_column_color*
|
|||
windows.
|
||||
|
||||
|
||||
g:ale_close_preview_on_insert *g:ale_close_preview_on_insert*
|
||||
|
||||
Type: |Number|
|
||||
Default: `0`
|
||||
|
||||
When this option is set to `1`, ALE's |preview-window| will be automatically
|
||||
closed upon entering Insert Mode. This option can be used in combination
|
||||
with |g:ale_cursor_detail| for automatically displaying the preview window
|
||||
on problem lines, and automatically closing it again when editing text.
|
||||
|
||||
This setting must be set to `1` before ALE is loaded for this behavior
|
||||
to be enabled. See |ale-lint-settings-on-startup|.
|
||||
|
||||
|
||||
g:ale_command_wrapper *g:ale_command_wrapper*
|
||||
*b:ale_command_wrapper*
|
||||
Type: |String|
|
||||
|
@ -893,6 +908,27 @@ g:ale_completion_max_suggestions *g:ale_completion_max_suggestions*
|
|||
Adjust this option as needed, depending on the complexity of your codebase
|
||||
and your available processing power.
|
||||
|
||||
g:ale_cursor_detail *g:ale_cursor_detail*
|
||||
|
||||
Type: |Number|
|
||||
Default: `0`
|
||||
|
||||
When this option is set to `1`, ALE's |preview-window| will be automatically
|
||||
opened when the cursor moves onto lines with problems. ALE will search for
|
||||
problems using the same logic that |g:ale_echo_cursor| uses. The preview
|
||||
window will be closed automatically when you move away from the line.
|
||||
|
||||
Messages are only displayed after a short delay. See |g:ale_echo_delay|.
|
||||
|
||||
The preview window is opened without stealing focus, which means your cursor
|
||||
will stay in the same buffer as it currently is.
|
||||
|
||||
The preview window can be closed automatically upon entering Insert mode
|
||||
by setting |g:ale_close_preview_on_insert| to `1`.
|
||||
|
||||
Either this setting or |g:ale_echo_cursor| must be set to `1` before ALE is
|
||||
loaded for messages to be displayed. See |ale-lint-settings-on-startup|.
|
||||
|
||||
|
||||
g:ale_echo_cursor *g:ale_echo_cursor*
|
||||
|
||||
|
@ -903,11 +939,14 @@ g:ale_echo_cursor *g:ale_echo_cursor*
|
|||
cursor is near a warning or error. ALE will attempt to find the warning or
|
||||
error at a column nearest to the cursor when the cursor is resting on a line
|
||||
which contains a warning or error. This option can be set to `0` to disable
|
||||
this behaviour.
|
||||
The format of the message can be customizable in |g:ale_echo_msg_format|.
|
||||
this behavior.
|
||||
|
||||
You should set this setting once before ALE is loaded, and restart Vim if
|
||||
you want to change your preferences. See |ale-lint-settings-on-startup|.
|
||||
Messages are only displayed after a short delay. See |g:ale_echo_delay|.
|
||||
|
||||
The format of the message can be customized with |g:ale_echo_msg_format|.
|
||||
|
||||
Either this setting or |g:ale_cursor_detail| must be set to `1` before ALE
|
||||
is loaded for messages to be displayed. See |ale-lint-settings-on-startup|.
|
||||
|
||||
|
||||
g:ale_echo_delay *g:ale_echo_delay*
|
||||
|
@ -916,7 +955,7 @@ g:ale_echo_delay *g:ale_echo_delay*
|
|||
Default: `10`
|
||||
|
||||
Given any integer, this option controls the number of milliseconds before
|
||||
ALE will echo a message for a problem near the cursor.
|
||||
ALE will echo or preview a message for a problem near the cursor.
|
||||
|
||||
The value can be increased to decrease the amount of processing ALE will do
|
||||
for files displaying a large number of problems.
|
||||
|
|
|
@ -109,6 +109,13 @@ let g:ale_set_highlights = get(g:, 'ale_set_highlights', has('syntax'))
|
|||
" This flag can be set to 0 to disable echoing when the cursor moves.
|
||||
let g:ale_echo_cursor = get(g:, 'ale_echo_cursor', 1)
|
||||
|
||||
" This flag can be set to 1 to automatically show errors in the preview window.
|
||||
let g:ale_cursor_detail = get(g:, 'ale_cursor_detail', 0)
|
||||
|
||||
" This flag can be set to 1 to automatically close the preview window upon
|
||||
" entering Insert Mode.
|
||||
let g:ale_close_preview_on_insert = get(g:, 'ale_close_preview_on_insert', 0)
|
||||
|
||||
" This flag can be set to 0 to disable balloon support.
|
||||
let g:ale_set_balloons = get(g:, 'ale_set_balloons', has('balloon_eval') && has('gui_running'))
|
||||
|
||||
|
|
Reference in a new issue