diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index ce69a22e49..158e366a37 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -1277,13 +1277,13 @@ local get_context_state = function(context) -- Do not override already set state and fall back to `vim.NIL` for -- state `nil` values (which still needs restoring later) - res[sc][name] = res[sc][name] or vim[sc][name] or vim.NIL + res[sc][name] = vim.F.if_nil(res[sc][name], vim[sc][name], vim.NIL) -- Always track global option value to properly restore later. -- This matters for at least `o` and `wo` (which might set either/both -- local and global option values). - if sc ~= 'env' then - res.go[name] = res.go[name] or vim.go[name] + if sc ~= 'env' and res.go[name] == nil then + res.go[name] = vim.go[name] end end end diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 5f3be02048..1571269c0b 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -529,7 +529,7 @@ static void chan_close_on_err(Channel *channel, char *msg, int loglevel) for (size_t i = 0; i < kv_size(channel->rpc.call_stack); i++) { ChannelCallFrame *frame = kv_A(channel->rpc.call_stack, i); if (frame->returned) { - continue; // Don't overwrite an already received result. + continue; // Don't overwrite an already received result. #24214 } frame->returned = true; frame->errored = true; diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 95435509d6..4db1ce4d53 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -396,7 +396,7 @@ describe('server -> client', function() eq({}, api.nvim_get_chan_info(id)) -- Channel is closed. end) - it('response works with channel closed just after response', function() + it('response works with channel closed just after response #24214', function() local id = start_server_and_client() eq( 'RESPONSE', diff --git a/test/functional/lua/with_spec.lua b/test/functional/lua/with_spec.lua index 92e798e7f3..5c5217e5c7 100644 --- a/test/functional/lua/with_spec.lua +++ b/test/functional/lua/with_spec.lua @@ -71,6 +71,11 @@ describe('vim._with', function() vim.bo[cur_buf].undolevels = 250 vim.go.undolevels = 500 + -- 'autoread' is global or local to buffer (global-local) and boolean + vim.bo[other_buf].autoread = false + vim.bo[cur_buf].autoread = false + vim.go.autoread = true + _G.get_state = function() return { bo = { @@ -78,10 +83,13 @@ describe('vim._with', function() cms_other = vim.bo[other_buf].commentstring, ul_cur = vim.bo[cur_buf].undolevels, ul_other = vim.bo[other_buf].undolevels, + ar_cur = vim.bo[cur_buf].autoread, + ar_other = vim.bo[other_buf].autoread, }, go = { cms = vim.go.commentstring, ul = vim.go.undolevels, + ar = vim.go.autoread, }, } end @@ -90,7 +98,7 @@ describe('vim._with', function() it('works', function() local out = exec_lua [[ - local context = { bo = { commentstring = '-- %s', undolevels = 0 } } + local context = { bo = { commentstring = '-- %s', undolevels = 0, autoread = true } } local before = get_state() local inner = vim._with(context, function() @@ -102,15 +110,22 @@ describe('vim._with', function() ]] eq({ - bo = { cms_cur = '-- %s', cms_other = '## %s', ul_cur = 0, ul_other = 100 }, - go = { cms = '$$ %s', ul = 500 }, + bo = { + cms_cur = '-- %s', + cms_other = '## %s', + ul_cur = 0, + ul_other = 100, + ar_cur = true, + ar_other = false, + }, + go = { cms = '$$ %s', ul = 500, ar = true }, }, out.inner) eq(out.before, out.after) end) it('sets options in `buf` context', function() local out = exec_lua [[ - local context = { buf = other_buf, bo = { commentstring = '-- %s', undolevels = 0 } } + local context = { buf = other_buf, bo = { commentstring = '-- %s', undolevels = 0, autoread = true } } local before = get_state() local inner = vim._with(context, function() @@ -122,8 +137,15 @@ describe('vim._with', function() ]] eq({ - bo = { cms_cur = '// %s', cms_other = '-- %s', ul_cur = 250, ul_other = 0 }, - go = { cms = '$$ %s', ul = 500 }, + bo = { + cms_cur = '// %s', + cms_other = '-- %s', + ul_cur = 250, + ul_other = 0, + ar_cur = false, + ar_other = true, + }, + go = { cms = '$$ %s', ul = 500, ar = true }, }, out.inner) eq(out.before, out.after) end) @@ -143,12 +165,26 @@ describe('vim._with', function() ]] eq({ - bo = { cms_cur = '!! %s', cms_other = '## %s', ul_cur = 750, ul_other = 100 }, - go = { cms = '$$ %s', ul = 500 }, + bo = { + cms_cur = '!! %s', + cms_other = '## %s', + ul_cur = 750, + ul_other = 100, + ar_cur = false, + ar_other = false, + }, + go = { cms = '$$ %s', ul = 500, ar = true }, }, out.inner) eq({ - bo = { cms_cur = '// %s', cms_other = '## %s', ul_cur = 750, ul_other = 100 }, - go = { cms = '$$ %s', ul = 500 }, + bo = { + cms_cur = '// %s', + cms_other = '## %s', + ul_cur = 750, + ul_other = 100, + ar_cur = false, + ar_other = false, + }, + go = { cms = '$$ %s', ul = 500, ar = true }, }, out.after) end) @@ -164,9 +200,9 @@ describe('vim._with', function() it('can be nested', function() local out = exec_lua [[ local before, before_inner, after_inner = get_state(), nil, nil - vim._with({ bo = { commentstring = '-- %s', undolevels = 0 } }, function() + vim._with({ bo = { commentstring = '-- %s', undolevels = 0, autoread = true } }, function() before_inner = get_state() - inner = vim._with({ bo = { commentstring = '!! %s' } }, get_state) + inner = vim._with({ bo = { commentstring = '!! %s', autoread = false } }, get_state) after_inner = get_state() end) return { @@ -177,6 +213,7 @@ describe('vim._with', function() ]] eq('!! %s', out.inner.bo.cms_cur) eq(0, out.inner.bo.ul_cur) + eq(false, out.inner.bo.ar_cur) eq(out.before_inner, out.after_inner) eq(out.before, out.after) end) @@ -404,6 +441,7 @@ describe('vim._with', function() vim.wo.winblend = 25 vim.go.winblend = 50 vim.go.langmap = 'xy,yx' + vim.go.confirm = false _G.get_state = function() return { @@ -413,6 +451,7 @@ describe('vim._with', function() cms = vim.go.commentstring, winbl = vim.go.winblend, lmap = vim.go.langmap, + cf = vim.go.confirm, }, } end @@ -422,7 +461,7 @@ describe('vim._with', function() it('works', function() local out = exec_lua [[ local context = { - go = { commentstring = '-- %s', winblend = 75, langmap = 'ab,ba' }, + go = { commentstring = '-- %s', winblend = 75, langmap = 'ab,ba', cf = true }, } local before = get_state() local inner = vim._with(context, get_state) @@ -432,7 +471,7 @@ describe('vim._with', function() eq({ bo = { cms = '## %s' }, wo = { winbl = 25 }, - go = { cms = '-- %s', winbl = 75, lmap = 'ab,ba' }, + go = { cms = '-- %s', winbl = 75, lmap = 'ab,ba', cf = true }, }, out.inner) eq(out.before, out.after) end) @@ -467,12 +506,12 @@ describe('vim._with', function() eq({ bo = { cms = '## %s' }, wo = { winbl = 25 }, - go = { cms = '!! %s', winbl = 75, lmap = 'uv,vu' }, + go = { cms = '!! %s', winbl = 75, lmap = 'uv,vu', cf = false }, }, out.inner) eq({ bo = { cms = '## %s' }, wo = { winbl = 25 }, - go = { cms = '!! %s', winbl = 75, lmap = 'xy,yx' }, + go = { cms = '!! %s', winbl = 75, lmap = 'xy,yx', cf = false }, }, out.after) end) @@ -806,6 +845,7 @@ describe('vim._with', function() vim.go.winblend = 50 vim.go.langmap = 'xy,yx' + vim.go.confirm = false _G.get_state = function() return { @@ -827,6 +867,7 @@ describe('vim._with', function() ve = vim.go.virtualedit, winbl = vim.go.winblend, lmap = vim.go.langmap, + cf = vim.go.confirm, }, } end @@ -842,6 +883,7 @@ describe('vim._with', function() virtualedit = 'all', winblend = 75, langmap = 'ab,ba', + confirm = true, }, } @@ -861,7 +903,7 @@ describe('vim._with', function() eq({ bo = { cms_cur = '-- %s', cms_other = '## %s', ul_cur = -123456, ul_other = 100 }, wo = { ve_cur = 'all', ve_other = 'block', winbl_cur = 75, winbl_other = 10 }, - go = { cms = '-- %s', ul = 0, ve = 'all', winbl = 75, lmap = 'ab,ba' }, + go = { cms = '-- %s', ul = 0, ve = 'all', winbl = 75, lmap = 'ab,ba', cf = true }, }, out.inner) eq(out.before, out.after) end) @@ -886,7 +928,7 @@ describe('vim._with', function() -- to 50. It seems to be equal to 0 because `context.buf` uses -- `aucmd_prepbuf` C approach which has no guarantees about window or -- window option values inside context. - go = { cms = '-- %s', ul = 0, ve = 'none', winbl = 0, lmap = 'xy,yx' }, + go = { cms = '-- %s', ul = 0, ve = 'none', winbl = 0, lmap = 'xy,yx', cf = false }, }, out.inner) eq(out.before, out.after) end) @@ -907,7 +949,7 @@ describe('vim._with', function() eq({ bo = { cms_cur = '// %s', cms_other = '## %s', ul_cur = 250, ul_other = 100 }, wo = { winbl_cur = 25, winbl_other = 75, ve_cur = 'insert', ve_other = 'all' }, - go = { cms = '$$ %s', ul = 500, winbl = 75, ve = 'all', lmap = 'xy,yx' }, + go = { cms = '$$ %s', ul = 500, winbl = 75, ve = 'all', lmap = 'xy,yx', cf = false }, }, out.inner) eq(out.before, out.after) end) @@ -934,12 +976,12 @@ describe('vim._with', function() eq({ bo = { cms_cur = '!! %s', cms_other = '## %s', ul_cur = -123456, ul_other = 100 }, wo = { ve_cur = 'onemore', ve_other = 'block', winbl_cur = 99, winbl_other = 10 }, - go = { cms = '!! %s', ul = 750, ve = 'onemore', winbl = 99, lmap = 'uv,vu' }, + go = { cms = '!! %s', ul = 750, ve = 'onemore', winbl = 99, lmap = 'uv,vu', cf = false }, }, out.inner) eq({ bo = { cms_cur = '!! %s', cms_other = '## %s', ul_cur = 250, ul_other = 100 }, wo = { ve_cur = 'onemore', ve_other = 'block', winbl_cur = 25, winbl_other = 10 }, - go = { cms = '!! %s', ul = 500, ve = 'onemore', winbl = 50, lmap = 'xy,yx' }, + go = { cms = '!! %s', ul = 500, ve = 'onemore', winbl = 50, lmap = 'xy,yx', cf = false }, }, out.after) end) @@ -1236,6 +1278,11 @@ describe('vim._with', function() vim.wo[cur_win].winblend = 25 vim.go.winblend = 50 + -- 'number' is local to window and boolean + vim.wo[other_win].number = false + vim.wo[cur_win].number = false + vim.go.number = true + _G.get_state = function() return { wo = { @@ -1243,10 +1290,13 @@ describe('vim._with', function() ve_other = vim.wo[other_win].virtualedit, winbl_cur = vim.wo[cur_win].winblend, winbl_other = vim.wo[other_win].winblend, + nu_cur = vim.wo[cur_win].number, + nu_other = vim.wo[other_win].number, }, go = { ve = vim.go.virtualedit, winbl = vim.go.winblend, + nu = vim.go.number, }, } end @@ -1255,7 +1305,7 @@ describe('vim._with', function() it('works', function() local out = exec_lua [[ - local context = { wo = { virtualedit = 'all', winblend = 75 } } + local context = { wo = { virtualedit = 'all', winblend = 75, number = true } } local before = get_state() local inner = vim._with(context, function() @@ -1267,15 +1317,22 @@ describe('vim._with', function() ]] eq({ - wo = { ve_cur = 'all', ve_other = 'block', winbl_cur = 75, winbl_other = 10 }, - go = { ve = 'none', winbl = 75 }, + wo = { + ve_cur = 'all', + ve_other = 'block', + winbl_cur = 75, + winbl_other = 10, + nu_cur = true, + nu_other = false, + }, + go = { ve = 'none', winbl = 75, nu = true }, }, out.inner) eq(out.before, out.after) end) it('sets options in `win` context', function() local out = exec_lua [[ - local context = { win = other_win, wo = { virtualedit = 'all', winblend = 75 } } + local context = { win = other_win, wo = { virtualedit = 'all', winblend = 75, number = true } } local before = get_state() local inner = vim._with(context, function() @@ -1287,8 +1344,15 @@ describe('vim._with', function() ]] eq({ - wo = { ve_cur = 'insert', ve_other = 'all', winbl_cur = 25, winbl_other = 75 }, - go = { ve = 'none', winbl = 75 }, + wo = { + ve_cur = 'insert', + ve_other = 'all', + winbl_cur = 25, + winbl_other = 75, + nu_cur = false, + nu_other = true, + }, + go = { ve = 'none', winbl = 75, nu = true }, }, out.inner) eq(out.before, out.after) end) @@ -1308,12 +1372,26 @@ describe('vim._with', function() ]] eq({ - wo = { ve_cur = 'onemore', ve_other = 'block', winbl_cur = 99, winbl_other = 10 }, - go = { ve = 'none', winbl = 99 }, + wo = { + ve_cur = 'onemore', + ve_other = 'block', + winbl_cur = 99, + winbl_other = 10, + nu_cur = false, + nu_other = false, + }, + go = { ve = 'none', winbl = 99, nu = true }, }, out.inner) eq({ - wo = { ve_cur = 'onemore', ve_other = 'block', winbl_cur = 25, winbl_other = 10 }, - go = { ve = 'none', winbl = 50 }, + wo = { + ve_cur = 'onemore', + ve_other = 'block', + winbl_cur = 25, + winbl_other = 10, + nu_cur = false, + nu_other = false, + }, + go = { ve = 'none', winbl = 50, nu = true }, }, out.after) end) @@ -1329,9 +1407,9 @@ describe('vim._with', function() it('can be nested', function() local out = exec_lua [[ local before, before_inner, after_inner = get_state(), nil, nil - vim._with({ wo = { winblend = 75, virtualedit = 'all' } }, function() + vim._with({ wo = { winblend = 75, virtualedit = 'all', number = true } }, function() before_inner = get_state() - inner = vim._with({ wo = { winblend = 99 } }, get_state) + inner = vim._with({ wo = { winblend = 99, number = false } }, get_state) after_inner = get_state() end) return { @@ -1342,6 +1420,7 @@ describe('vim._with', function() ]] eq(99, out.inner.wo.winbl_cur) eq('all', out.inner.wo.ve_cur) + eq(false, out.inner.wo.nu_cur) eq(out.before_inner, out.after_inner) eq(out.before, out.after) end)