Code Monkey home page Code Monkey logo

lscolors's Introduction

lscolors

CICD Crates.io Documentation

A cross-platform library for colorizing paths according to the LS_COLORS environment variable (like ls).

Usage

use lscolors::{LsColors, Style};

let lscolors = LsColors::from_env().unwrap_or_default();

let path = "some/folder/test.tar.gz";
let style = lscolors.style_for_path(path);

// If you want to use `ansi_term`:
let ansi_style = style.map(Style::to_ansi_term_style)
                      .unwrap_or_default();
println!("{}", ansi_style.paint(path));

// If you want to use `nu-ansi-term` (fork of ansi_term) or `gnu_legacy`:
let nu_ansi_style = style.map(Style::to_nu_ansi_term_style)
                      .unwrap_or_default();
println!("{}", nu_ansi_style.paint(path));

// If you want to use `crossterm`:
let crossterm_style = style.map(Style::to_crossterm_style)
                      .unwrap_or_default();
println!("{}", crossterm_style.apply(path));

Command-line application

This crate also comes with a small command-line program lscolors that can be used to colorize the output of other commands:

> find . -maxdepth 2 | lscolors

> rg foo -l | lscolors

You can install it by running cargo install lscolors or by downloading one of the prebuilt binaries from the release page. If you want to build the application from source, you can run

cargo build --release --features=nu-ansi-term --locked

Features

// Cargo.toml

[dependencies]
// use ansi-term coloring
lscolors = { version = "v0.14.0", features = ["ansi_term"] }
// use crossterm coloring
lscolors = { version = "v0.14.0", features = ["crossterm"] }
// use nu-ansi-term coloring
lscolors = { version = "v0.14.0", features = ["nu-ansi-term"] }
// use nu-ansi-term coloring in gnu legacy mode with double digit styles
lscolors = { version = "v0.14.0", features = ["gnu_legacy"] }

License

Licensed under either of

at your option.

References

Information about the LS_COLORS environment variable is sparse. Here is a short list of useful references:

lscolors's People

Contributors

alexkunde avatar dbuch avatar dduan avatar fdncred avatar jcaesar avatar meain avatar nickelc avatar nn1ks avatar realervolker1 avatar sharkdp avatar sholderbach avatar sophiajt avatar sylvestre avatar tavianator avatar tmccombs avatar windsoilder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lscolors's Issues

Release a new version for the support of crossterm

Lscolors have added the crossterm feature support in master for nearly a year, but not yet release a version, I am looking forward to using this feature in lsd-rs/lsd#452, could the maintainer release a newer version please, so that we don't have to implement it ourselves or use the master branch.

option to set "root" path

it seems that the location when running lscolors changes the way its input is colored

screenshot_2023-07-07_12-12-14

when in another directory and with the same input, colors differ; also note that the some files are colored as they should, one of the files is executable and doesn't have the same color but that's understandable.

lscolors_no_color

I run lscolors in a subshell as a fix it but it may surprise some users and it would be more usable if the result is the same, and for users without a sub shell an option to set the "root" path may be helpful.

Released a new version?

Hi, do we have a chance to release a new version? So some crates which uses crossterm 0.26.1 won't conflict with it :-)

Option to colorize paths component-wise

for a path like

some/folder/symlink/another-folder/test.md

colorize each component (some/, folder/, symlink/, ...) accordingly.

This could be implemented both in the library as well as in the executable.

[feature request] API to style file paths that don't exist on disk

Use case

I have an arbitrary &Path that represents a normal file name, but it was programmatically generated and does not correspond to a file on disk (e.g. when inspecting a tarball), and I want a way to get the appropriate Style for it based on the file extension.

None of the existing APIs can do this:

  • style_for_path calls std::fs::symlink_metadata, which fails if the path does not exist in the filesystem
  • style_for_path_with_metadata could work, except that it's impossible to manually construct a std::fs::Metadata object
  • style_for_indicator doesn't use the suffix_mapping table so I miss out on coloring files based on extension

Proposed API

