Search code examples
bashluaneovim

How to use Bash echo as a condition in a Lua if statement?


I'm trying to write a Lua function for Neovim that, with the help of a few Bash commands, checks if a process is running; if it's running, close it, and if it's not, run a new instance.

Here's what I've managed to write so far:

isrunning = vim.cmd([[!pgrep -u $UID -x livereload > /dev/null && echo "true" || echo "false"]])
print(isrunning)

if isrunning == "true" then
  print('Closing Livereload...')
  vim.cmd('!killall livereload')
else
  print('Opening Livereload...')
  vim.cmd('!cd build; livereload &; firefox http://localhost:35729/"%<.html"')
end

The problem is that even if livereload is already running and the value of isrunning is "true", the first half of the if statement never runs, only what's after else. What do I need to change to fix that?


Update: Here's the output of :luafile %, when the above code is run in Neovim 0.5.0:

:!pgrep -u $UID -x livereload > /dev/null && echo "true" || echo "false"
true

:!cd build; livereload &; firefox http://localhost:35729/"livereload.html"

opening...

That made me think that the second line, true, must be the output of the command print(isrunning). After having some discussion in the comments section, I realized that this is not the case.

Here's the output when I change the print command to print("Answer: " .. isrunning .. "Length: " .. isrunning:len())

:!pgrep -u $UID -x livereload > /dev/null && echo "true" || echo "false"
true

Answer: Length: 0
:!cd build; livereload &; firefox http://localhost:35729/"livereload.html"

opening...

So, Neovim correctly shows the output of !pgrep -u $UID -x livereload > /dev/null && echo "true" || echo "false", but that output doesn't seem to be stored in the variable isrunning.


Solution

  • I've finally come up with a solution, which is twofold:

    1. Using the combination of io.popen and a file handle, as written in this answer to another question. This allows the value of echo to be read from Lua.
    2. Using echo -n to suppress the newline character, as mentioned by Piglet in an answer here.

    With these changes in place, here's the final code:

    handle = io.popen([[pgrep -u $UID -x livereload > /dev/null && echo -n "true" || echo -n "false"]])
    isrunning = handle:read("*a")
    handle:close()
    
    if isrunning == "true" then
      print('closing...')
      vim.cmd('!killall livereload')
    else
      print('opening...')
      vim.cmd('!cd build; livereload &; firefox http://localhost:35729/"%<.html"')
    end