I find that the easiest way to work with Bazel is with fzf.
If you haven’t already discovered fzf, it’s great. It’s a command-line fuzzy finder, which means you can use it to replace tab completion at the command line with a fuzzy drop-down picker. It’s straight magic, it’s quick to set up, and you’re in for a treat.
One of the best parts of fzf is that you can script it.Fun fzf tip: the kill
command is already
configured using this completion API: try typing
kill -p **<TAB>
and you’ll never see
kill
the same way again 🙂
In the screen cast above, you see how I’m using
**<TAB>
to trigger fzf to list all bazel targets. It
uses the Custom
fuzzy completion API to register a shell function to run on
TAB
.
Here’s the code you can add to your config files (like your
~/.zshrc
):
Note: zsh automatically discovers these functions
based on their name. But if you’re using Bash, you need a few
extra lines to register these functions.
At its core, these functions invoke bazel query
to list
all the targets, and then pass the output to fzf
so they
can be filtered.
There’s special handling for bazel
(which is usually
bazel build
) as well as bazel test
(which
limits the output to only test
and test_suite
targets).
You can see one caveat in the comment there:If you have a solution to this, please let me
know!
it doesn’t do all that well at finding every external
target. For example, the Sorbet repo has a bunch of
:ruby.tar.gz
defined in various external
(@
-prefixed) repository rules, but since Bazel doesn’t have
an easy way to list all those external repos, and because they’re not
transitive deps of anything in //...
, they don’t show up in
the output.
One last trick: I have a ton of bazel
shell aliases. Because of how zsh auto-discovers these two
_fzf_complete_*
functions, using if the first token isn’t
literally bazel
then zsh won’t find the right methods.
That’s easy enough to fix: just have one more function per alias:
And that about sums it up. If you have tips for how I could improve these functions, please let me know!