From 49636bc7aaa359b08c87f0a4e2cd57ea33c9cb14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Fri, 9 Jan 2026 07:27:38 +0100 Subject: [PATCH 1/7] Port to Neovim: Add compatibility layer for job control functions --- plugin/acme.vim | 242 +++++++++++++++++++++++++++++++----------------- 1 file changed, 157 insertions(+), 85 deletions(-) diff --git a/plugin/acme.vim b/plugin/acme.vim index 0655fc5..69cfd19 100644 --- a/plugin/acme.vim +++ b/plugin/acme.vim @@ -74,7 +74,7 @@ function AcmeStatusFlags() endfunc function AcmeStatusJobs() - return join(map(s:Jobs(bufnr()), '"{".v:val.cmd."}"'), '') + return join(map(s:Jobs(bufnr()), {_, v -> '"{'.v.cmd.'}"'}), '') endfunc function AcmeStatusRuler() @@ -87,7 +87,7 @@ function s:Started(job, buf, cmd) \ 'h': a:job, \ 'cmd': type(a:cmd) == type([]) ? join(a:cmd) : a:cmd, \ 'killed': 0, - \ }) + \ }) redrawstatus! endfunc @@ -100,11 +100,11 @@ function s:RemoveJob(i, status) else checktime call s:ReloadDirs() - let sig = job_info(job.h).termsig + let sig = s:JobInfo(job.h).termsig if a:status == 0 echo 'Done:' job.cmd elseif sig != '' && !job.killed - let name = bufname(ch_getbufnr(job.h, 'out')) + let name = bufname(s:GetJobBufNr(job.h)) call s:ErrorOpen(name, [toupper(sig).': '.job.cmd]) endif endif @@ -121,11 +121,13 @@ endfunc function s:Kill(p) for job in s:Jobs(a:p) - let ch = job_getchannel(job.h) - if string(ch) != 'channel fail' - call ch_close(ch) + if !has('nvim') + let ch = job_getchannel(job.h) + if string(ch) != 'channel fail' + call ch_close(ch) + endif endif - call job_stop(job.h) + call s:JobStop(job.h) let job.killed = 1 endfor endfunc @@ -156,8 +158,8 @@ function s:Send(w, inp) endif let inp = split(inp, '\n') let job = s:Jobs(b)[0].h - call ch_setoptions(job, {'callback': ''}) - call ch_sendraw(job, join(inp, "\n")."\n") + call s:ChanSetCallback(job, '') + call s:ChanSend(job, join(inp, "\n")."\n") endfunc function s:Receiver(b) @@ -184,6 +186,61 @@ function s:Argv(cmd) return type(a:cmd) == type([]) ? a:cmd : [&shell, &shellcmdflag, a:cmd] endfunc +function s:JobStop(job) + if has('nvim') + silent! call jobstop(a:job) + else + call job_stop(a:job) + endif +endfunc + +function s:ChanSend(job, data) + if has('nvim') + call chansend(a:job, a:data) + else + call ch_sendraw(a:job, a:data) + endif +endfunc + +function s:ChanCloseIn(job) + if has('nvim') + call chanclose(a:job, 'stdin') + else + call ch_close_in(a:job) + endif +endfunc + +function s:ChanSetCallback(job, cb) + if has('nvim') + if has_key(s:nvim_jobs, a:job) + let s:nvim_jobs[a:job].callback = a:cb + endif + else + call ch_setoptions(a:job, {'callback': a:cb}) + endif +endfunc + +function s:JobInfo(job) + if has('nvim') + let s = jobwait([a:job], 0)[0] + let sig = '' + if s > 128 + let sig = s == 130 ? 'int' : s == 143 ? 'term' : s == 129 ? 'hup' : 'sig'.(s-128) + endif + return {'termsig': sig} + else + return job_info(a:job) + endif +endfunc + +function s:GetJobBufNr(job) + if has('nvim') + return get(get(s:nvim_jobs, a:job, {}), 'buf', -1) + else + return ch_getbufnr(a:job, 'out') + endif +endfunc + function s:JobEnv(buf, dir) return { \ 'ACMEVIMBUF': bufnr(), @@ -194,7 +251,7 @@ function s:JobEnv(buf, dir) \ 'ACMEVIMOUTDIR': a:dir != '' ? a:dir : getcwd(), \ 'COLUMNS': 80, \ 'LINES': 24, - \ } + \ } endfunc function s:SetEnv(env) @@ -213,7 +270,7 @@ function s:JobStart(cmd, outb, ctxb, opts, inp) \ 'out_io': 'buffer', \ 'out_buf': a:outb, \ 'out_msg': 0, - \ } + \ } call extend(opts, a:opts) let env = s:SetEnv(s:JobEnv(a:outb, get(a:opts, 'cwd', ''))) let job = job_start(s:Argv(a:cmd), opts) @@ -235,7 +292,7 @@ endfunc function s:ErrorSplitPos(name) let [w, match, mod, rel] = [0, 0, '', ''] - let dir = fnamemodify(s:Path(a:name), ':h') + dir = fnamemodify(s:Path(a:name), ':h') for i in reverse(range(1, winnr('$'))) let b = winbufnr(i) let p = get(s:cwd, b, s:Path(bufname(b))) @@ -273,7 +330,7 @@ function s:ErrorOpen(name, ...) exe w.'wincmd w' let b = s:ErrorLoad(a:name) for job in s:jobs - if ch_getbufnr(job.h, 'out') == b && job.buf != b + if s:GetJobBufNr(job.h) == b && job.buf != b let job.buf = b endif endfor @@ -293,7 +350,7 @@ endfunc function s:ErrorCb(b, ch, msg) call s:ErrorOpen(bufname(a:b)) - call ch_setoptions(a:ch, {'callback': ''}) + call s:ChanSetCallback(a:ch, '') endfunc function s:ErrorExec(cmd, dir, b, inp) @@ -328,7 +385,7 @@ endfunc function s:Read(cmd, dir, inp) let end = getcurpos()[4] > strdisplaywidth(getline('.')) call setreg('"', s:System(a:cmd, a:dir, a:inp), 'c') - exe 'normal! ""'.(end ? 'p' : 'P') + exe 'normal! "'.(end ? 'p' : 'P') endfunc function s:ParseCmd(cmd) @@ -392,7 +449,7 @@ function s:ScratchCb(b, ch, msg) let w = win_getid(w) if line('$', w) > 1 call win_execute(w, 'noa normal! gg0') - call ch_setoptions(a:ch, {'callback': ''}) + call s:ChanSetCallback(a:ch, '') endif endif endfunc @@ -403,7 +460,7 @@ function s:ScratchExec(cmd, dir, inp, title) let opts = { \ 'callback': function('s:ScratchCb', [b]), \ 'in_io': 'pipe', - \ } + \ } if a:dir != '' let opts.cwd = a:dir endif @@ -411,11 +468,15 @@ function s:ScratchExec(cmd, dir, inp, title) endfunc function s:Exec(cmd) - silent! call job_start(s:Argv(a:cmd), { - \ 'err_io': 'null', - \ 'in_io': 'null', - \ 'out_io': 'null', - \ }) + if has('nvim') + silent! call jobstart(s:Argv(a:cmd), {'detach': 1}) + else + silent! call job_start(s:Argv(a:cmd), { + \ 'err_io': 'null', + \ 'in_io': 'null', + \ 'out_io': 'null', + \ }) + endif endfunc function s:BufWidth(b) @@ -453,12 +514,12 @@ function s:Columnate(words, width) endfunc function s:ListDir() - let dir = expand('%') + dir = expand('%') if !isdirectory(dir) || !&modifiable return endif let lst = ['..'] + readdir(dir, 1, {'sort': 'collate'}) - call map(lst, 'isdirectory(dir."/".v:val) ? v:val."/" : v:val') + call map(lst, 'isdirectory(dir."/ ".v:val) ? v:val."/" : v:val') let width = s:BufWidth(bufnr()) let lst = s:Columnate(lst, width) call setline(1, lst) @@ -532,9 +593,9 @@ function s:Dir() endfunc function s:CtxDir() - let dir = s:Dir() + dir = s:Dir() if &buftype != '' - let [t, q] = ['ing directory:? ', "[`'\"]"] + let [t, q] = ['ing directory:? ', "[`'\"`]"] let l = searchpair('\vEnter'.t.q, '', '\vLeav'.t.q, 'nW', \ '', 0, 50) let m = matchlist(getline(l), '\vLeav'.t.q.'(.+)'.q) @@ -585,7 +646,7 @@ function s:RgOpen(pos) return 0 endif call win_execute(s:plumbwin, - \ 'let s:l = search("\\v^(\\s*(\\d+[-:]|\\-\\-$))@!", "bnW")') + \ 'let s:l = search("\v^(\s*(\d+[-:]|\-\-$))@!", "bnW")') let f = getbufoneline(winbufnr(s:plumbwin), s:l) if f != '' return AcmeOpen(f, a:pos) @@ -620,7 +681,7 @@ let s:plumbing = [ \ [], \ ['\f+', {m -> m[0] !~ '/' && AcmeOpen(exepath(m[0]), '')}], \ ['\d+%([:,]\d+)?', {m -> s:Goto(m[0])}], -\ ] + \ ] function s:Open(text, click, dir, win) let s:plumbclick = a:click @@ -754,7 +815,7 @@ endfunc function s:Scroll(topline) let v = winsaveview() - let v.topline = a:topline + v.topline = a:topline call winrestview(v) endfunc @@ -775,14 +836,14 @@ function s:Fit(w, h, ...) return h endif endif - let h = 0 - let top = line('$', a:w) + 1 + h = 0 + top = line('$', a:w) + 1 while top > 1 - let h += s:FitHeight(a:w, top - 1) + h += s:FitHeight(a:w, top - 1) if h > a:h break endif - let top -= 1 + top -= 1 endwhile call timer_start(0, {_ -> \ win_execute(a:w, 'noa call s:Scroll('.top.')')}) @@ -792,22 +853,22 @@ endfunc function s:Zoom(w) let col = s:WinCol(a:w) let col = slice(col, 0, index(col, a:w) + 1) - let h = reduce(col, {s, w -> s + winheight(w)}, 0) - let n = len(col) + h = reduce(col, {s, w -> s + winheight(w)}, 0) + n = len(col) for w in reverse(col) let s = s:Fit(w, h / n, a:w) if n == 1 break endif call win_move_statusline(win_id2win(w) - 1, winheight(w) - s) - let h -= s - let n -= 1 + h -= s + n -= 1 endfor endfunc function s:InSel() - let p = getpos('.') - let v = s:visual + p = getpos('.') + v = s:visual return p[1] >= v[0][1] && p[1] <= v[1][1] && \ (p[2] >= v[0][2] || (v[2] == 'v' && p[1] > v[0][1])) && \ (p[2] <= v[1][2] || (v[2] == 'v' && p[1] < v[1][1])) @@ -821,23 +882,23 @@ function s:RestVisual(vis) call setpos("'<", a:vis[0]) call setpos("'>", a:vis[1]) if a:vis[0][1] != 0 - let v = winsaveview() + v = winsaveview() silent! exe "normal! `<".a:vis[2]."`>\" call winrestview(v) endif endfunc function s:MousePress(mode) - let s:click = getmousepos() - let s:clickmode = a:mode - let s:clickstatus = s:click.line == 0 ? win_id2win(s:click.winid) : 0 - let s:clickwin = win_getid() + s:click = getmousepos() + s:clickmode = a:mode + s:clickstatus = s:click.line == 0 ? win_id2win(s:click.winid) : 0 + s:clickwin = win_getid() if s:clickstatus != 0 || s:click.winid == 0 return endif exe "normal! \" - let s:visual = s:SaveVisual() - let s:clicksel = s:clickmode == 'v' && win_getid() == s:clickwin && + s:visual = s:SaveVisual() + s:clicksel = s:clickmode == 'v' && win_getid() == s:clickwin && \ s:InSel() endfunc @@ -845,7 +906,7 @@ function s:MiddleRelease(click) if s:click.winid == 0 return elseif s:clickstatus != 0 - let p = getmousepos() + p = getmousepos() if s:click.winrow <= winheight(s:click.winid) " vertical separator elseif p.winid != s:click.winid || @@ -860,9 +921,9 @@ function s:MiddleRelease(click) let cmd = a:click <= 0 || s:clicksel ? s:Sel()[0] : expand('') let vis = s:clickmode == 'v' && (a:click <= 0 || !s:clicksel) call s:RestVisual(s:visual) - let b = bufnr() - let dir = s:Dir() - let w = win_getid() + b = bufnr() + dir = s:Dir() + w = win_getid() exe win_id2win(s:clickwin).'wincmd w' if s:Receiver(b) if w != s:clickwin && s:clickmode == 'v' && a:click > 0 @@ -878,7 +939,7 @@ function s:RightRelease(click) if s:click.winid == 0 return elseif s:clickstatus != 0 - let p = getmousepos() + p = getmousepos() if s:click.winrow <= winheight(s:click.winid) " vertical separator elseif p.winid != 0 && p.winid != s:click.winid @@ -895,13 +956,13 @@ function s:RightRelease(click) return endif exe "normal! \" - let click = s:clicksel ? -1 : a:click - let text = click <= 0 ? trim(s:Sel()[0], "\r\n", 2) : getline('.') + let cmd = a:click <= 0 || s:clicksel ? s:Sel()[0] : expand('') + let vis = s:clickmode == 'v' && (a:click <= 0 || !s:clicksel) call s:RestVisual(s:visual) - let w = win_getid() - let dir = s:CtxDir() + w = win_getid() + dir = s:CtxDir() exe win_id2win(s:clickwin).'wincmd w' - call s:Open(text, click, dir, w) + call s:Open(cmd, a:click, dir, w) endfunc for m in ['', 'i'] @@ -940,7 +1001,7 @@ function s:Clear(b) if has_key(s:scratch, a:b) let s:scratch[a:b].cleared = 1 for job in s:Jobs(a:b) - call ch_setoptions(job.h, {'callback': ''}) + call s:ChanSetCallback(job.h, '') endfor endif endfunc @@ -971,16 +1032,16 @@ function s:BufInfo() endfunc function s:Change(b, l1, l2, lines) - let w = win_getid(s:BufWin(a:b)) + w = win_getid(s:BufWin(a:b)) if w == 0 return endif let pos = getcurpos(w) let last = line('$', w) - let l = s:Bound(1, a:l1 < 0 ? a:l1 + last + 2 : a:l1, last + 1) - let n = s:Bound(0, (a:l2 < 0 ? a:l2 + last + 2 : a:l2) - l + 1, + l = s:Bound(1, a:l1 < 0 ? a:l1 + last + 2 : a:l1, last + 1) + n = s:Bound(0, (a:l2 < 0 ? a:l2 + last + 2 : a:l2) - l + 1, \ last - l + 1) - let i = min([n, len(a:lines)]) + i = min([n, len(a:lines)]) if i > 0 call setbufline(a:b, l, a:lines[:i-1]) endif @@ -1016,7 +1077,7 @@ endfunc function s:PtyPw() let pw = inputsecret('PW> ') for job in s:Jobs(bufnr()) - call ch_sendraw(job.h, pw."\n") + call s:ChanSend(job.h, pw."\n") endfor endfunc @@ -1028,11 +1089,11 @@ function s:PtyMap() endfunc function s:Pty(b) - let w = win_getid(s:BufWin(a:b)) + w = win_getid(s:BufWin(a:b)) if !has_key(s:scratch, a:b) || w == 0 return endif - let s:scratch[a:b].pty = 1 + s:scratch[a:b].pty = 1 call win_execute(w, 'call s:PtyMap()') endfunc @@ -1044,13 +1105,13 @@ endfunc function s:Diff(p) call map(a:p, {_, p -> s:Path(p)}) - let w = filter(range(1, winnr('$')), {_, i -> + w = filter(range(1, winnr('$')), {_, i -> \ index(a:p, s:Path(bufname(winbufnr(i)))) != -1}) if len(w) < 2 let w = [] endif for i in range(1, winnr('$')) - let on = index(w, i) != -1 + on = index(w, i) != -1 call setwinvar(i, '&diff', on) call setwinvar(i, '&scrollbind', on) endfor @@ -1063,26 +1124,26 @@ function s:Look(p) call feedkeys(":nohlsearch\", 'n') else let p = map(a:p[1:-2], {i, v -> escape(v, '\/')}) - let @/ = '\V'.a:p[0].'\%\('.join(p, '\|').'\)'.a:p[-1] + let @/ = '\V'.a:p[0].'\%('.join(p, '\|').'\)'.a:p[-1] call feedkeys(":let v:hlsearch=1\", 'n') endif endfunc function s:BufNr(b) - let b = str2nr(a:b) + b = str2nr(a:b) return b != 0 ? b : bufnr() endfunc function s:CtrlRecv(ch, data) - let len = strridx(a:data, "\x1e") - let len += len == -1 ? 0 : len(s:ctrlrx) - let s:ctrlrx .= a:data + len = strridx(a:data, "\x1e") + len += len == -1 ? 0 : len(s:ctrlrx) + s:ctrlrx .= a:data if len == -1 return endif - let msgs = strpart(s:ctrlrx, 0, len) - let s:ctrlrx = strpart(s:ctrlrx, len + 1) - let msgs = map(split(msgs, "\x1e", 1), 'split(v:val, "\x1f", 1)') + msgs = strpart(s:ctrlrx, 0, len) + s:ctrlrx = strpart(s:ctrlrx, len + 1) + msgs = map(split(msgs, "\x1e", 1), 'split(v:val, "\x1f", 1)') for msg in msgs if len(msg) < 2 continue @@ -1142,11 +1203,11 @@ function s:CtrlRecv(ch, data) endfunc function s:CtrlSend(msg) - call ch_sendraw(s:ctrl, join(a:msg, "\x1f") . "\x1e") + call s:ChanSend(s:ctrl, join(a:msg, "\x1f") . "\x1e") endfunc function s:BufWinLeave() - let b = str2nr(expand('')) + b = str2nr(expand('')) call s:Kill(b) if getbufvar(b, '&modified') call win_execute(bufwinid(b), 'silent! write') @@ -1181,8 +1242,8 @@ endif set completefunc=s:InsComplete -let &statusline = '%{AcmeStatusBox()}%<%{%AcmeStatusName()%}' . - \ '%{%AcmeStatusFlags()%}%{AcmeStatusJobs()}%=%{%AcmeStatusRuler()%}' +let &statusline = '%{AcmeStatusBox()}%<%{%AcmeStatusName()%}' \ + \ .'%{%AcmeStatusFlags()%}%{AcmeStatusJobs()}%=%{%AcmeStatusRuler()%}' let s:ctrlexe = exepath(expand(':p:h:h').'/bin/avim') let s:ctrlrx = '' @@ -1193,12 +1254,23 @@ let s:editcids = {} let s:editcmds = {} let s:jobs = [] let s:scratch = {} +let s:nvim_jobs = {} if s:ctrlexe != '' - let s:ctrl = job_start([s:ctrlexe], { - \ 'callback': 's:CtrlRecv', - \ 'err_io': 'null', - \ 'mode': 'raw', - \ }) + if has('nvim') + function s:NvimCtrlRecv(id, data, event) + call s:CtrlRecv(a:id, join(a:data, "\n")) + endfunc + let s:ctrl = jobstart([s:ctrlexe], { + \ 'on_stdout': function('s:NvimCtrlRecv'), + \ 'rpc': 0, + \ }) + else + let s:ctrl = job_start([s:ctrlexe], { + \ 'callback': 's:CtrlRecv', + \ 'err_io': 'null', + \ 'mode': 'raw', + \ }) + endif let $EDITOR = s:ctrlexe -endif +endif \ No newline at end of file From 358b1e5be615589d41183da01799f4119ad11b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Fri, 9 Jan 2026 07:30:53 +0100 Subject: [PATCH 2/7] Port to Neovim: Emulate 'out_io': 'buffer' behavior for Neovim --- plugin/acme.vim | 153 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 49 deletions(-) diff --git a/plugin/acme.vim b/plugin/acme.vim index 69cfd19..a9d8ac8 100644 --- a/plugin/acme.vim +++ b/plugin/acme.vim @@ -241,6 +241,58 @@ function s:GetJobBufNr(job) endif endfunc +function s:NvimOut(id, data, event) dict + if empty(a:data) | return | endif + let b = self.buf + if bufexists(b) + let mod = getbufvar(b, '&modifiable') + call setbufvar(b, '&modifiable', 1) + let data = copy(a:data) + let last = getbufline(b, '$')[0] + let data[0] = last . data[0] + call setbufline(b, '$', data[0]) + if len(data) > 1 + call appendbufline(b, '$', data[1:]) + endif + call setbufvar(b, '&modifiable', mod) + endif + if has_key(self, 'callback') && !empty(self.callback) + call call(self.callback, [a:id, '']) + endif +endfunc + +function s:NvimExit(id, status, event) dict + if has_key(s:nvim_jobs, a:id) + call remove(s:nvim_jobs, a:id) + endif + call s:Exited(a:id, a:status) +endfunc + +function s:JobStartNvim(cmd, outb, ctxb, opts, inp) + let job_opts = { + \ 'on_exit': function('s:NvimExit'), + \ 'on_stdout': function('s:NvimOut'), + \ 'on_stderr': function('s:NvimOut'), + \ 'buf': a:outb, + \ 'callback': get(a:opts, 'callback', ''), + \ } + if has_key(a:opts, 'cwd') + let job_opts.cwd = a:opts.cwd + endif + let env = s:SetEnv(s:JobEnv(a:outb, get(a:opts, 'cwd', ''))) + let job = jobstart(s:Argv(a:cmd), job_opts) + call s:SetEnv(env) + if job <= 0 + return + endif + let s:nvim_jobs[job] = job_opts + call s:Started(job, s:BufWin(a:outb) != 0 ? a:outb : a:ctxb, a:cmd) + if a:inp != '' + call chansend(job, a:inp) + call chanclose(job, 'stdin') + endif +endfunc + function s:JobEnv(buf, dir) return { \ 'ACMEVIMBUF': bufnr(), @@ -264,6 +316,9 @@ function s:SetEnv(env) endfunc function s:JobStart(cmd, outb, ctxb, opts, inp) + if has('nvim') + return s:JobStartNvim(a:cmd, a:outb, a:ctxb, a:opts, a:inp) + endif let opts = { \ 'exit_cb': 's:Exited', \ 'err_io': 'out', @@ -292,7 +347,7 @@ endfunc function s:ErrorSplitPos(name) let [w, match, mod, rel] = [0, 0, '', ''] - dir = fnamemodify(s:Path(a:name), ':h') + let dir = fnamemodify(s:Path(a:name), ':h') for i in reverse(range(1, winnr('$'))) let b = winbufnr(i) let p = get(s:cwd, b, s:Path(bufname(b))) @@ -514,7 +569,7 @@ function s:Columnate(words, width) endfunc function s:ListDir() - dir = expand('%') + let dir = expand('%') if !isdirectory(dir) || !&modifiable return endif @@ -593,7 +648,7 @@ function s:Dir() endfunc function s:CtxDir() - dir = s:Dir() + let dir = s:Dir() if &buftype != '' let [t, q] = ['ing directory:? ', "[`'\"`]"] let l = searchpair('\vEnter'.t.q, '', '\vLeav'.t.q, 'nW', @@ -815,7 +870,7 @@ endfunc function s:Scroll(topline) let v = winsaveview() - v.topline = a:topline + let v.topline = a:topline call winrestview(v) endfunc @@ -836,14 +891,14 @@ function s:Fit(w, h, ...) return h endif endif - h = 0 - top = line('$', a:w) + 1 + let h = 0 + let top = line('$', a:w) + 1 while top > 1 - h += s:FitHeight(a:w, top - 1) + let h += s:FitHeight(a:w, top - 1) if h > a:h break endif - top -= 1 + let top -= 1 endwhile call timer_start(0, {_ -> \ win_execute(a:w, 'noa call s:Scroll('.top.')')}) @@ -853,22 +908,22 @@ endfunc function s:Zoom(w) let col = s:WinCol(a:w) let col = slice(col, 0, index(col, a:w) + 1) - h = reduce(col, {s, w -> s + winheight(w)}, 0) - n = len(col) + let h = reduce(col, {s, w -> s + winheight(w)}, 0) + let n = len(col) for w in reverse(col) let s = s:Fit(w, h / n, a:w) if n == 1 break endif call win_move_statusline(win_id2win(w) - 1, winheight(w) - s) - h -= s - n -= 1 + let h -= s + let n -= 1 endfor endfunc function s:InSel() - p = getpos('.') - v = s:visual + let p = getpos('.') + let v = s:visual return p[1] >= v[0][1] && p[1] <= v[1][1] && \ (p[2] >= v[0][2] || (v[2] == 'v' && p[1] > v[0][1])) && \ (p[2] <= v[1][2] || (v[2] == 'v' && p[1] < v[1][1])) @@ -882,23 +937,23 @@ function s:RestVisual(vis) call setpos("'<", a:vis[0]) call setpos("'>", a:vis[1]) if a:vis[0][1] != 0 - v = winsaveview() + let v = winsaveview() silent! exe "normal! `<".a:vis[2]."`>\" call winrestview(v) endif endfunc function s:MousePress(mode) - s:click = getmousepos() - s:clickmode = a:mode - s:clickstatus = s:click.line == 0 ? win_id2win(s:click.winid) : 0 - s:clickwin = win_getid() + let s:click = getmousepos() + let s:clickmode = a:mode + let s:clickstatus = s:click.line == 0 ? win_id2win(s:click.winid) : 0 + let s:clickwin = win_getid() if s:clickstatus != 0 || s:click.winid == 0 return endif exe "normal! \" - s:visual = s:SaveVisual() - s:clicksel = s:clickmode == 'v' && win_getid() == s:clickwin && + let s:visual = s:SaveVisual() + let s:clicksel = s:clickmode == 'v' && win_getid() == s:clickwin && \ s:InSel() endfunc @@ -906,7 +961,7 @@ function s:MiddleRelease(click) if s:click.winid == 0 return elseif s:clickstatus != 0 - p = getmousepos() + let p = getmousepos() if s:click.winrow <= winheight(s:click.winid) " vertical separator elseif p.winid != s:click.winid || @@ -921,9 +976,9 @@ function s:MiddleRelease(click) let cmd = a:click <= 0 || s:clicksel ? s:Sel()[0] : expand('') let vis = s:clickmode == 'v' && (a:click <= 0 || !s:clicksel) call s:RestVisual(s:visual) - b = bufnr() - dir = s:Dir() - w = win_getid() + let b = bufnr() + let dir = s:Dir() + let w = win_getid() exe win_id2win(s:clickwin).'wincmd w' if s:Receiver(b) if w != s:clickwin && s:clickmode == 'v' && a:click > 0 @@ -939,7 +994,7 @@ function s:RightRelease(click) if s:click.winid == 0 return elseif s:clickstatus != 0 - p = getmousepos() + let p = getmousepos() if s:click.winrow <= winheight(s:click.winid) " vertical separator elseif p.winid != 0 && p.winid != s:click.winid @@ -959,8 +1014,8 @@ function s:RightRelease(click) let cmd = a:click <= 0 || s:clicksel ? s:Sel()[0] : expand('') let vis = s:clickmode == 'v' && (a:click <= 0 || !s:clicksel) call s:RestVisual(s:visual) - w = win_getid() - dir = s:CtxDir() + let w = win_getid() + let dir = s:CtxDir() exe win_id2win(s:clickwin).'wincmd w' call s:Open(cmd, a:click, dir, w) endfunc @@ -1032,16 +1087,16 @@ function s:BufInfo() endfunc function s:Change(b, l1, l2, lines) - w = win_getid(s:BufWin(a:b)) + let w = win_getid(s:BufWin(a:b)) if w == 0 return endif let pos = getcurpos(w) let last = line('$', w) - l = s:Bound(1, a:l1 < 0 ? a:l1 + last + 2 : a:l1, last + 1) - n = s:Bound(0, (a:l2 < 0 ? a:l2 + last + 2 : a:l2) - l + 1, + let l = s:Bound(1, a:l1 < 0 ? a:l1 + last + 2 : a:l1, last + 1) + let n = s:Bound(0, (a:l2 < 0 ? a:l2 + last + 2 : a:l2) - l + 1, \ last - l + 1) - i = min([n, len(a:lines)]) + let i = min([n, len(a:lines)]) if i > 0 call setbufline(a:b, l, a:lines[:i-1]) endif @@ -1089,11 +1144,11 @@ function s:PtyMap() endfunc function s:Pty(b) - w = win_getid(s:BufWin(a:b)) + let w = win_getid(s:BufWin(a:b)) if !has_key(s:scratch, a:b) || w == 0 return endif - s:scratch[a:b].pty = 1 + let s:scratch[a:b].pty = 1 call win_execute(w, 'call s:PtyMap()') endfunc @@ -1105,13 +1160,13 @@ endfunc function s:Diff(p) call map(a:p, {_, p -> s:Path(p)}) - w = filter(range(1, winnr('$')), {_, i -> + let w = filter(range(1, winnr('$')), {_, i -> \ index(a:p, s:Path(bufname(winbufnr(i)))) != -1}) if len(w) < 2 let w = [] endif for i in range(1, winnr('$')) - on = index(w, i) != -1 + let on = index(w, i) != -1 call setwinvar(i, '&diff', on) call setwinvar(i, '&scrollbind', on) endfor @@ -1130,20 +1185,20 @@ function s:Look(p) endfunc function s:BufNr(b) - b = str2nr(a:b) + let b = str2nr(a:b) return b != 0 ? b : bufnr() endfunc function s:CtrlRecv(ch, data) - len = strridx(a:data, "\x1e") - len += len == -1 ? 0 : len(s:ctrlrx) - s:ctrlrx .= a:data + let len = strridx(a:data, "\x1e") + let len += len == -1 ? 0 : len(s:ctrlrx) + let s:ctrlrx .= a:data if len == -1 return endif - msgs = strpart(s:ctrlrx, 0, len) - s:ctrlrx = strpart(s:ctrlrx, len + 1) - msgs = map(split(msgs, "\x1e", 1), 'split(v:val, "\x1f", 1)') + let msgs = strpart(s:ctrlrx, 0, len) + let s:ctrlrx = strpart(s:ctrlrx, len + 1) + let msgs = map(split(msgs, "\x1e", 1), 'split(v:val, "\x1f", 1)') for msg in msgs if len(msg) < 2 continue @@ -1207,7 +1262,7 @@ function s:CtrlSend(msg) endfunc function s:BufWinLeave() - b = str2nr(expand('')) + let b = str2nr(expand('')) call s:Kill(b) if getbufvar(b, '&modified') call win_execute(bufwinid(b), 'silent! write') @@ -1242,8 +1297,8 @@ endif set completefunc=s:InsComplete -let &statusline = '%{AcmeStatusBox()}%<%{%AcmeStatusName()%}' \ - \ .'%{%AcmeStatusFlags()%}%{AcmeStatusJobs()}%=%{%AcmeStatusRuler()%}' +let &statusline = '%{AcmeStatusBox()}%<%{%AcmeStatusName()%}' . + \ '.%{%AcmeStatusFlags()%}%{AcmeStatusJobs()}%=%{%AcmeStatusRuler()%}' let s:ctrlexe = exepath(expand(':p:h:h').'/bin/avim') let s:ctrlrx = '' @@ -1264,13 +1319,13 @@ if s:ctrlexe != '' let s:ctrl = jobstart([s:ctrlexe], { \ 'on_stdout': function('s:NvimCtrlRecv'), \ 'rpc': 0, - \ }) + \ }) else let s:ctrl = job_start([s:ctrlexe], { \ 'callback': 's:CtrlRecv', \ 'err_io': 'null', \ 'mode': 'raw', - \ }) + \ }) endif let $EDITOR = s:ctrlexe -endif \ No newline at end of file +endif From 8dd9dc9ce2d55c9931800e357bcfa257c047ecfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Fri, 9 Jan 2026 07:34:29 +0100 Subject: [PATCH 3/7] Port to Neovim: Handle signal sending via vim.loop.kill --- plugin/acme.vim | 61 +++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/plugin/acme.vim b/plugin/acme.vim index a9d8ac8..4aca04b 100644 --- a/plugin/acme.vim +++ b/plugin/acme.vim @@ -194,6 +194,24 @@ function s:JobStop(job) endif endfunc +function s:JobKill(job, sig) + if has('nvim') + let sig = a:sig + if type(sig) == type("") + let map = { + \ 'int': 2, + \ 'hup': 1, + \ 'term': 15, + \ 'kill': 9 + \ } + let sig = get(map, sig, 15) + endif + silent! call luaeval("vim.loop.kill(vim.fn.jobpid(_A), _B)", [a:job, sig]) + else + call job_stop(a:job, a:sig) + endif +endfunc + function s:ChanSend(job, data) if has('nvim') call chansend(a:job, a:data) @@ -870,7 +888,7 @@ endfunc function s:Scroll(topline) let v = winsaveview() - let v.topline = a:topline + v.topline = a:topline call winrestview(v) endfunc @@ -938,7 +956,7 @@ function s:RestVisual(vis) call setpos("'>", a:vis[1]) if a:vis[0][1] != 0 let v = winsaveview() - silent! exe "normal! `<".a:vis[2]."`>\" + silent! exe "normal! `<".a:vis[2]." \" call winrestview(v) endif endfunc @@ -1020,37 +1038,6 @@ function s:RightRelease(click) call s:Open(cmd, a:click, dir, w) endfunc -for m in ['', 'i'] - for n in ['', '2-', '3-', '4-'] - for c in ['Mouse', 'Drag', 'Release'] - exe m.'noremap <'.n.'Middle'.c.'> ' - exe m.'noremap <'.n.'Right'.c.'> ' - endfor - endfor - exe m.'noremap ' - exe m.'noremap ' -endfor -for n in ['', '2-', '3-', '4-'] - exe 'nnoremap <'.n.'MiddleMouse>' - \ ':call MousePress("")' - exe 'vnoremap <'.n.'MiddleMouse>' - \ ':call MousePress("v")' - exe 'nnoremap <'.n.'MiddleRelease>' - \ ':call MiddleRelease(col("."))' - exe 'nnoremap <'.n.'RightMouse>' - \ ':call MousePress("")' - exe 'vnoremap <'.n.'RightMouse>' - \ ':call MousePress("v")' - exe 'nnoremap <'.n.'RightRelease>' - \ ':call RightRelease(col("."))' -endfor -inoremap :call MousePress('') -inoremap :call MiddleRelease(col('.')) -vnoremap :call MiddleRelease(-1) -inoremap :call MousePress('') -inoremap :call RightRelease(col('.')) -vnoremap :call RightRelease(-1) - function s:Clear(b) call deletebufline(a:b, 1, "$") if has_key(s:scratch, a:b) @@ -1117,7 +1104,7 @@ endfunc function s:Signal(sig) for job in s:Jobs(bufnr()) - call job_stop(job.h, a:sig) + call s:JobKill(job.h, a:sig) endfor endfunc @@ -1297,8 +1284,8 @@ endif set completefunc=s:InsComplete -let &statusline = '%{AcmeStatusBox()}%<%{%AcmeStatusName()%}' . - \ '.%{%AcmeStatusFlags()%}%{AcmeStatusJobs()}%=%{%AcmeStatusRuler()%}' +let &statusline = '%{AcmeStatusBox()}%<%{%AcmeStatusName()%}' . + \ '%{%AcmeStatusFlags()%}%{AcmeStatusJobs()}%=%{%AcmeStatusRuler()%}' let s:ctrlexe = exepath(expand(':p:h:h').'/bin/avim') let s:ctrlrx = '' @@ -1328,4 +1315,4 @@ if s:ctrlexe != '' \ }) endif let $EDITOR = s:ctrlexe -endif +endif \ No newline at end of file From 4358e11c751f3970a7c38567ab0c7ea9101a1b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Fri, 9 Jan 2026 07:37:45 +0100 Subject: [PATCH 4/7] Port to Neovim: Initialize script-local click variables to prevent E121 errors if Release event triggers before Mouse event. --- plugin/acme.vim | 62 +++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/plugin/acme.vim b/plugin/acme.vim index 4aca04b..9e0d75b 100644 --- a/plugin/acme.vim +++ b/plugin/acme.vim @@ -1,3 +1,9 @@ +let s:click = {'winid': 0} +let s:clicksel = 0 +let s:clickwin = 0 +let s:visual = [[0,0,0,0], [0,0,0,0], ''] +let s:clickstatus = 0 + function s:Bound(min, n, max) return max([a:min, min([a:n, a:max])]) endfunc @@ -13,8 +19,8 @@ function s:FileWin(name) endfunc function s:Sel() - let text = getreg('"') - let type = getregtype('"') + let text = getreg("'") + let type = getregtype("'") let view = winsaveview() silent normal! gv""y let sel = [getreg('"'), getregtype('"')] @@ -198,12 +204,7 @@ function s:JobKill(job, sig) if has('nvim') let sig = a:sig if type(sig) == type("") - let map = { - \ 'int': 2, - \ 'hup': 1, - \ 'term': 15, - \ 'kill': 9 - \ } + let map = {'int': 2, 'hup': 1, 'term': 15, 'kill': 9} let sig = get(map, sig, 15) endif silent! call luaeval("vim.loop.kill(vim.fn.jobpid(_A), _B)", [a:job, sig]) @@ -365,7 +366,7 @@ endfunc function s:ErrorSplitPos(name) let [w, match, mod, rel] = [0, 0, '', ''] - let dir = fnamemodify(s:Path(a:name), ':h') + dir = fnamemodify(s:Path(a:name), ':h') for i in reverse(range(1, winnr('$'))) let b = winbufnr(i) let p = get(s:cwd, b, s:Path(bufname(b))) @@ -587,7 +588,7 @@ function s:Columnate(words, width) endfunc function s:ListDir() - let dir = expand('%') + dir = expand('%') if !isdirectory(dir) || !&modifiable return endif @@ -666,7 +667,7 @@ function s:Dir() endfunc function s:CtxDir() - let dir = s:Dir() + dir = s:Dir() if &buftype != '' let [t, q] = ['ing directory:? ', "[`'\"`]"] let l = searchpair('\vEnter'.t.q, '', '\vLeav'.t.q, 'nW', @@ -771,7 +772,8 @@ function s:Open(text, click, dir, win) endfunc function s:FileComplete(arg, line, pos) - let p = a:arg =~ '^[~/]' ? a:arg : s:Dir().'/'.a:arg + let p = a:arg =~ '^[~/]' ? a:arg : s:Dir().'/ +'.a:arg let p = fnamemodify(p, ':p') if a:arg =~ '[^/]$' let p = substitute(p, '/*$', '', '') @@ -909,14 +911,14 @@ function s:Fit(w, h, ...) return h endif endif - let h = 0 - let top = line('$', a:w) + 1 + h = 0 + top = line('$', a:w) + 1 while top > 1 - let h += s:FitHeight(a:w, top - 1) + h += s:FitHeight(a:w, top - 1) if h > a:h break endif - let top -= 1 + top -= 1 endwhile call timer_start(0, {_ -> \ win_execute(a:w, 'noa call s:Scroll('.top.')')}) @@ -934,8 +936,8 @@ function s:Zoom(w) break endif call win_move_statusline(win_id2win(w) - 1, winheight(w) - s) - let h -= s - let n -= 1 + h -= s + n -= 1 endfor endfunc @@ -956,7 +958,7 @@ function s:RestVisual(vis) call setpos("'>", a:vis[1]) if a:vis[0][1] != 0 let v = winsaveview() - silent! exe "normal! `<".a:vis[2]." \" + silent! exe "normal! `<".a:vis[2]."`>\" call winrestview(v) endif endfunc @@ -995,8 +997,8 @@ function s:MiddleRelease(click) let vis = s:clickmode == 'v' && (a:click <= 0 || !s:clicksel) call s:RestVisual(s:visual) let b = bufnr() - let dir = s:Dir() - let w = win_getid() + dir = s:Dir() + w = win_getid() exe win_id2win(s:clickwin).'wincmd w' if s:Receiver(b) if w != s:clickwin && s:clickmode == 'v' && a:click > 0 @@ -1032,8 +1034,8 @@ function s:RightRelease(click) let cmd = a:click <= 0 || s:clicksel ? s:Sel()[0] : expand('') let vis = s:clickmode == 'v' && (a:click <= 0 || !s:clicksel) call s:RestVisual(s:visual) - let w = win_getid() - let dir = s:CtxDir() + w = win_getid() + dir = s:CtxDir() exe win_id2win(s:clickwin).'wincmd w' call s:Open(cmd, a:click, dir, w) endfunc @@ -1074,16 +1076,16 @@ function s:BufInfo() endfunc function s:Change(b, l1, l2, lines) - let w = win_getid(s:BufWin(a:b)) + w = win_getid(s:BufWin(a:b)) if w == 0 return endif let pos = getcurpos(w) let last = line('$', w) - let l = s:Bound(1, a:l1 < 0 ? a:l1 + last + 2 : a:l1, last + 1) - let n = s:Bound(0, (a:l2 < 0 ? a:l2 + last + 2 : a:l2) - l + 1, + l = s:Bound(1, a:l1 < 0 ? a:l1 + last + 2 : a:l1, last + 1) + n = s:Bound(0, (a:l2 < 0 ? a:l2 + last + 2 : a:l2) - l + 1, \ last - l + 1) - let i = min([n, len(a:lines)]) + i = min([n, len(a:lines)]) if i > 0 call setbufline(a:b, l, a:lines[:i-1]) endif @@ -1131,7 +1133,7 @@ function s:PtyMap() endfunc function s:Pty(b) - let w = win_getid(s:BufWin(a:b)) + w = win_getid(s:BufWin(a:b)) if !has_key(s:scratch, a:b) || w == 0 return endif @@ -1179,7 +1181,7 @@ endfunc function s:CtrlRecv(ch, data) let len = strridx(a:data, "\x1e") let len += len == -1 ? 0 : len(s:ctrlrx) - let s:ctrlrx .= a:data + s:ctrlrx .= a:data if len == -1 return endif @@ -1315,4 +1317,4 @@ if s:ctrlexe != '' \ }) endif let $EDITOR = s:ctrlexe -endif \ No newline at end of file +endif From 89f333f35f90b5c4b60eb5c35078ce03d6f0f04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Fri, 9 Jan 2026 09:04:07 +0100 Subject: [PATCH 5/7] Port to Neovim: Add fallback to s:RightRelease to use getmousepos() if s:click is uninitialized, ensuring plumbing works even if RightMouse event is missed or blocked. --- plugin/acme.vim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugin/acme.vim b/plugin/acme.vim index 9e0d75b..3a7fb52 100644 --- a/plugin/acme.vim +++ b/plugin/acme.vim @@ -1011,6 +1011,14 @@ function s:MiddleRelease(click) endfunc function s:RightRelease(click) + if s:click.winid == 0 + let s:click = getmousepos() + let s:clickwin = win_getid() + let s:clickstatus = s:click.line == 0 ? win_id2win(s:click.winid) : 0 + let s:clickmode = 'n' + let s:clicksel = 0 + endif + if s:click.winid == 0 return elseif s:clickstatus != 0 From 08d3c0d6229dea4b0451616980269cbe3ea6be9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Fri, 9 Jan 2026 09:09:41 +0100 Subject: [PATCH 6/7] Port to Neovim: Add public AcmeActivate function --- plugin/acme.vim | 82 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 23 deletions(-) diff --git a/plugin/acme.vim b/plugin/acme.vim index 3a7fb52..3dec612 100644 --- a/plugin/acme.vim +++ b/plugin/acme.vim @@ -19,8 +19,8 @@ function s:FileWin(name) endfunc function s:Sel() - let text = getreg("'") - let type = getregtype("'") + let text = getreg('"') + let type = getregtype('"') let view = winsaveview() silent normal! gv""y let sel = [getreg('"'), getregtype('"')] @@ -93,7 +93,7 @@ function s:Started(job, buf, cmd) \ 'h': a:job, \ 'cmd': type(a:cmd) == type([]) ? join(a:cmd) : a:cmd, \ 'killed': 0, - \ }) + \ }) redrawstatus! endfunc @@ -294,7 +294,7 @@ function s:JobStartNvim(cmd, outb, ctxb, opts, inp) \ 'on_stderr': function('s:NvimOut'), \ 'buf': a:outb, \ 'callback': get(a:opts, 'callback', ''), - \ } + \ } if has_key(a:opts, 'cwd') let job_opts.cwd = a:opts.cwd endif @@ -322,7 +322,7 @@ function s:JobEnv(buf, dir) \ 'ACMEVIMOUTDIR': a:dir != '' ? a:dir : getcwd(), \ 'COLUMNS': 80, \ 'LINES': 24, - \ } + \ } endfunc function s:SetEnv(env) @@ -344,7 +344,7 @@ function s:JobStart(cmd, outb, ctxb, opts, inp) \ 'out_io': 'buffer', \ 'out_buf': a:outb, \ 'out_msg': 0, - \ } + \ } call extend(opts, a:opts) let env = s:SetEnv(s:JobEnv(a:outb, get(a:opts, 'cwd', ''))) let job = job_start(s:Argv(a:cmd), opts) @@ -366,7 +366,7 @@ endfunc function s:ErrorSplitPos(name) let [w, match, mod, rel] = [0, 0, '', ''] - dir = fnamemodify(s:Path(a:name), ':h') + let dir = fnamemodify(s:Path(a:name), ':h') for i in reverse(range(1, winnr('$'))) let b = winbufnr(i) let p = get(s:cwd, b, s:Path(bufname(b))) @@ -534,7 +534,7 @@ function s:ScratchExec(cmd, dir, inp, title) let opts = { \ 'callback': function('s:ScratchCb', [b]), \ 'in_io': 'pipe', - \ } + \ } if a:dir != '' let opts.cwd = a:dir endif @@ -549,7 +549,7 @@ function s:Exec(cmd) \ 'err_io': 'null', \ 'in_io': 'null', \ 'out_io': 'null', - \ }) + \ }) endif endfunc @@ -588,7 +588,7 @@ function s:Columnate(words, width) endfunc function s:ListDir() - dir = expand('%') + let dir = expand('%') if !isdirectory(dir) || !&modifiable return endif @@ -667,7 +667,7 @@ function s:Dir() endfunc function s:CtxDir() - dir = s:Dir() + let dir = s:Dir() if &buftype != '' let [t, q] = ['ing directory:? ', "[`'\"`]"] let l = searchpair('\vEnter'.t.q, '', '\vLeav'.t.q, 'nW', @@ -772,8 +772,7 @@ function s:Open(text, click, dir, win) endfunc function s:FileComplete(arg, line, pos) - let p = a:arg =~ '^[~/]' ? a:arg : s:Dir().'/ -'.a:arg + let p = a:arg =~ '^[~/]' ? a:arg : s:Dir().'/'.a:arg let p = fnamemodify(p, ':p') if a:arg =~ '[^/]$' let p = substitute(p, '/*$', '', '') @@ -911,14 +910,14 @@ function s:Fit(w, h, ...) return h endif endif - h = 0 - top = line('$', a:w) + 1 + let h = 0 + let top = line('$', a:w) + 1 while top > 1 - h += s:FitHeight(a:w, top - 1) + let h += s:FitHeight(a:w, top - 1) if h > a:h break endif - top -= 1 + let top -= 1 endwhile call timer_start(0, {_ -> \ win_execute(a:w, 'noa call s:Scroll('.top.')')}) @@ -1048,6 +1047,43 @@ function s:RightRelease(click) call s:Open(cmd, a:click, dir, w) endfunc +function AcmeActivate(mode) + let text = a:mode == 'v' ? trim(s:Sel()[0], "\r\n", 2) : getline('.') + let click = a:mode == 'v' ? -1 : col('.') + call s:Open(text, click, s:CtxDir(), win_getid()) +endfunc + +for m in ['', 'i'] + for n in ['', '2-', '3-', '4-'] + for c in ['Mouse', 'Drag', 'Release'] + exe m.'noremap <'.n.'Middle'.c.'> ' + exe m.'noremap <'.n.'Right'.c.'> ' + endfor + endfor + exe m.'noremap ' + exe m.'noremap ' +endfor +for n in ['', '2-', '3-', '4-'] + exe 'nnoremap <'.n.'MiddleMouse>' + \ ':call MousePress("")' + exe 'vnoremap <'.n.'MiddleMouse>' + \ ':call MousePress("v")' + exe 'nnoremap <'.n.'MiddleRelease>' + \ ':call MiddleRelease(col("."))' + exe 'nnoremap <'.n.'RightMouse>' + \ ':call MousePress("")' + exe 'vnoremap <'.n.'RightMouse>' + \ ':call MousePress("v")' + exe 'nnoremap <'.n.'RightRelease>' + \ ':call RightRelease(col("."))' +endfor +inoremap :call MousePress('') +inoremap :call MiddleRelease(col('.')) +vnoremap :call MiddleRelease(-1) +inoremap :call MousePress('') +inoremap :call RightRelease(col('.')) +vnoremap :call RightRelease(-1) + function s:Clear(b) call deletebufline(a:b, 1, "$") if has_key(s:scratch, a:b) @@ -1084,7 +1120,7 @@ function s:BufInfo() endfunc function s:Change(b, l1, l2, lines) - w = win_getid(s:BufWin(a:b)) + let w = win_getid(s:BufWin(a:b)) if w == 0 return endif @@ -1141,7 +1177,7 @@ function s:PtyMap() endfunc function s:Pty(b) - w = win_getid(s:BufWin(a:b)) + let w = win_getid(s:BufWin(a:b)) if !has_key(s:scratch, a:b) || w == 0 return endif @@ -1189,7 +1225,7 @@ endfunc function s:CtrlRecv(ch, data) let len = strridx(a:data, "\x1e") let len += len == -1 ? 0 : len(s:ctrlrx) - s:ctrlrx .= a:data + let s:ctrlrx .= a:data if len == -1 return endif @@ -1316,13 +1352,13 @@ if s:ctrlexe != '' let s:ctrl = jobstart([s:ctrlexe], { \ 'on_stdout': function('s:NvimCtrlRecv'), \ 'rpc': 0, - \ }) + \ }) else let s:ctrl = job_start([s:ctrlexe], { \ 'callback': 's:CtrlRecv', \ 'err_io': 'null', \ 'mode': 'raw', - \ }) + \ }) endif let $EDITOR = s:ctrlexe -endif +endif \ No newline at end of file From f92ec3b5b39be25c58d7587de992960368dcc8d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Thu, 8 Jan 2026 18:11:08 +0100 Subject: [PATCH 7/7] fix: readdir() has only two parameters, not three --- plugin/acme.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/acme.vim b/plugin/acme.vim index 3dec612..b7a8351 100644 --- a/plugin/acme.vim +++ b/plugin/acme.vim @@ -592,8 +592,8 @@ function s:ListDir() if !isdirectory(dir) || !&modifiable return endif - let lst = ['..'] + readdir(dir, 1, {'sort': 'collate'}) - call map(lst, 'isdirectory(dir."/ ".v:val) ? v:val."/" : v:val') + let lst = ['..'] + readdir(dir, 1) + call map(lst, 'isdirectory(dir."/".v:val) ? v:val."/" : v:val') let width = s:BufWidth(bufnr()) let lst = s:Columnate(lst, width) call setline(1, lst)