#1889 Add support for automatically previewing messages based on the cursor position

This commit is contained in:
w0rp 2018-09-14 12:42:26 +01:00
parent f380d8508e
commit 43d7e8fde9
No known key found for this signature in database
GPG key ID: 0FC1ECAA8C81CD83
5 changed files with 116 additions and 39 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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'))