@@ -10,6 +10,8 @@ use crate::output::escape;
10
10
use crate :: output:: icons:: { icon_for_file, iconify_style} ;
11
11
use crate :: output:: render:: FiletypeColours ;
12
12
13
+ const HYPERLINK_START : & str = "\x1B ]8;;" ;
14
+ const HYPERLINK_END : & str = "\x1B \x5C " ;
13
15
14
16
/// Basically a file name factory.
15
17
#[ derive( Debug , Copy , Clone ) ]
@@ -346,59 +348,32 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
346
348
let file_style = self . style ( ) ;
347
349
let mut bits = Vec :: new ( ) ;
348
350
349
- self . escape_color_and_hyperlinks (
351
+ let mut display_hyperlink = false ;
352
+ if self . options . embed_hyperlinks == EmbedHyperlinks :: On {
353
+ if let Some ( abs_path) = self . file . path . canonicalize ( ) . unwrap ( ) . as_os_str ( ) . to_str ( ) {
354
+ bits. insert ( 0 , ANSIString :: from ( format ! (
355
+ "{}file://{}{}{}" ,
356
+ HYPERLINK_START ,
357
+ gethostname:: gethostname( ) . to_str( ) . unwrap_or( "" ) ,
358
+ urlencoding:: encode( abs_path) . replace( "%2F" , "/" ) ,
359
+ HYPERLINK_END ,
360
+ ) ) ) ;
361
+ display_hyperlink = true ;
362
+ }
363
+ }
364
+
365
+ escape (
366
+ self . file . name . clone ( ) ,
350
367
& mut bits,
351
368
file_style,
352
369
self . colours . control_char ( ) ,
353
370
) ;
354
371
355
- bits
356
- }
357
-
358
- // An adapted version of escape::escape.
359
- // afaik of all the calls to escape::escape, only for escaped_file_name, the call to escape needs to be checked for hyper links
360
- // and if that's the case then I think it's best to not try and generalize escape::escape to this case,
361
- // as this adaptation would incur some unneeded operations there
362
- pub fn escape_color_and_hyperlinks ( & self , bits : & mut Vec < ANSIString < ' _ > > , good : Style , bad : Style ) {
363
- let string = self . file . name . clone ( ) ;
364
-
365
- if string. chars ( ) . all ( |c| c >= 0x20 as char && c != 0x7f as char ) {
366
- let painted = good. paint ( string) ;
367
-
368
- let adjusted_filename = if let EmbedHyperlinks :: On = self . options . embed_hyperlinks {
369
- ANSIString :: from ( format ! ( "\x1B ]8;;{}\x1B \x5C {}\x1B ]8;;\x1B \x5C " , self . file. path. display( ) , painted) )
370
- } else {
371
- painted
372
- } ;
373
- bits. push ( adjusted_filename) ;
374
- return ;
372
+ if display_hyperlink {
373
+ bits. push ( ANSIString :: from ( format ! ( "{HYPERLINK_START}{HYPERLINK_END}" ) ) ) ;
375
374
}
376
375
377
- // again adapted from escape::escape
378
- // still a slow route, but slightly improved to at least not reallocate buff + have a predetermined buff size
379
- //
380
- // also note that buff would never need more than len,
381
- // even tho 'in total' it will be lenghier than len (as we expand with escape_default),
382
- // because we clear it after an irregularity
383
- let mut buff = String :: with_capacity ( string. len ( ) ) ;
384
- for c in string. chars ( ) {
385
- // The `escape_default` method on `char` is *almost* what we want here, but
386
- // it still escapes non-ASCII UTF-8 characters, which are still printable.
387
-
388
- if c >= 0x20 as char && c != 0x7f as char {
389
- buff. push ( c) ;
390
- }
391
- else {
392
- if ! buff. is_empty ( ) {
393
- bits. push ( good. paint ( std:: mem:: take ( & mut buff) ) ) ;
394
- }
395
- // biased towards regular characters, so we still collect on first sight of bad char
396
- for e in c. escape_default ( ) {
397
- buff. push ( e) ;
398
- }
399
- bits. push ( bad. paint ( std:: mem:: take ( & mut buff) ) ) ;
400
- }
401
- }
376
+ bits
402
377
}
403
378
404
379
/// Figures out which colour to paint the filename part of the output,
0 commit comments