Commit Graph

841 Commits

Author SHA1 Message Date
Benjamin Sago
9e15c616cc dir_action comments and docs 2017-08-12 11:29:40 +01:00
Benjamin Sago
673e894d25 Give the filter modules some love 2017-08-12 10:09:33 +01:00
Benjamin Sago
a7d8e1c84b Make the dir action a bit more lenient
More strict mode checks I forgot to take out
2017-08-11 22:56:52 +01:00
Benjamin Sago
eec1a4f78a Stop --git from complaining too
Re-fixes #152
2017-08-11 21:43:56 +01:00
Benjamin Sago
5189d66e2c Hide xattr errors unless --extended
exa now ignores errors when checking for extended attributes when the user didn’t explicitly demand that they be checked. If a file does have xattrs, it’ll still display the @ in the permissions column; errors will now just cause the @ to be hidden instead.

This changed a lot of the xtests, which were displaying the error message in a few situations. Those tests have gained @-suffixed companions so the actual error messages can still be tested.

Fixes #178 (finally)
2017-08-11 12:36:14 +01:00
Benjamin Sago
b286676667 Add actual error messages for the error messages
The annoying part is trying to format!() an OsStr.
2017-08-10 23:34:39 +01:00
Benjamin Sago
adaa36e1c5 Integrate strict mode, use it to test file sizes
It’s a good test to be able to switch strict mode on in run.sh and not have it break anything! Now, the EXA_STRICT environment variable will toggle it on. We can even switch it off and see that it doesn’t error.
2017-08-10 18:45:26 +01:00
Benjamin Sago
dbebd60c4e Extract var_os and use the mock to test
Some of the deduce functions used to just blatantly call std::env::var_os and not care, introducing global state into a module that was otherwise nice and functional and self-contained. (Well, almost. There’s still terminal width.)

Anyway, this made it hard to test, because we couldn’t test it fully with this global dependency in place. It *is* possible to work around this by actually setting the environment variables in the tests, but this way is more self-documenting.

With this in place, we can start to unit test things like deriving the view by passing in what the $COLUMNS environment variable should be, and that’s one of the first things checked.

src/options/mod.rs *almost* has all its tests moved to where they should be!
2017-08-10 17:54:28 +01:00
Benjamin Sago
532ebbc591 Only complain about long options in strict mode
Fixes #152. It just puts the check behind a flag and moves the tests around.
2017-08-10 13:59:39 +01:00
Benjamin Sago
f389943bf1 New macro for testing deduce errors
Sometimes, the type in the Ok part of the Result wouldn’t implement PartialEq, so the first macro (which uses assert_eq) won’t work. In these cases, this new macro can be used instead, which just unwraps the Err’s contents. In other cases, it can shave off a ) at the end of a few lines.
2017-08-10 13:59:09 +01:00
Benjamin Sago
6755ee6ae9 Extract table columns into a struct
The table Options struct is roughly half runtime configuration and half flags to select which columns to display The column fields might as well be in their own struct, and now that the ‘for_dir’ function doesn’t use SizeFormat, it can be moved to Columns.
2017-08-09 22:25:16 +01:00
Benjamin Sago
e98c765078 Move size format out of Column
Way in the past, the size format was the only variable column; the others were all fixed. Now there are many configurable columns and this field was still hanging around. The code that does the rendering just gets the size format as an argument, and now it works the same way as the TimeFormat.
2017-08-09 21:47:51 +01:00
Benjamin Sago
6b309d5cfc Make SizeFormat lenient, and add tests
This changes the SizeFormat option parser from its old, strict-by-default behaviour (where passing both --bytes and --binary would be an error) to the new, use-the-last-argument behaviour (where passing --bytes --binary would use --binary because it came later).

Doing this meant adding functionality to Matches so that it could return *which* argument matched. Previously, the order of --bytes and --binary didn’t matter, because they couldn’t both be present, but now it does.
2017-08-09 19:18:31 +01:00
Benjamin Sago
b2947ed590 Document and test time formats 2017-08-09 17:14:16 +01:00
Benjamin Sago
0b87392fd4 Decouple assert_eq! and assert_parses
The assert_parses function was problematic because it insisted on using assert_eq! to check its contents. This won’t work for any type we want to test that doesn’t implement PartialEq, such as TimeFormat, which holds references to years and date strings and other such.

To go about fixing this, the first step is to change that function so it only does the initial processing, rather than the assertion, which is now done outside of it in the test macros instead.
2017-08-09 13:41:07 +01:00
Benjamin Sago
ff497b52e5 Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)

The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.

In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.

Help and Version continue doing their own thing.
2017-08-09 09:21:29 +01:00
Benjamin Sago
d97f603ee3 Make these tests less long 2017-08-08 09:20:46 +01:00
Benjamin Sago
00379cce63 Thread Strictness through the parser
The value is ignored, but this broke quite a lot of tests that assumed MatchedFlags had only one field.

Parsing tests have to have OsStr flags because I couldn’t get that part working right, but in general, some tests now re-use common functionality too.
2017-08-08 09:18:17 +01:00
Benjamin Sago
c1e206669e Give IgnorePatterns a better interface
This commit gives IgnorePatterns a bunch of constructor methods that mean its option-parsing sister file doesn’t need to know that it’s a vec of glob patterns inside: it can work with anything that iterates over strings. Now, the options module doesn’t need to know about the glob crate.
2017-08-07 09:16:56 +01:00
Christopher Vittal
1bce51c9c8 Add extra types to compressed filetype filter.
This adds a few more common compressed filetypes to the is_compressed
fuction. Notably, xz, and two common package file formats, deb and rpm.
2017-08-07 00:57:29 -04:00
Benjamin Sago
dd0c5f6bef Merge pull request #250 from ogham/exa/issue-213
fix issue #213 iso date format inversion
2017-08-06 20:38:21 +01:00
Benjamin Sago
999c9d56f5 Merge pull request #247 from ogham/exa/date_output
Fix month name widths once and for all #244
2017-08-06 20:23:09 +01:00
Benjamin Sago
68210c5e8c Merge branch 'master' of github.com:ogham/exa 2017-08-06 17:59:10 +01:00
Benjamin Sago
89540edb22 Allow xattrs to be shown in --tree without --long
This restriction was originally only there because a standalone --tree wasn’t a thing. Now it’s there, there’s no reason to forbid the combination.
2017-08-06 12:02:17 +01:00
Nontawat Numor
e43e288d19 Add raw file type for Olympus and Nikon 2017-08-06 17:47:15 +07:00
Alfred Sawaya
fca5b6b970 fix issue #213 iso date format inversion 2017-08-06 12:36:00 +02:00
Alfred Sawaya
cb2e94a796 Fix month name widths once and for all #244
To render the date, Exa now find out the month with the longest name
among all months, and use the width of that.
2017-08-06 03:59:46 +02:00
Benjamin Sago
b5bcf22612 Merge remote-tracking branch origin/option-pars-ng
This merges in exa’s own new options parser, which has the following features:

