#144 - Implement commands for moving through warnings/errors

This commit is contained in:
w0rp 2016-10-24 22:09:41 +01:00
parent 1bcee7ef33
commit c8821fc049
4 changed files with 156 additions and 6 deletions

View File

@ -30,6 +30,7 @@ In other words, this plugin allows you to lint while you type.
4. [How can I show errors or warnings in my statusline?](#faq-statusline) 4. [How can I show errors or warnings in my statusline?](#faq-statusline)
5. [How can I change the format for echo messages?](#faq-echo-format) 5. [How can I change the format for echo messages?](#faq-echo-format)
6. [How can I execute some code when ALE stops linting?](#faq-autocmd) 6. [How can I execute some code when ALE stops linting?](#faq-autocmd)
7. [How can I navigate between errors quickly?](#faq-navigation)
<a name="supported-languages"></a> <a name="supported-languages"></a>
@ -290,3 +291,19 @@ augroup YourGroup
autocmd User ALELint call YourFunction() autocmd User ALELint call YourFunction()
augroup END augroup END
``` ```
<a name="faq-navigation"></a>
### 4.vii. How can I navigate between errors quickly?
ALE offers some commands with `<Plug>` keybinds for moving between warnings and
errors quickly. You can map the keys Ctrl+j and Ctrl+k to moving between errors
for example:
```vim
nmap <silent> <C-k> <Plug>(ale_previous_wrap)
nmap <silent> <C-j> <Plug>(ale_next_wrap)
```
For more information, consult the online documentation with
`:help ale-navigation-commands`.

View File

@ -0,0 +1,88 @@
" Author: w0rp <devw0rp@gmail.com>
" Description: This file implements functions for jumping around in a file
" based on errors and warnings in the loclist.
function! s:GetSortedLoclist() abort
let l:loclist = []
for l:item in getloclist(winnr())
if l:item.lnum < 1
" Remove items we can't even jump to.
continue
endif
call add(l:loclist, l:item)
endfor
" We must sort the list again, as the loclist could contain items set
" by other plugins.
call sort(l:loclist, 'ale#util#LocItemCompare')
return l:loclist
endfunction
" Search for the nearest line either before or after the current position
" in the loclist. The argument 'wrap' can be passed to enable wrapping
" around the end of the list.
"
" If there are no items or we have hit the end with wrapping off, an empty
" List will be returned, otherwise a pair of [line_number, column_number] will
" be returned.
function! ale#loclist_jumping#FindNearest(direction, wrap) abort
let l:loclist = s:GetSortedLoclist()
if empty(l:loclist)
" We couldn't find anything, so stop here.
return []
endif
let l:search_item = {'lnum': getcurpos()[1], 'col': getcurpos()[2]}
" When searching backwards, so we can find the next smallest match.
if a:direction ==# 'before'
call reverse(l:loclist)
endif
" Look for items before or after the current position.
for l:item in l:loclist
" Compare the cursor with a item where the column number is bounded,
" such that it's possible for the cursor to actually be on the given
" column number, without modifying the cursor number we return. This
" will allow us to move through matches, but still let us move the
" cursor to a line without changing the column, in some cases.
let l:cmp_value = ale#util#LocItemCompare(
\ {
\ 'lnum': l:item.lnum,
\ 'col': min([max([l:item.col, 1]), len(getline(l:item.lnum))]),
\ },
\ l:search_item
\)
if a:direction ==# 'before' && l:cmp_value < 0
return [l:item.lnum, l:item.col]
endif
if a:direction ==# 'after' && l:cmp_value > 0
return [l:item.lnum, l:item.col]
endif
endfor
" If we found nothing, and the wrap option is set to 1, then we should
" wrap around the list of warnings/errors
if a:wrap
let l:item = get(l:loclist, 0)
return [l:item.lnum, l:item.col]
endif
return []
endfunction
" As before, find the nearest match, but position the cursor at it.
function! ale#loclist_jumping#Jump(direction, wrap) abort
let l:nearest = ale#loclist_jumping#FindNearest(a:direction, a:wrap)
if !empty(l:nearest)
call cursor(l:nearest)
endif
endfunction

View File

@ -23,9 +23,10 @@ CONTENTS *ale-contents*
4.11. luacheck..............................|ale-linter-options-luacheck| 4.11. luacheck..............................|ale-linter-options-luacheck|
4.12. c-cppcheck............................|ale-linter-options-c-cppcheck| 4.12. c-cppcheck............................|ale-linter-options-c-cppcheck|
4.13. cpp-cppcheck..........................|ale-linter-options-cpp-cppcheck| 4.13. cpp-cppcheck..........................|ale-linter-options-cpp-cppcheck|
5. API........................................|ale-api| 5. Commands/Keybinds..........................|ale-commands|
6. Special Thanks.............................|ale-special-thanks| 6. API........................................|ale-api|
7. Contact....................................|ale-contact| 7. Special Thanks.............................|ale-special-thanks|
8. Contact....................................|ale-contact|
=============================================================================== ===============================================================================
1. Introduction *ale-introduction* 1. Introduction *ale-introduction*
@ -549,7 +550,39 @@ g:ale_cpp_cppcheck_options *g:ale_cpp_cppcheck_options
=============================================================================== ===============================================================================
5. API *ale-api* 5. Commands/Keybinds *ale-commands*
ALEPrevious *ALEPrevious*
ALEPreviousWrap *ALEPreviousWrap*
ALENext *ALENext*
ALENextWrap *ALENextWrap*
*ale-navigation-commands*
Move between warnings or errors in a buffer.
`ALEPrevious` and `ALENext` will stop at the top and bottom of a file, while
`ALEPreviousWrap` and `ALENextWrap` will wrap around the file to find
the last or first warning or error in the file, respectively.
The following |<Plug>| mappings are defined for the commands: >
<Plug>(ale_previous) - ALEPrevious
<Plug>(ale_previous_wrap) - ALEPreviousWrap
<Plug>(ale_next) - ALENext
<Plug>(ale_next_wrap) - ALENextWrap
<
For example, these commands could be bound to the keys Ctrl + j
and Ctrl + k: >
" Map movement through errors without wrapping.
nmap <silent> <C-k> <Plug>(ale_previous)
nmap <silent> <C-j> <Plug>(ale_next)
" OR map keys to use wrapping.
nmap <silent> <C-k> <Plug>(ale_previous_wrap)
nmap <silent> <C-j> <Plug>(ale_next_wrap)
<
===============================================================================
6. API *ale-api*
ale#Queue(delay) *ale#Queue()* ale#Queue(delay) *ale#Queue()*
Run linters for the current buffer, based on the filetype of the buffer, Run linters for the current buffer, based on the filetype of the buffer,
@ -671,13 +704,13 @@ ALELint *ALELint*
=============================================================================== ===============================================================================
6. Special Thanks *ale-special-thanks* 7. Special Thanks *ale-special-thanks*
Special thanks to Mark Grealish (https://www.bhalash.com/) for providing ALE's Special thanks to Mark Grealish (https://www.bhalash.com/) for providing ALE's
snazzy looking ale glass logo. Cheers, Mark! snazzy looking ale glass logo. Cheers, Mark!
=============================================================================== ===============================================================================
7. Contact *ale-contact* 8. Contact *ale-contact*
If you like this plugin, and wish to get in touch, check out the GitHub If you like this plugin, and wish to get in touch, check out the GitHub
page for issues and more at https://github.com/w0rp/ale page for issues and more at https://github.com/w0rp/ale

View File

@ -131,6 +131,18 @@ let g:ale_statusline_format = get(g:, 'ale_statusline_format',
let g:ale_warn_about_trailing_whitespace = let g:ale_warn_about_trailing_whitespace =
\ get(g:, 'ale_warn_about_trailing_whitespace', 1) \ get(g:, 'ale_warn_about_trailing_whitespace', 1)
" Define commands for moving through warnings and errors.
command! ALEPrevious :call ale#loclist_jumping#Jump('before', 0)
command! ALEPreviousWrap :call ale#loclist_jumping#Jump('before', 1)
command! ALENext :call ale#loclist_jumping#Jump('after', 0)
command! ALENextWrap :call ale#loclist_jumping#Jump('after', 1)
" <Plug> mappings for commands
nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return>
nnoremap <silent> <Plug>(ale_previous_wrap) :ALEPreviousWrap<Return>
nnoremap <silent> <Plug>(ale_next) :ALENext<Return>
nnoremap <silent> <Plug>(ale_next_wrap) :ALENextWrap<Return>
" Housekeeping " Housekeeping
augroup ALECleanupGroup augroup ALECleanupGroup