impl LsColors {
    pub fn style_for_regular_file<P: AsRef<Path>>(&self, path: P) -> Option<&Style>;
}

The result would be the same as style_for_path_with_metadata when that Metadata refers to a regular file.

Implementation

I'm planning on forking and writing my own implementation of this anyway, and I'm happy to send a PR incorporating whatever feedback you may have.

Create a style_for_string_with_enum method

Hi!

I would like to use lscolors into my lsd project but the current implementation make it a little difficult to integrate. In its current state lsd generate a custom Metadata object from the file path and the file metadata then use it for the rendering. The advantages are that it separate the metadata parsing logic from the rendering and it consume the path and the metadata object only once. One of the downside is that we don't have the arguments required by lscolors (path and metadata) inside the rendering logic which make difficult to integrate.

I would like to propose you to create a new public method which could be useful. I would look like to:

pub enum Filetype {
    Directory,
    Symlink,
    Executable,
    BrokenSymlink,
    Fifo,
    Socket,
    BlockDevice,
    CharDevice,
}

pub fn style_for_string_with_enum(&self, input: &str, filetype: FileType) -> Option<&Style> {}

What do you think of it?

Support more dircolors keys

Right now it supports the ones based on file types. But there's also

  • ca for files with capabilities set
  • do for doors (some Solaris thing)
  • fi for regular files
  • mh for files with multiple hard links
  • no the "normal" color which acts as a fallback
  • ow for directories writable by other users
  • su for setuid files
  • sg for setgid files
  • st for sticky files
  • tw for sticky directories that are writable by other users

Windows support?

Is this supposed to work in windows? I've tried a few things and can't seem to get it working.

  • I tried lscolors * and it just echos *
  • I tried dir | lscolors and it just shows the directory listing from dir without colors
  • I tried setting LS_COLORS = this and it shows the dir listing without colors
  • I tried it in powershell without success

I'm using Windows Terminal which supports ansi colors.
Windows 10 2004 (10.0.19041.388)

Crossterm conversion using incorrect colors

I am still not 100% certain on this and so I thought I would start a discussion around this. I believe we incorrectly converting to the bright variants in crossterm instead of the dark ones. For example 34 should be matched to 4 in crossterm which would be DarkBlue and not Blue.

lscolors/src/style.rs

Lines 58 to 63 in c6e191b

Color::Red => crossterm::style::Color::Red,
Color::Green => crossterm::style::Color::Green,
Color::Yellow => crossterm::style::Color::Yellow,
Color::Blue => crossterm::style::Color::Blue,
Color::Magenta => crossterm::style::Color::Magenta,
Color::Cyan => crossterm::style::Color::Cyan,

Add support for ln=target

Quoting from the ls source code:

/* When true, in a color listing, color each symlink name according to the
   type of file it points to.  Otherwise, color them according to the 'ln'
   directive in LS_COLORS.  Dangling (orphan) symlinks are treated specially,
   regardless.  This is set when 'ln=target' appears in LS_COLORS.  */

static bool color_symlink_as_referent;

Support LSCOLORS env variable on macOS

I wanted to customize fd colors and read the docs. I found out that it uses LS_COLORS for customization.

macOS builtin ls command reads colors from LSCOLORS env variable, not LS_COLORS.

man ls
     LSCOLORS            The value of this variable describes what color to use for which attribute when colors are enabled with CLICOLOR or COLORTERM.  This string is
                         a concatenation of pairs of the format fb, where f is the foreground color and b is the background color.

                         The color designators are as follows:

                               a     black
                               b     red
                               c     green
                               d     brown
                               e     blue
                               f     magenta
                               g     cyan
                               h     light grey
                               A     bold black, usually shows up as dark grey
                               B     bold red
                               C     bold green
                               D     bold brown, usually shows up as yellow
                               E     bold blue
                               F     bold magenta
                               G     bold cyan
                               H     bold light grey; looks like bright white
                               x     default foreground or background

                         Note that the above are standard ANSI colors.  The actual display may differ depending on the color capabilities of the terminal in use.

                         The order of the attributes are as follows:

                               1.   directory
                               2.   symbolic link
                               3.   socket
                               4.   pipe
                               5.   executable
                               6.   block special
                               7.   character special
                               8.   executable with setuid bit set
                               9.   executable with setgid bit set
                               10.  directory writable to others, with sticky bit
                               11.  directory writable to others, without sticky bit

                         The default is "exfxcxdxbxegedabagacad", i.e., blue foreground and default background for regular directories, black foreground and red
                         background for setuid executables, etc.

