if vim.g.loaded_guicursor then return end vim.g.loaded_guicursor = true local mode_lookup = { normal = "n-v", insert = "i-c-ci-ve", replace = "r-cr", operator = "o", showmatch = "sm", } local type_lookup = { block = "block", vertical = "ver", horizontal = "hor", } local function validate(mode, opts) vim.validate("mode", mode, function(v) return vim.tbl_contains({ "normal", "insert", "replace", "operator", "showmatch" }, v) end, "valid mode") vim.validate("opts", opts, function(v) vim.validate("type", v.type, function(t) return vim.tbl_contains({ "block", "vertical", "horizontal" }, t) end, "valid type") if v.type ~= "block" then vim.validate("size", v.size, function(s) return type(s) == "number" end, "valid size with type ~= block") end vim.validate("animate", v.animate, function(anim) vim.validate("wait", anim.wait, "number") vim.validate("on", anim.on, "number") vim.validate("off", anim.off, "number") return true end, true, "valid animation") return true end, "valid opts") end vim.once(function() if not vim.g.guicursor_config or vim.tbl_isempty(vim.g.guicursor_config) then return end local guicursorset = vim .iter(pairs(vim.g.guicursor_config)) :map(function(mode, opts) validate(mode, opts) local s = string.format( "%s:%s", mode_lookup[mode], opts.type ~= "block" and string.format("%s%d", type_lookup[opts.type], opts.size) or type_lookup[opts.type] ) if opts.animate then local anim = opts.animate local anim_str = string.format("blinkwait%d-blinkon%d-blinkoff%d", anim.wait, anim.on, anim.off) s = s .. "-" .. anim_str end return s end) :totable() vim.opt.guicursor = table.concat(guicursorset, ",") .. ",a:Cursor/lCursor" end)