Skip to content

Fix macOS editor launch (os error 2) + add open_at line/column targets - #14

Merged
sksizer merged 3 commits into
mainfrom
feat/open-at-targets-and-macos-launch
Jul 10, 2026
Merged

sksizer merged 3 commits into
mainfrom
feat/open-at-targets-and-macos-launch

Conversation

@sksizer

@sksizer sksizer commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Addresses the two path-opener findings from the Annado integration review (the other two findings in that PR were app-side UI polish and don't concern this crate).

Fix 1 — macOS editors fail to launch with os error 2

On macOS the GUI editors are detected by their .app bundle but were launched by their CLI shim (code, subl, cursor, zed). That shim is frequently not symlinked onto PATH (Sublime's subl never is by default), and a GUI-launched host (Tauri, etc.) inherits a stripped PATH — so open/open_with could throw NotFound for an app that detection reported as available.

Now, on macOS, a plain open of these editors goes through open -a "<App Name>" (LaunchServices, PATH-independent). Terminals already did this; cmux genuinely needs its CLI and is unchanged.

Fix 2 — jump to a line (was dropped in the rewrite)

New open_at(path, app_id, &Target) navigates to a location inside a file. Target { line, column } is a small carrier for sub-application markers, generalized so future markers (an anchor, a page, …) become new fields rather than a new open_* per coordinate.

  • Honored by the editors that can jump inside a file: VS Code, Cursor (--goto file:line:col) and Sublime, Zed (file:line:col suffix). Modeled as a first-class internal Editor type.
  • On macOS the editor CLI is resolved from inside the app bundle first, then PATH — so the jump works even when the shim is missing from PATH (Fix 1's whole problem). If neither resolves, the file still opens via open -a, just without the jump.
  • Every other opener (terminal, file manager, Obsidian) ignores the target and opens the path normally — open_at is always safe to call.
  • PathOpener.accepts_target exposes which detected openers qualify, so callers stop hardcoding the goto-capable list.
  • preview_command_at mirrors preview_command.

Verified on macOS (previews of the actual argv):

vscode open              -> open ["-a", "Visual Studio Code", "/tmp/proj"]
vscode @line42           -> /Applications/Visual Studio Code.app/.../bin/code ["--goto", ".../main.rs:42"]
zed    @5:3              -> /Applications/Zed.app/Contents/MacOS/cli [".../main.rs:5:3"]
sublime @10 (not installed) -> open ["-a", "Sublime Text", ".../main.rs"]   # graceful degrade
finder @line42           -> open [".../main.rs"]                            # target ignored

Compatibility

  • PathOpener gained accepts_target: bool — hand-built literals must fill it in.
  • macOS open/open_with/preview_command now spawn open -a for the GUI editors; the effective argv changed (more robust).
  • open_at, preview_command_at, and Target are additive.

Checks

just full-check (fmt + clippy) clean; cargo test green (28 unit + 10 doc) on default and --features specta.

sksizer added 3 commits July 4, 2026 15:19
…ror 2)

Addresses two path-opener issues surfaced by the Annado integration
(ABeehive/Annado#21).

Fix (os error 2): on macOS the GUI editors (VS Code, Cursor, Sublime,
Zed) are detected by their .app bundle but were launched via their CLI
shim (code, subl, ...). That shim is frequently not on PATH — and a
GUI-launched process inherits a stripped PATH — so open/open_with could
fail with NotFound for an app detection reported as available. They now
launch via `open -a "<App Name>"` (LaunchServices, PATH-independent).

Feature (jump to a location): new open_at(path, app_id, &Target) and a
Target { line, column } carrier for "sub-application markers". Editors
that accept a Target jump via their CLI (--goto file:line:col, or a
file:line:col suffix). On macOS the CLI is resolved from inside the app
bundle first, then PATH, degrading to a marker-less `open -a` if neither
resolves. Every other opener ignores the target and opens normally.

- PathOpener.accepts_target exposes which openers honor a Target, so
  callers stop hardcoding the goto-capable list.
- preview_command_at mirrors preview_command for targets.
- Editor is modeled as a first-class internal type (CLI resolution +
  goto encoding + macOS open -a).

Additive except: PathOpener gained accepts_target, and macOS
open/open_with/preview_command now spawn `open -a` for GUI editors.
…and-macos-launch

# Conflicts:
#	CHANGELOG.md
@sksizer
sksizer merged commit 3952f8d into main Jul 10, 2026
1 check passed
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.

1 participant