From 59dbca9b0c2eb12b7cd4432407c5bff6a1b32228 Mon Sep 17 00:00:00 2001 From: glepnir Date: Sat, 11 Jul 2026 08:34:08 +0800 Subject: [PATCH] fix(api): nvim_cmd() "args" type too narrow #40670 Problem: nvim_cmd() accepts number/boolean in args and converts them to strings, but the keyset declares ArrayOf(String). Solution: use ArrayOf(Union(Integer, String, Boolean)) and wrap union types in parens when generating array annotations. --- runtime/lua/vim/_meta/api_keysets.gen.lua | 2 +- src/gen/api_types.lua | 4 ++++ src/nvim/api/keysets_defs.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/runtime/lua/vim/_meta/api_keysets.gen.lua b/runtime/lua/vim/_meta/api_keysets.gen.lua index 2300e58351..dd14260893 100644 --- a/runtime/lua/vim/_meta/api_keysets.gen.lua +++ b/runtime/lua/vim/_meta/api_keysets.gen.lua @@ -26,7 +26,7 @@ error('Cannot require a meta file') --- @class vim.api.keyset.cmd --- @field addr? "line"|"arg"|"buf"|"load"|"win"|"tab"|"qf"|"none"|"?" ---- @field args? string[] +--- @field args? (integer|string|boolean)[] --- @field bang? boolean --- @field cmd? string --- @field count? integer diff --git a/src/gen/api_types.lua b/src/gen/api_types.lua index 4b9584ab29..0bcbda1949 100644 --- a/src/gen/api_types.lua +++ b/src/gen/api_types.lua @@ -37,6 +37,10 @@ local function api_type(t) if count then return ('[%s]'):format(ty:rep(count, ', ')) else + -- "foo|bar" => "(foo|bar)" + if ty:find('|', 1, true) and not vim.startswith(ty, '[') then + ty = ('(%s)'):format(ty) + end return ty .. '[]' end elseif container == 'Dict' or container == 'DictAs' then diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h index bab261ba7e..2474f5ef3a 100644 --- a/src/nvim/api/keysets_defs.h +++ b/src/nvim/api/keysets_defs.h @@ -314,7 +314,7 @@ typedef struct { Integer count; String reg; Boolean bang; - ArrayOf(String) args; + ArrayOf(Union(Integer, String, Boolean)) args; DictAs(cmd__magic) magic; DictAs(cmd__mods) mods; Union(Integer, Enum("?", "+", "*")) nargs;