Dir::readdir and File::from path now both return IoResults, rather than just calling fail! and exiting. This allows the program to continue after an error.
I'd much rather have this separate, as it has the definite potential to
balloon up to a huge size and end up making the other parts of the file
module hard to read. But on the other hand, it meant making a few more
methods public on file... readability over cleanliness, I guess.
This new object is then passed down to the File, so it can see what files are around it. This means it doesn't need to re-query the filesystem several times per file, instead using the in-memory copy.
Also, switch to using the built-in Path#with_extension method.
And an extra level of compiled files that don't get highlighted when their source files aren't present. I don't really like having two functions that do (almost) the same thing, but I have to due to the way colouring is done.
Compiled files with a source present (such as code.o when code.c is present) are now classified as temporary files. If the source isn't present, they're highlighted in a kind of drab colour (using the new 255-colour ability, yay!)
The code does do exists() checks on the filesystem when it could be possible to compare the files to the list of files we got from the call to readdir(), but it doesn't.
Add a Fixed(u8) constructor to Colour, which represents the 256 colours
that some terminals support. This means we can:
- stop using black bold to mean grey, which looks weird on terminals
that haven't been set up to use it;
- support a *lot* more file type colours.
I'm a little suspicious of how much string allocation is being done in
colours.rs, but that's a problem for another time.
Currently there's only one numeric column, and that's the file size, so it gets
special treatment.
I was originally going to have a folder file size field be filled up with '-'s
as far as it could go, leaving it entirely up to the column how its field gets
formatted. But then I saw just one '-' working just fine, so I left it like
that. In the first try, columns could do anything they want when padding a
string (including changing the padding character or just changing it entirely),
but now there's no point.
This finally means that the list of columns is no longer fixed, which means it has to be generated somewhere. And guess where it got moved to? That's right, the options object! (see previous commits)
I'm copying ls here because we don't really need the 'B' for bytes to be
listed every time. I think it looks better the new way. Unlike ls, don't
list directory sizes, because I've never found the pseudo-sizes they get
given at all useful.
Also, fix a bug where aligning columns didn't work when the number of
format characters (like '\x1B' and '[') were different between each
line.
This involves putting the entire output into a table before anything
is actually printed, in order to determine what the width of each
column should be. This should make it appear to output slower, as the
first line can only be printed after every file has been examined, but
it's still fast to me.
Also, reverse the way columns are rendered: before, a column took a stat and a name to render; now, a file takes a column type to render. This means that most of the File data/methods can be private.