簡體   English   中英

vim:執行帶有變量的shell命令並將輸出重定向到新緩沖區

[英]vim: execute shell command with variable and redirect output to new buffer

我想從下面的函數調用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

:read命令使用的文件不是vim表達式。 但是,它可以通過:read !{cmd}從標准輸出中:read !{cmd} 示例:%r!ls 使用:execute命令,您可以使用變量來構建新命令。

exe '%r!' . msbuild

或者,如果您想使用像system()這樣的表達式,可以將:put與表達式寄存器一起使用。 (可能想在此:0d_加上:0d_來刪除第一個空行)

put=system(msbuild)

現在看來,您正在嘗試構建項目並獲取錯誤列表。 我建議你看看:make時, 'makeprg'選項,並且quickfix列表,因為這是構建項目的更多VIM方式。

有關更多幫助,請參見:

:h :r!
:h :exe
:h :pu
:h @=
:h :make
:h 'makeprg'
:h quickfix

這是一個函數,您可以用來執行任意的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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM