Skip to content

Commit e630491

Browse files
committed
Port to Neovim: Add compatibility layer for job control functions
1 parent 087b634 commit e630491

1 file changed

Lines changed: 112 additions & 39 deletions

File tree

plugin/acme.vim

Lines changed: 112 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function AcmeStatusFlags()
7474
endfunc
7575

7676
function AcmeStatusJobs()
77-
return join(map(s:Jobs(bufnr()), '"{".v:val.cmd."}"'), '')
77+
return join(map(s:Jobs(bufnr()), {_, v -> '"{'.v.cmd.'}"'}), '')
7878
endfunc
7979

8080
function AcmeStatusRuler()
@@ -87,7 +87,7 @@ function s:Started(job, buf, cmd)
8787
\ 'h': a:job,
8888
\ 'cmd': type(a:cmd) == type([]) ? join(a:cmd) : a:cmd,
8989
\ 'killed': 0,
90-
\ })
90+
\ })
9191
redrawstatus!
9292
endfunc
9393

@@ -100,11 +100,11 @@ function s:RemoveJob(i, status)
100100
else
101101
checktime
102102
call s:ReloadDirs()
103-
let sig = job_info(job.h).termsig
103+
let sig = s:JobInfo(job.h).termsig
104104
if a:status == 0
105105
echo 'Done:' job.cmd
106106
elseif sig != '' && !job.killed
107-
let name = bufname(ch_getbufnr(job.h, 'out'))
107+
let name = bufname(s:GetJobBufNr(job.h))
108108
call s:ErrorOpen(name, [toupper(sig).': '.job.cmd])
109109
endif
110110
endif
@@ -121,11 +121,13 @@ endfunc
121121

122122
function s:Kill(p)
123123
for job in s:Jobs(a:p)
124-
let ch = job_getchannel(job.h)
125-
if string(ch) != 'channel fail'
126-
call ch_close(ch)
124+
if !has('nvim')
125+
let ch = job_getchannel(job.h)
126+
if string(ch) != 'channel fail'
127+
call ch_close(ch)
128+
endif
127129
endif
128-
call job_stop(job.h)
130+
call s:JobStop(job.h)
129131
let job.killed = 1
130132
endfor
131133
endfunc
@@ -156,8 +158,8 @@ function s:Send(w, inp)
156158
endif
157159
let inp = split(inp, '\n')
158160
let job = s:Jobs(b)[0].h
159-
call ch_setoptions(job, {'callback': ''})
160-
call ch_sendraw(job, join(inp, "\n")."\n")
161+
call s:ChanSetCallback(job, '')
162+
call s:ChanSend(job, join(inp, "\n")."\n")
161163
endfunc
162164

163165
function s:Receiver(b)
@@ -182,6 +184,61 @@ function s:ArgvAxec(cmd, cwd)
182184
\ ? [s:avimdir.'/bin/axec'] + argv : argv
183185
endfunc
184186

187+
function s:JobStop(job)
188+
if has('nvim')
189+
silent! call jobstop(a:job)
190+
else
191+
call job_stop(a:job)
192+
endif
193+
endfunc
194+
195+
function s:ChanSend(job, data)
196+
if has('nvim')
197+
call chansend(a:job, a:data)
198+
else
199+
call ch_sendraw(a:job, a:data)
200+
endif
201+
endfunc
202+
203+
function s:ChanCloseIn(job)
204+
if has('nvim')
205+
call chanclose(a:job, 'stdin')
206+
else
207+
call ch_close_in(a:job)
208+
endif
209+
endfunc
210+
211+
function s:ChanSetCallback(job, cb)
212+
if has('nvim')
213+
if has_key(s:nvim_jobs, a:job)
214+
let s:nvim_jobs[a:job].callback = a:cb
215+
endif
216+
else
217+
call ch_setoptions(a:job, {'callback': a:cb})
218+
endif
219+
endfunc
220+
221+
function s:JobInfo(job)
222+
if has('nvim')
223+
let s = jobwait([a:job], 0)[0]
224+
let sig = ''
225+
if s > 128
226+
let sig = s == 130 ? 'int' : s == 143 ? 'term' : s == 129 ? 'hup' : 'sig'.(s-128)
227+
endif
228+
return {'termsig': sig}
229+
else
230+
return job_info(a:job)
231+
endif
232+
endfunc
233+
234+
function s:GetJobBufNr(job)
235+
if has('nvim')
236+
return get(get(s:nvim_jobs, a:job, {}), 'buf', -1)
237+
else
238+
return ch_getbufnr(a:job, 'out')
239+
endif
240+
endfunc
241+
185242
function s:JobEnv(buf)
186243
return {
187244
\ 'ACMEVIMBUF': a:buf,
@@ -190,7 +247,7 @@ function s:JobEnv(buf)
190247
\ &buftype == '' ? expand('%:t') : '',
191248
\ 'COLUMNS': 80,
192249
\ 'LINES': 24,
193-
\ }
250+
\ }
194251
endfunc
195252

