# gradle-completion teaches your shell the tasks in your build

> The Gradle project's shell completion script completes task names for the current project and its sub-projects, along with CLI switches and common Gradle properties, and it handles custom build file names. Installing it takes one Homebrew command for zsh and a little more care for bash, where the config file you edit depends on how the shell was started.

**gradle/gradle-completion** — Gradle tab completion for bash and zsh

- Repository: https://github.com/gradle/gradle-completion
- Stars: 1,113 · Forks: 153
- Language: Shell
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/gradle-gradle-completion

## Completion follows the project you are standing in

The three things the script completes are listed plainly: Gradle tasks for the current project and its sub-projects, Gradle CLI switches such as `--parallel`, and common Gradle properties such as `-Dorg.gradle.debug`. The first of those is the one that needs work to do properly, because the task list is not static. It comes from the build in the directory you are in, and a multi-project build has a task list per sub-project, so the completion has to know which project you are in and which tasks belong to it. That is why the script has a cache and why initialising it can take a few seconds on a large project. The features are described as fast tab completion, and the mechanism behind that is a cache that is built once and then reused.

## Custom build file names are handled, not ignored

There is a detail that separates this from a generic Gradle completion script. It handles custom default build files, so a project that sets `rootProject.buildFileName = 'build.gradle.kts'` is supported. Most completion scripts assume the conventional `build.gradle` and quietly produce nothing for a Kotlin DSL project, which is exactly the kind of small failure that makes people uninstall a completion script rather than fix it. Handling that case means the script has to look for more than one file name when it enumerates the project. The repository layout supports the idea that this is a maintained, generated artefact rather than a single hand-written file, since there is both a `_gradle` file and a `_gradle.template`, and both a `gradle-completion.bash` and a `gradle-completion.bash.template`, plus a `gradle-completion.plugin.zsh`.

## Zsh needs one command, plus a check on fpath

For zsh 5.0 and later, the Homebrew route is short. You install the formula, and the documentation asks you to make sure the site-functions directory is on your fpath:

```bash
brew install gradle-completion

# Ensure /usr/local/share/zsh/site-functions is on $fpath. You should get a result from the following
echo $fpath | grep "/usr/local/share/zsh/site-functions"
```

That second command is a verification step rather than a step to copy, and it matters because a completion function that is not on fpath will never be found by the completion system even though the file is installed. The oh-my-zsh route is a tarball downloaded from the releases and extracted into the custom plugins directory, with `plugins+=(gradle-completion)` added to the .zshrc file, and the manual route puts the same tarball somewhere of your choosing and adds the directory to fpath before running `compinit`. The manual route also notes that you may need to disable the `gradle` plugin that oh-my-zsh ships, since the two would otherwise both define a completion for the same command.

## Bash completion is mostly a question of which file you edit

The bash instructions are longer, and the reason is a detail of how bash starts. Bash reads different config files depending on how it is started: a login shell reads `~/.bash_profile`, and a non-login interactive shell reads `~/.bashrc`. The documentation notes that since macOS Catalina in 2019 zsh is the default shell, so if you type `bash` to switch from zsh you get a non-login shell that only reads `~/.bashrc`. The bash-completion documentation is quoted for its recommendation: put all interactive bash configuration in `~/.bashrc`, have `~/.bash_profile` source `~/.bashrc`, and do not source bash-completion directly in `~/.bash_profile` because it will not work in non-login shells. Getting that wrong is the single most common reason completion appears to be installed but never fires.

## Homebrew bash-completion@2 changes where the file goes

The bash path also has a packaging wrinkle worth knowing. The script depends on the bash-completion framework, which is not installed on macOS by default, and Homebrew's `bash-completion@2` is patched to load completions from `bash_completion.d/`. If you install bash-completion@2 from source or from another package manager, it only loads from the `completions/` directory by default, and in that case you either install to the `completions/` directory or source `gradle-completion.bash` directly in your `~/.bashrc`. The manual installation downloads the script straight from the repository and puts it in place:

```bash
DEST="/usr/local/etc/bash_completion.d" # or DEST="${HOME}/bash_completion.d"
mkdir -p "$DEST"
curl -LA gradle-completion https://raw.githubusercontent.com/gradle/gradle-completion/master/gradle-completion.bash -o "$DEST/gradle"
```

The curl invocation carries a user agent label and a branch name, and it writes to a file named `gradle` rather than `gradle-completion.bash`, which is deliberate because the completion framework loads files by the command name.

## Three commands diagnose most problems

