Browse Source

Exa now recognizes pipes, devices, and sockets on unix systems. Fixes #112

Linden Krouse 9 years ago
parent
commit
a9bb275250
5 changed files with 75 additions and 9 deletions
  1. 1 1
      src/fs/fields.rs
  2. 59 6
      src/fs/file.rs
  3. 6 0
      src/output/colours.rs
  4. 4 1
      src/output/details.rs
  5. 5 1
      src/output/mod.rs

+ 1 - 1
src/fs/fields.rs

@@ -41,7 +41,7 @@ pub type uid_t = u32;
 /// file’s contents. So “link” is a type, but “image” is just a type of
 /// regular file. (See the `filetype` module for those checks.)
 pub enum Type {
-    File, Directory, Pipe, Link, Special,
+    File, Directory, Pipe, Link, Socket, CharDevice, BlockDevice, Special,
 }
 
 impl Type {

+ 59 - 6
src/fs/file.rs

@@ -10,6 +10,8 @@ use std::path::{Path, PathBuf};
 use fs::dir::Dir;
 use fs::fields as f;
 
+#[cfg(any(target_os = "macos", target_os = "linux"))]
+use std::os::unix::fs::FileTypeExt;
 
 /// Constant table copied from https://doc.rust-lang.org/src/std/sys/unix/ext/fs.rs.html#11-259
 /// which is currently unstable and lacks vision for stabilization,
@@ -145,12 +147,7 @@ impl<'dir> File<'dir> {
     /// Whether this file is a symlink on the filesystem.
     pub fn is_link(&self) -> bool {
         self.metadata.file_type().is_symlink()
-    }
-
-    /// Whether this file is a named pipe on the filesystem.
-    pub fn is_pipe(&self) -> bool {
-        false  // TODO: Still waiting on this one...
-    }
+    }    
 
     /// Whether this file is a dotfile, based on its name. In Unix, file names
     /// beginning with a dot represent system or configuration files, and
@@ -283,6 +280,15 @@ impl<'dir> File<'dir> {
         else if self.is_link() {
             f::Type::Link
         }
+        else if self.is_char_device() {
+            f::Type::CharDevice
+        }
+        else if self.is_block_device() {
+            f::Type::BlockDevice
+        }
+        else if self.is_socket() {
+            f::Type::Socket
+        }
         else {
             f::Type::Special
         }
@@ -347,6 +353,53 @@ impl<'dir> File<'dir> {
     }
 }
 
+#[cfg(any(target_os = "macos", target_os = "linux"))]
+impl<'dir> File<'dir> {
+    /// Whether this file is a named pipe on the filesystem.
+    pub fn is_pipe(&self) -> bool {
+        self.metadata.file_type().is_fifo()
+    }
+    
+    /// Whether this file is a char device on the filesystem.
+    pub fn is_char_device(&self) -> bool {
+        self.metadata.file_type().is_char_device()
+    }
+    
+    /// Whether this file is a block device on the filesystem.
+    pub fn is_block_device(&self) -> bool {
+        self.metadata.file_type().is_block_device()
+    }
+    
+    /// Whether this file is a socket on the filesystem.
+    pub fn is_socket(&self) -> bool {
+        self.metadata.file_type().is_socket()
+    }
+}
+
+#[cfg(not(any(target_os = "macos", target_os = "linux")))]
+impl<'dir> File<'dir> {
+    /// Whether this file is a named pipe on the filesystem.
+    pub fn is_pipe(&self) -> bool {
+        false
+    }
+    
+    /// Whether this file is a char device on the filesystem.
+    pub fn is_char_device(&self) -> bool {
+        false
+    }
+    
+    /// Whether this file is a block device on the filesystem.
+    pub fn is_block_device(&self) -> bool {
+        false
+    }
+    
+    /// Whether this file is a socket on the filesystem.
+    pub fn is_socket(&self) -> bool {
+        false
+    }
+}
+
+
 impl<'a> AsRef<File<'a>> for File<'a> {
     fn as_ref(&self) -> &File<'a> {
         &self

+ 6 - 0
src/output/colours.rs

@@ -27,6 +27,9 @@ pub struct FileTypes {
     pub normal: Style,
     pub directory: Style,
     pub symlink: Style,
+    pub pipe: Style,
+    pub device: Style,
+    pub socket: Style,
     pub special: Style,
     pub executable: Style,
     pub image: Style,
@@ -99,6 +102,9 @@ impl Colours {
                 normal:      Style::default(),
                 directory:   Blue.bold(),
                 symlink:     Cyan.normal(),
+                pipe:        Yellow.normal(),
+                device:      Yellow.bold(),
+                socket:      Red.bold(),
                 special:     Yellow.normal(),
                 executable:  Green.bold(),
                 image:       Fixed(133).normal(),

+ 4 - 1
src/output/details.rs

@@ -515,8 +515,11 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
         let type_char = match file_type {
             f::Type::File       => types.normal.paint("."),
             f::Type::Directory  => types.directory.paint("d"),
-            f::Type::Pipe       => types.special.paint("|"),
+            f::Type::Pipe       => types.pipe.paint("|"),
             f::Type::Link       => types.symlink.paint("l"),
+            f::Type::CharDevice => types.device.paint("c"),
+            f::Type::BlockDevice => types.device.paint("b"),
+            f::Type::Socket     => types.socket.paint("s"),
             f::Type::Special    => types.special.paint("?"),
         };
 

+ 5 - 1
src/output/mod.rs

@@ -84,7 +84,11 @@ pub fn file_colour(colours: &Colours, file: &File) -> Style {
         f if f.is_directory()        => colours.filetypes.directory,
         f if f.is_executable_file()  => colours.filetypes.executable,
         f if f.is_link()             => colours.filetypes.symlink,
-        f if !f.is_file()            => colours.filetypes.special,
+        f if f.is_pipe()               => colours.filetypes.pipe,
+        f if f.is_char_device() 
+           | f.is_block_device()     => colours.filetypes.device,
+        f if f.is_socket()           => colours.filetypes.socket,
+        f if !f.is_file()            => colours.filetypes.special,        
         f if f.is_immediate()        => colours.filetypes.immediate,
         f if f.is_image()            => colours.filetypes.image,
         f if f.is_video()            => colours.filetypes.video,