I suggest to support this variable and read from it on macOS. Also lib can provide default value (exfxcxdxbxegedabagacad) for it.

The style will be more consistent across ls and fd by default.

Release v0.5.0 is missing the non-musl .deb package

Hey David / @sharkdp,
first of all I'd like to thank you a thousand times for all these awesome rust cli applications/libraries you've released! ๐Ÿ‘ ๐Ÿ‘ ๐Ÿ‘
Each of them is great, absolutely on-point and you have single-handedly greatly improved my terminal environment with every single one them.

I'm using an ansible playbook to install all of them (fd, hexyl, ...) on basically any Debian based system I work with. I can share the playbook/roles in case you're interested.

I have included a variable that determines wether to use the *-musl-* variants if available (defaults to true) so I didn't recognize that my playbook was broken for the non-musl installation of the current release of lscolors until I updated my build system today.

Could you add the missing .deb to the release please? That'd be really cool and greatly appreciated.

Thanks in advance and again: kudos for all the great stuff you're sharing! ๐Ÿ˜„

Add complete set of filetypes

Currently, we only support directories, symlinks and executables. We should also add

  • broken symlinks
  • FIFOs
  • sockets
  • ...?

ls has default styles

If you do

$ LS_COLORS="" ls --color

you'll still get colored output, because GNU ls has a set of default styles. You can find them listed in man dir_colors (ls uses the following defaults: ...). Or here.

Setting one thing in LS_COLORS doesn't override the rest of the defaults, so you can do something like

$ LS_COLORS="ex=01:" ls --color

and only executables will change color, while directories etc. will stay like the defaults.

`or` and `mi` are different

On my system,

$ ln -s nowhere broken
$ ./target/debug/lscolors broken
broken

is printed without any color, despite ls showing it bold and red. The reason is that I have or=40;31;01:mi=00: in my LS_COLORS, and lscolors does

                            "or" | "mi" => lscolors.broken_symlink = Some(style),

so mi=00 overwrites or.

My understanding of the semantics is that or (orphan) is for broken links, and mi (missing) is for files that don't exist. So in

$ LS_COLORS='or=31;01:mi=33;01:' ls -lh broken
lrwxrwxrwx 1 tavianator users 7 Jan  7 14:23 broken -> nowhere

broken gets the red or color, and nowhere gets the yellow mi color. Additionally, mi falls back to or if mi is not set, so LS_COLORS='or=31;01:' results in both getting the red or color.

Finally, setting a key (besides rs) to a string containing only zeros is the same as having it unset, so
LS_COLORS='or=31;01:mi=00: keeps everything red.

I'm not sure if lscolors tries to color links differently than link targets, but regardless, mi=00: shouldn't be overwriting the or color.

Option to output colored file name only

Given "aaa/bbb/entry" return only "color + entry + color reset".

Use case:

I have "$HOME/downloads", which happens to be a link, and a lot of other files from different directories in a list and want to colorize them.

The only way to get correct colorization is to be in the right directory for each entry in the list, this means starting a process for each entry and is prohibitively expensive.

I can send the full path but then I'd have to parse the colored string.

An alternative would be to output the colored path and the colored entry on different lines.