- You can specify an option twice and it’ll use the second one, making aliases usable for defaults (fixes #144)
- Lets arguments be specified more than once (fixes #125)

Strict mode is not done yet; I just wanted to merge this in because it’s been a while, and there’s work that needs to be done on master so I don’t want them drifting apart any further.

It’s likely that you’ll find cases where multiple arguments doesn’t work or where the wrong value is being used. There aren’t tests for *everything* yet, and it still uses global environment variables.

# Conflicts:
#	src/options/view.rs
2017-08-05 21:34:57 +01:00
Benjamin Sago
4289f4d27e Specify that we need the width of stdout
The term_size crate introduced in #237 did things *slightly* differently than exa: it tried to get the terminal width of stdout, stderr, and stdin. This broke some tests that only redirected stdout.
2017-08-05 20:26:13 +01:00
Benjamin Sago
d701547ec4 Merge pull request #237 from ogham/exa/term_size
Use term_size crate to fetch terminal size.
2017-08-05 20:08:06 +01:00
Benjamin Sago
6759a5f97e Temporarily hush warnings 2017-08-05 19:56:42 +01:00
Benjamin Sago
7cb9a43541 Extract version info into its own struct
Now it’s more like help. There aren’t any other fields in its struct at the moment, but there will be in the future (listing the features, and extremely colourful vanity mode)
2017-08-05 19:46:47 +01:00
Benjamin Sago
411bdc4321 These help fields don’t need to be pub 2017-08-05 19:45:55 +01:00
Benjamin Sago
cdad6bb960 Make building the matches more bearable
Now, building the two result vectors doesn’t have to go through at least one field.
2017-08-05 19:15:27 +01:00
Benjamin Sago
9872eba821 Separate the matched flags from the free strings
Originally, both the matched flags and the list of free strings were returned from the parsing function and then passed around to every type that had a ‘deduce’ method. This worked, but the list of free strings was carried around with it, never used.

Now, only the flags are passed around. They’re in a new struct which has the methods the Matches had.

Both of Matches’s fields are now just data, and all of the methods on MatchedFlags don’t ignore any fields, so it’s more cohesive, at least I think that’s the word.

Building up the MatchedFlags is a bit more annoying though because the vector is now hidden behind a field.
2017-08-05 19:11:00 +01:00
Benjamin Sago
0456e7cfbd Document and organise the parser module 2017-08-05 17:46:38 +01:00
Benjamin Sago
3331feaee8 Turning off unused_variables revealed a warning 2017-08-05 15:40:15 +01:00
Benjamin Sago
b46fd1e32f Extract help checking and its tests 2017-08-05 14:33:32 +01:00
Benjamin Sago
82e6fa2352 Add tests for dir_option
One of the previous tests started to fail, because it was working when it shouldn’t have! It worked up until now because I forgot to flag --level as taking an argument, and “--level 4” still worked with 4 as a filename. So there’s now an early check for that functionality that got lost somewhere.
2017-08-05 13:57:20 +01:00
Benjamin Sago
f86c49cd4a Avoid early return 2017-08-05 11:55:41 +01:00
PJB3005
f249c8528b Use term_size crate to fetch terminal size.
Should be cross-platform, one step closer to Windows support.
2017-08-05 08:09:26 +02:00
pskuza
d76ce048c3 Update filetype.rs
Added a few video and audio extensions
2017-08-04 16:03:16 +02:00
Benjamin Sago
06157fdedd Add some tests for the time flags
Apparently I forgot to give the --time flag an argument, and this wasn’t actually covered by any of the xtests! Well, it’s tested now.

I’m not sure how to handle multiple --time arguments.
2017-07-26 23:37:58 +01:00
Benjamin Sago
817c7d2318 Add tests for size format 2017-07-26 23:06:08 +01:00
Benjamin Sago
adca0d3629 Add test for ignoring globs 2017-07-26 21:29:49 +01:00
Benjamin Sago
a2cd39e0a9 Fix --tree --all
Fixes #193. --all was treated the same as --all --all; now it’s treated differently.
2017-07-26 21:14:05 +01:00
Benjamin Sago
0831573669 Add tests for dot filters 2017-07-26 21:01:22 +01:00
Benjamin Sago
bc5c0194b4 Add tests for sort field
**
2017-07-26 20:53:57 +01:00
Benjamin Sago
45e1cb77a4 Streamline parser tests 2017-07-26 20:33:59 +01:00
Benjamin Sago
2d1f462bfa Switch to the new options parser
This commit removes the dependency on the ‘getopts’ crate entirely, and re-writes all its uses to use the new options parser instead.

As expected there are casualties galore:

- We now need to collect the options into a vector at the start, so we can use references to them, knowing they’ll be stored *somewhere*.
- Because OsString isn’t Display, its Debug impl gets used instead. (This is hopefully temporary)
- Options that take values (such as ‘sort’ or ‘time-style’) now parse those values with ‘to_string_lossy’. The ‘lossy’ part means “I’m at a loss for what to do here”
- Error messages got a lot worse, but “--tree --all --all” is now a special case of error rather than just another Misfire::Useless.
- Some tests had to be re-written to deal with the fact that the parser works with references.
- ParseError loses its lifetime and owns its contents, to avoid having to attach <'a> to Misfire.
- The parser now takes an iterator instead of a slice.
- OsStrings can’t be ‘match’ patterns, so the code devolves to using long Eq chains instead.
- Make a change to the xtest that assumed an input argument with invalid UTF-8 in was always an error to stderr, when that now in fact works!
- Fix a bug in Vagrant where ‘exa’ and ‘rexa’ didn’t properly escape filenames with spaces in.
2017-07-26 17:48:18 +01:00
Benjamin Sago
5b1966d261 Move filter and dir_action from options to fs
This commit moves the definitions of Filter and DirAction from the options module to the fs module, but leaves the parts that actually have to do with option parsing alone.

Now, the options module shouldn’t define any types that get used elsewhere in the program: it only adds functionality to types that already exist.
2017-07-24 08:34:50 +01:00
Benjamin Sago
8d96be7f6a Document the parsing decisions
Even though these can’t actually be viewed with `cargo doc` yet, they’re still good to have around.
2017-07-22 18:06:05 +01:00
Benjamin Sago
5227f09f5b Macro-ify the matching tests 2017-07-13 11:51:58 +01:00
Benjamin Sago
53dc370a41 Search for long options through matches
Casualty here was that you can’t have static values reference one another directly, so the static args slice had to be turned into a slice *of references* rather than of values. No big deal, just have to write & a few more times.
2017-07-13 11:51:50 +01:00
Benjamin Sago
e08d7fe524 Test for unknown arguments 2017-07-13 10:21:10 +01:00
Benjamin Sago
0e944d7b74 Macroify parser tests 2017-07-13 10:12:38 +01:00
Benjamin Sago
c9f6c45040 Add missing short arg functionality 2017-07-13 00:51:05 +01:00
Benjamin Sago
c41005a121 Change a bunch of variable names 2017-07-12 23:17:43 +01:00
Benjamin Sago
9bbe2d9816 Throw error immediately on lookup
Every time looking up an argument fails, it returns an error. We might as well just move this into the lookup function.
2017-07-12 22:59:04 +01:00
Benjamin Sago
c18302e46e This function was used in both 2017-07-12 22:49:10 +01:00
Benjamin Sago
62b85e3e93 Add some tests for split_equals 2017-07-12 22:47:17 +01:00
Benjamin Sago
bf643c65fe Start work on our own options parser
All the tests pass, but only half the functionality is there right now.
2017-07-12 12:03:07 +01:00
Benjamin Sago
c29170e345 Get the list of file extensions from the Options
The FileExtensions in the FileName is now a reference to the one in the original FileStyle, which gets put there in the options module.

This allows the extensions to be derived from the user, somehow, in the future when that part’s done.
2017-07-10 14:01:38 +01:00
Benjamin Sago
0d8d723408 Reify file extensions
Instead of having a File do its own extension checking, create a new type that takes a file and checks *that*. This new type (FileExtensions) is currently empty, but were it to contain values, those values could be used to determine the file’s colour.
2017-07-10 13:31:20 +01:00
Benjamin Sago
bfa65b3bec Make not showing paths in link targets the default
This commit replaces the “two normal cases” of showing a link’s target or not with “one default and one special case” of preferring to hide them, displaying the link targets by setting a flag instead.

Doing this simplifies the file name constructor, which gets to remove an argument.
2017-07-08 12:24:22 +01:00
Benjamin Sago
0d613652a7 Replace FileName::new with a factory
The new FileStyles value will contain all the fields necessary to “style” a file’s name. Right now this is only the Classify field, but there can be more later. The benefit of this is that when we add more, we won’t need to update all the places where file names are displayed.
2017-07-08 12:11:11 +01:00
Benjamin Sago
6afde85e18 Document --time-style, and completions 2017-07-06 00:52:27 +01:00
Benjamin Sago
3251378e91 Add iso time style 2017-07-06 00:39:54 +01:00
Benjamin Sago
f0eed9fde4 Add full-iso time style 2017-07-06 00:21:38 +01:00
Benjamin Sago
786e8f4d7f Add long-iso style and --time-style option
This has to do its own number formatting because *somebody* didn’t add “print the current month number” functionality to rust-datetime!
2017-07-06 00:01:45 +01:00
Benjamin Sago
98b63705be Expect different time formats 2017-07-05 23:27:48 +01:00
Benjamin Sago
aa5b1867dd Make nanoseconds available to times
The information was always in the Metadata struct; exa just never used it.
2017-07-05 23:08:56 +01:00
Benjamin Sago
5bdf6304bb Fix bug where accessed times were wrong!
It used the mtime, rather than the atime. Copy and paste error. Whoops!
2017-07-05 22:07:03 +01:00
Benjamin Sago
ba335bb6e7 Separate TimeFormat from the Environment
By moving it outside of the Environment::load_all() constructor, it can be set to different values.
2017-07-05 21:54:43 +01:00
Benjamin Sago
d93e168b4d Move Environment to a table’s Options
This commit moves the Environment field from the Table to its Options, and properly gets rid of the name ‘columns’ from the last commit.

Having it in the Options is important, because it means it can be generated from some command-line options. Also, it reduces the number of arguments that need to be passed to Table::new; there would have been 4 with the inclusion of the Environment, but by moving some of the code into the function, we can avoid this (and any further arguments).
2017-07-05 21:01:01 +01:00
Benjamin Sago
268b7d52dc Rename Columns to table::Options
The views have been renamed to be the Optionses of their module; now the options for the Table — Columns — has followed suit.

This works out, because the table module depended on everything in the columns module. It opens the door for other only-table-specific things to be included.

The casualty was that by making it non-Clone and non-PartialEq, a bunch of other #[derive]-d types had to have their derivions removed too.
2017-07-05 20:16:04 +01:00
Benjamin Sago
d27812f819 Environment Default trait
The Environment struct only used the Default trait so it could have the same call for both Environment<UsersCache> and Environment<MockUsers>. There’s no reason to keep it around anymore.
2017-07-05 08:21:24 +01:00
Benjamin Sago
f4ddbf3849 Fix tree permissions bug
There was a bug where if you tried to recurse into a directory you didn’t have permission to read the contents of, the error would be ignored.

It now displays the errors.
2017-07-04 17:48:30 +01:00
Benjamin Sago
4c41141cb9 Give Tree its own iterator
The goal of this part of the refactoring, if you wondered, is to make it so only the tree module is aware that it needs ‘depth’ and ‘last’ values to draw the tree.

As far as the details module is concerned, it should just be doing something to produce TreeParams values which it later consumes; that’s it.

This change should make it easier to have tables that may or may not have a tree in them.
2017-07-04 08:29:36 +01:00
Benjamin Sago
a32b0dfb47 Move this up 2017-07-04 08:10:37 +01:00
Benjamin Sago
80d5c2ad6d Rename some stuff 2017-07-03 23:25:56 +01:00
Benjamin Sago
c0a2cf50af Encapsulate tree depth
It only really gets used for zeroes and having one added to it.
2017-07-03 23:15:50 +01:00
Benjamin Sago
8453f45f99 Make struct for all tree parameters
The fields for ‘depth’ and ‘last’ were being passed around separately, but were always used together.
2017-07-03 22:22:40 +01:00
Benjamin Sago
09b6ee7097 I give up 2017-07-03 20:53:37 +01:00
Benjamin Sago
fec4c45301 Extract method for table widths total 2017-07-03 20:21:33 +01:00
Benjamin Sago
1b58f012e0 Split the details iterator in two
Instead of having one iterator that might or might not contain a table, have two, one per case.
2017-07-03 20:12:32 +01:00
Benjamin Sago
7b64176929 Encapsulate table widths
Adding a header row automatically added the widths to the table and returned the row, but adding a file’s row didn’t add the widths. Now they’re consistent.

By having the widths be in a separate type, we can separate the two out later, rather than having one refer to the other.
2017-07-03 17:40:05 +01:00
Benjamin Sago
97236128ea Only get an Env if one’s being used, also mutexes
This commit ties a table’s Environment to the fact that it contains columns.

Previously, the Details view would get its Environment, and then use those fields to actually display the details in the table: except for the case where we’re only displaying a tree, when it would just be ignored, instead.

This was caused by the “no columns” case using a Vec of no Columns behind the scenes, rather than disabling the table entirely; much like how a tap isn’t a zero-length swipe, the code should have been updated to reflect this. Now, the Environment is only created if it’s going to be used.

Also, fix a double-mutex-lock: the mutable Table had to be accessed under a lock, but the table contained a UsersCache, which *also* had to be accessed under a lock. This was changed so that the table is only updated *after* the threads have all been joined, so there’s no need for any lock at all. May fix #141, but not sure.
2017-07-03 17:04:37 +01:00
Benjamin Sago
652e27e6dd Extract time formatter
This commit collects all the time-related fields from the Environment and bundles them all together in their own encapsulated struct.
2017-07-03 08:45:14 +01:00
Benjamin Sago
fc60838ff3 Extract table from details and grid_details
This commit extracts the common table element from the details and grid_details modules, and makes it its own reusable thing.

- A Table no longer holds the values it’s rendering; it just holds a continually-updated version of the maximum widths for each column. This means that all of the resulting values that turn into Rows — which here are either files, or file eggs — need to be stored *somewhere*, and that somewhere is a secondary vector that gets passed around and modified alongside the Table.
- Likewise, all the mutable methods that were on Table that added a Row now *return* the row that would have been added, hoping that the row does get stored somewhere. (It does, don’t worry.)
- Because rendering with mock users is tested in the user-field-rendering module, we don’t need to bother threading different types of U through the Environment, so now it’s just been specialised to UsersCache.
- Accidentally speed up printing a table by not buffering its entire output first when not necessary.
2017-07-02 01:02:17 +01:00
Benjamin Sago
f61e3853c1 Document sorting by type 2017-06-29 14:57:43 +01:00
Benjamin Sago
f750536420 Add sorting by type
This isn’t perfect, as a file’s type isn’t cached, so it gets recomputed for every comparison in the sort! We can’t go off the file’s `st_mode` flag because it’s not guaranteed to be in any order between systems.
2017-06-29 14:52:02 +01:00
Benjamin Sago
7e302718fe Update the docs where it counts 2017-06-29 13:24:55 +01:00
Benjamin Sago
0aa33595d7 Use the optional argument trick 2017-06-29 13:17:26 +01:00
Benjamin Sago
31148eda7b Match up fields with parameter names
The arguments passed to File’s constructor were different from the field names used — these might as well both be the same.

Also, move ext and filename to be File methods to save an import, and add tests.

Also also, by passing a PathBuf in to the constructor directly, we can save one (possibly two) instance/s where we pass in a reference to something we were going to lose ownership of anyway, only to have it basically cloned.
2017-06-29 13:07:45 +01:00
Benjamin Sago
30f74b08b4 Always look up metadata
We can do this because the only File::new invocation that already has metadata is already in the file module, so it doesn’t need its own constructor.
2017-06-29 12:24:04 +01:00
Benjamin Sago
340bccbcfc Forbid --tree --all --all
There’s a problem with the tree view where it’ll still recurse through `.` and `..`. But if you were using tree view, would you even need to see them? They’d be in the tree already!
2017-06-29 12:07:46 +01:00
Benjamin Sago
dd8bff083f Override the names of . and ..
There was a problem when displaying . and .. in directory listings: their names would normalise to actual names! So instead of literally seeing `.`, you’d see the current directory’s name, inserted in sort order into the list of results. Obviously this is not what we want.

In unrelated news, putting `.` and `..` into the list of paths read from a directory just takes up more heap space for something that’s basically constant.

We can solve both these problems at once by moving the DotFilter to the files iterator in Dir, rather than at the Dir’s creation. Having the iterator know whether it should display `.` and `..` means it can emit those files first, and because it knows what those files really represent, it can override their file names to actually be those sequences of dots.

This is not a perfect solution: the main casualty is that a File can now be constructed with a name, some metadata, both, or neither. This is currently handled with a bunch of Options, and returns IOResult even without doing any IO operations.

But at least all the tests pass!
2017-06-28 18:41:31 +01:00
Benjamin Sago
4295b243e5 Make Dir construction a bit cleaner 2017-06-27 18:13:18 +01:00
Benjamin Sago
20793ce7f4 Implement . and .. by inserting them maually
I originally thought that the entries . and .. were in *every* directory entry, and exa was already doing something to filter it out. And then... I could find no such code! Turns out, if we want those entries present, we have to insert them ourselves.

This was harder than expected. Because the file filter doesn’t have access to the parent directory path, it can’t “filter” the files vector by inserting the files at the beginning.

Instead, we do it at the iterator level. A directory can be scanned in three different ways depending on what sort of dotfiles, if any, are wanted. At this point, we already have access to the parent directory’s path, so we can just insert them manually. The enum got moved to the dir module because it’s used most there.
2017-06-27 01:13:50 +01:00
Benjamin Sago
39fd905999 Allow passing in the --all option more than once 2017-06-26 23:48:55 +01:00
Benjamin Sago
5ace1264f2 Move the show-invisibles flag into a struct 2017-06-26 23:28:10 +01:00
Benjamin Sago
4be0a36d4e Inline this thing
If a function returns one of several enum variants, but we’re only interested in one, then just return its contents and have it apply the Mode “wrapper” later.
2017-06-26 08:38:56 +01:00
Benjamin Sago
65d94636d7 Remove filter and dir_action from Details
These two fields were originally needed to determine how to recurse when using tree view.

However, as there was no distinction between the “options parsed from the command-line” Details and the “values needed to render a table” Details, these had to be threaded through the options parser as a special-case to end up in the right struct.

No more! Because there are separate structs for options and rendering, we can just add them in later.
2017-06-26 08:28:32 +01:00
Benjamin Sago
14144e2ad3 Create Render structs from views
Instead of having render methods on the types that are now called Options, create new Render structs (one per view) and execute them. This means that it’s easier to extract methods from them — some of them are pretty long.

Also, remove the GridDetails struct, which got consumed by Mode (mostly)

By introducing another indirection between the structs that command-line options get parsed into and the structs that get rendered, it should be easier to refactor that horrible function in view.rs.
2017-06-26 00:53:48 +01:00
Benjamin Sago
66491cbae3 Separate colours from mode deduction
Now that colours don’t depend on a previously-calculated “should we be using colours” boolean anymore, their entire deduce function can be done separately to the mode’s one.
2017-06-25 14:59:38 +01:00
Benjamin Sago
84b01f2064 Fix bug where colours were incorrectly applied
exa assumed that the COLUMNS environment variable being present always meant that the output was to a terminal, so it should use colours. But because this variable can be overridden, colours were being incorrectly set!

The ‘fix’ is to stop trying to be clever while only calculating the terminal width once, and instead just stick it in a lazy_static so it’s usable everywhere.
2017-06-25 14:51:44 +01:00
Benjamin Sago
b8bb148fbb usize is Copy 2017-06-25 12:49:22 +01:00
Benjamin Sago
183ed9c135 Separate classify from the other two fields
This makes the code messier, but it’s just a stepping-stone until colours gets separated too.
2017-06-25 12:32:08 +01:00
Benjamin Sago
ed3d28f2cd Extract common classify 2017-06-24 22:53:34 +01:00
Benjamin Sago
aea0035f94 Move Colour and Classify to the View
All four view types — lines, grid, details, and grid-details — held their own colours and classify flags.

This didn’t make any sense for the grid-details view, which had to pick which one to use: the values were in there twice.

It also gave the Table in the details view access to more information than it really should have had.

Now, those two flags are returned separately from the view “mode”, which is the new term for one of those four things.
2017-06-24 22:39:15 +01:00
Benjamin Sago
81c5d8b7c6 Avoid allocating vectors for the help text 2017-06-23 22:58:07 +01:00
Benjamin Sago
4018165e26 Avoid an allocation when printing help text 2017-06-23 22:50:29 +01:00
Benjamin Sago
4e32b7fca9 Remove one last newline from help output 2017-06-23 22:30:48 +01:00
Benjamin Sago
aa17e4d3df Make a common module of exit statuses 2017-06-23 22:27:33 +01:00
Benjamin Sago
e4e603b4ee There’s more to erroneousness than an exit code 2017-06-23 22:12:21 +01:00
Benjamin Sago
a060782312 Require version and help text to be on stdout 2017-06-23 22:03:58 +01:00
Benjamin Sago
c5b18d0f6b Remove extra newline from help text 2017-06-23 21:25:55 +01:00
Benjamin Sago
ded829f073 Move help generation to its own function 2017-06-23 21:22:39 +01:00
Benjamin Sago
a2901c63cf Render higher permission bits
Unlike the others, setuid/setgid/sticky get merged with user/group/other execute in the rendered Permissions cell. So there had to be a bit of code change done to make sure that none of the bits clashed.
2017-05-30 15:31:24 +01:00
Benjamin Sago
f9f7ad2230 Read setuid/setgid/sticky bits
The problem here was that we were using `metadata.permissions().mode()`, which is capped at 0o777, rather than `metadata.mode()`, which exposes every bit. With this change, we can access the higher-order permission bits, and put them in the Permissions struct.
2017-05-30 15:29:29 +01:00
Benjamin Sago
b5d5509657 Timestamps will need more work 2017-05-22 08:52:45 +01:00
Benjamin Sago
4a5cb5361d Inode is probably the easiest one 2017-05-22 08:51:34 +01:00
Benjamin Sago
094e660003 Monday morning Blocks extraction 2017-05-22 08:48:32 +01:00
Benjamin Sago
eec81c4f48 Monday morning Links extraction 2017-05-22 08:43:09 +01:00
Benjamin Sago
f0cf5b4538 A Git status character should render itself, too 2017-05-21 17:01:22 +01:00
Benjamin Sago
5f497da85d This actually makes the Git part big enough
…for its own module.
2017-05-21 16:59:02 +01:00
Benjamin Sago
9642f69ce7 Tests for Git rendering 2017-05-21 16:54:40 +01:00
Benjamin Sago
b6c425c415 Did I forget to finish writing this comment? 2017-05-21 15:33:15 +01:00
Benjamin Sago
eb0bede837 Move the rest of the rendering into the render mod
On the plus side, this removes some imports from details, and makes the file shorter. On the minus side, the ‘render timestamp’ function has a hell of a signature.
2017-05-21 15:30:08 +01:00
Benjamin Sago
e83b019854 Inline field 2017-05-21 11:12:33 +01:00
Benjamin Sago
957c1925b1 PermissionsPlus holds the leftmost column values
The three pieces of information for the leftmost details view column (file type, permissions, and whether xattrs are present) used to be gathered from separate sources and passed around separately before being displayed at the end. Now, file type and permissions are put into a struct, along with the xattrs boolean that’s still getting passed around all over the place but not quite as much.

This was all done because I wanted to be able to test permissions rendering, without having file type and xattrs dragged into the same function.
2017-05-21 10:48:27 +01:00
Benjamin Sago
a2eb724483 Add unit tests for size rendering 2017-05-21 09:49:17 +01:00
Benjamin Sago
ddd34f3b1f Make DeviceIDs its own type
This is so we can define a render method on it.
2017-05-20 21:55:18 +01:00
Benjamin Sago
24a5d71f4b Extract file type render function 2017-05-20 21:49:00 +01:00
Benjamin Sago
fdd053d735 Put all the rendering functions into their own module 2017-05-20 21:45:08 +01:00
Benjamin Sago
fda88bedc2 Now move file size 2017-05-20 21:43:04 +01:00
Benjamin Sago
3f8b547f2d Now move permissions 2017-05-20 21:21:17 +01:00
Benjamin Sago
753fbc294a Flip the rendering functions around
A field can now render itself using colours and a users reference, rather than a Table doing the rendering. This way, only the relevant fields in the Environment can be made available to the render function, and the test code loses some lines.
2017-05-20 20:29:22 +01:00
Benjamin Sago
f2169faf94 Separate users into users and groups modules 2017-05-20 18:39:37 +01:00
Benjamin Sago
070fc76a8d Split user cell displaying into its own file
The details file was getting quite long, so it’s probably time to split it up
2017-05-20 18:14:04 +01:00
Benjamin Sago
d82e7b8e5c Some explanatory comments 2017-05-19 09:27:38 +01:00
Benjamin Sago
5537dd9b99 Static lifetime elision constants 2017-05-19 09:23:27 +01:00
Benjamin Sago
ef5fa90660 Display device IDs when listing devices
Override the size column for block and charater devices, so it shows the major and minor device IDs instead (which are in the Metadata struct somewhere).

This is what ls does when faced with a device.
2017-05-19 09:20:47 +01:00
Benjamin Sago
de60b95850 Don’t core dump when given invalid UTF-8 arguments
By parsing OsStrings rather than Strings, it’s the getopts crate that’s doing the UTF-8 checking rather than us, so if one of them isn’t valid, it’ll just fail to parse rather than crash exa.

Also, save a few allocations here and there.
2017-05-19 00:08:13 +01:00
Benjamin Sago
2f79b4db03 Start using new shorthand object field syntax 2017-05-18 22:43:32 +01:00
Kevin Ballard
15e08338d8 Remove lazy_static crate
It's not being used anymore.
2017-05-17 22:48:11 -07:00
Benjamin Sago
ce8a2e7ce9 Handle locales with 4-character-width months 2017-05-17 22:15:53 +01:00
Benjamin Sago
5bec218878 Merge pull request #177 from quininer/cjk
Fix TextCellContents cjk width
2017-05-17 21:18:17 +01:00
Benjamin Sago
510d2f7a76 --help and --version should have exit code 0
This makes it possible to use them in scripts. Also, I couldn’t find any other program returned a different error code! So it’s being changed to 0.

Fixed #180.
2017-05-17 21:01:12 +01:00
Benjamin Sago
b1be274276 Move scale colours to the Colours struct
Now everything’s customisable (in the future!) in its own place. This was the last thing to do for #65.
2017-05-16 20:54:39 +01:00
Benjamin Sago
108a402dbd Re-prefix the paths found by following symlinks
Fixes #134, a bug that showed symlinks incorrectly as broken, but only when the file was listed directly on the command-line *and* the file was in a different directory to the one exa was being run in.

I’m not sure why the old code used `String::new()`, but it doesn’t seem to affect anything.
2017-05-15 22:38:23 +01:00
quininer kel
0828133300 Fix TextCellContents cjk width 2017-05-10 16:26:50 +08:00
Benjamin Sago
205f18e848 It looks like you’re writing a letter 2017-05-07 17:39:01 +01:00
Benjamin Sago
4335f1978c Low-hanging clippy fruit 2017-05-07 17:15:22 +01:00
Benjamin Sago
e916097e0e Similarly, turn Classify into an enum 2017-05-07 15:31:00 +01:00
Benjamin Sago
39381bfb49 Document the recent changes 2017-05-07 15:14:06 +01:00
Benjamin Sago
9f6376a560 Give broken links a different style in grid view
Because the link style and status are now both available to the function that picks the colour style, we can have it highlight broken links differently.

Fixes #131.
2017-05-07 14:45:04 +01:00
Benjamin Sago
ccf8d44058 Replace the links boolean with an enum field 2017-05-07 14:08:36 +01:00
Benjamin Sago
88fecb7b26 Make the link target a field 2017-05-07 10:44:09 +01:00
Benjamin Sago
e2f73927c7 Make all the option descriptions the same
The old option descriptions were all written at different times, and needed some consistency. This makes everything consistent between the help text, README, man page, and shell completions, and fixes some mistakes made when writing them.

This also adds the missing options to the man page, fixing #175.
2017-05-06 23:00:45 +01:00
Benjamin Sago
f14ee48658 Make FileTypeExt non-optional
We already use MetadataExt and PermissionsExt, so it already requires a Unix system — there’s no point providing fallback implementations if it wouldn’t build on those systems anyway.
2017-05-03 17:51:17 +01:00
Benjamin Sago
7b2e701b25 Replace hard-coded constants with libc ones 2017-05-03 10:05:16 +01:00
Benjamin Sago
cac80410c9 Extract method for making a cell from its contents 2017-05-02 18:16:21 +01:00
Benjamin Sago
ba1c8c650f Fix bug where paths took up twice as much space
For some reason, the code that calculated the width of a cell with a path in counted the width of the path twice: once from the ANSIStrings containing it, and once more added on afterwards. This meant that the grid view thought that columns were wider than they really were, meaning fewer could be fit into a grid.
2017-05-02 17:40:32 +01:00
Benjamin Sago
437ac0ea60 file_name -> FileName#paint 2017-05-02 08:52:24 +01:00
Benjamin Sago
f51f5fe202 Also escape characters in broken symlinks 2017-05-02 08:46:43 +01:00
Benjamin Sago
395f9021ac Move these two imports down 2017-05-01 22:43:28 +01:00
Benjamin Sago
c81440429f Extract method add_parent_bits 2017-05-01 22:26:16 +01:00
Benjamin Sago
56d4d4c156 Also escape characters in links and headings
Doing this meant that the escaping functionality got used in three places, so it was extracted into a generalised function in its own module.

This is slighly slower for the case where escaped characters are displayed in the same colour as the displayable characters, which happens when listing a directory’s name when recursing. Optimise this, yeah?
2017-05-01 21:54:53 +01:00
Benjamin Sago
2d6d462439 Remember to escape characters in link targets
This was a bug introduced by 28fce347ff — it should have updated both places it does this in the function, rather than just one.
2017-05-01 16:53:51 +01:00
Benjamin Sago
5e0b9e0a10 A file’s colour is actually a style 2017-05-01 15:43:27 +01:00
Benjamin Sago
7531b2617c Split out function for --classify character 2017-05-01 15:41:29 +01:00
Benjamin Sago
05a0a5e199 Structify file_name -> FileName
This turns `file` into `self.file` and `colours` into `self.colours`, but it means we don’t need to pass arguments everywhere, which will be more of a problem the more functions there are.

Most of the code has just been indented.
2017-05-01 15:37:02 +01:00
Benjamin Sago
79feeba67d Move the functions in output to their own module
It didn’t feel quite right to have stand-alone functions in the module root file, which is usually just reserved for modules and exports.
2017-05-01 15:17:07 +01:00
Benjamin Sago
4249cf0fcc Give control characters their own colour 2017-05-01 15:10:39 +01:00
Benjamin Sago
eb7e53ef6c Only highlight escaped characters in file names
Rather than the *entire* file name.

The current method is extremely inefficient, but having control characters in file names is also extremely uncommon; it’s something that should be fixed, only eventually.
2017-05-01 15:06:37 +01:00
Benjamin Sago
a53c268c54 Measure, rather than calculating, cell widths
exa deals with cells and widths a lot: the items in a grid need to be aligned according to their *contents’* widths, rather than the length of their strings, which often included ANSI escape characters. As an optimisation, it used to calculate this separately based on the filename, and dealing with any extra characters (such as the classify ones) in that function too.

Recently, though, file names have become a lot more complicated. Classification added zero to one extra characters, and now with escaped control characters in file names, it’s not so easy to calculate the display width of a filename.

This commit removes the function that calculated the width, in favour of building the output string (it’s going to be displayed anyway) and just getting the width of what it displays instead.
2017-05-01 14:11:16 +01:00
Benjamin Sago
28fce347ff Initial implementation of file name escaping
It doesn’t do a perfect job, but at least there aren’t newlines littering the output anymore.
2017-05-01 12:23:28 +01:00
Benjamin Sago
70f8ae6e20 Move “coloured file name” into its own function 2017-05-01 11:50:52 +01:00
Benjamin Sago
91ad09e188 Merge pull request #169 from kballard/symlink_leading_path
Don't prepend current path to symlink targets
2017-04-30 11:13:00 +01:00
Kevin Ballard
f8624ed308 Don't prepend current path to symlink targets
It's confusing, and `ls` doesn't do this either. We're not prepending
the current path to all of the directory entries, and the user is going
to interpret the symlink target as relative to the directory containing
the symlink.
2017-04-29 15:01:54 -07:00
Kevin Ballard
4beb7b6cb1 Handle linking to root directories better
We don't need a special case for this.
2017-04-29 14:38:28 -07:00
Benjamin Sago
956aa85b3b Special-case the root directory when linking to it
It’s the only file where its path is the same as its file name, and has been the source of numerous bugs in the past… this special-case isn’t very clean, but it works.
2017-04-29 11:52:10 +01:00
Benjamin Sago
7d6c1eb724 Merge pull request #168 from kballard/dot_filename
Print . and .. components properly
2017-04-29 10:58:39 +01:00
Benjamin Sago
e671217d60 Merge pull request #167 from kballard/two_path_components
Print paths with 2 components properly
2017-04-29 10:43:08 +01:00
Benjamin Sago
c205c3592b Merge pull request #159 from MakeNowJust/feature/classify
Implement -F/--classify option
2017-04-28 23:24:52 +01:00
Kevin Ballard
dd63774e37 Print . and .. components properly
`Path.file_name()` returns `None` if the path ends in `.` or `..`, which
causes e.g. `exa -d ..` to print a blank line.
2017-04-26 22:28:34 -07:00
Kevin Ballard
a28bd8fa64 Print paths with 2 components properly
Previously, `exa -d foo/bar` would print the file as "bar", but
`exa -d foo/bar/baz` would correctly print "foo/bar/baz".
2017-04-25 15:55:05 -07:00
Raphaël Pinson
8ac68f9964
Add cr2 as image 2017-04-19 00:08:29 +02:00
TSUYUSATO Kitsune
e81b83b4ac Implement -F/--classify option 2017-04-14 07:27:37 +09:00
Benjamin Sago
3087565c01 Merge pull request #154 from neosilky/clippy-fixes
Fix some issues indicated by clippy
2017-04-11 08:18:55 +01:00
Laurent Arnoud
8b61a3a0f2
Exit with a non-zero status on error
With `ls` from Debian coreutils 8.26-2

```
ls /bad/path
echo $? # => 2
```

Reproduced same behaviour with exa

Fix https://github.com/ogham/exa/issues/135
2017-04-01 00:10:49 +02:00
Daniel Lockyer
cc4a65ac4b Remove lifetimes as they aren't needed 2017-03-31 17:12:20 +01:00
Daniel Lockyer
79b4f1a6ee Switch to better handling method 2017-03-31 17:12:01 +01:00
Daniel Lockyer
ec84f16da7 Collapse down similar branches of match-statement 2017-03-31 17:11:49 +01:00
Daniel Lockyer
91459d608c Replace double-quote with single-quote 2017-03-31 17:10:18 +01:00
Daniel Lockyer
b68627ce1a Switch to padding reference as variable not consumed 2017-03-31 17:09:50 +01:00
Daniel Lockyer
e059fb5ba7 Remove unnecessary reference 2017-03-31 17:09:32 +01:00
Daniel Lockyer
da3061d1b3 Replace use of .iter() with reference 2017-03-31 17:08:11 +01:00
Benjamin Sago
3bce55f569 Run Untry over the entire source tree 2017-03-26 17:35:50 +01:00
Ben S
0ffb331976 Wire up the colour-scale option 2016-10-30 16:42:33 +00:00
Ben S
86065f832d File size colours on a scale
This adds an option (always on at the moment) to use a colour scale of green to yellow to orange for the file size field instead of always green. See #65.
2016-10-30 15:50:09 +00:00
Ben S
91e8ef5c78 Prepare to make the size colour take an argument
This makes the Colours value pick a colour based on the size of the file, instead of necessarily having them all green. (They are all green for now, though.)
2016-10-30 15:09:36 +00:00
Ben S
93f8ad27dc Remember to add ignore-glob to the help 2016-10-30 14:47:38 +00:00
Ben S
95596297a9 Basic glob ignoring
See #97 and recently #130 too.

This allows the user to pass in options such as "--ignore '*.pyc'" to not list any files ending in '.pyc' in the output. It uses the Rust glob crate and currently does a simple split on pipe, without any escaping, so it’s not really *complete*, but is at least something.
2016-10-30 14:43:33 +00:00
Ben S
a6712994c5 Make the views non-Copy
This has to be done for when ignore patterns get introduced and have to be stored in a Vec.
2016-10-30 14:31:25 +00:00
Ben S
74358c188a Properly handle errors when following a symlink
Fixes #123. The code assumes that every File that has its link_target() method called would first have been checked to make sure it’s actually a link first. Unfortunately it also assumed that the only thing that can go wrong while following a link is if the file wasn’t a link, meaning it crashes when given a link it doesn’t have permission to follow.

This makes the file_target() method able to return either a file or path for displaying, as before, but also an IO error for when things go wrong.
2016-10-29 20:27:23 +01:00
Ben S
dcc17b1d15 This lint flag started to cause all kinds of fuss 2016-10-29 19:52:21 +01:00
Ben S
36d9b6844e Add .tgz to the compressed file extensions
Fixes #129
2016-10-29 19:28:41 +01:00
Ben S
a7e3456b0d Only engage the view when there are files to show
This changes the way that views are used to display the actual lists of files. It used to pass empty vectors to the view methods, which most of the time would not print anything because there are no files to list — except when there’s a header row which gets printed for no files.

By not calling the view method at all when there’s nothing to print, exa won’t ever print extra things in the view unless it needs to for a file.

This fixes #106 “Don’t print the header if the result set is empty”
2016-10-29 19:07:43 +01:00
Benjamin Sago
6d3e6b7cad Merge pull request #122 from quodlibetor/include-legal-args-in-error-messages
Add legal values to error messages
2016-10-05 16:48:55 +01:00
Benjamin Sago
a8b05fce83 Merge pull request #119 from gemmarx/use_stderr
Change to put error messages into stderr
2016-10-05 16:47:51 +01:00
Brandon W Maister
7e15e0dd49 Add legal values to error messages
Now when you do `--sort time` instead of saying "unknown option --sort
time" it will say "unknown options '--sort time' (choices: name...)"
with all legal options.

This also adds the legal values to the default help text.
2016-08-28 21:56:32 -04:00
Gemmarx
8d25719b6b Change to put error messages into stderr 2016-07-31 04:12:03 +09:00
Gemmarx
943ac87466 Change to ignore broken pipe error 2016-07-30 22:53:11 +09:00
Linden Krouse
a9bb275250 Exa now recognizes pipes, devices, and sockets on unix systems. Fixes #112 2016-06-13 23:14:36 -04:00
Ben S
b8191670c7 Fix, and add tests for, slashes in link paths 2016-06-11 16:54:06 +01:00
Ben S
331d5ea724 Rename underscored lifetimes
See https://github.com/rust-lang/rfcs/pull/1177
2016-06-11 13:35:40 +01:00
Hendrik Sollich
c2d42e7d84 Fix building without default features 2016-05-03 00:03:22 +02:00
Benjamin Sago
110a1c716b Convert exa into a library
This commit removes the 'main' function present in main.rs, renames it to exa.rs, and puts the 'main' function in its own binary. This, I think, makes it more clear how the program works and where the main entry point is.

Librarification also means that we can start testing as a whole. Two tests have been added that test everything, passing in raw command-line arguments then comparing against the binary coloured text that gets produced.

Casualties include having to specifically mark some code blocks in documentation as 'tests', as rustdoc kept on trying to execute my ANSI art.
2016-04-19 07:48:41 +01:00
Benjamin Sago
a02f37cb45 Change views to print to a Writer, not stdout
This will mean that we can test exa's output as a whole, without having to rely on process or IO or anything like that.
2016-04-18 18:39:32 +01:00
Benjamin Sago
476406f43b Remove unused argument 2016-04-17 21:01:30 +01:00
Benjamin Sago
78ff651326 Remove unnecessary .to_string()s from option tests 2016-04-17 20:56:06 +01:00
Benjamin Sago
e9e1161cec Split up the options module
The original options was becoming a bit unwieldy, and would have been even more so if I added the same amount of comments. So this commit splits it up.

There's no extra hiding going on here, or rearranging things within the module: (almost) everything now has to be marked 'pub' to let other sub-modules in the new options module to see it.
2016-04-17 20:38:37 +01:00
Benjamin Sago
b44ae1b56b Remove pointless OptionSet trait
The trait was only used internally to the options module, so it doesn't actually need to be exist or implemented on anything! We can just impl them directly on the types and have those methods be local to the module.
2016-04-16 22:25:24 +01:00
Benjamin Sago
45c93b1b63 Correct the list of crypto extensions
They were the same as the archive/compressed extensions, and I never noticed!
2016-04-16 22:17:12 +01:00
Benjamin Sago
fae0f3874e Create info module with business logic routines
Currently these routines number two: file type checking based on a file's name, and source file checking, also based on the file's name.
2016-04-16 22:05:50 +01:00
Benjamin Sago
b83844f384 Move a file's type out of its permissions field 2016-04-16 20:01:45 +01:00
Benjamin Sago
570fac0c18 Add comments to the new fields module 2016-04-16 19:56:44 +01:00
Benjamin Sago
efa372cb3b Source file rearrangements
This commit moves file, dir, and the feature modules into one parent 'fs' module. Now there are three main 'areas' of the code: main and options, the filesystem-touching code, and the output-displaying code.

It should be the case that nothing in 'output' touches 'std::fs'.
2016-04-16 18:59:25 +01:00
Benjamin Sago
b65043d6d9 Update raw libc types for Rust 1.8.0
Fixes #108. MetadataExt now returns direct numeric types rather than platform-specific ones, so we need to adjust the functions that use these to have the new types. I've just aliased the types to specific ones so the rest of the code remains the same (file.rs is the only place that uses this)

The RFC that changed this is here: https://github.com/rust-lang/rust/pull/31551
2016-04-16 17:06:26 +01:00
Benjamin Sago
9b87ef1da2 Print the parent path for passed-in files
This commit changes all the views to accommodate printing each path's prefix, if it has one.

Previously, each file was stripped of its ancestry, leaving only its file name to be displayed. So running "exa /usr/bin/*" would display only filenames, while running "ls /usr/bin/*" would display each file prefixed with "/usr/bin/". But running "ls /usr/bin/" -- without the glob -- would run ls on just the directory, printing out the file names with no prefix or anything.

This functionality turned out to be useful in quite a few situations: firstly, if the user passes in files from different directories, it would be hard to tell where they came from (especially if they have the same name, such as find | xargs). Secondly, this also applied when following symlinks, making it unclear exactly which file a symlink would be pointing to.

The reason that it did it this way beforehand was that I didn't think of these use-cases, rather than for any technical reason; this new method should not have any drawbacks save making the output slightly wider in a few cases. Compatibility with ls is also a big plus.

Fixes #104, and relates to #88 and #92.
2016-04-11 19:10:55 +01:00
Benjamin Sago
f35d28d1b8 Fix bug where the directory name was not printed 2016-04-11 07:48:23 +01:00
Benjamin Sago
c009a68ae5 Add Add impl and various tests for DisplayWidth 2016-04-05 18:45:35 +01:00
Ben S
f6c5c89f55 Always sort files the same way
This fixes a bug where extra sorting options (dirs first, reverse) were not applied when listing in long mode. In other words, fixes #105.

The bug occurred because the sorting function only took Files, but the details view uses File eggs that only contain Files. This commit changes the sorting function to accept anything that AsRefs to File, and impls that on both File and Egg so the same function works for both.
2016-03-31 23:13:15 +01:00
Ben S
eaa799c647 Replace deprecated raw types with libc ones
This limits it to stable until the APIs stabilise (weird, huh?)
2016-03-31 21:42:53 +01:00
Ben S
ee4c09dd30 Use only the time zone data present on the system
Thinking about it, it doesn't make sense to use an *external* time zone source when the program we want to compare it to, ls, uses the system one. So just use the system one.

Also, handle the case where the time zone data file can't be loaded by showing the files in UTC rather than falling over and quitting.
2016-03-31 21:19:29 +01:00
Ben S
8805ce9e3b Add case-insensitive extension sorting
This finishes off and closes #102. The code in this and the previous commit
were partly authored by `zv0n` on GitHub.
2016-03-19 15:06:26 +00:00
Benjamin Sago
3e9616cffa Add --sort=Name case-insensitive sorting
This uses the case-insensitive sort function in the `natord` crate to
convert both strings to lowercase lazily, sorting them as it goes. It
also adds tests for `--sort` in general.

The case sensitivity has been made an enum so it can be reused for other
fields (say, the file extension).

See #102.
2016-03-18 10:20:44 -04:00
Benjamin Sago
d3846468a3 Fix my own broken changes
- Fix visibility errors I stupidly didn't test before committing earlier
  today
- Silence warnings about casting that were necessary for ARM
- Update dependencies
2016-03-18 08:19:51 -04:00
Ben S
8ef316e1a4 Remove unnecessary FileTypes trait 2016-03-17 20:40:04 +00:00
Ben S
252eba4844 Improve error when we can't find a time zone 2016-02-11 15:52:40 +00:00
Ben S
2e8de3fb71 Fix import of TZResult 2016-02-10 19:11:10 +00:00
Ben S
7f480ab06b Improve system time zone detection 2016-02-10 19:02:20 +00:00
Ben S
b3d252522a Update test timezone to one we know exists
It wasn't the Arc unwrap causing the crash on Linux. Maybe it's this.
2016-02-10 16:16:09 +00:00
Ben S
2b213b3aea Rewrite tests to not use unwrap
Something about these seemed to be causing a crash on Travis (build 327)... I have no idea what would set it off, but this makes the code better anyway.
2016-02-10 16:08:15 +00:00
Ben S
75b2748ab1 Update packages to latest versions
- Users v0.5.1, which renames OSUsers to UsersCache
- Locale v0.2, which returns to libc v0.1
- Datetime v0.4.2, which mimics the locale update, and puts timezone definitions in:
- Zoneinfo-data, which is needed to obtain the current timezone
2016-02-10 15:22:43 +00:00
Benjamin Sago
4c3266310d Fix bug where xattr '@' characters weren't shown
The `--long` flag should show the '@' character in the permissions list if that feature has been compiled in, but only the `--extended` flag should actually show their keys, rather than just their presence.
2016-01-16 12:19:00 -10:00
Benjamin Sago
7f980935c5 Use Mutex lock on only the users columns
This makes use of a change in the `users` crate to change which parts of exa's code are accessed under a `Mutex`. The change is that the methods on `Users` can now take just `&self`, instead of `&mut self`. This has a knock-on effect in exa, as many methods now don't need to take a mutable `&self`, meaning that the Mutex can be moved to only containing the users information instead of having to be queried for *every column*. This means that threading should now be a lot faster, as fewer parts have to be executed on a single thread.

The main change to facilitate this is that `Table`'s structure has changed: everything environmental that gets loaded at the beginning is now in an `Environment` struct, which can be mocked out if necessary, as one of `Table`'s fields. (They were kind of in a variety of places before.)

Casualties include having to make some of the test code more verbose, as it explicitly takes the columns and environment as references rather than values, and those both need to be put on the stack beforehand. Also, all the colours are now hidden behind an `opts` field, so a lot of the rendering code is more verbose too (but not greatly so).
2016-01-16 11:56:37 -10:00
Benjamin Sago
d009ba5938 Move tree code to its module, and add tests
This commit separates the code used to generate the tree structure characters from the code used to build tables, meaning that it'll become possible to display tree structures without using any of the table code.

Also, some tests are added to make sure that the tree code *basically* works.
2015-12-22 15:44:51 +11:00
Benjamin Sago
54319a685e Use Vec::resize now that it has stabilised 2015-12-22 15:36:36 +11:00
Benjamin Sago
d1ea4c0ff5 Move TreePart to its own module 2015-12-22 13:14:32 +11:00
Benjamin Sago
2e15b81249 Optimise imports
1. imports from std
2. imports from external crates
3. imports from local modules
4. imports from self
2015-12-22 12:15:59 +11:00
Benjamin Sago
1b3492ce45 Move colours module into output
This commit moves the colours module to be a sub-module of the output one.
This makes sense because finding which colour a certain file should be is only
done during output, and (I think) the only places that the `Colours` struct's
fields are ever queried is from the output module.

The only casualty was that the `file_colour` from the filetype module had to
be moved, as determining colours is no longer part of that module - only
determining filetype is. So it now reflects its name!
2015-12-20 17:56:57 +11:00
Benjamin Sago
15cd67abe6 Turn TextCellContents into a struct
The benefit of this is that it make it possible to convert text cell contents
vectors into text cells with a method (see next commit). Casualties include
having to call `.into()` on vectors everywhere, which I'm not convinced is a
bad thing.
2015-12-17 17:51:42 +08:00
Benjamin Sago
39aa210437 Rename cell 'length' to 'width'
Because, strictly speaking, it's not a length, it's a width!

Also, re-order some struct constructors so that they're no longer
order-dependent (it's no longer the case that a value will be borrowed for one
field then consumed in another, meaning they have to be ordered in a certain
way to compile. Now the value is just worked out beforehand and the fields can
be specified in any order)
2015-12-17 10:34:11 +08:00
Benjamin Sago
88653a00eb Remove dependency between file and output mods
By removing the `File#file_name_width` method, we can make the file module
have no dependency on the output module -- in other words, the model (file)
and the view (output) are now separate again!
2015-12-17 10:27:44 +08:00
Benjamin Sago
4c2bf2f2e6 Encapsulate "display width" in a struct
This commit introduces the `output::cell::DisplayWidth` struct, which
encapsulates the Unicode *display width* of a string in a struct that makes it
less easily confused with the *length* of a string.

The use of this type means that it's now harder to accidentally use a string's
length-in-bytes as its width. I've fixed at least one case in the code where
this was being done!

The only casualty is that it introduces a dependency on the output module from
the file module, which will be removed next commit.
2015-12-17 10:15:09 +08:00
Benjamin Sago
c911b5f6e4 Replace Cells with growable TextCells
A recent change to ansi-term [1] means that `ANSIString`s can now hold either
owned *or* borrowed data (Rust calls this the Cow type). This means that we
can delay formatting ANSIStrings into ANSI-control-code-formatted strings
until it's absolutely necessary. The process for doing this was:

1. Replace the `Cell` type with a `TextCell` type that holds a vector of
   `ANSIString` values instead of a formatted string. It still does the
   width tracking.

2. Rework the details module's `render` functions to emit values of this
   type.

3. Similarly, rework the functions that produce cells containing filenames
   to use a `File` value's `name` field, which is an owned `String` that
   can now be re-used.

4. Update the printing, formatting, and width-calculating code in the
   details and grid-details views to produce a table by adding vectors
   together instead of adding strings together, delaying the formatting as
   long as it can.

This results in fewer allocations (as fewer `String` values are produced), and
makes the API tidier (as fewer `String` values are being passed around without
having their contents specified).

This also paves the way to Windows support, or at least support for
non-ANSI terminals: by delaying the time until strings are formatted,
it'll now be easier to change *how* they are formatted.

Casualties include:

- Bump to ansi_term v0.7.1, which impls `PartialEq` and `Debug` on
  `ANSIString`.
- The grid_details and lines views now need to take a vector of files, rather
  than a borrowed slice, so the filename cells produced now own the filename
  strings that get taken from files.
- Fixed the signature of `File#link_target` to specify that the
  file produced refers to the same directory, rather than some phantom
  directory with the same lifetime as the file. (This was wrong from the
  start, but it broke nothing until now)

References:

[1]: ansi-term@f6a6579ba8174de1cae64d181ec04af32ba2a4f0
2015-12-17 08:25:20 +08:00
Benjamin Sago
95c0d63045 io::Result -> IOResult 2015-12-15 21:47:37 +00:00
Benjamin Sago
47b088d662 Merge pull request #87 from petevine/master
Fix compilation on arm using stable rust 1.5
2015-12-15 20:15:16 +00:00
Jan Beich
92328d9093 Move CString to where it's actually used
src/feature/xattr.rs:6:5: 6:22 warning: unused import, #[warn(unused_imports)] on by default
src/feature/xattr.rs:6 use std::ffi::CString;
                           ^~~~~~~~~~~~~~~~~
2015-12-14 03:13:40 +00:00
Jan Beich
b35927f247 Fix logic inversion with --git in --help
$ exa --help
[...]
  -@, --extended     display extended attribute keys and sizes

$ exa -@
Unrecognized option: '@'.

$ exa --extended
Unrecognized option: 'extended'.

$ exa --git
Option --git is useless without option --long.

$ exa -l --git
.rw-r--r--  11k user 10 Dec 18:26 -- Cargo.lock
[...]
2015-12-14 04:11:03 +03:00
Jan Beich
b9eb364823 Fix getting tty window size on more BSDs
src/term.rs:37:39: 37:49 error: unresolved name `TIOCGWINSZ` [E0425]
src/term.rs:37     let result = ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut window);
                                                     ^~~~~~~~~~
2015-12-14 04:10:46 +03:00
petevine
734c5084ba Update xattr.rs 2015-12-11 05:50:20 +01:00
Ben S
1756a0a841 Fix bug where details view needed a terminal width
The buggy code assumed that, if output isn't to a terminal, then the only view available is the Lines view. This is incorrect, as the Details view doesn't require a set width either, so check for --long even when there's no set width.
2015-11-19 12:47:53 +00:00
Ben S
f92459d957 Add --colo[u]r options
The user can now control the output parameters by specifying the console width and when to show colours.

Fixes #75.
2015-11-19 12:31:43 +00:00
Ben S
c543e61ced Improve code in two insignificant little places 2015-11-19 12:19:04 +00:00
Ben S
ceae7e747c Rearrange trait definitions in options
This puts the impls for the structs defined in the module first, then impls for the structs defined in the columns module second.
2015-11-15 21:04:48 +00:00
Ben S
e07992d08c Use lazy_static to cache datetime formats
One of those two date formats was re-compiled before any date was displayed. Now they are compiled only the first time they're used, and cached versions are used thereafter, resulting in a speedup.
2015-11-15 19:26:58 +00:00
Ben S
edeec0f6f2 Improve help text
Instead of using the getopts crate’s dynamically-generated usage string, use a more static one:

- The options are organised by category now
- You can use `--help --long` to display only the ones that pertain to `--long`
- They’re aligned in a table sort of way

It could be generated statically, because all the options to change it are determined at compile time, but they’re not, yet...
2015-11-15 17:18:02 +00:00
Ben S
590fb9cd60 Move time type picking to details module
Technically speaking, picking which timestamp to show for a file is a function of an output module, rather than the file itself. This also means that the `output::column` and `file` modules are now completely separate.
2015-11-15 16:12:16 +00:00
Ben S
ca65c981f1 Avoid cloning the file names vector
By taking the file names as a mutable vector, we can avoid having to allocate a new one when it’s empty. The recent changes to Options::getopts have made it more obvious that we could move the same vector out of getopts’s matches, instead of cloning it there.
2015-11-15 15:52:55 +00:00
Ben S
2efaf7ec45 Options and FileFilter are also deducible
We may as well use this trait now that it’s available!
2015-11-15 15:07:19 +00:00
Ben S
534d3c3fa5 Extract 'bad argument' method 2015-11-15 00:02:39 +00:00
Ben S
8b9f074d63 Inline SortField::from_word
With the new OptionSet trait, the from_word constructor doesn't really do much by itself.
2015-11-14 23:47:13 +00:00
Ben S
10468797bb Move many Options structs to the output module
This cleans up the options module, moving the structs that were *only* in use for the columns view out of it.

The new OptionSet trait is used to add the ‘deduce’ methods that used to be present on the values.
2015-11-14 23:32:57 +00:00
Florian Gilcher
48d1e5164c Move file mode constants to a private module 2015-11-04 15:56:37 +01:00
Florian Gilcher
d083d26eaf Fix tree output 2015-11-04 15:22:51 +01:00
Florian Gilcher
77fa8974c4 Fixup: split prefix tests by property 2015-11-04 11:39:01 +01:00
Florian Gilcher
7a97b7d40c Reserve Vector elements instead of resizing 2015-11-04 11:07:31 +01:00
Florian Gilcher
7f53da73b7 Use slicing instead of future slice_last 2015-11-04 11:07:08 +01:00
Florian Gilcher
e8ea96ee86 Avoid unstable c_string conversion features 2015-11-04 10:25:20 +01:00
Florian Gilcher
b3e3825417 Replace unstable fs_mode by internal constants 2015-11-04 09:51:34 +01:00
Florian Gilcher
679b9e18b2 Replace sum call by stable fold(0, Add::add) 2015-11-04 09:41:49 +01:00
Ben S
63bd929eb5 Upgrade to latest ansi_term
Changes to the way ANSIStrings work mean we need to dereference the strings before putting them in an ANSIString. There's more that can be done here, but this gets it to compile for now.
2015-11-03 11:17:44 +00:00
Ben S
bc47073281 Feature slice_splits and vec_resize stabilised
As of rustc 1.6.0-nightly (1a2eaffb6 2015-10-31), anyway.
2015-11-03 11:16:19 +00:00
Ben S
f7131a740b Fix warning when building on 64-bit systems
This warning was 'caused' by the previous commit (but it's small and easy to fix, so don't worry)
2015-10-02 00:56:09 +01:00
rhysd
3dbc441c78 Fix integer length error on 32bit environment
this commit fixes below type mismatch error:

```
src/output/details.rs:585:49: 585:60 error: mismatched types:
 expected `i64`,
    found `i32`
(expected i64,
    found i32) [E0308]
src/output/details.rs:585         let date = self.tz.at(LocalDateTime::at(timestamp.0));
                                                                          ^~~~~~~~~~~
src/output/details.rs:585:49: 585:60 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error
Could not compile `exa`.
```
2015-09-28 11:42:52 +09:00
Ben S
41fb02a02d Upgrade to latest version of datetime crate
- VariableOffset -> TimeZone::VariableOffset
2015-09-21 00:15:07 +01:00
Benjamin Sago
3d3acc2e93 Dismiss some compile-time warnings
The `unused_results` lint was complaining that the results of inserting into a `MockUsers` object weren't being inspected. These are mock users, so all that would be returned is `None` to indicate that they weren't already in the table -- they're fine to ignore! So, suppress the warnings for those two testing modules.
2015-09-15 20:05:27 +01:00
Michael Neumann
6317417a98 This makes exa work on other platforms than linux and macosx. 2015-09-14 01:37:52 +02:00
Benjamin Sago
6cf9274828 Do not attempt to print nothing
This fixes a bug where an extra header line was printed when in --long --grid mode.
2015-09-05 17:40:02 +01:00
Ben S
65967355a8 Make sure we check the ioctl term size result 2015-09-04 11:30:46 +01:00
Ben S
d1e682b0c1 Remove pad crate and unnecessary qualifications 2015-09-04 11:20:13 +01:00
Ben S
f526d24911 Remove trivial cast 2015-09-04 11:17:59 +01:00
Ben S
10fecbd7f6 Details view comments and tidy-ups 2015-09-03 18:48:53 +01:00
Ben S
a14f1d82f0 It's hardly worth giving Exa its own constructor 2015-09-03 13:38:18 +01:00
Ben S
83f05ffb3c Remove redundant attribute field 2015-09-03 13:38:06 +01:00