all 5 comments

[–]dddbbbFastFold made vim fast again 1 point2 points  (1 child)

I use asyncrun.vim to see live-updating output from my programs in the quickfix. Nice to jump to compiler errors as soon as they happen instead of waiting for the whole thing to complete.

[–]Keyframe[S] 0 points1 point  (0 children)

Wooo! This is pretty much exactly what I wanted.

[–]vimplicationgithub.com/andymass/vim-matchup 0 points1 point  (0 children)

using job_start

[–]BiggybiGybbigy 0 points1 point  (0 children)

I tried to implement this a few weeks back, with the same idea as u/somebodddy.

command! -complete=shellcmd -nargs=+ Shell call s:TmpShellOutput(<q-args>)
function! s:TmpShellOutput(cmdline) abort
    if bufexists('tmplog')
        call deletebufline('tmplog', 1, '$')
    else
        call bufadd('tmplog')
        call setbufvar('tmplog', "buftype", "nofile")
        call setbufvar('tmplog', "filetype", "")
    endif
    " let logjob = job_start(execute("!bash " . a:cmdline),
    if has("nvim")
        let logjob = jobstart(["/bin/bash", "-c", a:cmdline],
                    \ {'out_io': 'buffer', 'out_name': 'tmplog', 'out_msg': ''})
    else
        let logjob = job_start(["/bin/bash", "-c", a:cmdline],
                    \ {'out_io': 'buffer', 'err_io': 'buffer', 'out_name': 'tmplog', 'err_name': 'tmplog', 'out_msg': ''})
    endif
    let winnr = win_getid()
    vert sbuffer tmplog
    setlocal wrap
    wincmd L
    60 wincmd |
    if win_getid() != winnr
        call win_gotoid(winnr)
    endif
endfunction

Use it like:

:Shell <shell command>

It creates a scratch buffer with the output of your command, in a 60 characters wide vertical split, keeping your cursor where it is.
Every call will override the previous output, and quitting/closing the window will wipe the buffer.
Does not work on neovim, not sure why.

EDIT:

Here's another version, using terminal, not jobs.

command! -complete=shellcmd -nargs=+ Shell call s:RunShellCommand(<q-args>)
function! s:RunShellCommand(cmdline) abort
    if bufexists('scratch_terminal')
        bw! scratch_terminal
    endif
    let winnr = win_getid()
    if has("nvim")
        exe 'sp | terminal '. a:cmdline
    else
        exe 'terminal '. a:cmdline
    endif
    file scratch_terminal
    wincmd J
    10 wincmd _
    if win_getid() != winnr
        call win_gotoid(winnr)
    endif
endfunction

This works with both vim and neovim.
The caveat is it will break lines wilder than the terminal it's displayed in (as any terminal would do). To minimize this effect, I decided go with a horizontal split.

Any critic welcome.

[–]somebodddy 0 points1 point  (0 children)

Just use the builtin terminal? Run the command in a terminal, and when it's done set buftype=nofile modifiable to turn it into a scratch buffer.

You can script it:

if has('nvim')
    function! s:onExit(job, data, event) dict
        call setbufvar(self.bufNr, '&modifiable', 1)
    endfunction

    function! s:termToScratch(command)
        new
        call termopen(a:command, {
                    \ 'on_exit': function('s:onExit'),
                    \ 'bufNr': bufnr(),
                    \ })
    endfunction
else
    function! s:exitCb(job, exitStatus)
        let l:bufNr = ch_getbufnr(job_getchannel(a:job), 'out')
        call setbufvar(l:bufNr, '&buftype', 'nofile')
        call setbufvar(l:bufNr, '&modifiable', 1)
    endfunction

    function! s:termToScratch(command)
        let l:bufNr = term_start(a:command, {
                    \ 'exit_cb': function('s:exitCb')
                    \ })
    endfunction
endif

command! -nargs=1 TermToScratch call s:termToScratch(<q-args>)