Last active
August 29, 2015 14:06
-
-
Save osyo-manga/afcce564ce284e85f47b to your computer and use it in GitHub Desktop.
vimproc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let s:base = { | |
\ "__reunions_process_base" : { | |
\ "result" : "", | |
\ } | |
\} | |
function! s:base.start(...) | |
let args = get(a:, 1, "") | |
let args = get(a:, 1, "") | |
let self.__reunions_process_base.result = "" | |
let self.__reunions_process_base.vimproc | |
\ = vimproc#pgroup_open(self.__reunions_process_base.command . ' ' . args) | |
endfunction | |
function! s:base.update() | |
if !self.is_alive() | |
return self.status() | |
endif | |
try | |
let vimproc = self.__reunions_process_base.vimproc | |
let var = self.__reunions_process_base | |
if !vimproc.stdout.eof | |
let var.result .= vimproc.stdout.read() | |
endif | |
if !vimproc.stderr.eof | |
let var.result .= vimproc.stderr.read() | |
endif | |
let var.result = substitute(var.result, "\r\n", "\n", "g") | |
finally | |
if self.is_exit() | |
call self.kill() | |
endif | |
endtry | |
return self.status() | |
endfunction | |
function! s:base.kill() | |
if !self.is_alive() | |
return | |
endif | |
let vimproc = self.__reunions_process_base.vimproc | |
call vimproc.stdout.close() | |
call vimproc.stderr.close() | |
" ↓の行をコメントアウトすると再現しなくなる | |
call vimproc.kill(9) | |
call vimproc.waitpid() | |
if has_key(self, "then") | |
call self.then(self.__reunions_process_base.result, self.as_result()) | |
endif | |
endfunction | |
function! s:base.is_alive() | |
let vimproc = get(self.__reunions_process_base, "vimproc", {}) | |
return !empty(vimproc) && vimproc.is_valid | |
endfunction | |
function! s:base.is_exit() | |
let vimproc = get(self.__reunions_process_base, "vimproc", {}) | |
return !empty(vimproc) && vimproc.stdout.eof && vimproc.stderr.eof | |
endfunction | |
function! s:base.status() | |
let vimproc = get(self.__reunions_process_base, "vimproc", {}) | |
return self.is_exit() && has_key(vimproc, "status") && vimproc.status ? "failure" | |
\ : self.is_exit() && has_key(vimproc, "status") && !vimproc.status ? "success" | |
\ : self.is_exit() ? "kill" | |
\ : self.is_alive() ? "processing" | |
\ : "none" | |
endfunction | |
function! s:base.wait_for(time) | |
let time = a:time | |
let start_time = reltime() | |
while !self.is_exit() | |
if time > 0.0 && str2float(reltimestr(reltime(start_time))) > time | |
return "timeout" | |
endif | |
call self.update() | |
endwhile | |
if self.is_exit() | |
return "exit" | |
endif | |
return "processing" | |
endfunction | |
function! s:base.error_code() | |
endfunction | |
function! s:base.as_result() | |
return { | |
\ "status" : self.status(), | |
\ "body" : self.__reunions_process_base.result, | |
\ } | |
endfunction | |
function! s:make(cmd) | |
let process = deepcopy(s:base) | |
let process.__reunions_process_base.command = a:cmd | |
return process | |
endfunction | |
function! Test() | |
let process = s:make("ruby") | |
echo process.status() | |
call process.start("-e 'sleep 1; puts 42'") | |
" function! process.then(output, ...) | |
" echo a:output | |
" endfunction | |
echo process.kill() | |
" echo process.status() | |
" while !process.is_exit() | |
" echo process.update() | |
" endwhile | |
" echo process.status() | |
" echo process.as_result().body | |
endfunction | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment