Open in editor: prefer an IDE running Revue Companion #68

Closed
opened 2026-11-12 01:46:44 +01:00 by thatrichan · 1 comment
Owner

Open in editor (the PR header's button, open_in_editor_here, PrView::open_in, and links that open a pull request in an editor) uses the default editor from Settings → Behavior. Today a running JetBrains IDE is only asked (jetbrains::open over /api/revue-* on jetbrains::PORTS) when the default editor is that JetBrains IDE. If you're working in an IDE that runs Revue Companion (the plugin, dev.cleangame.revue.companion, formerly "Revue") but your default editor is something else, the pull request opens there instead of in the IDE you have open.

Revue Companion will come to more editors over time (VS Code and others, not only JetBrains IDEs), so this is about any editor running a companion, not JetBrains only.

What it should do

When opening a pull request (or a file or line of it) in an editor, without an editor named explicitly (the button's menu still opens the one picked):

  1. No companion running: the default editor, as today.
  2. One companion running: that IDE, even if it isn't the default editor.
  3. Several running, and one is the default editor: the default editor's instance.
  4. Several running, none of them the default editor: one of them, picked the same way every time: the first in a fixed order (see below).

Within a chosen IDE, what happens is unchanged: the window that has the PR's branch comes forward, else the folder opens in a new window of that IDE.

Picking among several (case 4)

Sort the running companions in a stable order and take the first:

  1. One that already has a window with the PR's repository on its branch (Instance::has(slug, Some(branch))), since that's where the work is.
  2. Then one with the repository open on any branch.
  3. Then the one with a focused window (Instance::focused).
  4. Then by the IDE's place in jetbrains::IDES (or a future editors::COMPANIONS list), then by port, so the choice never flips between two equal ones.

Steps 1–3 also break ties within case 3: when the default editor runs twice (two instances of the same IDE, on two ports), take its instance that has the branch, else the focused one, else the first.

Implementation notes

  • Finding companions: jetbrains already scans PORTS for instances (GET /api/revue-projects → Instance { ide, product, projects, port }). Add a running() -> Vec<Instance> that every open asks first (it already has short timeouts, SCAN), so the choice is known before launching anything.
  • The default editor as an IDE: match apps::App (Settings' default editor) to an instance with jetbrains::ide_of(program, name) and Ide::is(ide, product).
  • Several kinds of companion later: keep the choice in a function independent of the transport, e.g. fn choose(default: Option<&App>, running: &[Companion], repo, branch) -> Choice, with Companion a small enum or trait over JetBrains instances (and later VS Code etc.), so a new companion only adds a finder.
  • A companion that disappears between the scan and the open (the IDE closed): fall back to the default editor, as when none is running.
  • No change when an editor is picked explicitly from the button's menu, or for Open in terminal / Open folder.

Tests

choose on generic fixtures, one test per case:

  • none running → the default editor;
  • one running (not the default) → it;
  • several, the default among them → the default;
  • several, the default not among them → the one with the branch, else with the repository, else the focused one, else the first by IDE order and port;
  • the default running twice → its instance with the branch;
  • the chosen one gone at open time → the default editor.

Plus one UI test with the mock /api/revue-projects server (as the existing jetbrains tests do): Open in editor goes to the running companion when the default editor is another app.

Docs

docs/editors.md: how Revue chooses the editor when Revue Companion is running, and the plugin's new name (Marketplace search Revue Companion, source at jetbrains-plugins/revue-companion).

**Open in editor** (the PR header's button, `open_in_editor_here`, `PrView::open_in`, and links that open a pull request in an editor) uses the default editor from **Settings → Behavior**. Today a running JetBrains IDE is only asked (`jetbrains::open` over `/api/revue-*` on `jetbrains::PORTS`) when the default editor *is* that JetBrains IDE. If you're working in an IDE that runs **Revue Companion** (the plugin, `dev.cleangame.revue.companion`, formerly "Revue") but your default editor is something else, the pull request opens there instead of in the IDE you have open. Revue Companion will come to more editors over time (VS Code and others, not only JetBrains IDEs), so this is about any editor running a companion, not JetBrains only. ## What it should do When opening a pull request (or a file or line of it) in an editor, without an editor named explicitly (the button's menu still opens the one picked): 1. **No companion running:** the default editor, as today. 2. **One companion running:** that IDE, even if it isn't the default editor. 3. **Several running, and one is the default editor:** the default editor's instance. 4. **Several running, none of them the default editor:** one of them, picked the same way every time: the first in a fixed order (see below). Within a chosen IDE, what happens is unchanged: the window that has the PR's branch comes forward, else the folder opens in a new window of that IDE. ## Picking among several (case 4) Sort the running companions in a stable order and take the first: 1. One that already has a window with the PR's repository on its branch (`Instance::has(slug, Some(branch))`), since that's where the work is. 2. Then one with the repository open on any branch. 3. Then the one with a focused window (`Instance::focused`). 4. Then by the IDE's place in `jetbrains::IDES` (or a future `editors::COMPANIONS` list), then by port, so the choice never flips between two equal ones. Steps 1–3 also break ties within case 3: when the default editor runs twice (two instances of the same IDE, on two ports), take its instance that has the branch, else the focused one, else the first. ## Implementation notes - **Finding companions:** `jetbrains` already scans `PORTS` for instances (`GET /api/revue-projects` → `Instance { ide, product, projects, port }`). Add a `running() -> Vec<Instance>` that every open asks first (it already has short timeouts, `SCAN`), so the choice is known before launching anything. - **The default editor as an IDE:** match `apps::App` (Settings' default editor) to an instance with `jetbrains::ide_of(program, name)` and `Ide::is(ide, product)`. - **Several kinds of companion later:** keep the choice in a function independent of the transport, e.g. `fn choose(default: Option<&App>, running: &[Companion], repo, branch) -> Choice`, with `Companion` a small enum or trait over JetBrains instances (and later VS Code etc.), so a new companion only adds a finder. - **A companion that disappears** between the scan and the open (the IDE closed): fall back to the default editor, as when none is running. - **No change** when an editor is picked explicitly from the button's menu, or for Open in terminal / Open folder. ## Tests `choose` on generic fixtures, one test per case: - none running → the default editor; - one running (not the default) → it; - several, the default among them → the default; - several, the default not among them → the one with the branch, else with the repository, else the focused one, else the first by IDE order and port; - the default running twice → its instance with the branch; - the chosen one gone at open time → the default editor. Plus one UI test with the mock `/api/revue-projects` server (as the existing jetbrains tests do): Open in editor goes to the running companion when the default editor is another app. ## Docs `docs/editors.md`: how Revue chooses the editor when Revue Companion is running, and the plugin's new name (Marketplace search **Revue Companion**, source at `jetbrains-plugins/revue-companion`).
Author
Owner

Done in 738fa92 (docs in 1940b53).

  • A new module, src/companion.rs, holds Companion, an enum with a JetBrains variant today, plus running() and choose(default, running, repo, branch). If the default editor's instances are running, the choice is among them; otherwise it's among all running companions. They're ranked by having the PR's branch, then the repository, then a focused window, then IDE order and port.
  • Opening in the editor without a named app scans for companions first, which takes at most about 1 s. If none is chosen, or the chosen one is gone, the default editor starts. Picking an app from the menu, and the terminal and folder buttons, work as before. The repository view's editor button follows the same rule.
  • There are tests for each case of choose, plus a test against the mock /api/revue-projects with a VS Code default.
  • docs/editors.md has a new section, "Which editor opens", and uses the plugin's new name.
Done in 738fa92 (docs in 1940b53). - A new module, `src/companion.rs`, holds `Companion`, an enum with a `JetBrains` variant today, plus `running()` and `choose(default, running, repo, branch)`. If the default editor's instances are running, the choice is among them; otherwise it's among all running companions. They're ranked by having the PR's branch, then the repository, then a focused window, then IDE order and port. - Opening in the editor without a named app scans for companions first, which takes at most about 1 s. If none is chosen, or the chosen one is gone, the default editor starts. Picking an app from the menu, and the terminal and folder buttons, work as before. The repository view's editor button follows the same rule. - There are tests for each case of `choose`, plus a test against the mock `/api/revue-projects` with a VS Code default. - `docs/editors.md` has a new section, "Which editor opens", and uses the plugin's new name.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thatrichan/revue#68
No description provided.