我已经看到了几个关于将Vim中的行号传递给外部命令的问题,但我想做相反的事情。我想通过jshint运行一个文件,然后根据jshint输出对每个行号应用更正。
例如,我正在尝试在缺少一行的每一行上附加分号。现在我正在炮轰jshint并解析输出,但我不知道如何使用它来在多行上运行宏。
我目前的想法是:
G<LINE_NUMBER>A;
这是我到目前为止解析jshint输出的内容:
:r ! jshint % | grep 'Missing semicolon' | awk '{ print $3 }' | sed 's/,//'
我是否可以方便地在Vim中执行xargs
之类的操作,或者将外部命令的输出解析为可以循环的数组?
答案 0 :(得分:2)
errorformat
:
let lines = split(system('jshint --verbose ' . shellescape(expand('%', 1))), "\n", 1)
let &errorformat = '%f: line %l\, col %v\, %m'
cgetexpr lines
for line in uniq(sort(map(filter(getqflist(), 'v:val["valid"] && v:val["text"] =~# "\\m^Missing semicolon"'), 'v:val["lnum"]')))
execute line . 's/$/;/'
endfor
不是我所谓的“方便”,但我知道什么。
然后你可能会发现丢失的分号可能并不总是在行尾。所以你要修改这样的代码:
function! Cmp(a, b)
return a:a[0] == a:b[0] ? a:b[1] - a:a[1] : a:b[0] - a:a[0]
endfunction
let lines = split(system('jshint --verbose ' . shellescape(expand('%', 1))), "\n", 1)
let &errorformat = '%f: line %l\, col %v\, %m'
cgetexpr lines
for p in uniq(sort(map(filter(getqflist(), 'v:val["valid"] && v:val["text"] =~# "\\m^Missing semicolon"'),
\ '[str2nr(v:val["lnum"]), str2nr(v:val["col"])]'), 'Cmp'))
let line = getline(p[0])
call setline(p[0], line[ : p[1]-2] . ';' . line[p[1]-1 :])
endfor
然后你可能会发现这不处理标签的情况。这是一个问题,因为默认情况下JSHint的选项卡的概念是tab stop = 4,而Vim是tab stop = 8.然后你...可以修复它作为练习,或者你可能会理解并使用真正的JavaScript解析器修复这个而不是Vim。 :)