mirror of
https://github.com/eza-community/eza.git
synced 2025-08-04 17:08:42 +00:00
fix(hyperlink): escape spaces in file path to make them work correctly
Some terminal emulator do it themselves, but we want to be correct everywhere
This commit is contained in:
parent
5bf6e3d06b
commit
dc6075474f
2 changed files with 34 additions and 17 deletions
|
@ -6,6 +6,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
use super::file_name::QuoteStyle;
|
||||
use nu_ansi_term::{AnsiString as ANSIString, Style};
|
||||
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
|
||||
|
||||
pub fn escape(
|
||||
string: String,
|
||||
|
@ -43,3 +44,34 @@ pub fn escape(
|
|||
bits.push(quote_bit);
|
||||
}
|
||||
}
|
||||
|
||||
const HYPERLINK_ESCAPE_CHARS: &AsciiSet = &CONTROLS.add(b' ');
|
||||
const HYPERLINK_OPENING_START: &str = "\x1B]8;;";
|
||||
const HYPERLINK_OPENING_END: &str = "\x1B\x5C";
|
||||
// Combination of both above tags
|
||||
pub const HYPERLINK_CLOSING: &str = "\x1B]8;;\x1B\x5C";
|
||||
|
||||
pub fn get_hyperlink_start_tag(abs_path: &str) -> String {
|
||||
let abs_path = utf8_percent_encode(abs_path, HYPERLINK_ESCAPE_CHARS).to_string();
|
||||
|
||||
// On Windows, `std::fs::canonicalize` adds the Win32 File prefix, which we need to remove
|
||||
#[cfg(target_os = "windows")]
|
||||
let abs_path = abs_path.strip_prefix("\\\\?\\").unwrap_or(&abs_path);
|
||||
|
||||
format!("{HYPERLINK_OPENING_START}file://{abs_path}{HYPERLINK_OPENING_END}")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn hyperlink_start_tag_escape_spaces() {
|
||||
assert_eq!(
|
||||
get_hyperlink_start_tag("/folder name/file name").to_string(),
|
||||
format!(
|
||||
"{HYPERLINK_OPENING_START}file:///folder%20name/file%20name{HYPERLINK_OPENING_END}"
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -408,11 +408,6 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
|
|||
&self,
|
||||
style_override: Option<Style>,
|
||||
) -> Vec<ANSIString<'unused>> {
|
||||
use percent_encoding::{utf8_percent_encode, CONTROLS};
|
||||
|
||||
const HYPERLINK_START: &str = "\x1B]8;;";
|
||||
const HYPERLINK_END: &str = "\x1B\x5C";
|
||||
|
||||
let file_style = style_override.unwrap_or(self.style());
|
||||
let mut bits = Vec::new();
|
||||
|
||||
|
@ -423,15 +418,7 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
|
|||
.absolute_path()
|
||||
.and_then(|p| p.as_os_str().to_str())
|
||||
{
|
||||
let abs_path = utf8_percent_encode(abs_path, CONTROLS).to_string();
|
||||
|
||||
// On Windows, `std::fs::canonicalize` adds the Win32 File prefix, which we need to remove
|
||||
#[cfg(target_os = "windows")]
|
||||
let abs_path = abs_path.strip_prefix("\\\\?\\").unwrap_or(&abs_path);
|
||||
|
||||
bits.push(ANSIString::from(format!(
|
||||
"{HYPERLINK_START}file://{abs_path}{HYPERLINK_END}"
|
||||
)));
|
||||
bits.push(ANSIString::from(escape::get_hyperlink_start_tag(abs_path)));
|
||||
|
||||
display_hyperlink = true;
|
||||
}
|
||||
|
@ -446,9 +433,7 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
|
|||
);
|
||||
|
||||
if display_hyperlink {
|
||||
bits.push(ANSIString::from(format!(
|
||||
"{HYPERLINK_START}{HYPERLINK_END}"
|
||||
)));
|
||||
bits.push(ANSIString::from(escape::HYPERLINK_CLOSING));
|
||||
}
|
||||
|
||||
bits
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue