Skip to content

Commit adbaa51

Browse files
committed
Use new io + path + fs libraries (LOTS OF CHANGES)
Exa now uses the new IO, Path, and Filesystem libraries that have been out for a while now. Unfortunately, the new libraries don't *entirely* cover the range of the old libraries just yet: in particular, to become more cross-platform, the data in `UnstableFileStat` isn't available in the Unix `MetadataExt` yet. Much of this is contained in rust-lang/rfcs#1044 (which is due to be implemented in rust-lang/rust#14711), but it's not *entirely* there yet. As such, this commits a serious loss of functionality: no symlink viewing, no hard links or blocks, or users or groups. Also, some of the code could now be optimised. I just wanted to commit this to sort out most of the 'teething problems' of having a different path system in advance. Here's an example problem that took ages to fix for you, just because you read this far: when I first got exa to compile, it worked mostly fine, except calling `exa` by itself didn't list the current directory. I traced where the command-line options were being generated, to where files and directories were sorted, to where the threads were spawned... and the problem turned out to be that it was using the full path as the file name, rather than just the last component, and these paths happened to begin with `.`, so it thought they were dotfiles.
1 parent eee49ec commit adbaa51

File tree

10 files changed

+261
-216
lines changed

10 files changed

+261
-216
lines changed

Cargo.lock

Lines changed: 77 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/column.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::iter::repeat;
2-
use unicode::str::UnicodeStr;
32

43
use ansi_term::Style;
54

src/dir.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
use std::old_io::{fs, IoResult};
2-
use std::old_path::GenericPath;
3-
use std::old_path::posix::Path;
4-
51
use feature::Git;
62
use file::{File, GREY};
73

4+
use std::io;
5+
use std::fs;
6+
use std::path::{Path, PathBuf};
7+
88
/// A **Dir** provides a cached list of the file paths in a directory that's
99
/// being listed.
1010
///
1111
/// This object gets passed to the Files themselves, in order for them to
1212
/// check the existence of surrounding files, then highlight themselves
1313
/// accordingly. (See `File#get_source_files`)
1414
pub struct Dir {
15-
contents: Vec<Path>,
16-
path: Path,
15+
contents: Vec<PathBuf>,
16+
path: PathBuf,
1717
git: Option<Git>,
1818
}
1919

@@ -22,10 +22,10 @@ impl Dir {
2222
/// Create a new Dir object filled with all the files in the directory
2323
/// pointed to by the given path. Fails if the directory can't be read, or
2424
/// isn't actually a directory.
25-
pub fn readdir(path: &Path) -> IoResult<Dir> {
26-
fs::readdir(path).map(|paths| Dir {
27-
contents: paths,
28-
path: path.clone(),
25+
pub fn readdir(path: &Path) -> io::Result<Dir> {
26+
fs::read_dir(path).map(|dir_obj| Dir {
27+
contents: dir_obj.map(|entry| entry.unwrap().path()).collect(),
28+
path: path.to_path_buf(),
2929
git: Git::scan(path).ok(),
3030
})
3131
}
@@ -50,11 +50,11 @@ impl Dir {
5050

5151
/// Whether this directory contains a file with the given path.
5252
pub fn contains(&self, path: &Path) -> bool {
53-
self.contents.contains(path)
53+
self.contents.iter().any(|ref p| p.as_path() == path)
5454
}
5555

5656
/// Append a path onto the path specified by this directory.
57-
pub fn join(&self, child: Path) -> Path {
57+
pub fn join(&self, child: &Path) -> PathBuf {
5858
self.path.join(child)
5959
}
6060

src/feature/git.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use std::old_path::GenericPath;
2-
use std::old_path::posix::Path;
1+
use std::path::{Path, PathBuf};
32

43
use ansi_term::{ANSIString, ANSIStrings};
54
use ansi_term::Colour::*;
@@ -9,38 +8,31 @@ use file::GREY;
98

109
/// Container of Git statuses for all the files in this folder's Git repository.
1110
pub struct Git {
12-
statuses: Vec<(Path, git2::Status)>,
11+
statuses: Vec<(PathBuf, git2::Status)>,
1312
}
1413

1514
impl Git {
1615

1716
/// Discover a Git repository on or above this directory, scanning it for
1817
/// the files' statuses if one is found.
1918
pub fn scan(path: &Path) -> Result<Git, git2::Error> {
20-
use std::os::unix::ffi::OsStrExt;
21-
use std::ffi::AsOsStr;
22-
23-
// TODO: libgit2-rs uses the new Path module, but exa still uses the
24-
// old_path one, and will have to continue to do so until the new IO
25-
// module gets a bit more developed. So we have to turn Paths into
26-
// old_path::Paths. Yes, this is hacky, but hopefully temporary.
27-
let new_path = path.as_os_str();
28-
let repo = try!(git2::Repository::discover(new_path));
19+
let repo = try!(git2::Repository::discover(path));
2920
let workdir = match repo.workdir() {
30-
Some(w) => Path::new(w.as_os_str().as_bytes()),
21+
Some(w) => w,
3122
None => return Ok(Git { statuses: vec![] }), // bare repo
3223
};
3324

3425
let statuses = try!(repo.statuses(None)).iter()
35-
.map(|e| (workdir.join(e.path_bytes()), e.status()))
26+
.map(|e| (workdir.join(Path::new(e.path().unwrap())), e.status()))
3627
.collect();
28+
3729
Ok(Git { statuses: statuses })
3830
}
3931

4032
/// Get the status for the file at the given path, if present.
4133
pub fn status(&self, path: &Path) -> String {
4234
let status = self.statuses.iter()
43-
.find(|p| &p.0 == path);
35+
.find(|p| p.0.as_path() == path);
4436
match status {
4537
Some(&(_, s)) => ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s) ]).to_string(),
4638
None => GREY.paint("--").to_string(),
@@ -52,7 +44,7 @@ impl Git {
5244
/// directories, which don't really have an 'official' status.
5345
pub fn dir_status(&self, dir: &Path) -> String {
5446
let s = self.statuses.iter()
55-
.filter(|p| dir.is_ancestor_of(&p.0))
47+
.filter(|p| p.0.starts_with(dir))
5648
.fold(git2::Status::empty(), |a, b| a | b.1);
5749

5850
ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s)] ).to_string()
@@ -83,3 +75,4 @@ impl Git {
8375
}
8476
}
8577
}
78+

0 commit comments

Comments
 (0)