From c14d9f330f8c397d5cff528992607af278dd814e Mon Sep 17 00:00:00 2001 From: Vladimir Romashchenko <52473614+eaglesemanation@users.noreply.github.com> Date: Thu, 5 Oct 2023 23:52:19 -0400 Subject: [PATCH] feat: namedEnum parameter type (#217) * Add namedEnum parameter * fix: remove editorconfig * refactor: display value in virtual text * lint: styling and type errors * fix: error handling for mixed enum types * Rollback to value default --------- Co-authored-by: Steven Arcangeli --- lua/overseer/form/init.lua | 15 +++++++++-- lua/overseer/form/utils.lua | 38 +++++++++++++++++++++++---- lua/overseer/template/vscode/init.lua | 18 +++++++++++-- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/lua/overseer/form/init.lua b/lua/overseer/form/init.lua index 102969e1..f29a4a4a 100644 --- a/lua/overseer/form/init.lua +++ b/lua/overseer/form/init.lua @@ -312,13 +312,24 @@ function Builder:on_cursor_move() cur[2] = name_end end local schema = self.schema[name] + local vtext = {} + if schema.type == "namedEnum" then + local value = schema.choices[text] + if value then + table.insert(vtext, { string.format("[%s] ", value), "Comment" }) + end + end if schema.desc then + table.insert(vtext, { schema.desc, "Comment" }) + end + if not vim.tbl_isempty(vtext) then vim.api.nvim_buf_set_extmark(self.bufnr, ns, cur[1] - 1, 0, { - virt_text = { { schema.desc, "Comment" } }, + virt_text = vtext, }) end local completion_schema = schema.subtype and schema.subtype or schema - local choices = completion_schema.type == "boolean" and { "true", "false" } + local choices = (completion_schema.type == "boolean" and { "true", "false" }) + or (completion_schema.type == "namedEnum" and vim.tbl_keys(completion_schema.choices)) or completion_schema.choices vim.api.nvim_buf_set_var(0, "overseer_choices", choices) end diff --git a/lua/overseer/form/utils.lua b/lua/overseer/form/utils.lua index d381b731..157914f2 100644 --- a/lua/overseer/form/utils.lua +++ b/lua/overseer/form/utils.lua @@ -4,7 +4,7 @@ local log = require("overseer.log") local util = require("overseer.util") local M = {} ----@alias overseer.Param overseer.StringParam|overseer.BoolParam|overseer.NumberParam|overseer.IntParam|overseer.ListParam|overseer.EnumParam|overseer.OpaqueParam +---@alias overseer.Param overseer.StringParam|overseer.BoolParam|overseer.NumberParam|overseer.IntParam|overseer.ListParam|overseer.EnumParam|overseer.NamedEnumParam|overseer.OpaqueParam ---@class overseer.BaseParam ---@field name? string @@ -29,22 +29,27 @@ local M = {} ---@field default? number ---@class overseer.IntParam : overseer.BaseParam ----@field type? "integer" +---@field type "integer" ---@field default? number ---@class overseer.ListParam : overseer.BaseParam ----@field type? "list" +---@field type "list" ---@field subtype? overseer.Param ---@field delimiter? string ---@field default? table ---@class overseer.EnumParam : overseer.BaseParam ----@field type? "enum" +---@field type "enum" ---@field default? string ---@field choices string[] +---@class overseer.NamedEnumParam : overseer.BaseParam +---@field type "namedEnum" +---@field default? string +---@field choices? table + ---@class overseer.OpaqueParam : overseer.BaseParam ----@field type? "opaque" +---@field type "opaque" ---@field default? any local default_schema = { @@ -89,6 +94,15 @@ M.render_value = function(schema, value) end if schema.type == "opaque" then return "" + elseif schema.type == "namedEnum" then + local label + for k, v in pairs(schema.choices) do + if v == value then + label = k + break + end + end + return label or value elseif type(value) == "table" then local rendered_values = {} for _, v in ipairs(value) do @@ -120,6 +134,8 @@ local function validate_type(schema, value) return true elseif ptype == "enum" then return vim.tbl_contains(schema.choices, value) + elseif ptype == "namedEnum" then + return vim.tbl_contains(vim.tbl_values(schema.choices), value) elseif ptype == "list" then return type(value) == "table" and vim.tbl_islist(value) elseif ptype == "number" then @@ -199,6 +215,18 @@ M.parse_value = function(schema, value) end end return best ~= nil, best + elseif schema.type == "namedEnum" then + local key = "^" .. value:lower() + local best + ---@cast schema overseer.NamedEnumParam + for k, v in pairs(schema.choices) do + if k == value then + return true, v + elseif k:lower():match(key) then + best = v + end + end + return best ~= nil, best elseif schema.type == "number" then local num = tonumber(value) if num then diff --git a/lua/overseer/template/vscode/init.lua b/lua/overseer/template/vscode/init.lua index 7d031955..85ec72ad 100644 --- a/lua/overseer/template/vscode/init.lua +++ b/lua/overseer/template/vscode/init.lua @@ -19,17 +19,31 @@ local function extract_params(params, str, inputs) if schema then if schema.type == "pickString" then local choices = {} + local paramType = nil for _, v in ipairs(schema.options) do + local choiceType if type(v) == "table" then - table.insert(choices, v.value) + choiceType = "namedEnum" + -- NOTE: There is an assumption that labels are unique + -- VSCode does not seem to require that, but it's too much of a hassle to deal with it + choices[v.label] = v.value else + choiceType = "enum" table.insert(choices, v) end + + if paramType == nil or choiceType == paramType then + paramType = choiceType + else + log.error("VS Code task input %s mixes labeled and unlabeled options", name) + break + end end + params[name] = { desc = schema.desc, default = schema.default, - type = "enum", + type = paramType, choices = choices, } elseif schema.type == "promptString" then