Commit Graph

62 Commits

Author SHA1 Message Date
Benjamin Sago
dd838c2dc1 Move Colours and LSColors to their own module
The ‘options’ module is allowed to depend on ‘style’, but ‘options::render’ is not.
2017-08-26 21:40:37 +01:00
Benjamin Sago
945fa1e83d Isolate and document the environment variables 2017-08-26 21:36:27 +01:00
Benjamin Sago
bfb8a5a573 Extract trait above file name colours
This commit meddles about with both the Colours and the FileExtensions.

Even though all the renderable fields were turned into traits, the FileName struct kept on accessing fields directly on the Colours value instead of calling methods on it. It also did the usual amount of colour misappropriation (such as ‘punctuation’ instead of specifying ‘normal_arrow’)

In preparation for when custom file colours are configurable (any day now), the colourise-file-by-kind functionality (links, sockets, or directories) was separated from the colourise-file-by-name functionality (images, videos, archives). The FileStyle struct already allowed for both to be separate; it was only changed so that a type other than FileExtensions could be used instead, as long as it implements the FileColours trait. (I feel like I should re-visit the naming of all these at some point in the future)

The decision to separate the two means that FileExtensions is the one assigning the colours, rather than going through the fields on a Colours value, which have all been removed. This is why a bunch of arbitrary Styles now exist in filetype.rs.

Because the decision on which colourise-file-by-name code to use (currently just the standard extensions, or nothing if we aren’t colourising) is now determined by the Colours type (instead of being derived), it’s possible to get it wrong. And wrong it was! There was a bug where file names were colourised even though the rest of the --long output wasn’t, and this wasn’t caught by the xtests. It is now.
2017-08-26 20:43:47 +01:00
Benjamin Sago
fb3395883e Start actually parsing ls_colors
So far it only changes the colour of a directory, but it’s a start.
2017-08-25 17:43:36 +01:00
Benjamin Sago
4907565baf Move colour options to their own file 2017-08-24 23:38:26 +01:00
Benjamin Sago
30f3c6eb00 Strict mode and tests for colour scale 2017-08-23 11:45:29 +01:00
Benjamin Sago
bcf5213cc8 Tie the row threshold to EXA_GRID_ROWS
This makes it its own type, rather than just another environment variable that’s easily missed.
2017-08-13 11:15:40 +01:00
Benjamin Sago
6740faa781 env vars should be referenced, not copied
Just because the type that gets used right now is Copy and Clone doesn’t mean that when we pass mock ones in for tests they’ll be those two as well. So we have to go through and add &s everywhere.
2017-08-13 11:14:58 +01:00
Benjamin Sago
33e83accd0 match-to-if-let 2017-08-12 22:51:45 +01:00
Benjamin Sago
da00e2fda2 Thread the row threshold through grid_details
No new features here, just some restructuring. Mode::GridDetails was nice and elegant with those two fields, but now there’s a grid-details-only option the elegance has gone out the window.
2017-08-12 22:49:16 +01:00
Benjamin Sago
eec1a4f78a Stop --git from complaining too
Re-fixes #152
2017-08-11 21:43:56 +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
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
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
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
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
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
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
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
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
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
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
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
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
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