Add a bunch more file types

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.
Cache readdir results in a Dir object

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.
Move file-type detection to its own module

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.
Make file types a trait
Merge the two source-file methods
Merge branch 'refs/heads/file-types'