mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-11-22 20:15:11 +00:00
Code changes in preparation for recursion
This commit is contained in:
parent
c7e8a28e17
commit
6d4b30d531
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -2,17 +2,17 @@
|
||||
name = "exa"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ansi_term 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"git2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"natord 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"number_prefix 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"users 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"natord 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"number_prefix 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"users 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"regex 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.1.4"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -55,7 +55,7 @@ name = "libressl-pnacl-sys"
|
||||
version = "2.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"pnacl-build-helper 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pnacl-build-helper 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -83,12 +83,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "natord"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "number_prefix"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -107,7 +107,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "pnacl-build-helper"
|
||||
version = "1.3.1"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -139,6 +139,6 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "users"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
|
@ -8,7 +8,7 @@ name = "exa"
|
||||
|
||||
[dependencies]
|
||||
ansi_term = "0.4.2"
|
||||
getopts = "0.1.4"
|
||||
getopts = "0.2.0"
|
||||
natord = "1.0.6"
|
||||
number_prefix = "0.2.1"
|
||||
users = "0.2.1"
|
||||
|
@ -21,6 +21,7 @@ exa is a replacement for `ls` written in Rust.
|
||||
- **-i**, **--inode**: show inode number column
|
||||
- **-l**, **--long**: display extended details and attributes
|
||||
- **-r**, **--reverse**: reverse sort order
|
||||
- **-R**, **--recurse**: recurse into subdirectories
|
||||
- **-s**, **--sort=(field)**: field to sort by
|
||||
- **-S**, **--blocks**: show number of file system blocks
|
||||
- **-x**, **--across**: sort multi-column view entries across
|
||||
|
@ -45,7 +45,7 @@ impl<'a> File<'a> {
|
||||
|
||||
/// Create a new File object from the given Stat result, and other data.
|
||||
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 v = path.filename().unwrap_or_else(|| panic!("Failed to get filename for {:?}", path)); // fails if / or . or ..
|
||||
let filename = String::from_utf8_lossy(v);
|
||||
|
||||
File {
|
||||
|
23
src/main.rs
23
src/main.rs
@ -1,6 +1,8 @@
|
||||
#![feature(collections, core, io, libc, os, path, std_misc)]
|
||||
|
||||
extern crate ansi_term;
|
||||
extern crate getopts;
|
||||
extern crate natord;
|
||||
extern crate number_prefix;
|
||||
extern crate users;
|
||||
|
||||
@ -12,7 +14,7 @@ use std::os::{args, set_exit_status};
|
||||
|
||||
use dir::Dir;
|
||||
use file::File;
|
||||
use options::Options;
|
||||
use options::{Options, DirAction};
|
||||
|
||||
pub mod column;
|
||||
pub mod dir;
|
||||
@ -30,15 +32,26 @@ fn exa(options: &Options) {
|
||||
// more than one of them.
|
||||
let mut count = 0;
|
||||
|
||||
let mut stack = options.path_strs.clone();
|
||||
|
||||
// Separate the user-supplied paths into directories and files.
|
||||
// Files are shown first, and then each directory is expanded
|
||||
// and listed second.
|
||||
for file in options.path_strings() {
|
||||
let path = Path::new(file);
|
||||
loop {
|
||||
let file = match stack.pop() {
|
||||
None => break,
|
||||
Some(f) => f,
|
||||
};
|
||||
|
||||
let path = Path::new(file.clone());
|
||||
match fs::stat(&path) {
|
||||
Ok(stat) => {
|
||||
if !options.list_dirs && stat.kind == FileType::Directory {
|
||||
dirs.push(file.clone());
|
||||
if stat.kind == FileType::Directory {
|
||||
match options.dir_action {
|
||||
DirAction::AsFile => files.push(File::with_stat(stat, &path, None)),
|
||||
DirAction::List => dirs.push(file.clone()),
|
||||
DirAction::Recurse => { /* todo */ },
|
||||
}
|
||||
}
|
||||
else {
|
||||
// May as well reuse the stat result from earlier
|
||||
|
@ -1,6 +1,3 @@
|
||||
extern crate getopts;
|
||||
extern crate natord;
|
||||
|
||||
use dir::Dir;
|
||||
use file::File;
|
||||
use column::{Column, SizeFormat};
|
||||
@ -13,14 +10,17 @@ use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::slice::Iter;
|
||||
|
||||
use getopts;
|
||||
use natord;
|
||||
|
||||
use self::Misfire::*;
|
||||
|
||||
/// The *Options* struct represents a parsed version of the user's
|
||||
/// command-line options.
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Options {
|
||||
pub list_dirs: bool,
|
||||
path_strs: Vec<String>,
|
||||
pub dir_action: DirAction,
|
||||
pub path_strs: Vec<String>,
|
||||
reverse: bool,
|
||||
show_invisibles: bool,
|
||||
sort_field: SortField,
|
||||
@ -43,6 +43,7 @@ impl Options {
|
||||
getopts::optflag("l", "long", "display extended details and attributes"),
|
||||
getopts::optflag("i", "inode", "show each file's inode number"),
|
||||
getopts::optflag("r", "reverse", "reverse order of files"),
|
||||
getopts::optflag("R", "recurse", "recurse into directories"),
|
||||
getopts::optopt ("s", "sort", "field to sort by", "WORD"),
|
||||
getopts::optflag("S", "blocks", "show number of file system blocks"),
|
||||
getopts::optflag("x", "across", "sort multi-column view entries across"),
|
||||
@ -64,7 +65,7 @@ impl Options {
|
||||
};
|
||||
|
||||
Ok(Options {
|
||||
list_dirs: matches.opt_present("list-dirs"),
|
||||
dir_action: try!(dir_action(&matches)),
|
||||
path_strs: if matches.free.is_empty() { vec![ ".".to_string() ] } else { matches.free.clone() },
|
||||
reverse: matches.opt_present("reverse"),
|
||||
show_invisibles: matches.opt_present("all"),
|
||||
@ -73,11 +74,6 @@ impl Options {
|
||||
})
|
||||
}
|
||||
|
||||
/// Iterate over the non-option arguments left oven from getopts.
|
||||
pub fn path_strings(&self) -> Iter<String> {
|
||||
self.path_strs.iter()
|
||||
}
|
||||
|
||||
/// Display the files using this Option's View.
|
||||
pub fn view(&self, dir: Option<&Dir>, files: Vec<File>) {
|
||||
self.view.view(dir, files)
|
||||
@ -113,7 +109,13 @@ impl Options {
|
||||
}
|
||||
}
|
||||
|
||||
/// User-supplied field to sort by
|
||||
/// What to do when encountering a directory?
|
||||
#[derive(PartialEq, Debug, Copy)]
|
||||
pub enum DirAction {
|
||||
AsFile, List, Recurse
|
||||
}
|
||||
|
||||
/// User-supplied field to sort by.
|
||||
#[derive(PartialEq, Debug, Copy)]
|
||||
pub enum SortField {
|
||||
Unsorted, Name, Extension, Size, FileInode
|
||||
@ -228,7 +230,7 @@ fn view(matches: &getopts::Matches) -> Result<View, Misfire> {
|
||||
/// Finds out which file size the user has asked for.
|
||||
fn file_size(matches: &getopts::Matches) -> Result<SizeFormat, Misfire> {
|
||||
let binary = matches.opt_present("binary");
|
||||
let bytes = matches.opt_present("bytes");
|
||||
let bytes = matches.opt_present("bytes");
|
||||
|
||||
match (binary, bytes) {
|
||||
(true, true ) => Err(Misfire::Conflict("binary", "bytes")),
|
||||
@ -238,6 +240,18 @@ fn file_size(matches: &getopts::Matches) -> Result<SizeFormat, Misfire> {
|
||||
}
|
||||
}
|
||||
|
||||
fn dir_action(matches: &getopts::Matches) -> Result<DirAction, Misfire> {
|
||||
let recurse = matches.opt_present("recurse");
|
||||
let list = matches.opt_present("list-dirs");
|
||||
|
||||
match (recurse, list) {
|
||||
(true, true ) => Err(Misfire::Conflict("recurse", "list-dirs")),
|
||||
(true, false) => Ok(DirAction::Recurse),
|
||||
(false, true ) => Ok(DirAction::AsFile),
|
||||
(false, false) => Ok(DirAction::List),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Copy, Debug)]
|
||||
pub struct Columns {
|
||||
size_format: SizeFormat,
|
||||
|
Loading…
Reference in New Issue
Block a user