[Windows] Hints can't open drive-letter / UNC / MSYS-style paths — mintty's path-opening pipeline as a design reference
Environment
- Windows 11 (26100), rio 0.5.28 — also verified against current
main - Shell: MSYS2 fish emitting OSC 7 in
file:///D:/...drive-letter form on every prompt (terminal.current_directoryconfirmed set)
What works / what fails (OSC 7 cwd set; targets exist on disk)
| hint text | default regex matches | opens |
|---|---|---|
https://... and other listed schemes |
yes | yes |
./foo.rs, ../bar, src/main.rs (relative) |
yes | yes (joined with OSC 7 cwd) |
C:\Users\me\file.txt |
no | — |
\\server\share\file.txt (UNC) |
no | — |
/d/projects/foo (MSYS absolute) |
yes (rooted-path branch) | no — silently fails |
Root causes (refs from current main)
DEFAULT_URL_REGEX(rio-backend/src/config/hints.rs) is a verbatim port of ghostty'ssrc/config/url.zig. ghostty ships no Windows frontend, so the regex has no drive-letter/UNC alternations. Windows users must hand-write a rule — and defining any rule replaces the built-in default, forcing a re-paste of the whole regex just to add one branch.resolve_path_for_opening(frontends/rioterm/src/hints.rs): for/d/projects/foo,PathBuf::is_absolute()is false on Windows (no drive letter), so it is joined with cwd,exists()fails, and the caller falls back to handing the raw text toShellExecuteW— a no-op from the user's perspective (only atracing::warn). There is no POSIX↔Windows conversion layer.URI_SCHEMES(frontends/rioterm/src/hints.rs) is a hard-coded closed list, so custom registered protocols (vscode://,jetbrains://, ...) never route to the OS opener.
Related: #440 tracks the sibling gap — foreground_process_path is unimplemented on Windows, so spawn contexts have no cwd either. This issue is specifically about the hint open pipeline, where OSC 7 already works.
Reference: how mintty gets "almost everything" right
mintty has no user-facing regexes in this pipeline at all:
- Word extraction without regex:
src/termmouse.cexpands bidirectionally from the click point using character classes (_#%~+-,.$@/\), balanced parens, escaped spaces. - URL decision is a heuristic, not a list:
win_open(src/winclip.c) treats "leading alpha segment +:" as a URL and hands it toShellExecuteW— the registry decides the protocol, so custom schemes work for free. - Path resolution:
guardpath(src/winmain.c) does~expansion, joins relative paths against the foreground shell's cwd, stripsfile:. - POSIX↔Windows conversion:
path_posix_to_win_wmaps/cygdrive/d/...and WSL/mnt/d/...toD:\...beforeshell_exec.
The one mintty capability rio cannot port: mintty reads the foreground shell's cwd via /proc/<fgpid>/cwd (src/child.c get_foreground_cwd, 2ms race retry) — a Cygwin privilege with no Win32 equivalent. rio's OSC 7 cwd is the correct substitute (ghostty's resolvePathForOpening likewise relies on OSC 7 getPwd), so that part is already at parity.
Suggested changes (all Windows-scoped)
- Platform-specific default regex: add drive-letter (
[A-Za-z]:[\\/]...) and UNC (\\\\host\\share...) alternations to the built-in default rule on Windows. - In
resolve_path_for_opening, before giving up, try POSIX→Windows conversions with existence checks:/x/...→X:\...(MSYS),/cygdrive/x/...,/mnt/x/...(WSL) — mirroring mintty'spath_posix_to_win_w; fixes the silent/d/...failure. - Keep the closed-list safety model of
Open(the #1811 fix was the right call), but make the list extendable via config so users can opt invscode://etc. (mintty's blanket "letters +:" heuristic would also route risky registered handlers likesearch-ms:, so I would not copy it wholesale.)
Happy to test patches on Windows (MSYS2 CLANG64 + native toolchains available).
Source: raphamorim/rio