Skip to content

Commit b521537

Browse files
committed
fix: prefer Git for Windows bash.exe when available on Windows
Per @orhun's review on orhun#66: most users running terminal apps on Windows want a POSIX shell so the Ratatui demos behave the same as on Linux/macOS. The default-shell lookup now walks, in order: 1. `$SHELL` (already supported — useful when launching from Git Bash so the inherited shell is honoured). 2. Git for Windows `bash.exe` in well-known install locations: - `%ProgramW6432%\Git\{bin,usr/bin}\bash.exe` - `%ProgramFiles%\Git\{bin,usr/bin}\bash.exe` - `%ProgramFiles(x86)%\Git\{bin,usr/bin}\bash.exe` - `%LOCALAPPDATA%\Programs\Git\{bin,usr/bin}\bash.exe` 3. `bash.exe` anywhere on `PATH` (covers scoop / chocolatey installs). 4. `%COMSPEC%` (typically resolves to `cmd.exe`). 5. Literal `cmd.exe` as the final fallback. Verified on Windows 11 with Git for Windows installed at the default location — `bash.exe` is now the spawned PTY child: ProcessId : 204736 Name : bash.exe CommandLine : "C:\Program Files\Git/bin/bash.exe" Removing the Git install reverts to the `%COMSPEC%` / `cmd.exe` fallback verified by the previous commit.
1 parent 46cfe53 commit b521537

1 file changed

Lines changed: 56 additions & 2 deletions

File tree

src/runtime.rs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,17 @@ pub struct TerminalRuntime {
186186

187187
/// Returns the default shell for the current platform.
188188
///
189-
/// On Windows this prefers `%COMSPEC%` (the resolved command processor) and
190-
/// falls back to `cmd.exe`. On other platforms it falls back to `/bin/sh`.
189+
/// On Windows this prefers Git for Windows' `bash.exe` when it can be found
190+
/// (most users running terminal apps on Windows want a POSIX shell so the
191+
/// Ratatui demos behave the same as on Linux/macOS), then `%COMSPEC%` (the
192+
/// resolved command processor), and finally `cmd.exe`. On other platforms
193+
/// it falls back to `/bin/sh`.
191194
fn default_shell() -> String {
192195
#[cfg(windows)]
193196
{
197+
if let Some(bash) = find_git_bash() {
198+
return bash;
199+
}
194200
env::var("COMSPEC").unwrap_or_else(|_| "cmd.exe".to_string())
195201
}
196202
#[cfg(not(windows))]
@@ -199,6 +205,54 @@ fn default_shell() -> String {
199205
}
200206
}
201207

208+
/// Looks for a Git for Windows `bash.exe` in the well-known install
209+
/// locations, then on `PATH`. Returns the first match.
210+
#[cfg(windows)]
211+
fn find_git_bash() -> Option<String> {
212+
use std::path::PathBuf;
213+
214+
// Standard Git for Windows install locations resolved via env vars so we
215+
// honour installs on non-C: drives. `usr/bin/bash.exe` is the MSYS shell
216+
// bundled with Git for Windows; `bin/bash.exe` is the shim used by the
217+
// Git Bash launcher. Either is a fine PTY shell.
218+
let env_bases = ["ProgramW6432", "ProgramFiles", "ProgramFiles(x86)"];
219+
let install_subpaths = ["Git/bin/bash.exe", "Git/usr/bin/bash.exe"];
220+
221+
for env_var in env_bases {
222+
let Ok(base) = env::var(env_var) else {
223+
continue;
224+
};
225+
for sub in install_subpaths {
226+
let candidate = PathBuf::from(&base).join(sub);
227+
if candidate.is_file() {
228+
return candidate.into_os_string().into_string().ok();
229+
}
230+
}
231+
}
232+
233+
// Per-user install (Git for Windows scoop / user installer).
234+
if let Ok(local_appdata) = env::var("LOCALAPPDATA") {
235+
for sub in install_subpaths {
236+
let candidate = PathBuf::from(&local_appdata).join("Programs").join(sub);
237+
if candidate.is_file() {
238+
return candidate.into_os_string().into_string().ok();
239+
}
240+
}
241+
}
242+
243+
// Fall back to a `PATH` lookup so a custom install or `scoop shim` works.
244+
if let Ok(path) = env::var("PATH") {
245+
for entry in env::split_paths(&path) {
246+
let candidate = entry.join("bash.exe");
247+
if candidate.is_file() {
248+
return candidate.into_os_string().into_string().ok();
249+
}
250+
}
251+
}
252+
253+
None
254+
}
255+
202256
impl TerminalRuntime {
203257
/// Spawns the shell PTY runtime.
204258
///

0 commit comments

Comments
 (0)