Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make pre_cmd background forkable #557

Open
omani opened this issue Mar 23, 2024 · 3 comments
Open

Make pre_cmd background forkable #557

omani opened this issue Mar 23, 2024 · 3 comments

Comments

@omani
Copy link

omani commented Mar 23, 2024

Im trying to use
pre_cmd = ["/usr/bin/xdotool sleep 1 search --onlyvisible --classname Navigator windowactivate --sync key F5 &"]

to refresh the browser once the binary (golang echo framework) started. hence the sleep so the refresh happens after the http listening on the port is available.

I need to put the xdotool command into background & because otherwise air will wait for the command to finish and then run the webserver. which will obviously fail.

I checked the code for the runner. it seems that forking into background exits the process immediately (the exec commad in utils_linux.go is "/bin/sh -c"...so ofc air wont wait and dismiss the command right away.

so my question is:
any chance to implement a background forkable pre_cmd and the appropriate directive in air.toml?

@omani
Copy link
Author

omani commented Mar 23, 2024

I solved this issue by moving the command invocation into my main:go (where I start the echo webserver):

cmd := exec.Command("/usr/bin/xdotool", "search", "--onlyvisible", "--classname", "Navigator", "key", "F5")
err := cmd.Start()
if err != nil {
   log.Printf("Failed to start cmd: %v", err)
} else {
   if err := cmd.Wait(); err != nil {
	log.Printf("Cmd returned error: %v", err)
}
}

this refreshes the browser WITHOUT leaving neovim and losing focus from the IDE.

feel free to close this issue if you are not interested in implementing a forkable pre_cmd for air.

@awoelf
Copy link

awoelf commented Mar 24, 2024

I have a similar solution for hot-reloading the code with air, but I used goroutines.

refresh.sh

set -o errexit
set -o nounset

keystroke="CTRL+F5"
browser="${1:-firefox}"

# find all visible browser windows
browser_windows="$(xdotool search --sync --all --onlyvisible --name ${browser})"

# Send keystroke
for bw in $browser_windows; do
    xdotool key --window "$bw" "$keystroke"
done

In my main.go file, I run the .sh file and the listen command as goroutines.

main.go

// ... other code

func main() {
    // Locate .sh file
    cmd := exec.Command("/bin/sh", "refresh.sh")

    engine := html.New("./views", ".html")

    app := fiber.New(fiber.Config{
	Views: engine,
    })

    app.Static("/", "./public")

    app.Get("/", func(c *fiber.Ctx) error {
	return c.Render("index", fiber.Map{
		"title": "Hello, World!",
	}, "layouts/main")
    })

    // Run both the refresh command and start the app
    go cmd.Run()
    go log.Fatal(app.Listen(":3000"))
}

The main drawback with this refresh command is that it will only refresh the current, visible tab. So it won't refresh the working page unless it's open. I wish there was a way to refresh the working tab even when it's not visible.

@omani
Copy link
Author

omani commented Mar 24, 2024

The main drawback with this refresh command is that it will only refresh the current, visible tab. So it won't refresh the working page unless it's open. I wish there was a way to refresh the working tab even when it's not visible.

for me this is ok since I only work with the browser page/tab open side by side to my neovim environment, so I can see the changes immediately when eg. working on the tailwindcss part.

for now Im happy with this solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants