entr is an extremely useful little tool that can watch files and run a command automatically upon a file change. So, for example, the following can be used to watch all Rust source files and run the tests:
ls src/**/*.rs | entr -s "cargo test"
This works great and I've been using it for years. However, recently I switched to a Mac which restricts the number of files that can be watched to 256. This is a problem for large codebases. Furthermore, it can sometimes be very difficult to figure out which files to watch exactly. For instance when watching LaTeX files, it is important to not watch the log files or
entr would go into an infinite loop.
To solve this, I stumbled into a solution that works so well and is in hindsight so obvious that I wonder how I ever lived without this. Just make the editor write to some central file and track that!
Specifically, I've added the following line to Neovim:
autocmd BufWritePost * silent! !echo $(date +\%s) > /Users/rik/last_nvim_write.txt
Now when I'm working in some file
foo.txt and save it, both
/Users/rik/last_nvim_write.txt will be updated. To
last_nvim_write.txt the full timestamp in seconds since 1970-01-01 00:00:00 UTC is written each time.
Next, I've added the following Shell script:
#!/usr/bin/env bash echo "/Users/rik/last_nvim_write.txt" | entr -s "$@"
and made it globally available as
ee. Now to rebuild a project upon change, use:
ee 'cargo test'