feat(picker): open contest picker directly from :CP <platform>

Problem: `:CP codechef` (platform with no contest) returned a "too few
arguments" error, forcing users to type `:CP pick` separately.

Solution: When a platform name is given with no contest, parse it as a
`pick` action with the platform pre-selected, skipping the platform
selection step in the picker UI.
This commit is contained in:
Barrett Ruth 2026-03-06 23:02:40 -05:00
parent 1f0414de8e
commit 645417f86b
Signed by: barrett
GPG key ID: A6C96C9349D2FC81
4 changed files with 28 additions and 15 deletions

View file

@ -257,10 +257,7 @@ local function parse_command(args)
if vim.tbl_contains(platforms, first) then if vim.tbl_contains(platforms, first) then
if #args == 1 then if #args == 1 then
return { return { type = 'action', action = 'pick', requires_context = false, platform = first }
type = 'error',
message = 'Too few arguments - specify a contest.',
}
elseif #args == 2 then elseif #args == 2 then
if args[2] == 'login' or args[2] == 'logout' or args[2] == 'signup' then if args[2] == 'login' or args[2] == 'logout' or args[2] == 'signup' then
return { type = 'action', action = args[2], requires_context = false, platform = first } return { type = 'action', action = args[2], requires_context = false, platform = first }
@ -362,6 +359,7 @@ local function check_platform_enabled(platform)
end end
--- Core logic for handling `:CP ...` commands --- Core logic for handling `:CP ...` commands
---@param opts { fargs: string[] }
---@return nil ---@return nil
function M.handle_command(opts) function M.handle_command(opts)
local cmd = parse_command(opts.fargs) local cmd = parse_command(opts.fargs)
@ -400,7 +398,7 @@ function M.handle_command(opts)
setup.navigate_problem(-1, cmd.language) setup.navigate_problem(-1, cmd.language)
elseif cmd.action == 'pick' then elseif cmd.action == 'pick' then
local picker = require('cp.commands.picker') local picker = require('cp.commands.picker')
picker.handle_pick_action(cmd.language) picker.handle_pick_action(cmd.language, cmd.platform)
elseif cmd.action == 'edit' then elseif cmd.action == 'edit' then
local edit = require('cp.ui.edit') local edit = require('cp.ui.edit')
edit.toggle_edit(cmd.test_index) edit.toggle_edit(cmd.test_index)

View file

@ -5,8 +5,9 @@ local logger = require('cp.log')
--- Dispatch `:CP pick` to appropriate picker --- Dispatch `:CP pick` to appropriate picker
---@param language? string ---@param language? string
---@param platform? string
---@return nil ---@return nil
function M.handle_pick_action(language) function M.handle_pick_action(language, platform)
local config = config_module.get_config() local config = config_module.get_config()
if not (config.ui and config.ui.picker) then if not (config.ui and config.ui.picker) then
@ -54,7 +55,7 @@ function M.handle_pick_action(language)
picker = fzf_picker picker = fzf_picker
end end
picker.pick(language) picker.pick(language, platform)
end end
return M return M

View file

@ -58,11 +58,18 @@ local function contest_picker(platform, refresh, language)
}) })
end end
function M.pick(language) ---@param language? string
---@param platform? string
function M.pick(language, platform)
if platform then
contest_picker(platform, false, language)
return
end
local fzf = require('fzf-lua') local fzf = require('fzf-lua')
local platforms = picker_utils.get_platforms() local platforms = picker_utils.get_platforms()
local entries = vim.tbl_map(function(platform) local entries = vim.tbl_map(function(p)
return platform.display_name return p.display_name
end, platforms) end, platforms)
return fzf.fzf_exec(entries, { return fzf.fzf_exec(entries, {
@ -74,16 +81,16 @@ function M.pick(language)
end end
local selected_name = selected[1] local selected_name = selected[1]
local platform = nil local found = nil
for _, p in ipairs(platforms) do for _, p in ipairs(platforms) do
if p.display_name == selected_name then if p.display_name == selected_name then
platform = p found = p
break break
end end
end end
if platform then if found then
contest_picker(platform.id, false, language) contest_picker(found.id, false, language)
end end
end, end,
}, },

View file

@ -64,7 +64,14 @@ local function contest_picker(opts, platform, refresh, language)
:find() :find()
end end
function M.pick(language) ---@param language? string
---@param platform? string
function M.pick(language, platform)
if platform then
contest_picker({}, platform, false, language)
return
end
local opts = {} local opts = {}
local platforms = picker_utils.get_platforms() local platforms = picker_utils.get_platforms()