11use ansi_term:: { ANSIString , Colour , Style } ;
2+ use lscolors:: { Indicator , LsColors } ;
23use std:: collections:: HashMap ;
34
45#[ allow( dead_code) ]
@@ -62,6 +63,7 @@ pub enum Theme {
6263
6364pub struct Colors {
6465 colors : Option < HashMap < Elem , Colour > > ,
66+ lscolors : Option < LsColors > ,
6567}
6668
6769impl Colors {
@@ -70,15 +72,63 @@ impl Colors {
7072 Theme :: NoColor => None ,
7173 Theme :: Default => Some ( Self :: get_light_theme_colour_map ( ) ) ,
7274 } ;
75+ let lscolors = LsColors :: from_env ( ) ;
7376
74- Self { colors }
77+ Self { colors, lscolors }
7578 }
7679
7780 pub fn colorize < ' a > ( & self , input : String , elem : & Elem ) -> ColoredString < ' a > {
7881 self . style ( elem) . paint ( input)
7982 }
8083
84+ pub fn colorize_using_path < ' a > (
85+ & self ,
86+ input : String ,
87+ path : & str ,
88+ elem : & Elem ,
89+ ) -> ColoredString < ' a > {
90+ let style_from_path = self . style_from_path ( path) ;
91+ match style_from_path {
92+ Some ( style_from_path) => style_from_path. paint ( input) ,
93+ None => self . colorize ( input, elem) ,
94+ }
95+ }
96+
97+ fn style_from_path ( & self , path : & str ) -> Option < Style > {
98+ match & self . lscolors {
99+ Some ( lscolors) => {
100+ let style = lscolors
101+ . style_for_path ( path)
102+ . map ( lscolors:: Style :: to_ansi_term_style) ;
103+ if let Some ( style) = style {
104+ Some ( style)
105+ } else {
106+ None
107+ }
108+ }
109+ None => None ,
110+ }
111+ }
112+
81113 fn style ( & self , elem : & Elem ) -> Style {
114+ match & self . lscolors {
115+ Some ( lscolors) => {
116+ let indicator = self . get_indicator_from_elem ( elem) ;
117+ match indicator {
118+ Some ( style) => {
119+ let style = lscolors. style_for_indicator ( style) ;
120+ style
121+ . map ( lscolors:: Style :: to_ansi_term_style)
122+ . unwrap_or_default ( )
123+ }
124+ None => self . style_default ( elem) ,
125+ }
126+ }
127+ None => self . style_default ( elem) ,
128+ }
129+ }
130+
131+ fn style_default ( & self , elem : & Elem ) -> Style {
82132 if let Some ( ref colors) = self . colors {
83133 let style_fg = Style :: default ( ) . fg ( colors[ elem] ) ;
84134 if elem. has_suid ( ) {
@@ -91,6 +141,41 @@ impl Colors {
91141 }
92142 }
93143
144+ fn get_indicator_from_elem ( & self , elem : & Elem ) -> Option < Indicator > {
145+ let indicator_string = match elem {
146+ Elem :: File { exec, uid } => {
147+ if * uid {
148+ None
149+ } else {
150+ if * exec {
151+ Some ( "ex" )
152+ } else {
153+ Some ( "fi" )
154+ }
155+ }
156+ }
157+ Elem :: Dir { uid } => {
158+ if * uid {
159+ None
160+ } else {
161+ Some ( "di" )
162+ }
163+ }
164+ Elem :: SymLink => Some ( "ln" ) ,
165+ Elem :: Pipe => Some ( "pi" ) ,
166+ Elem :: Socket => Some ( "so" ) ,
167+ Elem :: BlockDevice => Some ( "bd" ) ,
168+ Elem :: CharDevice => Some ( "cd" ) ,
169+ Elem :: BrokenSymLink => Some ( "or" ) ,
170+ _ => None ,
171+ } ;
172+
173+ match indicator_string {
174+ Some ( ids) => Indicator :: from ( ids) ,
175+ None => None ,
176+ }
177+ }
178+
94179 // You can find the table for each color, code, and display at:
95180 //
96181 //https://jonasjacek.github.io/colors/
0 commit comments