196253
function s:SetEnv(env)
@@ -209,7 +266,7 @@ function s:JobStart(cmd, outb, ctxb, opts, inp)
209266
\ 'out_io': 'buffer',
210267
\ 'out_buf': a:outb,
211268
\ 'out_msg': 0,
212-
\ }
269+
\ }
213270
call extend(opts, a:opts)
214271
let cwd = get(a:opts, 'cwd', getcwd())
215272
let env = s:SetEnv(s:JobEnv(a:outb))
@@ -270,7 +327,7 @@ function s:ErrorOpen(name, ...)
270327
exe w.'wincmd w'
271328
let b = s:ErrorLoad(a:name)
272329
for job in s:jobs
273-
if ch_getbufnr(job.h, 'out') == b && job.buf != b
330+
if s:GetJobBufNr(job.h) == b && job.buf != b
274331
let job.buf = b
275332
endif
276333
endfor
@@ -290,7 +347,7 @@ endfunc
290347

291348
function s:ErrorCb(b, ch, msg)
292349
call s:ErrorOpen(bufname(a:b))
293-
call ch_setoptions(a:ch, {'callback': ''})
350+
call s:ChanSetCallback(a:ch, '')
294351
endfunc
295352

296353
function s:ErrorExec(cmd, dir, b, inp)
@@ -389,7 +446,7 @@ function s:ScratchCb(b, ch, msg)
389446
let w = win_getid(w)
390447
if line('$', w) > 1
391448
call win_execute(w, 'noa normal! gg0')
392-
call ch_setoptions(a:ch, {'callback': ''})
449+
call s:ChanSetCallback(a:ch, '')
393450
endif
394451
endif
395452
endfunc
@@ -400,19 +457,23 @@ function s:ScratchExec(cmd, dir, inp, title)
400457
let opts = {
401458
\ 'callback': function('s:ScratchCb', [b]),
402459
\ 'in_io': 'pipe',
403-
\ }
460+
\ }
404461
if a:dir != ''
405462
let opts.cwd = a:dir
406463
endif
407464
call s:JobStart(a:cmd, b, b, opts, a:inp)
408465
endfunc
409466

410467
function s:Exec(cmd)
411-
silent! call job_start(s:Argv(a:cmd), {
412-
\ 'err_io': 'null',
413-
\ 'in_io': 'null',
414-
\ 'out_io': 'null',
415-
\ })
468+
if has('nvim')
469+
silent! call jobstart(s:Argv(a:cmd), {'detach': 1})
470+
else
471+
silent! call job_start(s:Argv(a:cmd), {
472+
\ 'err_io': 'null',
473+
\ 'in_io': 'null',
474+
\ 'out_io': 'null',
475+
\ })
476+
endif
416477
endfunc
417478

418479
function s:BufWidth(b)
@@ -535,7 +596,7 @@ endfunc
535596
function s:CtxDir()
536597
let dir = s:Dir()
537598
if &buftype != ''
538-
let [t, q] = ['ing directory:? ', "[`'\"]"]
599+
let [t, q] = ['ing directory:? ', "[`'\"`]"]
539600
let l = searchpair('\vEnter'.t.q, '', '\vLeav'.t.q, 'nW',
540601
\ '', 0, 50)
541602
let m = matchlist(getline(l), '\vLeav'.t.q.'(.+)'.q)
@@ -623,7 +684,7 @@ let s:plumbing = [
623684
\ [],
624685
\ ['\f+', {m -> m[0] !~ '/' && AcmeOpen(exepath(m[0]), '')}],
625686
\ ['\d+%([:,]\d+)?', {m -> s:Goto(m[0])}],
626-
\ ]
687+
\ ]
627688

628689
function s:Open(text, click, dir, win)
629690
let s:plumbclick = a:click
@@ -742,7 +803,7 @@ endfunc
742803

743804
function s:Scroll(topline)
744805
let v = winsaveview()
745-
let v.topline = a:topline
806+
v.topline = a:topline
746807
call winrestview(v)
747808
endfunc
748809

