diff --git a/Cargo.lock b/Cargo.lock index e223f44..f077439 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,13 +4,13 @@ version = "0.1.0" dependencies = [ "ansi_term 0.3.0 (git+https://github.com/ogham/rust-ansi-term.git)", "natord 1.0.0 (git+https://github.com/lifthrasiir/rust-natord.git)", - "users 0.1.0 (git+https://github.com/ogham/rust-users)", + "users 0.1.0 (git+https://github.com/ogham/rust-users.git)", ] [[package]] name = "ansi_term" version = "0.3.0" -source = "git+https://github.com/ogham/rust-ansi-term.git#4b9ea6cf266053e1a771e75b935b4e54c586c139" +source = "git+https://github.com/ogham/rust-ansi-term.git#e17d8d3dc56526247f88b0f279f90dc46342db49" [[package]] name = "natord" @@ -20,5 +20,5 @@ source = "git+https://github.com/lifthrasiir/rust-natord.git#83ebf6e7999fe2646bc [[package]] name = "users" version = "0.1.0" -source = "git+https://github.com/ogham/rust-users#221a1463d3e25acac41615186a1c7fdcf0ad36d7" +source = "git+https://github.com/ogham/rust-users.git#221a1463d3e25acac41615186a1c7fdcf0ad36d7" diff --git a/src/column.rs b/src/column.rs index f583eeb..ec19bb1 100644 --- a/src/column.rs +++ b/src/column.rs @@ -49,8 +49,8 @@ impl Column { impl Alignment { pub fn pad_string(&self, string: &String, padding: uint) -> String { match *self { - Alignment::Left => string.clone() + " ".repeat(padding).as_slice(), - Alignment::Right => " ".repeat(padding) + string.as_slice(), + Alignment::Left => format!("{}{}", string, " ".repeat(padding).as_slice()), + Alignment::Right => format!("{}{}", " ".repeat(padding), string.as_slice()), } } } diff --git a/src/dir.rs b/src/dir.rs index debd06a..16f80ad 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -24,7 +24,7 @@ impl Dir { let mut files = vec![]; for path in self.contents.iter() { - match File::from_path(path.clone(), Some(self)) { + match File::from_path(path, Some(self)) { Ok(file) => files.push(file), Err(e) => println!("{}: {}", path.display(), e), } diff --git a/src/exa.rs b/src/exa.rs index 44a735a..491e614 100644 --- a/src/exa.rs +++ b/src/exa.rs @@ -56,7 +56,7 @@ fn exa(opts: &Options) { else { // May as well reuse the stat result from earlier // instead of just using File::from_path(). - files.push(File::with_stat(stat, path, None)); + files.push(File::with_stat(stat, &path, None)); } } Err(e) => println!("{}: {}", file, e), @@ -72,7 +72,7 @@ fn exa(opts: &Options) { view(opts, files); } - for dir_name in dirs.into_iter() { + for dir_name in dirs.iter() { if first { first = false; } @@ -155,13 +155,12 @@ fn grid_view(across: bool, console_width: uint, files: Vec) { } let ref file = files[num]; - let file_name = file.name.clone(); - let styled_name = file.file_colour().paint(file_name.as_slice()).to_string(); + let styled_name = file.file_colour().paint(file.name.as_slice()).to_string(); if x == num_columns - 1 { print!("{}", styled_name); } else { - print!("{}", Left.pad_string(&styled_name, max_column_length - file_name.len() + 1)); + print!("{}", Left.pad_string(&styled_name, max_column_length - file.name.len() + 1)); } } print!("\n"); @@ -192,7 +191,7 @@ fn details_view(options: &Options, columns: &Vec, files: Vec) { // results are cached. let lengths: Vec> = table.iter() - .map(|row| row.iter().map(|col| strip_formatting(col.clone()).len()).collect()) + .map(|row| row.iter().map(|col| strip_formatting(col.as_slice()).len()).collect()) .collect(); let column_widths: Vec = range(0, columns.len()) diff --git a/src/file.rs b/src/file.rs index cb91ae1..ef7f9a6 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,5 +1,6 @@ use std::io::{fs, IoResult}; use std::io; +use std::str::CowString; use ansi_term::{ANSIString, Colour, Style}; use ansi_term::Style::Plain; @@ -31,27 +32,27 @@ pub struct File<'a> { } impl<'a> File<'a> { - pub fn from_path(path: Path, parent: Option<&'a Dir>) -> IoResult> { + pub fn from_path(path: &Path, parent: Option<&'a Dir>) -> IoResult> { // Use lstat here instead of file.stat(), as it doesn't follow // symbolic links. Otherwise, the stat() call will fail if it // encounters a link that's target is non-existent. - fs::lstat(&path).map(|stat| File::with_stat(stat, path.clone(), parent)) + fs::lstat(path).map(|stat| File::with_stat(stat, path, parent)) } - pub fn with_stat(stat: io::FileStat, path: Path, parent: Option<&'a Dir>) -> File<'a> { + pub fn with_stat(stat: io::FileStat, path: &Path, parent: Option<&'a Dir>) -> File<'a> { let v = path.filename().unwrap(); // fails if / or . or .. - let filename = String::from_utf8(v.to_vec()).unwrap_or_else(|_| panic!("Name was not valid UTF-8")); + let filename = String::from_utf8_lossy(v); File { path: path.clone(), dir: parent, stat: stat, - name: filename.clone(), - ext: File::ext(filename.clone()), + name: filename.to_string(), + ext: File::ext(filename), } } - fn ext(name: String) -> Option { + fn ext(name: CowString) -> Option { // The extension is the series of characters after a dot at // the end of a filename. This deliberately also counts // dotfiles - the ".git" folder has the extension "git". @@ -75,29 +76,30 @@ impl<'a> File<'a> { // without a .coffee. pub fn get_source_files(&self) -> Vec { - if self.ext.is_none() { - return vec![]; + if let Some(ref ext) = self.ext { + let ext = ext.as_slice(); + match ext { + "class" => vec![self.path.with_extension("java")], // Java + "css" => vec![self.path.with_extension("sass"), self.path.with_extension("less")], // SASS, Less + "elc" => vec![self.path.with_extension("el")], // Emacs Lisp + "hi" => vec![self.path.with_extension("hs")], // Haskell + "js" => vec![self.path.with_extension("coffee"), self.path.with_extension("ts")], // CoffeeScript, TypeScript + "o" => vec![self.path.with_extension("c"), self.path.with_extension("cpp")], // C, C++ + "pyc" => vec![self.path.with_extension("py")], // Python + + "aux" => vec![self.path.with_extension("tex")], // TeX: auxiliary file + "bbl" => vec![self.path.with_extension("tex")], // BibTeX bibliography file + "blg" => vec![self.path.with_extension("tex")], // BibTeX log file + "lof" => vec![self.path.with_extension("tex")], // TeX list of figures + "log" => vec![self.path.with_extension("tex")], // TeX log file + "lot" => vec![self.path.with_extension("tex")], // TeX list of tables + "toc" => vec![self.path.with_extension("tex")], // TeX table of contents + + _ => vec![], // No source files if none of the above + } } - - let ext = self.ext.clone().unwrap(); - match ext.as_slice() { - "class" => vec![self.path.with_extension("java")], // Java - "css" => vec![self.path.with_extension("sass"), self.path.with_extension("less")], // SASS, Less - "elc" => vec![self.path.with_extension("el")], // Emacs Lisp - "hi" => vec![self.path.with_extension("hs")], // Haskell - "js" => vec![self.path.with_extension("coffee"), self.path.with_extension("ts")], // CoffeeScript, TypeScript - "o" => vec![self.path.with_extension("c"), self.path.with_extension("cpp")], // C, C++ - "pyc" => vec![self.path.with_extension("py")], // Python - - "aux" => vec![self.path.with_extension("tex")], // TeX: auxiliary file - "bbl" => vec![self.path.with_extension("tex")], // BibTeX bibliography file - "blg" => vec![self.path.with_extension("tex")], // BibTeX log file - "lof" => vec![self.path.with_extension("tex")], // TeX list of figures - "log" => vec![self.path.with_extension("tex")], // TeX log file - "lot" => vec![self.path.with_extension("tex")], // TeX list of tables - "toc" => vec![self.path.with_extension("tex")], // TeX table of contents - - _ => vec![], + else { + vec![] // No source files if there's no extension, either! } } @@ -182,7 +184,7 @@ impl<'a> File<'a> { Some(dir) => dir.path.join(path), None => path, }; - format!("{} {}", displayed_name, self.target_file_name_and_arrow(target_path)) + format!("{} {}", displayed_name, self.target_file_name_and_arrow(&target_path)) } Err(_) => displayed_name.to_string(), } @@ -196,16 +198,16 @@ impl<'a> File<'a> { self.name.as_slice().width(false) } - fn target_file_name_and_arrow(&self, target_path: Path) -> String { + fn target_file_name_and_arrow(&self, target_path: &Path) -> String { let v = target_path.filename().unwrap(); - let filename = String::from_utf8_lossy(v).to_string(); + let filename = String::from_utf8_lossy(v); // Use stat instead of lstat - we *want* to follow links. - let link_target = fs::stat(&target_path).map(|stat| File { + let link_target = fs::stat(target_path).map(|stat| File { path: target_path.clone(), dir: self.dir, stat: stat, - name: filename.clone(), + name: filename.to_string(), ext: File::ext(filename.clone()), }); diff --git a/src/filetype.rs b/src/filetype.rs index 7a8f905..f4812bf 100644 --- a/src/filetype.rs +++ b/src/filetype.rs @@ -96,9 +96,8 @@ impl<'a> HasType for File<'a> { else if name.starts_with("README") || BUILD_TYPES.iter().any(|&s| s == name) { return Immediate; } - else if self.ext.is_some() { - let e = self.ext.clone().unwrap().to_ascii_lower(); - let ext = e.as_slice(); + else if let Some(ref e) = self.ext { + let ext = e.as_slice().to_ascii_lower(); if IMAGE_TYPES.iter().any(|&s| s == ext) { return Image; } @@ -125,7 +124,7 @@ impl<'a> HasType for File<'a> { } let source_files = self.get_source_files(); - if source_files.len() == 0 { + if source_files.is_empty() { return Normal; } else if source_files.iter().any(|path| self.dir.map(|d| d.contains(path)).unwrap_or(false)) { @@ -140,6 +139,7 @@ impl<'a> HasType for File<'a> { } } } + return Normal; // no filetype } }