Opening it in the IDE: open -a, code --wait, and a launcher pointing at a disk that is not there¶
Level: 101 · for newcomers
One line: The last line of a scratch script is open the folder in the editor, and on this Mac the obvious command for RustRover — rustrover "$dir" — prints a NSCocoaErrorDomain error and opens nothing, because the launcher on PATH was written by Toolbox in 2023 for an app that lived on a drive called T5; open -a RustRover "$dir" asks LaunchServices instead, which knows where the app went.
The four commands¶
| Command | What it does | Returns |
|---|---|---|
open -a RustRover "$dir" |
opens the folder as a project in the running RustRover, or starts it | immediately |
open -W -a RustRover "$dir" |
the same, then blocks | when RustRover quits — not when the project closes |
code --new-window "$dir" |
a new VS Code window on the folder | immediately |
code --wait --new-window "$dir" |
the same, then blocks | when that window closes |
The right-hand column is what decides which script can delete the project for you. VS Code's --wait is per window, so scratch.py --code removes the folder the moment you close it. RustRover's only waitable event is the whole IDE quitting — open's own help says -W blocks "until the used applications are closed (even if they were already running)", and measured here the call had still not returned a minute after the project was open — so scratch.py --rustrover deletes on the next run instead.
The launcher that is not¶
$ rustrover /tmp
The application /Volumes/T5/Applications/RustRover.app/Contents/MacOS/rustrover cannot be opened for an unexpected reason, error=Error Domain=NSCocoaErrorDomain Code=260 "The file “rustrover” couldn’t be opened because there is no such file."
/usr/local/bin/rustrover is a 20-line bash script, first line "Generated by JetBrains Toolbox 2.0.5.17700 at 2023-10-30", and its last line is open -na "/Volumes/T5/Applications/RustRover.app/Contents/MacOS/rustrover" …. The app is at /Volumes/T7/tools/RustRover.app today. Toolbox writes the launcher once, at install, with the path baked in; move the app and the launcher keeps the old path, and nothing on the machine notices until a script calls it. Two ways to fix it, and the second is the one the scripts here use:
- Regenerate it — Toolbox, Settings → Tools → Shell scripts, or delete the file and let Toolbox write it again.
- Do not use it.
open -a RustRoverresolves the app through LaunchServices, the same database Finder and Spotlight use, andlsregister -dumpshows it holding the T7 path. That works from a script on any Mac where RustRover has ever been opened, whichever folder it is in.
code, by contrast, is a symlink into Visual Studio Code.app/Contents/Resources/app/bin/code, and the app is in /Applications; it is the one launcher here that has not moved.
What RustRover does with a folder from open -a¶
2026-09-11 21:06:59,268 INFO - #c.i.i.i.ProjectUtil - Opening existing project with .idea at /private/var/folders/bc/gzwjtz8d6mx3l2f9yyf_p8yw0000gn/T/rust-scratch.cnwyCD
It opens the folder as a project, whether or not a .idea/ is there — that run had one, seeded by hand to test the next paragraph. The log says nothing about Cargo at open time; the attach shows up later, when the IDE syncs and then saves its workspace file:
2026-09-11 21:18:09,581 INFO - #org.rust.cargo.project.model.impl.CargoSyncTask - CargoSyncTask started
2026-09-11 21:18:10,245 INFO - org.rust.openapiext.CommandLineExt - Executing `/usr/local/opt/rustup/bin/rustup show active-toolchain` in working directory `/private/var/folders/bc/…/rust-scratch.cnwyCD`
2026-09-11 21:18:10,649 INFO - org.rust.openapiext.CommandLineExt - Executing `/usr/local/opt/rustup/bin/cargo metadata --verbose --format-version 1 --all-features …
<component name="CargoProjects">
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml">
So the Cargo.toml at the root was attached — .idea/workspace.xml went from the six seeded lines to 77, with a CargoProjects component naming it, and a modules.xml and .iml beside it. What the log cannot say is whether that sync was the IDE's own doing or a click on the banner's Attach Cargo.toml button in the eleven-minute gap; either way it is once per project, and the folder from open -a ends up a real Cargo project.
The toolchain is a per-project IDE setting, not a file Cargo reads. A new project can open under No Rust toolchain specified even though cargo is on PATH, because RustRover keeps the toolchain path in .idea/workspace.xml and nothing auto-detects Homebrew's rustup shims. The value it wants is /usr/local/opt/rustup/bin — RustRover setup has the whole story. That is the component the test above seeded:
<project version="4">
<component name="RustProjectSettings">
<option name="toolchainHomeDirectory" value="/usr/local/opt/rustup/bin" />
</component>
</project>
It was read: the sync above ran rustup and cargo from exactly that path, /usr/local/opt/rustup/bin/, and the component survived the IDE's rewrite of the file. So a scratch script can seed the toolchain and skip the Toolchain location dialog — which is what scratch.sh --rustrover does not yet do, and rust_scaffold.py could.
See also¶
- The hub — a disposable Rust workspace, six ways — the workflow these commands are the last step of
- RustRover setup — everything else the IDE needs told once
- Choosing an editor — where the toolchain-location trap is explained for every editor, not only this one
openon macOS ↗ —-a,-W,-n,-F, and what each waits for