我想从下面的函数调用msbuild并将输出重定向到新的缓冲区。
我的问题是我需要为文件名使用变量,因此无法使用'!' (我可以吗?),当我使用exe或system()时,读取抱怨我没有给它一个正确的文件。
func! myFunction()
let findstr = "findstr /s /m " . '"' . expand("%:t") . '"' . " *.vcxproj"
for project in split(system(findstr), nr2char(10))
echo "Building '" . project . "'"
let msbuild = "c:\\windows\\Microsoft.NET\\Framework\\v4.0.30319\\msbuild.exe" . " " . project . " " . "/t:rebuild /p:configuration=debug"
:tabnew | r system(msbuild) "<--THIS LINE HERE
endfor
endfunc
答案 0 :(得分:1)
:read
命令采用的文件不是vim表达式。但是它可以通过:read !{cmd}
从标准输出读入。示例:%r!ls
。使用:execute
命令,您可以使用变量构建新命令。
exe '%r!' . msbuild
或者,如果要使用:put
之类的表达式,可以将system()
与表达式寄存器一起使用。 (可能想跟:0d_
一起删除第一个空行)
put=system(msbuild)
现在看起来您正在尝试构建项目并获取错误列表。我建议您查看:make
,'makeprg'
选项和quickfix
列表,因为这是构建项目的更加方式。
如需更多帮助,请参阅:
:h :r!
:h :exe
:h :pu
:h @=
:h :make
:h 'makeprg'
:h quickfix
答案 1 :(得分:0)
这是一个可用于执行任意shell命令并在新窗口中显示其输出的函数(您可以将它放在_vimrc中):
let s:lastcmd = ''
function! s:RunShellCommand(cmdline, bang)
" Support for repeating last cmd with bang:
let _ = a:bang != '' ? s:lastcmd : a:cmdline == '' ? '' : join(map(split(a:cmdline), 'expand(v:val)'))
if _ == ''
return
endif
let s:lastcmd = _
let bufnr = bufnr('%')
let winnr = bufwinnr(_)
" You can position the new window whenever you want, I chose below + right:
silent! execute winnr < 0 ? 'belowright new ' . fnameescape(_) : winnr . 'wincmd w'
" I could set buftype=nofile, but then no switching back and forth buffers.
" The results are presented just for viewing, not editing, modify at will:
setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile wrap number
setlocal modifiable
silent! :%d
" Useful for debugging, if you encounter issues with fnameescape():
call setline(1, 'You entered: ' . a:cmdline)
call setline(2, 'Expanded to: ' . _)
call append(line('$'), substitute(getline(2), '.', '=', 'g'))
silent execute '$read !' . _
silent! execute 'autocmd BufUnload <buffer> execute bufwinnr(' . bufnr . ') . ''wincmd w'''
" If resizing is unwanted for commands with too much output, remove this line:
silent! execute 'autocmd BufEnter <buffer> execute ''resize '' . line(''$'')'
" You can use <localleader>r to re-execute the last command:
silent! execute 'nnoremap <silent> <buffer> <localleader>r :call <SID>RunShellCommand(''' . _ . ''', '''')<CR>'
execute 'resize ' . line('$')
setlocal nomodifiable
1
endfunction " RunShellCommand(cmdline)
command! -complete=shellcmd -nargs=* -bang Shell call s:RunShellCommand(<q-args>, '<bang>')
使用类似:
:Shell gcc -ggdb -o test test.c && ./test