Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): Make file types themeable #245

Merged
merged 9 commits into from
Sep 16, 2023
4 changes: 1 addition & 3 deletions man/eza_colors-explanation.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ files; setting `EXA_COLORS="reset"` will highlight nothing.

- eza now supports bright colours! As supported by most modern 256\-colour terminals, you can now choose from `bright` colour codes when selecting your custom colours in your `#EXA_COLORS` environment variable.

"Immediate" files are the files you should look at when downloading and building a project for the first time: READMEs, Makefiles, Cargo.toml, and others.
They are highlighted in _yellow_ and _underlined_.

- Build (Makefile, Cargo.toml, package.json) are yellow and underlined.
- Images (png, jpeg, gif) are purple.
- Videos (mp4, ogv, m2ts) are a slightly purpler purple.
- Music (mp3, m4a, ogg) is a deeper purple.
Expand Down
30 changes: 30 additions & 0 deletions man/eza_colors.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,36 @@ LIST OF CODES
`mp`
: a mount point

`im`
: a regular file that is an image

`vi`
: a regular file that is a video

`mu`
: a regular file that is lossy music

`lo`
: a regular file that is lossless music

`cr`
: a regular file that is related to cryptography (ex: key or certificate)

`do`
: a regular file that is a document (ex: office suite document or PDF)

`co`
: a regular file this is compressed

