@@ -478,42 +478,57 @@ static int new_blank_line_at_eof(struct emit_callback *ecbdata, const char *line
478
478
return ws_blank_line (line , len , ecbdata -> ws_rule );
479
479
}
480
480
481
- static void emit_add_line (const char * reset ,
482
- struct emit_callback * ecbdata ,
483
- const char * line , int len )
481
+ static void emit_line_checked (const char * reset ,
482
+ struct emit_callback * ecbdata ,
483
+ const char * line , int len ,
484
+ enum color_diff color ,
485
+ unsigned ws_error_highlight ,
486
+ char sign )
484
487
{
485
- const char * ws = diff_get_color (ecbdata -> color_diff , DIFF_WHITESPACE );
486
- const char * set = diff_get_color ( ecbdata -> color_diff , DIFF_FILE_NEW ) ;
488
+ const char * set = diff_get_color (ecbdata -> color_diff , color );
489
+ const char * ws = NULL ;
487
490
488
- if (!* ws )
489
- emit_line_0 (ecbdata -> opt , set , reset , '+' , line , len );
490
- else if (new_blank_line_at_eof (ecbdata , line , len ))
491
+ if (ecbdata -> opt -> ws_error_highlight & ws_error_highlight ) {
492
+ ws = diff_get_color (ecbdata -> color_diff , DIFF_WHITESPACE );
493
+ if (!* ws )
494
+ ws = NULL ;
495
+ }
496
+
497
+ if (!ws )
498
+ emit_line_0 (ecbdata -> opt , set , reset , sign , line , len );
499
+ else if (sign == '+' && new_blank_line_at_eof (ecbdata , line , len ))
491
500
/* Blank line at EOF - paint '+' as well */
492
- emit_line_0 (ecbdata -> opt , ws , reset , '+' , line , len );
501
+ emit_line_0 (ecbdata -> opt , ws , reset , sign , line , len );
493
502
else {
494
503
/* Emit just the prefix, then the rest. */
495
- emit_line_0 (ecbdata -> opt , set , reset , '+' , "" , 0 );
504
+ emit_line_0 (ecbdata -> opt , set , reset , sign , "" , 0 );
496
505
ws_check_emit (line , len , ecbdata -> ws_rule ,
497
506
ecbdata -> opt -> file , set , reset , ws );
498
507
}
499
508
}
500
509
501
- static void emit_del_line (const char * reset ,
510
+ static void emit_add_line (const char * reset ,
502
511
struct emit_callback * ecbdata ,
503
512
const char * line , int len )
504
513
{
505
- const char * set = diff_get_color (ecbdata -> color_diff , DIFF_FILE_OLD );
514
+ emit_line_checked (reset , ecbdata , line , len ,
515
+ DIFF_FILE_NEW , WSEH_NEW , '+' );
516
+ }
506
517
507
- emit_line_0 (ecbdata -> opt , set , reset , '-' , line , len );
518
+ static void emit_del_line (const char * reset ,
519
+ struct emit_callback * ecbdata ,
520
+ const char * line , int len )
521
+ {
522
+ emit_line_checked (reset , ecbdata , line , len ,
523
+ DIFF_FILE_OLD , WSEH_OLD , '-' );
508
524
}
509
525
510
526
static void emit_context_line (const char * reset ,
511
527
struct emit_callback * ecbdata ,
512
528
const char * line , int len )
513
529
{
514
- const char * set = diff_get_color (ecbdata -> color_diff , DIFF_PLAIN );
515
-
516
- emit_line_0 (ecbdata -> opt , set , reset , ' ' , line , len );
530
+ emit_line_checked (reset , ecbdata , line , len ,
531
+ DIFF_PLAIN , WSEH_CONTEXT , ' ' );
517
532
}
518
533
519
534
static void emit_hunk_header (struct emit_callback * ecbdata ,
@@ -3250,6 +3265,7 @@ void diff_setup(struct diff_options *options)
3250
3265
options -> rename_limit = -1 ;
3251
3266
options -> dirstat_permille = diff_dirstat_permille_default ;
3252
3267
options -> context = diff_context_default ;
3268
+ options -> ws_error_highlight = WSEH_NEW ;
3253
3269
DIFF_OPT_SET (options , RENAME_EMPTY );
3254
3270
3255
3271
/* pathchange left =NULL by default */
@@ -3636,6 +3652,40 @@ static void enable_patch_output(int *fmt) {
3636
3652
* fmt |= DIFF_FORMAT_PATCH ;
3637
3653
}
3638
3654
3655
+ static int parse_one_token (const char * * arg , const char * token )
3656
+ {
3657
+ return skip_prefix (* arg , token , arg ) && (!* * arg || * * arg == ',' );
3658
+ }
3659
+
3660
+ static int parse_ws_error_highlight (struct diff_options * opt , const char * arg )
3661
+ {
3662
+ const char * orig_arg = arg ;
3663
+ unsigned val = 0 ;
3664
+ while (* arg ) {
3665
+ if (parse_one_token (& arg , "none" ))
3666
+ val = 0 ;
3667
+ else if (parse_one_token (& arg , "default" ))
3668
+ val = WSEH_NEW ;
3669
+ else if (parse_one_token (& arg , "all" ))
3670
+ val = WSEH_NEW | WSEH_OLD | WSEH_CONTEXT ;
3671
+ else if (parse_one_token (& arg , "new" ))
3672
+ val |= WSEH_NEW ;
3673
+ else if (parse_one_token (& arg , "old" ))
3674
+ val |= WSEH_OLD ;
3675
+ else if (parse_one_token (& arg , "context" ))
3676
+ val |= WSEH_CONTEXT ;
3677
+ else {
3678
+ error ("unknown value after ws-error-highlight=%.*s" ,
3679
+ (int )(arg - orig_arg ), orig_arg );
3680
+ return 0 ;
3681
+ }
3682
+ if (* arg )
3683
+ arg ++ ;
3684
+ }
3685
+ opt -> ws_error_highlight = val ;
3686
+ return 1 ;
3687
+ }
3688
+
3639
3689
int diff_opt_parse (struct diff_options * options , const char * * av , int ac )
3640
3690
{
3641
3691
const char * arg = av [0 ];
@@ -3833,6 +3883,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
3833
3883
DIFF_OPT_SET (options , SUBMODULE_LOG );
3834
3884
else if (skip_prefix (arg , "--submodule=" , & arg ))
3835
3885
return parse_submodule_opt (options , arg );
3886
+ else if (skip_prefix (arg , "--ws-error-highlight=" , & arg ))
3887
+ return parse_ws_error_highlight (options , arg );
3836
3888
3837
3889
/* misc options */
3838
3890
else if (!strcmp (arg , "-z" ))
0 commit comments