Enable Windows terminal VT output
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
This commit is contained in:
+68
-3
@@ -10232,15 +10232,71 @@ fn save_cache(path: &std::path::Path, cred: &CachedCredential) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RawMode;
|
struct RawMode {
|
||||||
|
#[cfg(windows)]
|
||||||
|
console_modes: WindowsConsoleModeGuard,
|
||||||
|
}
|
||||||
|
|
||||||
impl RawMode {
|
impl RawMode {
|
||||||
fn enter() -> Result<Self> {
|
fn enter() -> Result<Self> {
|
||||||
flush_local_terminal_input();
|
flush_local_terminal_input();
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
|
let raw = Self {
|
||||||
|
#[cfg(windows)]
|
||||||
|
console_modes: WindowsConsoleModeGuard::enter(),
|
||||||
|
};
|
||||||
flush_local_terminal_input();
|
flush_local_terminal_input();
|
||||||
drain_local_terminal_input();
|
drain_local_terminal_input();
|
||||||
Ok(Self)
|
Ok(raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(not(any(test, windows)), allow(dead_code))]
|
||||||
|
fn windows_vt_output_mode(mode: u32) -> u32 {
|
||||||
|
const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x0004;
|
||||||
|
mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
struct WindowsConsoleModeGuard {
|
||||||
|
output: Option<(windows_sys::Win32::Foundation::HANDLE, u32)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
impl WindowsConsoleModeGuard {
|
||||||
|
fn enter() -> Self {
|
||||||
|
unsafe {
|
||||||
|
use windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE;
|
||||||
|
use windows_sys::Win32::System::Console::{
|
||||||
|
GetConsoleMode, GetStdHandle, STD_OUTPUT_HANDLE, SetConsoleMode,
|
||||||
|
};
|
||||||
|
|
||||||
|
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
if handle.is_null() || handle == INVALID_HANDLE_VALUE {
|
||||||
|
return Self { output: None };
|
||||||
|
}
|
||||||
|
let mut original = 0u32;
|
||||||
|
if GetConsoleMode(handle, &mut original) == 0 {
|
||||||
|
return Self { output: None };
|
||||||
|
}
|
||||||
|
let desired = windows_vt_output_mode(original);
|
||||||
|
if desired != original {
|
||||||
|
let _ = SetConsoleMode(handle, desired);
|
||||||
|
}
|
||||||
|
Self {
|
||||||
|
output: Some((handle, original)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore(&self) {
|
||||||
|
if let Some((handle, mode)) = self.output {
|
||||||
|
unsafe {
|
||||||
|
use windows_sys::Win32::System::Console::SetConsoleMode;
|
||||||
|
|
||||||
|
let _ = SetConsoleMode(handle, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10304,6 +10360,8 @@ impl Drop for RawMode {
|
|||||||
let mut stdout = std::io::stdout();
|
let mut stdout = std::io::stdout();
|
||||||
let _ = stdout.write_all(TERMINAL_CLEANUP);
|
let _ = stdout.write_all(TERMINAL_CLEANUP);
|
||||||
let _ = stdout.flush();
|
let _ = stdout.flush();
|
||||||
|
#[cfg(windows)]
|
||||||
|
self.console_modes.restore();
|
||||||
let _ = disable_raw_mode();
|
let _ = disable_raw_mode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10369,7 +10427,7 @@ mod tests {
|
|||||||
vscode_command_candidates, vscode_safe_alias, wake_repaint_retry_deadline,
|
vscode_command_candidates, vscode_safe_alias, wake_repaint_retry_deadline,
|
||||||
windows_command_word, windows_deferred_update_script, windows_effective_url_script,
|
windows_command_word, windows_deferred_update_script, windows_effective_url_script,
|
||||||
windows_mode_from_readonly, windows_readonly_from_mode, windows_update_script,
|
windows_mode_from_readonly, windows_readonly_from_mode, windows_update_script,
|
||||||
windows_url_reachable_script,
|
windows_url_reachable_script, windows_vt_output_mode,
|
||||||
};
|
};
|
||||||
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
|
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
|
||||||
use dosh::native::EnvVar;
|
use dosh::native::EnvVar;
|
||||||
@@ -10478,6 +10536,13 @@ mod tests {
|
|||||||
assert!(!windows_readonly_from_mode(0o755));
|
assert!(!windows_readonly_from_mode(0o755));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn windows_vt_output_mode_enables_ansi_sequences() {
|
||||||
|
assert_eq!(windows_vt_output_mode(0), 0x0004);
|
||||||
|
assert_eq!(windows_vt_output_mode(0x0001), 0x0005);
|
||||||
|
assert_eq!(windows_vt_output_mode(0x0005), 0x0005);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cleanup_stream_state_removes_all_per_stream_state_only_for_target() {
|
fn cleanup_stream_state_removes_all_per_stream_state_only_for_target() {
|
||||||
let stream_id = 42;
|
let stream_id = 42;
|
||||||
|
|||||||
Reference in New Issue
Block a user