Given a series of commands to run, where each subsequent command depends on the completion of the previous, how can one execute these commands sequentially in Lua via Neovim's job
control functionality?
As an example, when compiling .tex
files, one often needs to run pdflatex
twice, followed by biber
, and then a final run of pdflatex
in order to resolve all references/hyperlinks within the document.
When attempting to do this with multiple jobstart
calls as shown below, the calls are made in separate spawned jobs, which means that (in effect) they are happening "simultaneously", leading to compilation errors:
local pdflatex_cmd = "pdflatex file.tex"
local biber_cmd = "biber file.tex"
vim.fn.jobstart(pdflatex_cmd)
vim.fn.jobstart(pdflatex_cmd)
vim.fn.jobstart(biber_cmd)
vim.fn.jobstart(pdflatex_cmd)
Attempts to use job_running = vim.fn.jobwait({job_id}, 0)[0] == -1
in between each vim.fn.jobstart()
call with the corresponding job ID to iteratively check the status of a job (i.e. wait) fails to work.
Is there a way to ensure that the previous command issued with jobstart
has completed, either by using vim.fn.jobwait()
or by some other means?
Instead of attempting to run multiple commands separately, one can concatenate them with ;
as a separator and pass the result to jobstart
. For example:
local pdflatex_cmd = "pdflatex file.tex"
local biber_cmd = "biber file.tex"
local multiple_cmds = pdflatex_cmd .. "; " .. pdflatex_cmd .. "; " .. biber_cmd .. "; " .. pdflatex_cmd
vim.fn.jobstart(multiple_cmds)
On Linux, separating commands with ;
(e.g. cmd1; cmd2; cmd3
) allows one to run each command after the previous regardless of whether the previous command executed successfully, or with errors. For completeness:
&&
can be used. For example, when issuing cmd1 && cmd2 && cmd3
, if cmd1
fails, cmd2
won't be executed. Using this option would be ideal for compiling .tex
documents as one doesn't need subsequent commands to run if the previous failed.||
can be used. For example, when issuing cmd1 || cmd2 || cmd3
, if cmd1
fails, cmd2
will be executed.