Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **Open the folder in a console or the file explorer.** Two new built-in open targets sit alongside the
editors: **Console** (slug `term`) opens a terminal at the resolved folder, and **File Explorer** (slug
`files`) reveals it in the OS file manager. Both work on **Windows, macOS, and Linux** — Console finds
Windows Terminal / PowerShell / `cmd`, macOS **Terminal**, or a Linux terminal emulator
(`x-terminal-emulator`, `gnome-terminal`, `konsole`, `xterm`, …); File Explorer uses Explorer, Finder
(`open`), or `xdg-open`. Like every other target they get a **secondary button**, a **Ctrl+1 … Ctrl+9**
shortcut, and a **command-line slug** — so `fido feature/new-ui term` drops you into a terminal on that
branch and `fido feature/new-ui files` opens its folder. Both always hand over the **folder** (never a
`.sln`), and the **terminal program is configurable**: pick the **Console** / **File Explorer** kind for an
editor row in Settings and set its path (blank = the OS default) to use a specific terminal or file manager.
Existing configs are migrated forward once on load — Console and File Explorer are **appended** to the
editor list, preserving your existing order and default.

- **Solution filters (`.slnf`).** Fido now detects Visual Studio **solution filter** files alongside
`.sln`/`.slnx`, so a filtered subset of a solution shows up in the "which solution?" chooser and can
be handed straight to the editor (Rider, Visual Studio, etc. open `.slnf` directly). When a filter
Expand Down
66 changes: 47 additions & 19 deletions Docs/Features.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,28 +113,28 @@ When a choice is needed, Fido shows a keyboard-navigable list with rich, two-lin
(the repo root). If solution mode can't find the file, it falls back to opening the folder.
- **Branch-only mode:** the chooser lists each solution found in the folder plus an
"open the folder" option.
- **Folder-only editors:** some editors (e.g. **WebStorm**) only understand a project folder. When
one of those is the chosen editor, Fido always hands over the folder — it ignores the solution
toggle and skips the "which solution?" chooser.
- **Folder-only targets:** some targets only understand a project folder — **WebStorm**, and the
**Console** / **File Explorer** targets that open the folder itself. When one of those is chosen, Fido
always hands over the folder — it ignores the solution toggle and skips the "which solution?" chooser.

### Editors / IDEs

Fido can open the resolved target into any of several editors. The list is configured in Settings,
and one editor is the **default**:
Fido can open the resolved target into any of several editors — plus the **Console** and **File Explorer**
targets below. The list is configured in Settings, and one entry is the **default**:

- The **default** editor is launched by the **Open** button and **Enter**.
- Every other editor gets a **secondary button** on the main window and a numbered keyboard
shortcut, **Ctrl+1 … Ctrl+9** (Ctrl+N opens with the Nth editor in the list).
- The **default** target is launched by the **Open** button and **Enter**.
- Every other one gets a **secondary button** on the main window and a numbered keyboard
shortcut, **Ctrl+1 … Ctrl+9** (Ctrl+N opens with the Nth entry in the list).

Built-in editor kinds — **Rider**, **WebStorm**, **VS Code**, **Visual Studio**, **Zed** — auto-detect
when their path is left blank; a **Custom** editor opens whatever executable/app-bundle path you give it.
**WebStorm** is **folder-only**: it's always handed the repo folder rather than a `.sln`/`.slnx`/`.slnf`.
Optional extra command-line arguments can be supplied per editor (passed before the target path).

Each editor also carries a **slug** — a short command-line token (built-in defaults: `rider`, `ws`,
`vsc`, `vs`, `zed`) — so a specific editor can be picked when launching Fido from the command line (see
**Command-line launch**). The slug is editable per editor in Settings; leave it blank to make that
editor un-selectable from the CLI.
Each entry also carries a **slug** — a short command-line token (built-in defaults: `rider`, `ws`,
`vsc`, `vs`, `zed`, `term`, `files`) — so a specific one can be picked when launching Fido from the command
line (see **Command-line launch**). The slug is editable per entry in Settings; leave it blank to make that
entry un-selectable from the CLI.

