Repository navigation
Support user-defined custom editors in the Open In picker - #10
Merged
Merged
Conversation
`vp check` fails on the branch without this; the change is the formatter's own output. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a `customEditors` array to server settings (settings.json) so any
command can act as an "Open in" target, e.g. a terminal editor wrapped
in a terminal emulator:
"customEditors": [
{ "id": "nvim-ghostty", "name": "Neovim (Ghostty)",
"command": ["ghostty", "-e", "nvim", "{path}"] }
]
- contracts: EditorId widens to builtin literals | `custom:<slug>`
template literal; CustomEditorDefinition schema with a {path}
placeholder (target path appended when no arg contains it)
- server: resolveEditorLaunch resolves custom ids against definitions
passed by the shell.openInEditor RPC handler (sourced from server
settings, never from the client, so the client still only sends ids)
- web: picker lists custom editors (always shown - the user opted in
explicitly; a missing command surfaces as a launch error toast
instead of a hidden entry), preference resolution covers them, and
the existing mod+o editor.openFavorite shortcut works once a custom
editor is the last-used one
- settings.json edits hot-reload through the existing settings watcher
and stream to clients via the server config subscription
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kevinher7
added a commit
that referenced
this pull request
Jul 2, 2026
Resolves conflicts between upstream's client connection architecture rewrite (pingdotgg#2978) and downstream features: - Tag catalog / sidebar tag filtering (#1): ported tag state into the new client-runtime atom architecture (shellReducer tag events, tagEntities/tagCommands modules, useTags hook) and rewrote the Sidebar/ChatView tag command dispatch from readEnvironmentApi to atom commands. - Custom editors in the Open In picker (#10): threaded customEditors through the rewritten ExternalLauncher service (HostProcessPlatform, typed launcher errors) and replaced the deleted rpc/serverState selectors with a primaryServerCustomEditorsAtom. - Re-applied prTemplate/username text-generation prompt params and GitVcsDriver test mocks onto upstream's restructured providers. - Accepted upstream deletions of store.ts/serverState.ts and moved fork test fixtures (tags: [], listAllTags/getTagById mocks) to the relocated test files. vp check, vp run typecheck, and the client-runtime/web/server test suites pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
Adds a
customEditorsarray to server settings (settings.json) so any command can be offered in the "Open in" picker — e.g. a terminal editor wrapped in a terminal emulator:EditorIdwidens to built-in literals |custom:<slug>(Schema.TemplateLiteral, mirroring the existingscript.<id>.runpattern); newCustomEditorDefinitionwith a{path}placeholder (target path is appended when no argument contains it);ServerSettings.customEditorsdefaults to[]so existing settings files and persisted localStorage editor ids decode unchanged.resolveEditorLaunchresolvescustom:ids against definitions theshell.openInEditorRPC handler reads from server settings. Commands come exclusively from the server-side settings file — the client still only sends an editor id, so the security posture is unchanged.mod+o/editor.openFavoriteshortcut works once a custom editor is the last-used one.settings.jsonedits hot-reload through the existing settings watcher and stream to connected clients via the server config subscription — no restart needed.Also includes a separate commit fixing a pre-existing formatting issue in
Migrations.tsthat madevp checkfail on the base branch.Why
There is currently no way to open a session's worktree in a terminal editor like Neovim — the editor list is a hardcoded set of GUI editors. Rather than hardcoding one more entry (ghostty+nvim), this makes the list user-extensible through the already-existing, file-backed, hot-reloading server settings pipeline, which keeps the change small: no new service, no new RPC, no client-supplied commands.
UI Changes
Custom editors appear as additional entries in the existing Open In dropdown (terminal icon + configured name). No layout changes; no screenshots included.
Testing
resolveEditorLaunchunit tests:{path}substitution, append-when-no-placeholder, multi-argument substitution, unknown custom id failsvp run typecheckpasses for all 15 packages;vp checkpasses["/Applications/Ghostty.app/Contents/MacOS/ghostty", "-e", "nvim", "{path}"]in~/.t3/dev/settings.json(not yet exercised through the running app)Checklist
🤖 Generated with Claude Code