Преглед изворни кода

Merge branch 'main' into mac-major-device-fix

Christina Sørensen пре 2 година
родитељ
комит
401510a2ef
7 измењених фајлова са 134 додато и 110 уклоњено
  1. 3 1
      .github/workflows/label.yml
  2. 3 20
      Cargo.lock
  3. 1 2
      Cargo.toml
  4. 25 1
      man/eza_colors.5.md
  5. 12 16
      src/output/file_name.rs
  6. 11 0
      src/theme/mod.rs
  7. 79 70
      src/theme/ui_styles.rs

+ 3 - 1
.github/workflows/label.yml

@@ -8,7 +8,9 @@
 # For inspiration see: https://github.com/NixOS/nixpkgs/blob/master/.github/workflows/labels.yml
 
 name: Labeler
-on: [pull_request_target]
+on:
+  pull_request_target:
+    types: [opened]
 
 jobs:
   label:

+ 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]

+ 25 - 1
man/eza_colors.5.md

@@ -81,6 +81,9 @@ LIST OF CODES
 
 `EZA_COLORS` can use many more:
 
+`oc`
+: the permissions displayed as octal
+
 `ur`
 : the user-read permission bit
 
@@ -198,6 +201,9 @@ LIST OF CODES
 `gi`
 : an ignored flag in Git
 
+`gc`
+: a conflicted flag in Git
+
 `xx`
 : “punctuation”, including many background UI elements
 
@@ -222,6 +228,9 @@ LIST OF CODES
 `bO`
 : the overlay style for broken symlink paths
 
+`sp`
+: special (not file, dir, mount, exec, pipe, socket, block device, char device, or link)
+
 `mp`
 : a mount point
 
@@ -255,7 +264,22 @@ LIST OF CODES
 `bu`
 : a regular file that is used to build a project (ex: Makefile)
 
-Values in `EZA_COLORS` override those given in `LS_COLORS`, so you don’t need to re-write an existing `LS_COLORS` variable with proprietary extensions.
+`Sn`
+: No security context on a file
+
+`Su`
+: SELinux user
+
+`Sr`
+: SELinux role
+
+`St`
+: SELinux type
+
+`Sl`
+: SELinux level
+
+Values in `EXA_COLORS` override those given in `LS_COLORS`, so you don’t need to re-write an existing `LS_COLORS` variable with proprietary extensions.
 
 
 LIST OF STYLES

+ 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;

+ 11 - 0
src/theme/mod.rs

