sharkdp / lscolors Goto Github PK
View Code? Open in Web Editor NEWA Rust library and tool to colorize paths using LS_COLORS
License: Apache License 2.0
A Rust library and tool to colorize paths using LS_COLORS
License: Apache License 2.0
Is this supposed to work in windows? I've tried a few things and can't seem to get it working.
lscolors *
and it just echos *
dir | lscolors
and it just shows the directory listing from dir
without colorsLS_COLORS
= this and it shows the dir listing without colorsI'm using Windows Terminal
which supports ansi colors.
Windows 10 2004 (10.0.19041.388)
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
.
LS_COLORS="ex=m\07\033[0"
should ding a bell every time an executable file is encountered.
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.
use case:
"path/path/colored_file" will have color codes for all parts
"path/path/not_colored_file" will not have color codes for the not_colored_file which makes parsing the output more complicated than necessary
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;
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.
ls
is case-insensitive in the matching, so we should be, too.
Currently, we skip parsing when encountering an unsupported ANSI style:
Instead, we should at least ignore them (or support them, see #2)
see also: sharkdp/fd#552
Hey there. I made PR #80 a while ago, and one of my ideas was to make a better CLI for the lscolors
binary.
In my dotfiles, I have an example of something that could be built to function relatively okay-ish. https://github.com/REALERvolker1/homescripts/blob/main/.config/rustcfg/ls-colors-cli/src/runtime.rs
I don't want you to just copy the code verbatim, as I wrote it sort of like I would write a bash script -- because that was why I was writing it.
Eh, just some ideas lol
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
it seems that the location when running lscolors changes the way its input is colored
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.
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.
In addition to bold, underline and italic, there are also:
see: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
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.
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
Quoting from #10:
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 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
.
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.
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?
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.
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 :-)
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
.
Lines 58 to 63 in c6e191b
Right now it supports the ones based on file types. But there's also
ca
for files with capabilities setdo
for doors (some Solaris thing)fi
for regular filesmh
for files with multiple hard linksno
the "normal" color which acts as a fallbackow
for directories writable by other userssu
for setuid filessg
for setgid filesst
for sticky filestw
for sticky directories that are writable by other usersHello,
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!
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! ๐
It would be great to bump crossterm to 0.24 and build in support for their new underline styles. We use lscolors
in nushell and love it. Thanks for such a cool crate!
Quoting from #10:
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.
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
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.
Currently, we only support directories, symlinks and executables. We should also add
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 filesystemstyle_for_path_with_metadata
could work, except that it's impossible to manually construct a std::fs::Metadata
objectstyle_for_indicator
doesn't use the suffix_mapping table so I miss out on coloring files based on extensionimpl 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.
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.
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
Is it possible to use the styles from this library in tui-rs
?
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
A file_type() call on a DirEntry is cheap compared to a symlink_metadata() call on the path. See: https://doc.rust-lang.org/std/fs/struct.DirEntry.html#method.file_type
Would it be possible to use this call as an alternative to metadata() for style_for_path_with_metadata()?
Thanks for your work! Appreciate this project.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.