The troubleshooting section is a good model of what to check. To see whether the completion is loaded at all, run `type _gradle`: if it shows that `_gradle` is a function, completion is working, and if it says not found, the completion script has not been sourced. To see whether you are in a login shell, the documentation gives `shopt -q login_shell && echo "login" || echo "not login"`, and if it says not login you need your `~/.bash_profile` to source your `~/.bashrc`. To check the bash version, `echo $BASH_VERSION` prints it, and the note is that the macOS built-in Bash 3.2 is quite old and that a newer bash from Homebrew is worth installing if you hit issues. There is also a common mistake called out specifically, escaping the brew prefix command with a backslash so that it is written as a literal string rather than executed, because the backslash prevents the command from running at all.

## The cache can be warmed up before you need it

There is an optional step that addresses a real annoyance. Completion cache initialisation happens the first time you invoke completion, and usually takes a few seconds depending on the size of your project, which means your first tab press after a checkout is slow. You can initialise the cache manually, from inside your project directory, by sourcing the completion script and calling the init function:

```bash
cd path/to/your-project
# For oh-my-zsh installation:
source ~/.oh-my-zsh/plugins/gradle-completion-VERSION/_gradle 1>&2 2>/dev/null; __gradle-completion-init
# OR for manual installation:
source ~/.zsh/gradle-completion-VERSION/_gradle 1>&2 2>/dev/null; __gradle-completion-init
```

The output is redirected so the source step does not print anything into your terminal, and the version placeholder in the path has to be replaced with the one you installed. The repository also has a `tests/` directory and a `build.gradle.kts` with a `buildSrc/` directory and a `gradle/` wrapper directory, which tells you the script is built and tested as part of a Gradle build rather than only being a loose shell file, and the `CONTRIBUTING.md` file is there for people who want to change it.

## The version numbers in the docs lag the releases

One inconsistency is worth pointing out, because it will confuse anyone following the instructions literally. The release tags are recent and follow the Gradle version, with v9.8.0 from 2026-09-25, v9.7.1 from 2026-08-31 and v9.6.1 from 2026-07-02. But the documented install commands for both oh-my-zsh and the manual zsh route use `VERSION=1.4.4` with a comment telling you to replace it with the latest version from the releases page. So the number in the example is a placeholder from an older numbering scheme, and the release archive names follow the tag. The practical advice is to set the version variable to the tag you actually want, and to remember that the file name inside the tarball, which the fpath line and the source line both reference, is derived from that same version.

## Conclusion

Adopt gradle-completion if you work on Gradle builds from the command line and want task names for the current project and its sub-projects in your tab completion, since that is what the script is for and it keeps working as the task list changes. Do not adopt it expecting completion of build script contents, because it completes task names and switches rather than code. Verify first which shell config file your bash actually reads, since a login shell and a non-login shell read different files and the difference is the usual reason completion appears not to load, and check the version you install, since the release tags and the version number in the documented install command do not line up.

## FAQ

### How do I install gradle-completion for zsh?

Run `brew install gradle-completion`, then check that `/usr/local/share/zsh/site-functions` is on your fpath with `echo $fpath | grep "/usr/local/share/zsh/site-functions"`. The oh-my-zsh and manual routes download a release tarball instead.

### Why is bash completion not working after I installed it?

The usual cause is which config file your shell reads. A login shell reads `~/.bash_profile` and a non-login interactive shell reads `~/.bashrc`, and the bash-completion documentation recommends putting completions in `~/.bashrc` and having `~/.bash_profile` source it, rather than sourcing bash-completion directly in `~/.bash_profile`.

### What can gradle-completion actually complete?

Gradle tasks for the current project and its sub-projects, Gradle CLI switches such as `--parallel`, and common Gradle properties such as `-Dorg.gradle.debug`. It also handles custom default build file names such as `rootProject.buildFileName = 'build.gradle.kts'`.

### How do I check whether the completion script is loaded in bash?

Run `type _gradle`. If it reports that `_gradle` is a function, the completion is working. If it says not found, the script has not been sourced. The documentation also suggests `shopt -q login_shell && echo "login" || echo "not login"` to check the shell type, and `echo $BASH_VERSION` for the version.

### How can I speed up the first completion in a large project?

Initialise the cache manually before you need it, by sourcing the completion script and calling `__gradle-completion-init` from inside your project directory. The output of the source step is redirected so it does not print into your terminal.

## Sources

- [gradle/gradle-completion on GitHub](https://github.com/gradle/gradle-completion)
- [Issues](https://github.com/gradle/gradle-completion/issues)
- [License: MIT](https://github.com/gradle/gradle-completion/blob/master/LICENSE)
- [README](https://github.com/gradle/gradle-completion/blob/master/README.md)
- [Releases](https://github.com/gradle/gradle-completion/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gradle-gradle-completion
