@@ -58,10 +58,14 @@ static char diff_colors[][COLOR_MAXLEN] = {
5858 GIT_COLOR_YELLOW , /* COMMIT */
5959 GIT_COLOR_BG_RED , /* WHITESPACE */
6060 GIT_COLOR_NORMAL , /* FUNCINFO */
61- GIT_COLOR_MAGENTA , /* OLD_MOVED */
62- GIT_COLOR_BLUE , /* OLD_MOVED ALTERNATIVE */
63- GIT_COLOR_CYAN , /* NEW_MOVED */
64- GIT_COLOR_YELLOW , /* NEW_MOVED ALTERNATIVE */
61+ GIT_COLOR_BOLD_MAGENTA , /* OLD_MOVED */
62+ GIT_COLOR_BOLD_BLUE , /* OLD_MOVED ALTERNATIVE */
63+ GIT_COLOR_FAINT , /* OLD_MOVED_DIM */
64+ GIT_COLOR_FAINT_ITALIC , /* OLD_MOVED_ALTERNATIVE_DIM */
65+ GIT_COLOR_BOLD_CYAN , /* NEW_MOVED */
66+ GIT_COLOR_BOLD_YELLOW , /* NEW_MOVED ALTERNATIVE */
67+ GIT_COLOR_FAINT , /* NEW_MOVED_DIM */
68+ GIT_COLOR_FAINT_ITALIC , /* NEW_MOVED_ALTERNATIVE_DIM */
6569};
6670
6771static NORETURN void die_want_option (const char * option_name )
@@ -91,10 +95,18 @@ static int parse_diff_color_slot(const char *var)
9195 return DIFF_FILE_OLD_MOVED ;
9296 if (!strcasecmp (var , "oldmovedalternative" ))
9397 return DIFF_FILE_OLD_MOVED_ALT ;
98+ if (!strcasecmp (var , "oldmoveddimmed" ))
99+ return DIFF_FILE_OLD_MOVED_DIM ;
100+ if (!strcasecmp (var , "oldmovedalternativedimmed" ))
101+ return DIFF_FILE_OLD_MOVED_ALT_DIM ;
94102 if (!strcasecmp (var , "newmoved" ))
95103 return DIFF_FILE_NEW_MOVED ;
96104 if (!strcasecmp (var , "newmovedalternative" ))
97105 return DIFF_FILE_NEW_MOVED_ALT ;
106+ if (!strcasecmp (var , "newmoveddimmed" ))
107+ return DIFF_FILE_NEW_MOVED_DIM ;
108+ if (!strcasecmp (var , "newmovedalternativedimmed" ))
109+ return DIFF_FILE_NEW_MOVED_ALT_DIM ;
98110 return -1 ;
99111}
100112
@@ -262,8 +274,10 @@ static int parse_color_moved(const char *arg)
262274 return COLOR_MOVED_ZEBRA ;
263275 else if (!strcmp (arg , "default" ))
264276 return COLOR_MOVED_DEFAULT ;
277+ else if (!strcmp (arg , "dimmed_zebra" ))
278+ return COLOR_MOVED_ZEBRA_DIM ;
265279 else
266- return error (_ ("color moved setting must be one of 'no', 'default', 'zebra', 'plain'" ));
280+ return error (_ ("color moved setting must be one of 'no', 'default', 'zebra', 'dimmed_zebra', ' plain'" ));
267281}
268282
269283int git_diff_ui_config (const char * var , const char * value , void * cb )
@@ -649,6 +663,7 @@ enum diff_symbol {
649663#define DIFF_SYMBOL_CONTENT_BLANK_LINE_EOF (1<<16)
650664#define DIFF_SYMBOL_MOVED_LINE (1<<17)
651665#define DIFF_SYMBOL_MOVED_LINE_ALT (1<<18)
666+ #define DIFF_SYMBOL_MOVED_LINE_UNINTERESTING (1<<19)
652667#define DIFF_SYMBOL_CONTENT_WS_MASK (WSEH_NEW | WSEH_OLD | WSEH_CONTEXT | WS_RULE_MASK)
653668
654669/*
@@ -933,6 +948,67 @@ static void mark_color_as_moved(struct diff_options *o,
933948 free (pmb );
934949}
935950
951+ #define DIFF_SYMBOL_MOVED_LINE_ZEBRA_MASK \
952+ (DIFF_SYMBOL_MOVED_LINE | DIFF_SYMBOL_MOVED_LINE_ALT)
953+ static void dim_moved_lines (struct diff_options * o )
954+ {
955+ int n ;
956+ for (n = 0 ; n < o -> emitted_symbols -> nr ; n ++ ) {
957+ struct emitted_diff_symbol * prev = (n != 0 ) ?
958+ & o -> emitted_symbols -> buf [n - 1 ] : NULL ;
959+ struct emitted_diff_symbol * l = & o -> emitted_symbols -> buf [n ];
960+ struct emitted_diff_symbol * next =
961+ (n < o -> emitted_symbols -> nr - 1 ) ?
962+ & o -> emitted_symbols -> buf [n + 1 ] : NULL ;
963+
964+ /* Not a plus or minus line? */
965+ if (l -> s != DIFF_SYMBOL_PLUS && l -> s != DIFF_SYMBOL_MINUS )
966+ continue ;
967+
968+ /* Not a moved line? */
969+ if (!(l -> flags & DIFF_SYMBOL_MOVED_LINE ))
970+ continue ;
971+
972+ /*
973+ * If prev or next are not a plus or minus line,
974+ * pretend they don't exist
975+ */
976+ if (prev && prev -> s != DIFF_SYMBOL_PLUS &&
977+ prev -> s != DIFF_SYMBOL_MINUS )
978+ prev = NULL ;
979+ if (next && next -> s != DIFF_SYMBOL_PLUS &&
980+ next -> s != DIFF_SYMBOL_MINUS )
981+ next = NULL ;
982+
983+ /* Inside a block? */
984+ if ((prev &&
985+ (prev -> flags & DIFF_SYMBOL_MOVED_LINE_ZEBRA_MASK ) ==
986+ (l -> flags & DIFF_SYMBOL_MOVED_LINE_ZEBRA_MASK )) &&
987+ (next &&
988+ (next -> flags & DIFF_SYMBOL_MOVED_LINE_ZEBRA_MASK ) ==
989+ (l -> flags & DIFF_SYMBOL_MOVED_LINE_ZEBRA_MASK ))) {
990+ l -> flags |= DIFF_SYMBOL_MOVED_LINE_UNINTERESTING ;
991+ continue ;
992+ }
993+
994+ /* Check if we are at an interesting bound: */
995+ if (prev && (prev -> flags & DIFF_SYMBOL_MOVED_LINE ) &&
996+ (prev -> flags & DIFF_SYMBOL_MOVED_LINE_ALT ) !=
997+ (l -> flags & DIFF_SYMBOL_MOVED_LINE_ALT ))
998+ continue ;
999+ if (next && (next -> flags & DIFF_SYMBOL_MOVED_LINE ) &&
1000+ (next -> flags & DIFF_SYMBOL_MOVED_LINE_ALT ) !=
1001+ (l -> flags & DIFF_SYMBOL_MOVED_LINE_ALT ))
1002+ continue ;
1003+
1004+ /*
1005+ * The boundary to prev and next are not interesting,
1006+ * so this line is not interesting as a whole
1007+ */
1008+ l -> flags |= DIFF_SYMBOL_MOVED_LINE_UNINTERESTING ;
1009+ }
1010+ }
1011+
9361012static void emit_line_ws_markup (struct diff_options * o ,
9371013 const char * set , const char * reset ,
9381014 const char * line , int len , char sign ,
@@ -1007,24 +1083,56 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
10071083 flags & (DIFF_SYMBOL_CONTENT_WS_MASK ), 0 );
10081084 break ;
10091085 case DIFF_SYMBOL_PLUS :
1010- if (flags & DIFF_SYMBOL_MOVED_LINE_ALT )
1086+ switch (flags & (DIFF_SYMBOL_MOVED_LINE |
1087+ DIFF_SYMBOL_MOVED_LINE_ALT |
1088+ DIFF_SYMBOL_MOVED_LINE_UNINTERESTING )) {
1089+ case DIFF_SYMBOL_MOVED_LINE |
1090+ DIFF_SYMBOL_MOVED_LINE_ALT |
1091+ DIFF_SYMBOL_MOVED_LINE_UNINTERESTING :
1092+ set = diff_get_color_opt (o , DIFF_FILE_NEW_MOVED_ALT_DIM );
1093+ break ;
1094+ case DIFF_SYMBOL_MOVED_LINE |
1095+ DIFF_SYMBOL_MOVED_LINE_ALT :
10111096 set = diff_get_color_opt (o , DIFF_FILE_NEW_MOVED_ALT );
1012- else if (flags & DIFF_SYMBOL_MOVED_LINE )
1097+ break ;
1098+ case DIFF_SYMBOL_MOVED_LINE |
1099+ DIFF_SYMBOL_MOVED_LINE_UNINTERESTING :
1100+ set = diff_get_color_opt (o , DIFF_FILE_NEW_MOVED_DIM );
1101+ break ;
1102+ case DIFF_SYMBOL_MOVED_LINE :
10131103 set = diff_get_color_opt (o , DIFF_FILE_NEW_MOVED );
1014- else
1104+ break ;
1105+ default :
10151106 set = diff_get_color_opt (o , DIFF_FILE_NEW );
1107+ }
10161108 reset = diff_get_color_opt (o , DIFF_RESET );
10171109 emit_line_ws_markup (o , set , reset , line , len , '+' ,
10181110 flags & DIFF_SYMBOL_CONTENT_WS_MASK ,
10191111 flags & DIFF_SYMBOL_CONTENT_BLANK_LINE_EOF );
10201112 break ;
10211113 case DIFF_SYMBOL_MINUS :
1022- if (flags & DIFF_SYMBOL_MOVED_LINE_ALT )
1114+ switch (flags & (DIFF_SYMBOL_MOVED_LINE |
1115+ DIFF_SYMBOL_MOVED_LINE_ALT |
1116+ DIFF_SYMBOL_MOVED_LINE_UNINTERESTING )) {
1117+ case DIFF_SYMBOL_MOVED_LINE |
1118+ DIFF_SYMBOL_MOVED_LINE_ALT |
1119+ DIFF_SYMBOL_MOVED_LINE_UNINTERESTING :
1120+ set = diff_get_color_opt (o , DIFF_FILE_OLD_MOVED_ALT_DIM );
1121+ break ;
1122+ case DIFF_SYMBOL_MOVED_LINE |
1123+ DIFF_SYMBOL_MOVED_LINE_ALT :
10231124 set = diff_get_color_opt (o , DIFF_FILE_OLD_MOVED_ALT );
1024- else if (flags & DIFF_SYMBOL_MOVED_LINE )
1125+ break ;
1126+ case DIFF_SYMBOL_MOVED_LINE |
1127+ DIFF_SYMBOL_MOVED_LINE_UNINTERESTING :
1128+ set = diff_get_color_opt (o , DIFF_FILE_OLD_MOVED_DIM );
1129+ break ;
1130+ case DIFF_SYMBOL_MOVED_LINE :
10251131 set = diff_get_color_opt (o , DIFF_FILE_OLD_MOVED );
1026- else
1132+ break ;
1133+ default :
10271134 set = diff_get_color_opt (o , DIFF_FILE_OLD );
1135+ }
10281136 reset = diff_get_color_opt (o , DIFF_RESET );
10291137 emit_line_ws_markup (o , set , reset , line , len , '-' ,
10301138 flags & DIFF_SYMBOL_CONTENT_WS_MASK , 0 );
@@ -5420,6 +5528,8 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
54205528
54215529 add_lines_to_move_detection (o , & add_lines , & del_lines );
54225530 mark_color_as_moved (o , & add_lines , & del_lines );
5531+ if (o -> color_moved == COLOR_MOVED_ZEBRA_DIM )
5532+ dim_moved_lines (o );
54235533
54245534 hashmap_free (& add_lines , 0 );
54255535 hashmap_free (& del_lines , 0 );
0 commit comments