forked from github/copilot.vim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjob.vim
More file actions
106 lines (96 loc) · 3.15 KB
/
job.vim
File metadata and controls
106 lines (96 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
scriptencoding utf-8
function! copilot#job#Nop(...) abort
endfunction
function! s:Jobs(job_or_jobs) abort
let jobs = type(a:job_or_jobs) == v:t_list ? copy(a:job_or_jobs) : [a:job_or_jobs]
call map(jobs, { k, v -> type(v) == v:t_dict ? get(v, 'job', '') : v })
call filter(jobs, { k, v -> type(v) !=# type('') })
return jobs
endfunction
let s:job_stop = exists('*job_stop') ? 'job_stop' : 'jobstop'
function! copilot#job#Stop(job) abort
for job in s:Jobs(a:job)
call call(s:job_stop, [job])
endfor
return copilot#job#Wait(a:job)
endfunction
let s:sleep = has('patch-8.2.2366') ? 'sleep! 1m' : 'sleep 1m'
function! copilot#job#Wait(jobs) abort
let jobs = s:Jobs(a:jobs)
if exists('*jobwait')
call jobwait(jobs)
else
for job in jobs
while ch_status(job) !=# 'closed' || job_status(job) ==# 'run'
exe s:sleep
endwhile
endfor
endif
return a:jobs
endfunction
function! s:VimExitCallback(result, exit_cb, job, data) abort
let a:result.exit_status = a:data
if !has_key(a:result, 'closed')
return
endif
call remove(a:result, 'closed')
call a:exit_cb(a:result.exit_status)
endfunction
function! s:VimCloseCallback(result, exit_cb, job) abort
if !has_key(a:result, 'exit_status')
let a:result.closed = v:true
return
endif
call a:exit_cb(a:result.exit_status)
endfunction
function! s:NvimCallback(cb, job, data, type) dict abort
let self[a:type][0] .= remove(a:data, 0)
call extend(self[a:type], a:data)
while len(self[a:type]) > 1
call a:cb(substitute(remove(self[a:type], 0), "\r$", '', ''))
endwhile
endfunction
function! s:NvimExitCallback(out_cb, err_cb, exit_cb, job, data, type) dict abort
if len(self.stderr[0])
call a:err_cb(substitute(self.stderr[0], "\r$", '', ''))
endif
call a:exit_cb(a:data)
endfunction
function! copilot#job#Cwd() abort
let home = expand("~")
if !isdirectory(home) && isdirectory($VIM)
return $VIM
endif
return home
endfunction
function! copilot#job#Stream(argv, out_cb, err_cb, ...) abort
let exit_status = []
let ExitCb = function(a:0 && !empty(a:1) ? a:1 : { e -> add(exit_status, e) }, a:000[2:-1])
let OutCb = function(empty(a:out_cb) ? 'copilot#job#Nop' : a:out_cb, a:000[2:-1])
let ErrCb = function(empty(a:err_cb) ? 'copilot#job#Nop' : a:err_cb, a:000[2:-1])
let state = {'headers': {}, 'mode': 'headers', 'buffer': ''}
if exists('*job_start')
let result = {}
let job = job_start(a:argv, {
\ 'cwd': copilot#job#Cwd(),
\ 'out_mode': 'raw',
\ 'out_cb': { j, d -> OutCb(d) },
\ 'err_cb': { j, d -> ErrCb(d) },
\ 'exit_cb': function('s:VimExitCallback', [result, ExitCb]),
\ 'close_cb': function('s:VimCloseCallback', [result, ExitCb]),
\ })
else
let jopts = {
\ 'cwd': copilot#job#Cwd(),
\ 'stderr': [''],
\ 'on_stdout': { j, d, t -> OutCb(join(d, "\n")) },
\ 'on_stderr': function('s:NvimCallback', [ErrCb]),
\ 'on_exit': function('s:NvimExitCallback', [OutCb, ErrCb, ExitCb])}
let job = jobstart(a:argv, jopts)
endif
if a:0
return job
endif
call copilot#job#Wait(job)
return exit_status[0]
endfunction