David784
David784

Reputation: 7464

vim ale shortcut to add eslint-ignore hint

I've been using vim for years, but I've just started integrating eslint (through ALE). I've found that sometimes I want to be able to quickly add an /* eslint-ignore-next-line */. For example:

 ...
❌    if (m = /^-l(\d+)$/.exec(args[i])) t.len = m[1];
 ...
~/some/dir/file.js [+]          
cond-assign: Expected a conditional expression and instead saw an assignment.

It's really handy that ALE gives you the code at the bottom of the window, but being lazy I want to automate adding the comment/hint:

/* eslint-ignore-next-line cond-assign */

Is there a way to access that information at the bottom of the screen in a vim script/function?

Upvotes: 2

Views: 1022

Answers (2)

jonS90
jonS90

Reputation: 1379

Though not documented, ALE stores lint information in the b:ale_highlight_items variable.

David784's solution didn't work for me because I had customized the location-list text using ALE's g:ale_echo_msg_format configuration option. So I modified it to obtain the information directly from b:ale_highlight_items instead of parsing it out of the location-list.

Here it is:

command! ALEIgnoreEslint call AleIgnoreEslint()
function! AleIgnoreEslint()
  " https://stackoverflow.com/questions/54961318/vim-ale-shortcut-to-add-eslint-ignore-hint
  let l:codes = []
  if (!exists('b:ale_highlight_items'))
    echo 'cannot ignore eslint rule without b:ale_highlight_items'
    return
  endif
  for l:item in b:ale_highlight_items
    if (l:item['lnum']==line('.') && l:item['linter_name']=='eslint')
      let l:code = l:item['code']
      call add(l:codes, l:code)
    endif
  endfor
  if len(l:codes)
    exec 'normal O/* eslint-disable-next-line ' . join(l:codes, ', ') . ' */'
  endif
endfunction

Upvotes: 3

David784
David784

Reputation: 7464

Fortunately, ALE uses the built-in location-list to store its lint messages, and this is accessible via getloclist({nr}), where {nr} is the register. Current register is always 0.

So here's a method of getting all the lint messages for the current line, and adding them all to an eslint hint comment:

function AleIgnore()
  let codes = []
  for d in getloclist(0)
    if (d.lnum==line('.'))
      let code = split(d.text,':')[0]
      call add(codes, code)
    endif
  endfor
  if len(codes)
    exe 'normal O/* eslint-disable-next-line ' . join(codes, ', ') . ' */'
  endif
endfunction

This version will only add the eslint-disable-next-line hint immediately before the current line. It would also be pretty easy to expand this out to add a global eslint-disable hint at the top of the file...the hard part was figuring out about getloclist().

*EDIT: I'm adding an updated version that accepts a new-line parameter. If this is 0, it will add a global hint at the top of the file, and if it's 1 it will add the -next-line hint above the current line. But I'm keeping the previous version as well since it's a simpler example, without all the ternaries and stuff.

function AleIgnore(nl)
  let codes = []
  for d in getloclist(0)
    if (d.lnum==line('.'))
      let code = split(d.text,':')[0]
      call add(codes, code)
    endif
  endfor
  if len(codes)
    exe 'normal mq' . (a:nl?'':'1G') . 'O'
          \ . '/* eslint-disable' . (a:nl?'-next-line ':' ')
          \ . join(codes, ', ') . ' */' . "\<esc>`q"
  endif
endfunction

Upvotes: 2

Related Questions