Syntastic: :lnext with only one issue in the location list gives "E553 No more items"

Created on 17 Mar 2011  路  13Comments  路  Source: vim-syntastic/syntastic

Version 1.2.0

The issue should be clear from the title

Most helpful comment

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

All 13 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

albasili picture albasili  路  6Comments

rafee picture rafee  路  5Comments

jasonkuhrt picture jasonkuhrt  路  8Comments

ErikBjare picture ErikBjare  路  3Comments

noprompt picture noprompt  路  5Comments