@@ -404,6 +404,7 @@ mod customs_test {
 
     macro_rules! test {
         ($name:ident:  ls $ls:expr, exa $exa:expr  =>  colours $expected:ident -> $process_expected:expr) => {
+            #[allow(non_snake_case)]
             #[test]
             fn $name() {
                 let mut $expected = UiStyles::default();
@@ -546,6 +547,8 @@ mod customs_test {
     test!(exa_gd:  ls "", exa "gd=38;5;125"  =>  colours c -> { c.git.deleted               = Fixed(125).normal(); });
     test!(exa_gv:  ls "", exa "gv=38;5;126"  =>  colours c -> { c.git.renamed               = Fixed(126).normal(); });
     test!(exa_gt:  ls "", exa "gt=38;5;127"  =>  colours c -> { c.git.typechange            = Fixed(127).normal(); });
+    test!(exa_gi:  ls "", exa "gi=38;5;128"  =>  colours c -> { c.git.ignored               = Fixed(128).normal(); });
+    test!(exa_gc:  ls "", exa "gc=38;5;129"  =>  colours c -> { c.git.conflicted            = Fixed(129).normal(); });
 
     test!(exa_xx:  ls "", exa "xx=38;5;128"  =>  colours c -> { c.punctuation               = Fixed(128).normal(); });
     test!(exa_da:  ls "", exa "da=38;5;129"  =>  colours c -> { c.date                      = Fixed(129).normal(); });
@@ -554,9 +557,11 @@ mod customs_test {
     test!(exa_hd:  ls "", exa "hd=38;5;132"  =>  colours c -> { c.header                    = Fixed(132).normal(); });
     test!(exa_lp:  ls "", exa "lp=38;5;133"  =>  colours c -> { c.symlink_path              = Fixed(133).normal(); });
     test!(exa_cc:  ls "", exa "cc=38;5;134"  =>  colours c -> { c.control_char              = Fixed(134).normal(); });
+    test!(exa_oc:  ls "", exa "oc=38;5;135"  =>  colours c -> { c.octal                     = Fixed(135).normal(); });
     test!(exa_bo:  ls "", exa "bO=4"         =>  colours c -> { c.broken_path_overlay       = Style::default().underline(); });
 
     test!(exa_mp:  ls "", exa "mp=1;34;4"    =>  colours c -> { c.filekinds.mount_point     = Blue.bold().underline(); });
+    test!(exa_sp:  ls "", exa "sp=1;35;4"    =>  colours c -> { c.filekinds.special         = Purple.bold().underline(); });
 
     test!(exa_im:  ls "", exa "im=38;5;128"  =>  colours c -> { c.file_type.image           = Fixed(128).normal(); });
     test!(exa_vi:  ls "", exa "vi=38;5;129"  =>  colours c -> { c.file_type.video           = Fixed(129).normal(); });
@@ -569,6 +574,12 @@ mod customs_test {
     test!(exa_cm:  ls "", exa "cm=38;5;136"  =>  colours c -> { c.file_type.compiled        = Fixed(136).normal(); });
     test!(exa_ie:  ls "", exa "bu=38;5;137"  =>  colours c -> { c.file_type.build           = Fixed(137).normal(); });
 
+    test!(exa_Sn:  ls "", exa "Sn=38;5;128"  =>  colours c -> { c.security_context.none          = Fixed(128).normal(); });
+    test!(exa_Su:  ls "", exa "Su=38;5;129"  =>  colours c -> { c.security_context.selinux.user  = Fixed(129).normal(); });
+    test!(exa_Sr:  ls "", exa "Sr=38;5;130"  =>  colours c -> { c.security_context.selinux.role  = Fixed(130).normal(); });
+    test!(exa_St:  ls "", exa "St=38;5;131"  =>  colours c -> { c.security_context.selinux.typ   = Fixed(131).normal(); });
+    test!(exa_Sl:  ls "", exa "Sl=38;5;132"  =>  colours c -> { c.security_context.selinux.range = Fixed(132).normal(); });
+
     // All the while, LS_COLORS treats them as filenames:
     test!(ls_uu:   ls "uu=38;5;117", exa ""  =>  exts [ ("uu", Fixed(117).normal()) ]);
     test!(ls_un:   ls "un=38;5;118", exa ""  =>  exts [ ("un", Fixed(118).normal()) ]);

+ 79 - 70
src/theme/ui_styles.rs

@@ -21,7 +21,7 @@ pub struct UiStyles {
     pub inode:        Style,          // in
     pub blocks:       Style,          // bl
     pub header:       Style,          // hd
-    pub octal:        Style,
+    pub octal:        Style,          // oc
 
     pub symlink_path:         Style,  // lp
     pub control_char:         Style,  // cc
@@ -38,7 +38,7 @@ pub struct FileKinds {
     pub block_device: Style,  // bd
     pub char_device: Style,   // cd
     pub socket: Style,        // so
-    pub special: Style,
+    pub special: Style,       // sp
     pub executable: Style,    // ex
     pub mount_point: Style,   // mp
 }
@@ -104,21 +104,21 @@ pub struct Git {
     pub renamed: Style,     // gv
     pub typechange: Style,  // gt
     pub ignored: Style,     // gi
-    pub conflicted: Style,
+    pub conflicted: Style,  // gc
 }
 
 #[derive(Clone, Copy, Debug, Default, PartialEq)]
 pub struct SELinuxContext {
     pub colon: Style,
-    pub user:  Style,
-    pub role:  Style,
-    pub typ:   Style,
-    pub range: Style,
+    pub user:  Style,  // Su
+    pub role:  Style,  // Sr
+    pub typ:   Style,  // St
+    pub range: Style,  // Sl
 }
 
 #[derive(Clone, Copy, Debug, Default, PartialEq)]
 pub struct SecurityContext {
-    pub none:    Style,
+    pub none:    Style, // Sn
     pub selinux: SELinuxContext,
 }
 
@@ -174,71 +174,80 @@ impl UiStyles {
     /// so `set_ls` should have been run first.
     pub fn set_exa(&mut self, pair: &Pair<'_>) -> bool {
         match pair.key {
-            "ur" => self.perms.user_read          = pair.to_style(),
-            "uw" => self.perms.user_write         = pair.to_style(),
-            "ux" => self.perms.user_execute_file  = pair.to_style(),
-            "ue" => self.perms.user_execute_other = pair.to_style(),
-            "gr" => self.perms.group_read         = pair.to_style(),
-            "gw" => self.perms.group_write        = pair.to_style(),
-            "gx" => self.perms.group_execute      = pair.to_style(),
-            "tr" => self.perms.other_read         = pair.to_style(),
-            "tw" => self.perms.other_write        = pair.to_style(),
-            "tx" => self.perms.other_execute      = pair.to_style(),
-            "su" => self.perms.special_user_file  = pair.to_style(),
-            "sf" => self.perms.special_other      = pair.to_style(),
-            "xa" => self.perms.attribute          = pair.to_style(),
+            "ur" => self.perms.user_read                = pair.to_style(),
+            "uw" => self.perms.user_write               = pair.to_style(),
+            "ux" => self.perms.user_execute_file        = pair.to_style(),
+            "ue" => self.perms.user_execute_other       = pair.to_style(),
+            "gr" => self.perms.group_read               = pair.to_style(),
+            "gw" => self.perms.group_write              = pair.to_style(),
+            "gx" => self.perms.group_execute            = pair.to_style(),
+            "tr" => self.perms.other_read               = pair.to_style(),
+            "tw" => self.perms.other_write              = pair.to_style(),
+            "tx" => self.perms.other_execute            = pair.to_style(),
+            "su" => self.perms.special_user_file        = pair.to_style(),
+            "sf" => self.perms.special_other            = pair.to_style(),
+            "xa" => self.perms.attribute                = pair.to_style(),
 
             "sn" => self.set_number_style(pair.to_style()),
             "sb" => self.set_unit_style(pair.to_style()),
-            "nb" => self.size.number_byte         = pair.to_style(),
-            "nk" => self.size.number_kilo         = pair.to_style(),
-            "nm" => self.size.number_mega         = pair.to_style(),
-            "ng" => self.size.number_giga         = pair.to_style(),
-            "nt" => self.size.number_huge         = pair.to_style(),
-            "ub" => self.size.unit_byte           = pair.to_style(),
-            "uk" => self.size.unit_kilo           = pair.to_style(),
-            "um" => self.size.unit_mega           = pair.to_style(),
-            "ug" => self.size.unit_giga           = pair.to_style(),
-            "ut" => self.size.unit_huge           = pair.to_style(),
-            "df" => self.size.major               = pair.to_style(),
-            "ds" => self.size.minor               = pair.to_style(),
-
-            "uu" => self.users.user_you           = pair.to_style(),
-            "un" => self.users.user_someone_else  = pair.to_style(),
-            "gu" => self.users.group_yours        = pair.to_style(),
-            "gn" => self.users.group_not_yours    = pair.to_style(),
-
-            "lc" => self.links.normal             = pair.to_style(),
-            "lm" => self.links.multi_link_file    = pair.to_style(),
-
-            "ga" => self.git.new                  = pair.to_style(),
-            "gm" => self.git.modified             = pair.to_style(),
-            "gd" => self.git.deleted              = pair.to_style(),
-            "gv" => self.git.renamed              = pair.to_style(),
-            "gt" => self.git.typechange           = pair.to_style(),
-            "gi" => self.git.ignored              = pair.to_style(),
-
-            "xx" => self.punctuation              = pair.to_style(),
-            "da" => self.date                     = pair.to_style(),
-            "in" => self.inode                    = pair.to_style(),
-            "bl" => self.blocks                   = pair.to_style(),
-            "hd" => self.header                   = pair.to_style(),
-            "lp" => self.symlink_path             = pair.to_style(),
-            "cc" => self.control_char             = pair.to_style(),
-            "bO" => self.broken_path_overlay      = pair.to_style(),
-
-            "mp" => self.filekinds.mount_point    = pair.to_style(),
-
-            "im" => self.file_type.image          = pair.to_style(),
-            "vi" => self.file_type.video          = pair.to_style(),
-            "mu" => self.file_type.music          = pair.to_style(),
-            "lo" => self.file_type.lossless       = pair.to_style(),
-            "cr" => self.file_type.crypto         = pair.to_style(),
-            "do" => self.file_type.document       = pair.to_style(),
-            "co" => self.file_type.compressed     = pair.to_style(),
-            "tm" => self.file_type.temp           = pair.to_style(),
-            "cm" => self.file_type.compiled       = pair.to_style(),
-            "bu" => self.file_type.build          = pair.to_style(),
+            "nb" => self.size.number_byte               = pair.to_style(),
+            "nk" => self.size.number_kilo               = pair.to_style(),
+            "nm" => self.size.number_mega               = pair.to_style(),
+            "ng" => self.size.number_giga               = pair.to_style(),
+            "nt" => self.size.number_huge               = pair.to_style(),
+            "ub" => self.size.unit_byte                 = pair.to_style(),
+            "uk" => self.size.unit_kilo                 = pair.to_style(),
+            "um" => self.size.unit_mega                 = pair.to_style(),
+            "ug" => self.size.unit_giga                 = pair.to_style(),
+            "ut" => self.size.unit_huge                 = pair.to_style(),
+            "df" => self.size.major                     = pair.to_style(),
+            "ds" => self.size.minor                     = pair.to_style(),
+
+            "uu" => self.users.user_you                 = pair.to_style(),
+            "un" => self.users.user_someone_else        = pair.to_style(),
+            "gu" => self.users.group_yours              = pair.to_style(),
+            "gn" => self.users.group_not_yours          = pair.to_style(),
+
+            "lc" => self.links.normal                   = pair.to_style(),
+            "lm" => self.links.multi_link_file          = pair.to_style(),
+
+            "ga" => self.git.new                        = pair.to_style(),
+            "gm" => self.git.modified                   = pair.to_style(),
+            "gd" => self.git.deleted                    = pair.to_style(),
+            "gv" => self.git.renamed                    = pair.to_style(),
+            "gt" => self.git.typechange                 = pair.to_style(),
+            "gi" => self.git.ignored                    = pair.to_style(),
+            "gc" => self.git.conflicted                 = pair.to_style(),
+
+            "xx" => self.punctuation                    = pair.to_style(),
+            "da" => self.date                           = pair.to_style(),
+            "in" => self.inode                          = pair.to_style(),
+            "bl" => self.blocks                         = pair.to_style(),
+            "hd" => self.header                         = pair.to_style(),
+            "oc" => self.octal                          = pair.to_style(),
+            "lp" => self.symlink_path                   = pair.to_style(),
+            "cc" => self.control_char                   = pair.to_style(),
+            "bO" => self.broken_path_overlay            = pair.to_style(),
+
+            "mp" => self.filekinds.mount_point          = pair.to_style(),
+            "sp" => self.filekinds.special              = pair.to_style(),  // Catch-all for unrecognized file kind
+
+            "im" => self.file_type.image                = pair.to_style(),
+            "vi" => self.file_type.video                = pair.to_style(),
+            "mu" => self.file_type.music                = pair.to_style(),
+            "lo" => self.file_type.lossless             = pair.to_style(),
+            "cr" => self.file_type.crypto               = pair.to_style(),
+            "do" => self.file_type.document             = pair.to_style(),
+            "co" => self.file_type.compressed           = pair.to_style(),
+            "tm" => self.file_type.temp                 = pair.to_style(),
+            "cm" => self.file_type.compiled             = pair.to_style(),
+            "bu" => self.file_type.build                = pair.to_style(),
+
+            "Sn" => self.security_context.none          = pair.to_style(),
+            "Su" => self.security_context.selinux.user  = pair.to_style(),
+            "Sr" => self.security_context.selinux.role  = pair.to_style(),
+            "St" => self.security_context.selinux.typ   = pair.to_style(),
+            "Sl" => self.security_context.selinux.range = pair.to_style(),
 
              _   => return false,
         }