`tm`
: a regular file that is temporary (ex: a text editor's backup file)

`cm`
: a regular file that is a compilation artifact (ex: Java class file)

`bu`
: a regular file that is used to build a project (ex: Makefile)

Values in `EXA_COLORS` override those given in `LS_COLORS`, so you don’t need to re-write an existing `LS_COLORS` variable with proprietary extensions.


Expand Down
116 changes: 45 additions & 71 deletions src/info/filetype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
//! # Contributors
//! Please keep these lists sorted. If you're using vim, :sort i

use ansiterm::Style;
use phf::{phf_map, Map};

use crate::fs::File;
use crate::theme::FileColours;

#[derive(Debug, Clone)]
pub enum FileType {
Expand All @@ -24,55 +22,55 @@ pub enum FileType {
Compressed,
Temp,
Compiled,
Immediate // An “immediate” file is something that can be run or activated somehow in order to
Build // A “build file is something that can be run or activated somehow in order to
// kick off the build of a project. It’s usually only present in directories full of
// source code.
}

/// Mapping from full filenames to file type.
const FILENAME_TYPES: Map<&'static str, FileType> = phf_map! {
/* Immediate file - kick off the build of a project */
"Brewfile" => FileType::Immediate,
"bsconfig.json" => FileType::Immediate,
"BUILD" => FileType::Immediate,
"BUILD.bazel" => FileType::Immediate,
"build.gradle" => FileType::Immediate,
"build.sbt" => FileType::Immediate,
"build.xml" => FileType::Immediate,
"Cargo.toml" => FileType::Immediate,
"CMakeLists.txt" => FileType::Immediate,
"composer.json" => FileType::Immediate,
"configure" => FileType::Immediate,
"Containerfile" => FileType::Immediate,
"Dockerfile" => FileType::Immediate,
"Earthfile" => FileType::Immediate,
"flake.nix" => FileType::Immediate,
"Gemfile" => FileType::Immediate,
"GNUmakefile" => FileType::Immediate,
"Gruntfile.coffee" => FileType::Immediate,
"Gruntfile.js" => FileType::Immediate,
"jsconfig.json" => FileType::Immediate,
"Justfile" => FileType::Immediate,
"justfile" => FileType::Immediate,
"Makefile" => FileType::Immediate,
"makefile" => FileType::Immediate,
"meson.build" => FileType::Immediate,
"mix.exs" => FileType::Immediate,
"package.json" => FileType::Immediate,
"Pipfile" => FileType::Immediate,
"PKGBUILD" => FileType::Immediate,
"Podfile" => FileType::Immediate,
"pom.xml" => FileType::Immediate,
"Procfile" => FileType::Immediate,
"pyproject.toml" => FileType::Immediate,
"Rakefile" => FileType::Immediate,
"RoboFile.php" => FileType::Immediate,
"SConstruct" => FileType::Immediate,
"tsconfig.json" => FileType::Immediate,
"Vagrantfile" => FileType::Immediate,
"webpack.config.cjs" => FileType::Immediate,
"webpack.config.js" => FileType::Immediate,
"WORKSPACE" => FileType::Immediate,
"Brewfile" => FileType::Build,
"bsconfig.json" => FileType::Build,
"BUILD" => FileType::Build,
"BUILD.bazel" => FileType::Build,
"build.gradle" => FileType::Build,
"build.sbt" => FileType::Build,
"build.xml" => FileType::Build,
"Cargo.toml" => FileType::Build,
"CMakeLists.txt" => FileType::Build,
"composer.json" => FileType::Build,
"configure" => FileType::Build,
"Containerfile" => FileType::Build,
"Dockerfile" => FileType::Build,
"Earthfile" => FileType::Build,
"flake.nix" => FileType::Build,
"Gemfile" => FileType::Build,
"GNUmakefile" => FileType::Build,
"Gruntfile.coffee" => FileType::Build,
"Gruntfile.js" => FileType::Build,
"jsconfig.json" => FileType::Build,
"Justfile" => FileType::Build,
"justfile" => FileType::Build,
"Makefile" => FileType::Build,
"makefile" => FileType::Build,
"meson.build" => FileType::Build,
"mix.exs" => FileType::Build,
"package.json" => FileType::Build,
"Pipfile" => FileType::Build,
"PKGBUILD" => FileType::Build,
"Podfile" => FileType::Build,
"pom.xml" => FileType::Build,
"Procfile" => FileType::Build,
"pyproject.toml" => FileType::Build,
"Rakefile" => FileType::Build,
"RoboFile.php" => FileType::Build,
"SConstruct" => FileType::Build,
"tsconfig.json" => FileType::Build,
"Vagrantfile" => FileType::Build,
"webpack.config.cjs" => FileType::Build,
"webpack.config.js" => FileType::Build,
"WORKSPACE" => FileType::Build,
/* Cryptology files */
"id_dsa" => FileType::Crypto,
"id_ecdsa" => FileType::Crypto,
Expand All @@ -86,7 +84,7 @@ const FILENAME_TYPES: Map<&'static str, FileType> = phf_map! {
/// extension is added also update the extension icon map.
const EXTENSION_TYPES: Map<&'static str, FileType> = phf_map! {
/* Immediate file - kick off the build of a project */
"ninja" => FileType::Immediate,
"ninja" => FileType::Build,
/* Image files */
"arw" => FileType::Image,
"avif" => FileType::Image,
Expand Down Expand Up @@ -269,10 +267,10 @@ impl FileType {
/// Lookup the file type based on the file's name, by the file name
/// lowercase extension, or if the file could be compiled from related
/// source code.
fn get_file_type(file: &File<'_>) -> Option<FileType> {
pub(crate) fn get_file_type(file: &File<'_>) -> Option<FileType> {
// Case-insensitive readme is checked first for backwards compatibility.
if file.name.to_lowercase().starts_with("readme") {
return Some(Self::Immediate)
return Some(Self::Build)
}
if let Some(file_type) = FILENAME_TYPES.get(&file.name) {
return Some(file_type.clone())
Expand All @@ -291,27 +289,3 @@ impl FileType {
None
}
}

#[derive(Debug)]
pub struct FileTypeColor;

impl FileColours for FileTypeColor {
/// Map from the file type to the display style/color for the file.
fn colour_file(&self, file: &File<'_>) -> Option<Style> {
use ansiterm::Colour::*;

match FileType::get_file_type(file) {
Some(FileType::Compiled) => Some(Yellow.normal()),
Some(FileType::Compressed) => Some(Red.normal()),
Some(FileType::Crypto) => Some(Green.bold()),
Some(FileType::Document) => Some(Green.normal()),
Some(FileType::Image) => Some(Purple.normal()),
Some(FileType::Immediate) => Some(Yellow.bold().underline()),
Some(FileType::Lossless) => Some(Cyan.bold()),
Some(FileType::Music) => Some(Cyan.normal()),
Some(FileType::Temp) => Some(White.normal()),
Some(FileType::Video) => Some(Purple.bold()),
_ => None
}
}
}
13 changes: 13 additions & 0 deletions src/theme/default_theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ impl UiStyles {
},
},

file_type: FileType {
image: Purple.normal(),
video: Purple.bold(),
music: Cyan.normal(),
lossless: Cyan.bold(),
crypto: Green.bold(),
document: Green.normal(),
compressed: Red.normal(),
temp: White.normal(),
compiled: Yellow.normal(),
build: Yellow.bold().underline()
},

punctuation: DarkGray.bold(),
date: Blue.normal(),
inode: Purple.normal(),
Expand Down
Loading
Loading