diff options
Diffstat (limited to 'src/term.rs')
| -rw-r--r-- | src/term.rs | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/term.rs b/src/term.rs index b993108..4c6ac90 100644 --- a/src/term.rs +++ b/src/term.rs @@ -1,10 +1,13 @@ -use std::io::{self, BufRead, StdoutLock, Write}; +use std::{ + fmt, fs, + io::{self, BufRead, StdoutLock, Write}, +}; use crossterm::{ cursor::MoveTo, - style::{Color, ResetColor, SetForegroundColor}, + style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor}, terminal::{Clear, ClearType}, - QueueableCommand, + Command, QueueableCommand, }; /// Terminal progress bar to be used when not using Ratataui. @@ -68,3 +71,43 @@ pub fn press_enter_prompt(stdout: &mut StdoutLock) -> io::Result<()> { stdout.write_all(b"\n")?; Ok(()) } + +pub fn terminal_file_link(stdout: &mut StdoutLock, path: &str, color: Color) -> io::Result<()> { + let canonical_path = fs::canonicalize(path).ok(); + + let Some(canonical_path) = canonical_path.as_deref().and_then(|p| p.to_str()) else { + return stdout.write_all(path.as_bytes()); + }; + + // Windows itself can't handle its verbatim paths. + #[cfg(windows)] + let canonical_path = if canonical_path.len() > 5 && &canonical_path[0..4] == r"\\?\" { + &canonical_path[4..] + } else { + canonical_path + }; + + stdout + .queue(SetForegroundColor(color))? + .queue(SetAttribute(Attribute::Underlined))?; + write!( + stdout, + "\x1b]8;;file://{canonical_path}\x1b\\{path}\x1b]8;;\x1b\\", + )?; + stdout.queue(ResetColor)?; + + Ok(()) +} + +pub fn write_ansi(output: &mut Vec<u8>, command: impl Command) { + struct FmtWriter<'a>(&'a mut Vec<u8>); + + impl fmt::Write for FmtWriter<'_> { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.0.extend_from_slice(s.as_bytes()); + Ok(()) + } + } + + let _ = command.write_ansi(&mut FmtWriter(output)); +} |
