quickrun.vim で特定の範囲を出力しないようにする

欲しかったのでざっくり書いてみました。

[ソース]

echo "homu"

" ==== ここから ====
QuickRunVimScriptSilentBegin

echo "mado"
echo "saya"

QuickRunVimScriptSilentEnd
" ==== ここまでは出力されない =====

echo "mami"

[出力]

homu
mami


特定の範囲の出力のみを無視します。
で、これの何がいいのかって言うと :redir の出力も出力されなくなります。
つまり vital#of("vital") した場合でも scriptnames が出力されないように出来ます。
個人的にはこれがかなりネックでした。

[ソース]

QuickRunVimScriptSilentBegin

let V = vital#of("vital")
call V.import("Data.List", V)

QuickRunVimScriptSilentEnd

echo V.foldl("v:val + v:memo", 0, range(10))

[出力]

45


vital.vim 以外にも単純に scriptnames を使いたいケースはあるので重宝しそう。

[実装]

" vimscript{{{
let s:runner = {}
let s:runner.name = "vimscript"
let s:runner.kind = "runner"

let g:is_quickrun_vimscript_all_running = 0

function! s:runner.run(commands, input, session)
    let g:is_quickrun_vimscript_all_running = 1
    let code = 0
    for cmd in a:commands
        let [result, code] = s:execute(cmd)
        call a:session.output(result)
        if code != 0
            break
        endif
    endfor
    let g:is_quickrun_vimscript_all_running = 0
    return code
endfunction


" :QuickRun vim で呼び出しているので
if !exists("quickrun_running")
    function! s:execute(cmd)
        let result = ''
        let error = 0
        let temp = tempname()

        let save_vfile = &verbosefile
        let &verbosefile = temp

        let g:SetVerboseFile = reti#execute("let &verbosefile = temp", l:)
        let g:RewindVerboseFile = reti#execute("if &verbosefile ==# temp | let &verbosefile = save_vfile | endif", l:)

        let old_errmsg = v:errmsg
        let v:errmsg = ""

        try
            silent execute a:cmd
        catch
            let error = 1
            silent echo v:throwpoint
            silent echo matchstr(v:exception, '^Vim\%((\w*)\)\?:\s*\zs.*')
        finally
            let error = !empty(v:errmsg)
            let v:errmsg = old_errmsg
            if &verbosefile ==# temp
                let &verbosefile = save_vfile
            endif
        endtry

        if filereadable(temp)
            let result .= join(readfile(temp, 'b'), "\n")
            let result =  substitute(result, "\n行", "行", "g")
            call delete(temp)
        endif

        return [result, error]
    endfunction
endif

call quickrun#module#register(s:runner, 1)
unlet s:runner

command! QuickRunVimScriptSilentBegin
\   if g:is_quickrun_vimscript_all_running
\|      call g:RewindVerboseFile()
\|  endif

command! QuickRunVimScriptSilentEnd
\   if g:is_quickrun_vimscript_all_running
\|       call g:SetVerboseFile()
\|  endif