Tracking issue for incompatibilities with GNU ls

  • ln=target should color symlinks like their target

    #11 was closed as wontfix, but this might be possible now after #45.

  • ca (regular file with capabilities set)

    #6 was closed as mostly completed, but ca (and do) remain unimplemented.

    It is very slow to check for capabilities (at least two syscalls per file). ca is no longer part of the default GNU ls color scheme.

  • do (Solaris door)

    These are rare.

  • Custom control sequences

    #2 and #21 are relevant issues. Currently lscolors will ignore control sequences it doesn't understand, while GNU ls just passes everything through verbatim.

    GNU ls even supports non-ANSI terminals by customizing rs, lc, rc, ec, cl.

  • Escape sequences

    LS_COLORS="ex=m\07\033[0" should ding a bell every time an executable file is encountered.

  • fi=0 should not fall back to no

color input even if it has spaces at the beginning and end

if an input line has spaces the directory will not be colorized even if it's a valid directory

this would make it possible to colorize the output of a tool that generated directories indented, I discovered this while looking for a duplicates on my machine and hope that the large blob of files could be made more palatable by lscolors; it worked for the file and I scripted the rest but it would be nice if lscolors did it and I doubt that many people have real paths that start with space

    echo -e "\t/home/a.txt\n/home/a.txt" | lscolors

Reversed background/foreground for the sticky bit

With

mkdir sticky
chmod o+t sticky
use lscolors::LsColors;

fn main() {
    let tmp_file = "sticky";
    
    let lscolors = LsColors::from_env().unwrap_or_default();

    let style = lscolors.style_for_path(tmp_file).unwrap();
    let style = style.to_nu_ansi_term_style();
    println!("result = {}", style.paint("foo").to_string().escape_default());   
}

it returns
result = \u{1b}[44;37mfoo\u{1b}[0m

while GNU ls returns:

^[[0m^[[37;44msticky^[[0m

44 & 37 aren't in the same order.

with:

/usr/bin/ls -d --color=always sticky > a.txt
cat -v a.txt

README doesn't explain how to build the command-line application

There are no features defined in Cargo.toml for this either.

==>   Generating temporary packing list
  Installing lscolors v0.14.0 (/usr/ports/misc/lscolors/work/lscolors-0.14.0)
       Fresh lscolors v0.14.0 (/usr/ports/misc/lscolors/work/lscolors-0.14.0)
    Finished release [optimized] target(s) in 0.01s
warning: none of the package's binaries are available for install using the selected features
strip: open /usr/ports/misc/lscolors/work/stage/usr/local/bin/lscolors failed: No such file or directory
*** Error code 1

Feature request: Always add ANSI coloring sequence,

Hi, would it be possible to always have an ANSI coloring sequence even for files that are colored "no color", this makes it easier to use lscolors without having to parse it's output to see if the the sequences are there or not.

some background, I am implementing my own version of fff, because I can, and I use lscolors in it (I asked you to make it an application, would be strange ot not use it), I need to take substring from the colored file name and not having to deal with files that have the ansi sequences and those that are not simplify the logic

FYI: https://gist.github.com/nkh/6144e0dfcaf5848c43fa962ad47be865

Feature request: option to return a substring of the colored file name

Hi, I'd be cool to have these features:

"some input" | lscolors --length 10 --strip_start
would output the input colored with a length of maximum of 10 characters, removing excess characters att the beginning of the input

"some input" | lscolors --length 10 --strip_end
would output the input colored with a length of maximum of 10 characters , removing excess characters att the end of the input

a much fancy interface would be with a --printf so one could do something like :

stat somefile --printf "%x\t%f%y" | lscolors -d '\t' -printf "%5s %10lscolors_strip-end %s"

where %lscolors_strip_end is lscolors specific, it allows coloring of multiple files in the same input if wanted by the user and is a simple way to define a colorizer for stat or other commands listing files.

All this is to simplify short scripts, and make stat output a tad less dull in colored terminals, and can of course be dealt with outside lscolors

Clear up documentation on loading LSCOLORS env var

Hello,

I think that the example in the README should show more clearly that the LSCOLORS env var should be loaded only once at the beginning of the program for performance.

Simply writing a comment saying that should suffice. Or, consider updating the example to pass that in as a reference to some coloring function, or declare it statically with lazy_static.

Thanks for the great crate!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.