読者です 読者をやめる 読者になる 読者になる

関数対応版:Vim scriptをsourceしてエラーがあればquickfixに表示する

vim

前回:Vim scriptをsourceしてエラーがあればquickfixに表示する - ぼっち勉強会

指摘:

ということで関数にも対応させた。
動作環境は自分のMacVim+簡単なサンプルだけ。
vimrcに以下を追加。
なお、エラーメッセージは日本語と仮定する。英語は考慮してない。

" 指定したVim scriptをsourceしてエラーをquickfixに表示
function! s:vim_lint(file)
  let messages = s:vim_lint_messages(a:file)
  let srclines = readfile(a:file)
  let errors = []
  let start_pos = 0
  let info = {}
  for l in split(messages, "\n")
    if l =~ '^行'
      let info = {'filename': a:file}
      let info.lnum = start_pos + substitute(l, '行\s*\(\d*\):', '\1', '')
    elseif l =~ '^function'
      let start_pos = s:vim_lint_find_pos(srclines, substitute(l, '.*<SNR>\d*_\(.*\)\s.*', '\1', ''))
    elseif l =~ '^E'
      let info.text = l
      let start_pos = 0
      call add(errors, info)
      let info = {}
    endif
  endfor

  call setqflist(errors, 'r')
  cwindow
  silent! doautocmd QuickFixCmdPost make
endfunction

function! s:vim_lint_messages(file)
  let temp = tempname()
  let save_vfile = &verbosefile
  let &verbosefile = temp

  try
    silent! execute ':source ' . a:file
  finally
    if &verbosefile ==# temp
      let &verbosefile = save_vfile
    endif
  endtry

  let messages = ''
  if filereadable(temp)
    let messages .= join(readfile(temp, 'b'), "\n")
    call delete(temp)
  endif
  return messages
endfunction

function! s:vim_lint_find_pos(lines, funcname)
  for i in range(0, len(a:lines)-1)
    if a:lines[i] =~# 'function.*'.a:funcname
      return i + 1
    endif
  endfor
endfunction

command! -nargs=0 VimLint call s:vim_lint(expand('%:p'))
nnoremap <Space>l :<C-u>VimLint<CR>
  • 結果

関数内でもイケてる気がする

  • 辞書内関数

チャレンジ中