Version 1.2.0
The issue should be clear from the title
This does appear to work as expected, doesn't it?
What do you expect for it to happen instead?
Wouldn't you expect it to jump to the single location in the location list?
Aren't you at the first item already? (Vim jumps there by default)
Anyway, this is Vim core functionality and therefore not an issue with syntastic in particular, as far as I can see.
No I can be anywhere in the code and try to use :lnext or :lprev and I only get the No more items error. Using :ll seemed to work though. I just assumed that the location list would have been in vim long enough that it wouldn't have this blatant bugs anymore so that's why I suspected there may had been something weird with syntastic.
I would not say that this is a bug: the only item is selected (in the list), and both lnext and lprev error out with "no next/previous".
I just wanted to propose using :ll, but you've mentioned it yourself already.
After all, still not a bug with syntastic.
I could imagine fixing this through unimpaired, which provides [l and ]l to navigate the location list: it could catch the error and call :ll automatically. What do you think?
I have reported it over there already: https://github.com/tpope/vim-unimpaired/issues/7
Actually now that I know that it's just some idiosyncrasy of vim and have conditioned myself to use :ll when there's only one match I am not that bothered by this any more. It just seemed illogical.
Closing this issue off as it is to do with vims standard behaviour - not syntastic
I'll just post my workaround in case someone came across this issue:
function LocationListNavOrJustOne(cmd)
redir => output
silent! exec a:cmd
redir END
if match(output, "E553: No more items") >= 0
exec ':ll'
else
echom output
endif
endfunction
nmap ,, :call LocationListNavOrJustOne(":lprev")<CR>
nmap .. :call LocationListNavOrJustOne(":lnext")<CR>
Pretty straightforward: this will map ,, (two comma) to :lprev and .. (two period) to :lnext. When these two command return E553: No more items, run :ll to jump to the only result.
I was hoping to make :lprev jump to the last item when it reached the first one but I'm really not an expert in vimscripting.
I'd suggest something like this instead:
function! <SID>LocationPrevious()
try
lprev
catch /^Vim\%((\a\+)\)\=:E553/
llast
endtry
endfunction
function! <SID>LocationNext()
try
lnext
catch /^Vim\%((\a\+)\)\=:E553/
lfirst
endtry
endfunction
nnoremap <silent> <Plug>LocationPrevious :<C-u>exe 'call <SID>LocationPrevious()'<CR>
nnoremap <silent> <Plug>LocationNext :<C-u>exe 'call <SID>LocationNext()'<CR>
nmap <silent> ,, <Plug>LocationPrevious
nmap <silent> .. <Plug>LocationNext
@lcd047
Way better than mine. Thank you!
Based on @lcd047's code above I made the following to not produce a ugly multi-line erorr message if there are no entries in the location list:
" Allow :lprev to work with empty location list, or at first location
function! <SID>LocationPrevious()
try
lprev
catch /:E553:/
lfirst
catch /:E42:/
echo "Location list empty"
catch /.*/
echo v:exception
endtry
endfunction
" Allow :lnext to work with empty location list, or at last location
function! <SID>LocationNext()
try
lnext
catch /:E553:/
lfirst
catch /:E42:/
echo "Location list empty"
catch /.*/
echo v:exception
endtry
endfunction
Actually, this is an even better solution (but consider adding echo "List empty" rather than an null catch.)
For those stumbling on this behavior, maybe the solutions is "don't do that" - see this workflow/workaround.
Most helpful comment
I'd suggest something like this instead: