2

I want to call msbuild from the function below and redirect the output to a new buffer.

My problem is that I need to use a variable, for the filename, and therefore cant use '!' (can I?), and when I use exe or system() read complains that I'm not giving it a proper file.

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

2 Answers 2

2

The :read command takes a file not a vim expression. However it can read in from standard output via :read !{cmd}. Example :%r!ls. Using the :execute command you can build your new command with your variable.

exe '%r!' . msbuild

Or you can use :put along with the expression register if you want to use an expression like system(). (Probably want to follow this with :0d_ to delete the first empty line)

put=system(msbuild)

Now it looks like you are trying to build your project and get a list of errors. I would recommend you look into :make, the 'makeprg' option, and the quickfix list as this is a more vim way of building a project.

For more help see:

:h :r!
:h :exe
:h :pu
:h @=
:h :make
:h 'makeprg'
:h quickfix
Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant, I tip my hat to you, good sir! Followup question: what does the '%' in "exe '%r!'" do?
0

This is a function you can use to execute arbitrary shell commands and present their output in a new window ( you can put this in your _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>')

Use like:

:Shell gcc -ggdb -o test test.c && ./test

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.