1+ #[ cfg( feature = "color" ) ]
2+ use chromaterm:: { colors, prelude:: * } ;
13use clap:: Error as ClapError ;
24use clap:: { Parser , Subcommand , ValueEnum } ;
35use gengo:: { Analysis , Builder , Directory , Git , analysis:: SummaryOpts } ;
46use indexmap:: IndexMap ;
57#[ cfg( feature = "color" ) ]
6- use owo_colors:: Rgb ;
7- #[ cfg( feature = "color" ) ]
88use relative_luminance:: Luminance ;
99use std:: error:: Error as BaseError ;
1010use std:: io:: { self , Write } ;
@@ -45,7 +45,7 @@ pub struct CLI {
4545 breakdown : bool ,
4646 /// Control when colors are displayed.
4747 #[ cfg( feature = "color" ) ]
48- #[ arg( long, default_value = "always " ) ]
48+ #[ arg( long, default_value = "auto " ) ]
4949 color : ColorControl ,
5050 /// The format to use for output.
5151 #[ arg( short = 'F' , long, default_value = "pretty" ) ]
@@ -74,6 +74,8 @@ enum Commands {
7474#[ cfg( feature = "color" ) ]
7575#[ derive( ValueEnum , Debug , Clone ) ]
7676enum ColorControl {
77+ /// Automatically detect if colors are supported.
78+ Auto ,
7779 /// Always use colors.
7880 Always ,
7981 /// Use only the 8 ANSI colors.
@@ -92,6 +94,19 @@ enum Format {
9294
9395impl CLI {
9496 pub fn run ( & self , mut out : impl Write , mut err : impl Write ) -> Result < ( ) , io:: Error > {
97+ #[ cfg( feature = "color" ) ]
98+ {
99+ use ColorControl :: * ;
100+ use chromaterm:: ColorSupport ;
101+
102+ chromaterm:: config:: convert_to_supported ( true ) ;
103+ match self . color {
104+ Auto => chromaterm:: config:: use_default_color_support ( ) ,
105+ Always => chromaterm:: config:: use_color_support ( ColorSupport :: True ) ,
106+ Ansi => chromaterm:: config:: use_color_support ( ColorSupport :: Simple ) ,
107+ Never => chromaterm:: config:: use_color_support ( ColorSupport :: None ) ,
108+ }
109+ }
95110 let results = self . command . analyze ( self . read_limit ) ;
96111 let results = match results {
97112 Ok ( results) => results,
@@ -121,13 +136,13 @@ impl CLI {
121136 for ( language, size) in summary. iter ( ) {
122137 let percentage = ( * size * 100 ) as f64 / total;
123138 #[ cfg( feature = "color" ) ]
124- let color = language. owo_color ( ) ;
139+ let color = language. chromaterm_color ( ) ;
125140 #[ cfg( not( feature = "color" ) ) ]
126141 let color = ( ) ;
127142
128143 let stats = format ! ( "{:>6.2}% {}" , percentage, size) ;
129144 let line = format ! ( "{:<15} {}" , stats, language. name( ) ) ;
130- let line = self . colorize ( & line, color) ;
145+ let line = self . colorize ( & line, & color) ;
131146 writeln ! ( out, "{}" , line) ?;
132147 }
133148
@@ -183,11 +198,11 @@ impl CLI {
183198
184199 for ( language, files) in files_per_language. into_iter ( ) {
185200 #[ cfg( feature = "color" ) ]
186- let color = language. owo_color ( ) ;
201+ let color = language. chromaterm_color ( ) ;
187202 #[ cfg( not( feature = "color" ) ) ]
188203 let color = ( ) ;
189204
190- writeln ! ( out, "{}" , self . colorize( language. name( ) , color) ) ?;
205+ writeln ! ( out, "{}" , self . colorize( language. name( ) , & color) ) ?;
191206
192207 let files = {
193208 let mut files = files;
@@ -199,7 +214,7 @@ impl CLI {
199214 writeln ! (
200215 out,
201216 " {}" ,
202- self . colorize( & file. display( ) . to_string( ) , color)
217+ self . colorize( & file. display( ) . to_string( ) , & color)
203218 ) ?;
204219 }
205220 writeln ! ( out) ?;
@@ -208,61 +223,21 @@ impl CLI {
208223 }
209224
210225 #[ cfg( feature = "color" ) ]
211- fn colorize ( & self , s : & str , color : owo_colors:: Rgb ) -> String {
212- use ColorControl :: * ;
213- use owo_colors:: { AnsiColors :: * , OwoColorize , Rgb } ;
214-
215- match self . color {
216- Never => String :: from ( s) ,
217- Always => {
218- let fg = if Self :: is_bright ( color) {
219- Rgb ( 0 , 0 , 0 )
220- } else {
221- Rgb ( 0xFF , 0xFF , 0xFF )
222- } ;
223- s. on_color ( color) . color ( fg) . to_string ( )
224- }
225- Ansi => {
226- let ( bg, ( r, g, b) ) = Self :: closest_color ( color) ;
227- let fg = if Self :: is_bright ( Rgb ( r, g, b) ) {
228- Black
229- } else {
230- White
231- } ;
232- s. on_color ( bg) . color ( fg) . to_string ( )
233- }
234- }
235- }
226+ fn colorize ( & self , s : & str , color : & colors:: True ) -> String {
227+ use chromaterm:: { Color , colors:: True } ;
236228
237- #[ cfg( feature = "color" ) ]
238- fn is_bright < T : Into < RgbWrapper > > ( color : T ) -> bool {
239- color. into ( ) . relative_luminance ( ) > 0.5
229+ let fg = if Self :: is_bright ( color) {
230+ True :: from_rgb ( 0 , 0 , 0 )
231+ } else {
232+ True :: from_rgb ( 0xFF , 0xFF , 0xFF )
233+ } ;
234+ let ( r, g, b) = color. rgb_u8 ( ) ;
235+ s. on_rgb ( r, g, b) . color ( fg) . to_string ( )
240236 }
241237
242238 #[ cfg( feature = "color" ) ]
243- fn closest_color ( rgb : owo_colors:: Rgb ) -> ( owo_colors:: AnsiColors , ( u8 , u8 , u8 ) ) {
244- use owo_colors:: AnsiColors :: * ;
245- // NOTE Gets the closest color by Euclidean distance
246- [
247- ( Black , ( 0u8 , 0u8 , 0u8 ) ) ,
248- ( Red , ( 0xFF , 0 , 0 ) ) ,
249- ( Green , ( 0 , 0xFF , 0 ) ) ,
250- ( Yellow , ( 0xFF , 0xFF , 0 ) ) ,
251- ( Blue , ( 0 , 0 , 0xFF ) ) ,
252- ( Magenta , ( 0xFF , 0 , 0xFF ) ) ,
253- ( Cyan , ( 0 , 0xFF , 0xFF ) ) ,
254- ( White , ( 0xFF , 0xFF , 0xFF ) ) ,
255- ]
256- . into_iter ( )
257- . min_by_key ( |( _, ( r, g, b) ) | {
258- // NOTE As a shortcut we'll just skip the square root step
259- [ ( r, rgb. 0 ) , ( g, rgb. 1 ) , ( b, rgb. 2 ) ]
260- . into_iter ( )
261- . map ( |( p1, p2) | u32:: from ( p1. abs_diff ( p2) ) )
262- . map ( |diff| diff * diff)
263- . sum :: < u32 > ( )
264- } )
265- . unwrap ( )
239+ fn is_bright < ' a , T : Into < RgbWrapper < ' a > > > ( color : T ) -> bool {
240+ color. into ( ) . relative_luminance ( ) > 0.5
266241 }
267242
268243 #[ cfg( not( feature = "color" ) ) ]
@@ -293,13 +268,15 @@ impl Commands {
293268
294269#[ cfg( feature = "color" ) ]
295270mod color_support {
271+ use chromaterm:: Color ;
272+
296273 use super :: * ;
297274
298- pub ( super ) struct RgbWrapper ( Rgb ) ;
275+ pub ( super ) struct RgbWrapper < ' a > ( & ' a colors :: True ) ;
299276
300- impl Luminance < f32 > for RgbWrapper {
277+ impl Luminance < f32 > for RgbWrapper < ' _ > {
301278 fn luminance_rgb ( & self ) -> relative_luminance:: Rgb < f32 > {
302- let Rgb ( r, g, b) = self . 0 ;
279+ let ( r, g, b) = self . 0 . rgb_u8 ( ) ;
303280 // NOTE Normalize to the range [0.0, 1.0]
304281 relative_luminance:: Rgb :: new (
305282 f32:: from ( r) / 255.0 ,
@@ -309,8 +286,8 @@ mod color_support {
309286 }
310287 }
311288
312- impl From < Rgb > for RgbWrapper {
313- fn from ( rgb : Rgb ) -> Self {
289+ impl < ' a > From < & ' a colors :: True > for RgbWrapper < ' a > {
290+ fn from ( rgb : & ' a colors :: True ) -> Self {
314291 Self ( rgb)
315292 }
316293 }
0 commit comments