Commit Graph

706 Commits

Author SHA1 Message Date
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