**Auto-detection** for each known kind looks, in order, at an explicit path, then your **`PATH`**,
then common install locations:
Expand All @@ -151,6 +151,29 @@ then common install locations:
The editor is launched **detached** (Fido doesn't wait on it). If the chosen editor can't be found,
Fido says so and points you to its path setting.

### Console & file explorer

Beyond editors, Fido can open the resolved **folder** directly — handy when you just want a shell on the
branch or to browse its files. Two built-in targets, present out of the box and working on **Windows,
macOS, and Linux**:

- **Console** *(folder-only, slug `term`)* — opens a terminal **at the folder**. Auto-detection picks the
OS default: **Windows** — Windows Terminal (`wt`), else PowerShell (`pwsh`/`powershell`), else `cmd`;
**macOS** — the **Terminal** app (via `open -a`); **Linux** — the first of `x-terminal-emulator`,
`gnome-terminal`, `konsole`, `xfce4-terminal`, `kitty`, `alacritty`, `tilix`, `xterm` on `PATH`.
**The terminal is configurable:** set the Console row's **path** to a specific terminal program — a full
path *or* just a command name like `wt`, `pwsh`, or `gnome-terminal` (resolved on `PATH`, including Windows
Terminal's Store alias) — and add arguments if needed. Most terminals open in the folder because Fido sets
it as their working directory; Windows Terminal is pointed at it explicitly with `-d`.
- **File Explorer** *(folder-only, slug `files`)* — reveals the folder in the OS file manager: **Windows**
`explorer.exe`, **macOS** Finder (via `open`), **Linux** `xdg-open` (honouring your default file manager),
else `nautilus` / `dolphin` / `thunar` / `nemo` / `pcmanfm`. The file manager is configurable via the
row's **path** too.

Both behave like any other target — a secondary button, a **Ctrl+N** shortcut, and a CLI slug — so
`fido feature/new-ui term` opens a terminal on that branch and `fido feature/new-ui files` opens its folder.
They always hand over the **folder**, ignoring the Solution/Folder toggle and the "which solution?" chooser.

### Mission-control console

The in-app log narrates each launch like a flight-control "go around the horn" poll:
Expand Down Expand Up @@ -204,18 +227,19 @@ chooser/decision dialogs still appear when a choice is genuinely needed:
| Argument | Effect |
| --- | --- |
| `<name>` (bare, first) or `--branch` / `-b` `<name>` | Set the branch — **and auto-run the open** |
| `<slug>` (bare, second) or `--editor` / `-e` `<slug>` | Open with the editor whose **slug** matches (e.g. `rider`, `vsc`, `vs`, `zed`) instead of the default |
| `<slug>` (bare, second) or `--editor` / `-e` `<slug>` | Open with the target whose **slug** matches (e.g. `rider`, `vsc`, `vs`, `zed`, or `term` / `files` for a terminal / file manager) instead of the default |
| `--solution` / `-s` `<name>` | Set the solution name |
| `--folder` | Start in Folder open-mode |

For example, `fido feature/new-ui -s MyApp` opens that branch's `MyApp` solution and,
by default, closes Fido a few seconds after Rider is launched (see **Close after opening** and
**Close delay** below).

To pick a non-default editor, give its slug as the **second bare argument** — `fido feature/new-ui zed`
opens in Zed — or pass it explicitly with `--editor` / `-e`: `fido -b feature/new-ui -s MyApp -e vs`.
To pick a non-default target, give its slug as the **second bare argument** — `fido feature/new-ui zed`
opens in Zed, `fido feature/new-ui term` opens a terminal on the branch, `fido feature/new-ui files` opens
its folder — or pass it explicitly with `--editor` / `-e`: `fido -b feature/new-ui -s MyApp -e vs`.
An unrecognised slug stops with a **No-go** that names it (and lists the known slugs) rather than
silently falling back to the default editor.
silently falling back to the default.

---

Expand All @@ -224,11 +248,14 @@ silently falling back to the default editor.
### Settings (in the app's **Settings** panel)

- **Search roots** — directories to scan for solutions / working trees (one per line).
- **Editors** — the editors/IDEs Fido can open into. Each row has a name, an optional **slug** (the
- **Editors** — the targets Fido can open into. Each row has a name, an optional **slug** (the
command-line token that selects it, e.g. `rider`), a **kind** (Rider, WebStorm, VS Code, Visual Studio,
Zed, or Custom), and an optional path (blank = auto-detect for known kinds; required for Custom). Tick the
Zed, **Console**, **File Explorer**, or Custom), and an optional path (blank = auto-detect for known kinds;
required for Custom). For **Console** the path is the **terminal program** and for **File Explorer** the
**file manager** (blank = the OS default; a full path or a bare command name like `wt` / `pwsh` both work),
so you can point Fido at the terminal you prefer. Tick the
**●** radio to set the default (the Open button / Enter); the rest are reached by **Ctrl+1 … Ctrl+9**
or by their slug on the command line. **Add** appends a new editor; **✕** removes one.
or by their slug on the command line. **Add** appends a new row; **✕** removes one.
- **Worktree root** — leave blank for the sibling `<repo>.worktrees` convention.
- **New-branch repos** — the repositories Fido may place a branch into in **branch-only mode**
when the branch isn't checked out anywhere. Click **Detect** to scan your search roots for git
Expand Down Expand Up @@ -267,6 +294,7 @@ the next save writes to the new location.
| Placement | Switch main tree **or** create a linked worktree |
| Open target | `.sln` / `.slnx` / `.slnf` solution, or the repo folder |
| Editors | Rider / WebStorm / VS Code / Visual Studio / Zed / Custom — default + Ctrl+1…9, or by CLI slug |
| Folder targets | **Console** (`term`) opens a terminal, **File Explorer** (`files`) the OS file manager — Windows / macOS / Linux |
| Editor discovery | Explicit path → PATH → standard installs (per kind) |
| Commit links | Short HEAD hash, clickable to the GitHub commit |
| Config | `%APPDATA%\Fido\config.json` (migrates the legacy folder) |
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

Give it a branch name; it locates the matching Git worktree on disk — switching or
creating one when needed — and opens the solution or repo folder in your editor. Pick a default
(opened with **Enter**); other editors are a **Ctrl+1 … Ctrl+9** away.
(opened with **Enter**); other editors are a **Ctrl+1 … Ctrl+9** away. It can also drop you into a
**terminal** or open the folder in your **file explorer** — on Windows, macOS, and Linux.

<p align="center">
<img src="Docs/screenshots/the-eagle-has-landed.png" alt="Fido — GO! WebStorm launched; “The Eagle has landed”" width="440">
Expand All @@ -27,13 +28,15 @@ when a choice is genuinely needed):
fido feature/new-ui # resolve the branch, open in the default editor
fido feature/new-ui -s MyApp # open MyApp's solution on that branch
fido feature/new-ui zed # open in a specific editor by its slug
fido feature/new-ui term # open a terminal on that branch (files = file explorer)
fido -b feature/new-ui -s MyApp -e vs # the same, with explicit options
```

Each editor has a short **slug** (built-in: `rider`, `vsc`, `vs`, `zed`) that you can pass as the
**second argument** — or explicitly with `-e` / `--editor` — to open in that editor instead of the
default. Slugs are editable per editor in **Settings**; an unknown slug stops with a clear **No-go**
rather than silently using the default. See **[Features](Docs/Features.md)** for the full reference.
Each target has a short **slug** (built-in: `rider`, `vsc`, `vs`, `zed`, plus `term` for a terminal and
`files` for the file explorer) that you can pass as the **second argument** — or explicitly with `-e` /
`--editor` — to open in that target instead of the default. Slugs are editable in **Settings**; an unknown
slug stops with a clear **No-go** rather than silently using the default. See
**[Features](Docs/Features.md)** for the full reference.

---

Expand Down
2 changes: 1 addition & 1 deletion src/Models/AppConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public sealed class AppConfig
/// Latest config schema version. Bumped when a one-time forward-migration is needed (e.g. seeding a
/// newly-introduced built-in editor into existing lists); see <c>ConfigService.Normalize</c>.
/// </summary>
public const int CurrentConfigVersion = 1;
public const int CurrentConfigVersion = 2;

/// <summary>
/// Schema version of the loaded config; <c>0</c> for files written before versioning. Drives the
Expand Down
12 changes: 8 additions & 4 deletions src/Models/Editor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ public sealed class Editor
public EditorKind Kind { get; set; } = EditorKind.Custom;

/// <summary>
/// True when this editor understands only a project folder, never a <c>.sln</c>/<c>.slnx</c> (e.g. WebStorm).
/// Fido forces folder mode for these and skips the "which solution?" chooser, always handing over the folder.
/// True when this target understands only a project folder, never a <c>.sln</c>/<c>.slnx</c> — WebStorm,
/// or the non-editor <see cref="EditorKind.Console"/> / <see cref="EditorKind.FileExplorer"/> targets, which
/// always open the folder itself. Fido forces folder mode for these and skips the "which solution?" chooser.
/// </summary>
public bool OpensFolderOnly => Kind == EditorKind.WebStorm;
public bool OpensFolderOnly => Kind is EditorKind.WebStorm or EditorKind.Console or EditorKind.FileExplorer;

/// <summary>Explicit path to the executable/app bundle; auto-detected from <see cref="Kind"/> when null/empty.</summary>
public string? Path { get; set; }
Expand All @@ -36,13 +37,16 @@ public sealed class Editor
/// </summary>
public string? Arguments { get; set; }

/// <summary>The built-in editors offered out of the box, in shortcut order; Rider is the default.</summary>
/// <summary>The built-in targets offered out of the box, in shortcut order; Rider is the default. The
/// last two — Console and File Explorer — open the folder in a terminal or the OS file manager.</summary>
public static List<Editor> Defaults() => new()
{
new Editor { Name = "Rider", Kind = EditorKind.Rider, Slug = "rider" },
new Editor { Name = "WebStorm", Kind = EditorKind.WebStorm, Slug = "ws" },
new Editor { Name = "VS Code", Kind = EditorKind.VsCode, Slug = "vsc" },
new Editor { Name = "Visual Studio", Kind = EditorKind.VisualStudio, Slug = "vs" },
new Editor { Name = "Zed", Kind = EditorKind.Zed, Slug = "zed" },
new Editor { Name = "Console", Kind = EditorKind.Console, Slug = "term" },
new Editor { Name = "File Explorer", Kind = EditorKind.FileExplorer, Slug = "files" },
};
}
15 changes: 15 additions & 0 deletions src/Models/EditorKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,19 @@ public enum EditorKind

/// <summary>Zed.</summary>
Zed,

/// <summary>
/// A terminal/console opened at the folder. Not an editor: the located program is a terminal emulator
/// (Windows Terminal / cmd / PowerShell, macOS Terminal, a Linux terminal) and it's always handed the
/// folder, never a <c>.sln</c>. The configured <see cref="Editor.Path"/> picks the terminal; blank
/// auto-detects the OS default.
/// </summary>
Console,

/// <summary>
/// The OS file manager (Windows Explorer, macOS Finder, a Linux file manager) revealing the folder.
/// Like <see cref="Console"/> it always opens the folder; <see cref="Editor.Path"/> overrides the
/// file manager, blank auto-detects the OS default.
/// </summary>
FileExplorer,
}
9 changes: 9 additions & 0 deletions src/Services/ConfigService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ private static AppConfig Normalize(AppConfig cfg)
if (cfg.Editors.All(e => e.Kind != EditorKind.WebStorm))
cfg.Editors.Add(Editor.Defaults().First(e => e.Kind == EditorKind.WebStorm));
}
if (cfg.ConfigVersion < 2)
{
// Console and File Explorer became built-in open targets. Append whichever a pre-v2 config is
// missing — appended, like WebStorm, so existing editor positions and the default index hold.
// The version stamp below stops this re-running, so removing them later makes the removal stick.
foreach (var kind in new[] { EditorKind.Console, EditorKind.FileExplorer })
if (cfg.Editors.All(e => e.Kind != kind))
cfg.Editors.Add(Editor.Defaults().First(e => e.Kind == kind));
}
cfg.ConfigVersion = AppConfig.CurrentConfigVersion;

cfg.DefaultEditorIndex = Math.Clamp(cfg.DefaultEditorIndex, 0, cfg.Editors.Count - 1);
Expand Down
Loading
Loading