如何为vim.api.nvim_create_user_command传参执行mproc相关bash命令?
问题解决:在Neovim中通过传参命令控制mproc后台服务
背景与现有实现
我使用server模式的mproc在后台启动了docker、red、blue、green四个项目依赖服务,mproc服务端监听127.0.0.1:4050。目前已经通过以下Neovim配置实现了单个命令控制服务:
local ECP_SERVICE_CODE = { DOCKER = 0, RED = 1, BLUE = 2, GREEN = 3, } local MPROC_CMDS = { RESTART = "restart", KILL = "kill" } function EcpMproc(service, command) return [[!mprocs --server 127.0.0.1:4050 --ctl '{c: batch, cmds:[{c: select-proc, index: ]] .. tostring(service) .. [[}, {c: ]] .. tostring(command) .. [[-proc }, {c: select-proc, index: 0}]}'<cr>]] end vim.api.nvim_create_user_command("ColorsRedServiceKill", EcpMproc(ECP_SERVICE_CODE.RED, MPROC_CMDS.KILL), {}) vim.api.nvim_create_user_command("ColorsRedServiceRestart", EcpMproc(ECP_SERVICE_CODE.RED, MPROC_CMDS.RESTART), {}) vim.api.nvim_create_user_command("ColorsBlueServiceKill", EcpMproc(ECP_SERVICE_CODE.BLUE, MPROC_CMDS.KILL), {}) vim.api.nvim_create_user_command("ColorsBlueServiceRestart", EcpMproc(ECP_SERVICE_CODE.BLUE, MPROC_CMDS.RESTART), {}) vim.api.nvim_create_user_command("ColorsGreenServiceKill", EcpMproc(ECP_SERVICE_CODE.GREEN, MPROC_CMDS.KILL), {}) vim.api.nvim_create_user_command("ColorsGreenServiceRestart", EcpMproc(ECP_SERVICE_CODE.GREEN, MPROC_CMDS.RESTART), {})
现在可以通过:ColorsRedServiceKill<CR>或:ColorsBlueServiceRestart<CR>这类命令与mproc交互,但希望改成更简洁的传参方式,比如:Colors blue restart或:Colors 1 restart来控制服务。
原尝试代码的问题
之前的尝试代码未生效,核心问题有两点:
- Neovim用户命令的回调函数不能直接返回Ex命令字符串,需要主动调用
vim.cmd()执行命令 - 未处理服务名称(如
blue)到对应索引的映射,也没有参数校验逻辑
修正后的实现方案
以下是完整的修正代码,支持字符串或数字指定服务,同时加入参数校验和补全功能:
local ECP_SERVICE_CODE = { DOCKER = 0, RED = 1, BLUE = 2, GREEN = 3, } -- 新增反向映射,支持服务名称转索引 local SERVICE_NAME_TO_CODE = { docker = 0, red = 1, blue = 2, green = 3, } local MPROC_CMDS = { RESTART = "restart", KILL = "kill" } local VALID_COMMANDS = { restart = true, kill = true } function EcpMproc(service, command) return [[!mprocs --server 127.0.0.1:4050 --ctl '{c: batch, cmds:[{c: select-proc, index: ]] .. tostring(service) .. [[}, {c: ]] .. tostring(command) .. [[-proc }, {c: select-proc, index: 0}]}'<cr>]] end vim.api.nvim_create_user_command( "Colors", function(opts) local service_input = opts.fargs[1] local command = opts.fargs[2] -- 校验命令是否合法 if not VALID_COMMANDS[command] then vim.notify("无效命令,仅支持 kill/restart", vim.log.levels.ERROR) return end -- 处理服务参数:支持数字或小写名称 local service_code if tonumber(service_input) then service_code = tonumber(service_input) -- 校验数字是否在合法范围内 if service_code < 0 or service_code > 3 then vim.notify("服务索引无效,仅支持 0-3", vim.log.levels.ERROR) return end else service_code = SERVICE_NAME_TO_CODE[service_input:lower()] if not service_code then vim.notify("无效服务名称,仅支持 docker/red/blue/green", vim.log.levels.ERROR) return end end -- 执行生成的mproc命令 vim.cmd(EcpMproc(service_code, command)) end, { nargs = "+", bang = true, -- 加入参数补全,提升使用体验 complete = function(_, line) local parts = vim.split(line, "%s+") local n = #parts if n == 2 then return {"docker", "red", "blue", "green", "0", "1", "2", "3"} elseif n == 3 then return {"kill", "restart"} end return {} end } )
使用说明
- 通过
:Colors blue restart重启blue服务 - 通过
:Colors 1 kill终止red服务 - 输入命令时按
<Tab>可以自动补全服务名称/索引和命令
内容的提问来源于stack exchange,提问作者Vikram Venkataramanan
相关产品推荐
相关产品推荐

