Open in editor: jump from a diff into your editor at the first change (v0.1.4)#7
Merged
Conversation
A button in the file bar opens the selected file in the user's editor at the first changed line, delegating to the editor's CLI — arrow stays a viewer and never embeds an editor or an LSP (the mirror image of Claude Code's /ide). Backend (src-tauri/editor.rs): detect_editors() probes $PATH for a table of known editors (VS Code family incl. Cursor/Windsurf/Kiro/Antigravity + the separate Antigravity IDE/VSCodium/Trae, Zed, Sublime, JetBrains, Kate); open_in_editor() spawns the right per-family argv (VS Code `-g file:line:col`, Zed/Sublime positional, JetBrains `--line/--column`) as SEPARATE args, never a shell string, to dodge the space-in-path bug (vscode#39891, cursor#3796). Two Tauri commands wired into the handler. Parser (lib.rs): ContentOut gains firstChangedLine (min newStart across the session's hunks, after side) so the jump lands on the first change. Honest: it opens the current on-disk file, not the reconstructed before. Frontend: api.ts gains detectEditors()/openInEditor() (Tauri-only; no-op in the browser); a small OpenInEditor.svelte picker (remembers the choice via localStorage) in the file bar. Adds the first-changed-line parser test (20 total).
ROADMAP: a full entry for the feature (delegation model, per-family open syntax, firstChangedLine, honesty about opening the on-disk after-file) plus the deferred items spelled out — terminal editors (no TTY from a GUI app, would need a terminal-emulator host), JetBrains/Sublime/Kate as best-effort (unverified here), macOS/Windows binary resolution, and the smart-default cascade (~/.claude/ide lockfile + $EDITOR) left as a future enhancement since the remembered choice already suffices. CLAUDE.md: a short pointer (editor table is data in src-tauri/editor.rs, opens the after-file, Tauri-only) and the test count. editor.rs: note which rows are verified live vs best-effort.
An adversarial multi-agent audit surfaced 6 real issues (7 others refuted). Fixes, all verified (20 tests, clippy -D warnings, fmt, web build; #1 checked against real transcripts): - Line off-by-N (parser): first_changed_line used the hunk's raw newStart, which is the top of the CONTEXT window — landing the cursor ~3 lines above the first actual change on ~92% of files. Now advance each hunk's newStart past its leading context (' '-prefixed lines) before taking the min. The unit test that masked this (fixture had no leading context) now exercises a 3-line offset. - Honesty / gone-on-disk: open_in_editor now rejects a non-existent path (and a non-absolute one) instead of launching the editor on it — which in the VS Code family would open an empty buffer and fabricate a phantom file on save while arrow reported success. The button is also disabled (afterAvailable gate) when the file is no longer on disk. - Zombie children: the spawned launcher is now reaped on a detached thread instead of dropped, so defunct processes no longer accumulate one-per-click. - Detached stdio (Stdio::null) so a chatty launcher can't write into arrow's terminal when run from a shell/AppImage. - Stale error ⚠ cleared on file change (it used to carry a previous file's failure onto the newly selected file). - Accessibility: the error glyph gets role/aria-label/aria-live, matching the rest of the UI (previously the reason was mouse-hover-only).
Ship "Open in editor": a file-bar button that opens the selected file in the user's editor at the first changed line, delegating to the editor's CLI (no embedded editor/LSP). Hardened by a pre-release adversarial audit (line landed via leading-context offset, gone-on-disk gate, child reaping, a11y). Updates the four manifests + all lockfiles, the README status/desktop section and test count (20), and the ROADMAP entry.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
A button in the file bar opens the selected file in the user's editor at the first changed line, by detecting installed editors and delegating to the editor's CLI — arrow never embeds an editor or a language server (the mirror image of Claude Code's
/ide). Ships as v0.1.4.Backend (
src-tauri/src/editor.rs)detect_editors()probes$PATHover a data-driven table: VS Code family (Cursor, Windsurf, Kiro, Antigravity + the separate Antigravity IDE, VSCodium, Code-OSS, Trae), Zed, Sublime, JetBrains, Kate.open_in_editor()builds the per-family argv (VS Code-g {file}:{line}:{col}, Zed/Sublime positional, JetBrains--line/--column) as separate args, never a shell string (dodges vscode#39891 / cursor#3796). Two Tauri commands wired up.Parser (
src/lib.rs)ContentOut.firstChangedLine= the first actually-changed line on the after side (each hunk'snewStartadvanced past its leading context). Honest: it points at the current on-disk file, not the reconstructed before.Frontend
api.ts:detectEditors/openInEditor(Tauri-only; no-op in the browser). NewOpenInEditor.sveltepicker that remembers the choice.Pre-release adversarial audit
Before shipping, a multi-agent audit reviewed the diff across 6 dimensions and adversarially verified each finding (6 confirmed real, 7 refuted). All 6 fixed:
firstChangedLineused the hunk's rawnewStart(top of the context window), landing ~3 lines above the first change on ~92% of files. Fixed via leading-context offset; the masking test now exercises it. Verified against real transcripts (e.g. 4→7, 6→9, 43→46).afterAvailableis false.Stdio::null).role/aria-label/aria-live, matching the rest of the UI.Verification
cargo fmt --all --check,cargo clippy --all-targets --all-features -- -D warnings(root + src-tauri),cargo test --release→ 20 passed,npm --prefix web run build— all green.cargo tauri build→.deb+ AppImage (v0.1.4); tested live opening VS Code, Cursor, Kiro, Antigravity, Antigravity IDE, Zed at the correct line.