@@ -789,8 +850,8 @@ function s:Layout(col)
789850
let s = float2nr(h / (n * (n > s:tops ? 1.75 : 1)))
790851
endif
791852
call win_move_statusline(win_id2win(w) - 1, winheight(w) - s)
792-
let h -= s
793-
let n -= 1
853+
h -= s
854+
n -= 1
794855
endfor
795856
call timer_start(0, {_ -> s:Fit(a:col)})
796857
endfunc
@@ -900,13 +961,13 @@ function s:RightRelease(click)
900961
return
901962
endif
902963
exe "normal! \<LeftRelease>"
903-
let click = s:clicksel ? -1 : a:click
904-
let text = click <= 0 ? trim(s:Sel()[0], "\r\n", 2) : getline('.')
964+
let cmd = a:click <= 0 || s:clicksel ? s:Sel()[0] : expand('<cWORD>')
965+
let vis = s:clickmode == 'v' && (a:click <= 0 || !s:clicksel)
905966
call s:RestVisual(s:visual)
906967
let w = win_getid()
907968
let dir = s:CtxDir()
908969
exe win_id2win(s:clickwin).'wincmd w'
909-
call s:Open(text, click, dir, w)
970+
call s:Open(cmd, a:click, dir, w)
910971
endfunc
911972

912973
for m in ['', 'i']
@@ -945,7 +1006,7 @@ function s:Clear(b)
9451006
if has_key(s:scratch, a:b)
9461007
let s:scratch[a:b].cleared = 1
9471008
for job in s:Jobs(a:b)
948-
call ch_setoptions(job.h, {'callback': ''})
1009+
call s:ChanSetCallback(job.h, '')
9491010
endfor
9501011
endif
9511012
endfunc
@@ -1021,7 +1082,7 @@ endfunc
10211082
function s:PtyPw()
10221083
let pw = inputsecret('PW> ')
10231084
for job in s:Jobs(bufnr())
1024-
call ch_sendraw(job.h, pw."\n")
1085+
call s:ChanSend(job.h, pw."\n")
10251086
endfor
10261087
endfunc
10271088

@@ -1037,7 +1098,7 @@ function s:Pty(b)
10371098
if !has_key(s:scratch, a:b) || w == 0
10381099
return
10391100
endif
1040-
let s:scratch[a:b].pty = 1
1101+
s:scratch[a:b].pty = 1
10411102
call win_execute(w, 'call s:PtyMap()')
10421103
endfunc
10431104

@@ -1070,7 +1131,8 @@ function s:Look(p)
10701131
else
10711132
let hl = 1
10721133
let p = map(a:p[1:-2], {i, v -> escape(v, '\/')})
1073-
let @/ = '\V'.a:p[0].'\%\('.join(p, '\|').'\)'.a:p[-1]
1134+
let @/ = '\V'.a:p[0].'\%('.join(p, '\|').'\)'.a:p[-1]
1135+
call feedkeys(":let v:hlsearch=1\<CR>", 'n')
10741136
endif
10751137
let esc = mode() == 'i' ? "\<C-o>" : ""
10761138
call feedkeys(esc.":let v:hlsearch=".hl."\<CR>", 'n')
@@ -1150,7 +1212,7 @@ function s:CtrlRecv(ch, data)
11501212
endfunc
11511213

11521214
function s:CtrlSend(msg)
1153-
call ch_sendraw(s:ctrl, join(a:msg, "\x1f") . "\x1e")
1215+
call s:ChanSend(s:ctrl, join(a:msg, "\x1f") . "\x1e")
11541216
endfunc
11551217

11561218
function s:BufWinLeave()
@@ -1233,12 +1295,23 @@ let s:jobs = []
12331295
let s:minimized = {}
12341296
let s:scratch = {}
12351297
let s:tops = 1
1298+
let s:nvim_jobs = {}
12361299

12371300
if s:ctrlexe != ''
1238-
let s:ctrl = job_start([s:ctrlexe], {
1239-
\ 'callback': 's:CtrlRecv',
1240-
\ 'err_io': 'null',
1241-
\ 'mode': 'raw',
1242-
\ })
1301+
if has('nvim')
1302+
function s:NvimCtrlRecv(id, data, event)
1303+
call s:CtrlRecv(a:id, join(a:data, "\n"))
1304+
endfunc
1305+
let s:ctrl = jobstart([s:ctrlexe], {
1306+
\ 'on_stdout': function('s:NvimCtrlRecv'),
1307+
\ 'rpc': 0,
1308+
\ })
1309+
else
1310+
let s:ctrl = job_start([s:ctrlexe], {
1311+
\ 'callback': 's:CtrlRecv',
1312+
\ 'err_io': 'null',
1313+
\ 'mode': 'raw',
1314+
\ })
1315+
endif
12431316
let $EDITOR = s:ctrlexe
12441317
endif

0 commit comments

Comments
 (0)