Skip to content

Add tab completion to cda#46

Open
mbercx wants to merge 5 commits intoaiidateam:mainfrom
mbercx:new/tab-completion
Open

Add tab completion to cda#46
mbercx wants to merge 5 commits intoaiidateam:mainfrom
mbercx:new/tab-completion

Conversation

@mbercx
Copy link
Copy Markdown
Member

@mbercx mbercx commented Apr 5, 2026

Supersedes #14

image

@t-reents originally I was planning to update your PR, but I noticed that you opened it from your fork's main branch. I felt awkward about force pushing your main, so opened a new PR, hope that's ok! I added you as a co-author in the relevant commits.

Besides adding tab-completion, I realised that we need some way to be able to update these shell scripts without the user having to remove and add them every time, that seemed really fragile and annoying. So in d648aaf makes sure we have a separate source file for each shell. But then how would users know to run init? They would need to know something changed. To track that, you need a version, hence 073cc15. 8353c59 was an improvement triggered while working on that.

So I went down a little rabbit hole. I hope it's not over-engineered. But frankly I think we're going to want to change these source files over time (also because I'm not an expert on shell scripting: the cda changes were partially vibe-coded for bash and zsh). I think this infrastructure will come in handy, and it doesn't add that much code to maintain.

I also think we're writing too many files to $HOME. So I would also move all our config files + environments into .aiida_project. But will think about / implement that after this PR is merged. Hopefully then we can limit the pain of these migrations to a single release.

@mbercx
Copy link
Copy Markdown
Member Author

mbercx commented Apr 5, 2026

CI fails because we have to merge 4c471bf to drop Python 3.9 support.

@mbercx mbercx force-pushed the new/tab-completion branch from b98ea6a to 92df178 Compare April 12, 2026 18:17
Running `init` more than once appended duplicate lines to the shell rc file and prompted
the user to confirm, which required manually cleaning up old lines afterwards. This led
to duplicates and made it tedious to update the shell instructions when we want to change
them.

Dedicated shell init files in `~/.aiida_project/` (`init.bash`, `init.zsh`) are now
simply overwritten on re-run — no duplicates, no prompt. The `fish` shell already had a
dedicated file approach, but was also appending instead of overwriting. The new
`write_config` method on the `Shell` class overwrites the file and checks if it existed
beforehand, which is used to inform the user whether this is the first init or a re-init.

For bash and zsh, the `ensure_source_line` method adds a single `source` line to the rc
file (`.bashrc`, `.zshrc`) inside a named block with a timestamp, making it
machine-parseable for future tooling. Since the block is only added if not already
present, and the init file is overwritten completely, the operation is idempotent and the
confirmation prompt can be dropped.

The shell config logic is consolidated onto the `Shell` model (`write_config`,
`ensure_source_line`) and `ShellType` gains an `rc_file` property — keeping the knowledge
of which shells need a source line in one place.
@mbercx mbercx force-pushed the new/tab-completion branch from 92df178 to b89eef6 Compare April 23, 2026 13:55
mbercx and others added 4 commits April 23, 2026 16:01
Rename `is_not_initialised()` to `is_initialised()`, which avoids double negation for
checks that check if the config is initialised (`not is_not_initialised`).

Move the error message out of `ProjectConfig.is_initialised()` and into command
logic. This allows us to reuse the command in other contexts where we don't want to
print an error.
Since `init` is now idempotent, updating is trivial — but the user has no way of knowing
their config is outdated after an upgrade.

Add a `version` to the `shell_fields.yaml` file, which is written to the dedicated shell
source file as a `# version: N` header. The `is_outdated` property is added, which reads
the version from the source file and is used in the callback of the CLI to check for an
outdated shell config version. This check is skipped for the init command and in case
if `aiida-project init` has not been run yet
Without tab completion, the user has to remember or look up project names when calling
`cda`. Moreover, they would have to type them out completely (yuck!). Adding
tab-completion is essential for any environment management tool.

The completion logic reads the available projects from the `.aiida_projects/` directory
at completion time, so it always reflects the current state without any Python process
overhead.

Each shell uses its native completion mechanism: bash uses `compgen`/`complete`,
zsh uses `compadd`/`compdef`, and fish uses `complete -c cda -f`. Because zsh
now needs shell-specific completion code, it can no longer share `init_lines`
with bash via the YAML anchor and gets its own block.

The completion logic ships as part of the same release that introduces versioning, so no
version bump is needed.

Co-Authored-By: Timo Reents <77727843+t-reents@users.noreply.github.com>
Co-Authored-By: Timo Reents <77727843+t-reents@users.noreply.github.com>
@mbercx mbercx force-pushed the new/tab-completion branch from b89eef6 to 671fd94 Compare April 23, 2026 14:01
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

Successfully merging this pull request may close these issues.

🐛 init still prints "has been initialised" even when user selects no

1 participant