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