Search code examples
luaneovim

Passing arguments to vim.api.nvim_create_user_command in order to execute a bash command


I've been using mproc in server mode to start a bunch of project dependencies in the background.

mproc is currently running in the background with the server receiving commands at 127.0.0.1:4050. It started four services for me: docker, red, blue, green.

I want to interact with server without leaving neovim. I was able to partially accomplish this with the following code

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", ColorsMproc(ECP_SERVICE_CODE.RED, MPROC_CMDS.KILL), {})
vim.api.nvim_create_user_command("ColorsRedServiceRestart", ColorsMproc(ECP_SERVICE_CODE.RED, MPROC_CMDS.RESTART), {})

vim.api.nvim_create_user_command("ColorsBlueServiceKill", ColorsMproc(ECP_SERVICE_CODE.BLUE, MPROC_CMDS.KILL), {})
vim.api.nvim_create_user_command("ColorsBlueServiceRestart", ColorsMproc(ECP_SERVICE_CODE.BLUE, MPROC_CMDS.RESTART), {})

vim.api.nvim_create_user_command("ColorsGreenServiceKill", ColorsMproc(ECP_SERVICE_CODE.GREEN, MPROC_CMDS.KILL), {})
vim.api.nvim_create_user_command("ColorsGreenServiceRestart", ColorsMproc(ECP_SERVICE_CODE.GREEN, MPROC_CMDS.RESTART), {})

I can now interact with my running mproc instance by using commands like :ColorsRedServiceKill<CR> or :ColorsBlueServiceRestart<CR>.

Without worrying so much about robustness or corner cases, I want to be able to make use of the argument passing to neovim commands and instead call this function with something more along the lines of :Colors 1 restart or better yet (:Colors blue restart)

Here's my best go at this. It's not having the desired effects :(

vim.api.nvim_create_user_command(
    "Colors",
    function(opts)
        local service = opts.fargs[1]
        local command = opts.fargs[2]

        return ColorsMproc(service, command)
    end,
    {nargs = "+", bang = true}
)

Solution

  • From what I understand you shouldn't need to use return. I'm also assuming that ColorsMproc is defined already somewhere else in the .lua files, otherwise you'd need to access it with vim.fn (I'm pretty sure). So then it may look something like this:

    vim.api.nvim_create_user_command(
        "Colors",
        function()
            local service = vim.fn.input "service: "
            local command = vim.fn.input "command: "
    
            ColorsMproc(service, command)
        end,
        {nargs = "+", bang = true}
    )
    

    I think you can put 'service' and 'command' in the same line by doing something like: local sc = vim.split(vim.fn.input "service/command: ", " ").

    I was referencing this video: https://www.youtube.com/watch?v=HlfjpstqXwE