Просмотр исходного кода

fix(hyperlink): respect spec on Windows and make it for with Konsole

Mélanie Chauvel 2 лет назад
Родитель
Сommit
c5249db189
3 измененных файлов с 16 добавлено и 38 удалено
  1. 3 20
      Cargo.lock
  2. 1 2
      Cargo.toml
  3. 12 16
      src/output/file_name.rs

+ 3 - 20
Cargo.lock

@@ -361,7 +361,6 @@ dependencies = [
  "ansiterm",
  "chrono",
  "criterion",
- "gethostname",
  "git2",
  "glob",
  "lazy_static",
@@ -371,6 +370,7 @@ dependencies = [
  "natord",
  "num_cpus",
  "number_prefix",
+ "percent-encoding",
  "phf",
  "proc-mounts",
  "scoped_threadpool",
@@ -379,7 +379,6 @@ dependencies = [
  "timeago",
  "trycmd",
  "unicode-width",
- "urlencoding",
  "uzers",
  "zoneinfo_compiled",
 ]
@@ -412,16 +411,6 @@ dependencies = [
  "percent-encoding",
 ]
 
-[[package]]
-name = "gethostname"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
-dependencies = [
- "libc",
- "windows-targets",
-]
-
 [[package]]
 name = "git2"
 version = "0.18.0"
@@ -753,9 +742,9 @@ dependencies = [
 
 [[package]]
 name = "percent-encoding"
-version = "2.1.0"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
 
 [[package]]
 name = "phf"
@@ -1258,12 +1247,6 @@ dependencies = [
  "percent-encoding",
 ]
 
-[[package]]
-name = "urlencoding"
-version = "2.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
-
 [[package]]
 name = "utf8parse"
 version = "0.2.1"

+ 1 - 2
Cargo.toml

@@ -72,7 +72,6 @@ name = "eza"
 
 [dependencies]
 ansiterm = "0.12.2"
-gethostname = "0.4.3"
 chrono = { version = "0.4.31", default-features = false, features = ["clock"] }
 glob = "0.3"
 lazy_static = "1.3"
@@ -82,13 +81,13 @@ log = "0.4"
 natord = "1.0"
 num_cpus = "1.16"
 number_prefix = "0.4"
+percent-encoding = "2.3.0"
 phf = { version = "0.11.2", features = ["macros"] }
 scoped_threadpool = "0.1"
 term_grid = "0.1"
 terminal_size = "0.2.6"
 timeago = { version = "0.4.2", default-features = false }
 unicode-width = "0.1"
-urlencoding = "2.1.3"
 zoneinfo_compiled = "0.5.1"
 
 [dependencies.git2]

+ 12 - 16
src/output/file_name.rs

@@ -10,9 +10,6 @@ use crate::output::escape;
 use crate::output::icons::{icon_for_file, iconify_style};
 use crate::output::render::FiletypeColours;
 
-const HYPERLINK_START: &str = "\x1B]8;;";
-const HYPERLINK_END: &str = "\x1B\x5C";
-
 /// Basically a file name factory.
 #[derive(Debug, Copy, Clone)]
 pub struct Options {
@@ -345,26 +342,25 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
     /// So in that situation, those characters will be escaped and highlighted in
     /// a different colour.
     fn escaped_file_name<'unused>(&self) -> Vec<ANSIString<'unused>> {
+        use percent_encoding::{CONTROLS, utf8_percent_encode};
+
+        const HYPERLINK_START: &str = "\x1B]8;;";
+        const HYPERLINK_END: &str = "\x1B\x5C";
+
         let file_style = self.style();
         let mut bits = Vec::new();
 
         let mut display_hyperlink = false;
         if self.options.embed_hyperlinks == EmbedHyperlinks::On {
             if let Some(abs_path) = self.file.absolute_path().and_then(|p| p.as_os_str().to_str()) {
-                #[cfg(not(target_os = "windows"))]
-                bits.insert(0, ANSIString::from(format!(
-                    "{}file://{}{}{}",
-                    HYPERLINK_START,
-                    gethostname::gethostname().to_str().unwrap_or(""),
-                    urlencoding::encode(abs_path).replace("%2F", "/"),
-                    HYPERLINK_END,
-                )));
+                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")]
-                bits.insert(0, ANSIString::from(format!(
-                    "{}file://{}{}",
-                    HYPERLINK_START,
-                    abs_path.replace("\\\\?\\", ""),
-                    HYPERLINK_END,
+                let abs_path = abs_path.strip_prefix("\\\\?\\").unwrap_or(&abs_path);
+
+                bits.push(ANSIString::from(format!(
+                    "{HYPERLINK_START}file://{abs_path}{HYPERLINK_END}"
                 )));
 
                 display_hyperlink = true;