#1943·rio

[Windows] Hints can't open drive-letter / UNC / MSYS-style paths — mintty's path-opening pipeline as a design reference

Author: abcfy2Created Sep 18, 2026Updated Sep 18, 2026

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_directory confirmed 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)

  1. DEFAULT_URL_REGEX (rio-backend/src/config/hints.rs) is a verbatim port of ghostty's src/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.
  2. 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 to ShellExecuteW — a no-op from the user's perspective (only a tracing::warn). There is no POSIX↔Windows conversion layer.
  3. 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.c expands 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 to ShellExecuteW — 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, strips file:.
  • POSIX↔Windows conversion: path_posix_to_win_w maps /cygdrive/d/... and WSL /mnt/d/... to D:\... before shell_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)

  1. Platform-specific default regex: add drive-letter ([A-Za-z]:[\\/]...) and UNC (\\\\host\\share...) alternations to the built-in default rule on Windows.
  2. 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's path_posix_to_win_w; fixes the silent /d/... failure.
  3. 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 in vscode:// etc. (mintty's blanket "letters + :" heuristic would also route risky registered handlers like search-ms:, so I would not copy it wholesale.)

Happy to test patches on Windows (MSYS2 CLANG64 + native toolchains available).