Merge branch 'jk/diff-highlight-module' into maint
The 'diff-highlight' program (in contrib/) has been restructured for easier reuse by an external project 'diff-so-fancy'. * jk/diff-highlight-module: diff-highlight: split code into module
This commit is contained in:
		
							
								
								
									
										2
									
								
								contrib/diff-highlight/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								contrib/diff-highlight/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | |||||||
|  | shebang.perl | ||||||
|  | diff-highlight | ||||||
							
								
								
									
										40
									
								
								contrib/diff-highlight/diff-highlight → contrib/diff-highlight/DiffHighlight.pm
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										40
									
								
								contrib/diff-highlight/diff-highlight → contrib/diff-highlight/DiffHighlight.pm
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @ -1,4 +1,4 @@ | |||||||
| #!/usr/bin/perl | package DiffHighlight; | ||||||
| 
 | 
 | ||||||
| use 5.008; | use 5.008; | ||||||
| use warnings FATAL => 'all'; | use warnings FATAL => 'all'; | ||||||
| @ -29,13 +29,14 @@ my @removed; | |||||||
| my @added; | my @added; | ||||||
| my $in_hunk; | my $in_hunk; | ||||||
| 
 | 
 | ||||||
| # Some scripts may not realize that SIGPIPE is being ignored when launching the | our $line_cb = sub { print @_ }; | ||||||
| # pager--for instance scripts written in Python. | our $flush_cb = sub { local $| = 1 }; | ||||||
| $SIG{PIPE} = 'DEFAULT'; | 
 | ||||||
|  | sub handle_line { | ||||||
|  | 	local $_ = shift; | ||||||
| 
 | 
 | ||||||
| while (<>) { |  | ||||||
| 	if (!$in_hunk) { | 	if (!$in_hunk) { | ||||||
| 		print; | 		$line_cb->($_); | ||||||
| 		$in_hunk = /^$GRAPH*$COLOR*\@\@ /; | 		$in_hunk = /^$GRAPH*$COLOR*\@\@ /; | ||||||
| 	} | 	} | ||||||
| 	elsif (/^$GRAPH*$COLOR*-/) { | 	elsif (/^$GRAPH*$COLOR*-/) { | ||||||
| @ -49,7 +50,7 @@ while (<>) { | |||||||
| 		@removed = (); | 		@removed = (); | ||||||
| 		@added = (); | 		@added = (); | ||||||
| 
 | 
 | ||||||
| 		print; | 		$line_cb->($_); | ||||||
| 		$in_hunk = /^$GRAPH*$COLOR*[\@ ]/; | 		$in_hunk = /^$GRAPH*$COLOR*[\@ ]/; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -62,15 +63,22 @@ while (<>) { | |||||||
| 	# place to flush. Flushing on a blank line is a heuristic that | 	# place to flush. Flushing on a blank line is a heuristic that | ||||||
| 	# happens to match git-log output. | 	# happens to match git-log output. | ||||||
| 	if (!length) { | 	if (!length) { | ||||||
| 		local $| = 1; | 		$flush_cb->(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # Flush any queued hunk (this can happen when there is no trailing context in | sub flush { | ||||||
| # the final diff of the input). | 	# Flush any queued hunk (this can happen when there is no trailing | ||||||
| show_hunk(\@removed, \@added); | 	# context in the final diff of the input). | ||||||
|  | 	show_hunk(\@removed, \@added); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| exit 0; | sub highlight_stdin { | ||||||
|  | 	while (<STDIN>) { | ||||||
|  | 		handle_line($_); | ||||||
|  | 	} | ||||||
|  | 	flush(); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| # Ideally we would feed the default as a human-readable color to | # Ideally we would feed the default as a human-readable color to | ||||||
| # git-config as the fallback value. But diff-highlight does | # git-config as the fallback value. But diff-highlight does | ||||||
| @ -88,7 +96,7 @@ sub show_hunk { | |||||||
| 
 | 
 | ||||||
| 	# If one side is empty, then there is nothing to compare or highlight. | 	# If one side is empty, then there is nothing to compare or highlight. | ||||||
| 	if (!@$a || !@$b) { | 	if (!@$a || !@$b) { | ||||||
| 		print @$a, @$b; | 		$line_cb->(@$a, @$b); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -97,17 +105,17 @@ sub show_hunk { | |||||||
| 	# stupid, and only handle multi-line hunks that remove and add the same | 	# stupid, and only handle multi-line hunks that remove and add the same | ||||||
| 	# number of lines. | 	# number of lines. | ||||||
| 	if (@$a != @$b) { | 	if (@$a != @$b) { | ||||||
| 		print @$a, @$b; | 		$line_cb->(@$a, @$b); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	my @queue; | 	my @queue; | ||||||
| 	for (my $i = 0; $i < @$a; $i++) { | 	for (my $i = 0; $i < @$a; $i++) { | ||||||
| 		my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]); | 		my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]); | ||||||
| 		print $rm; | 		$line_cb->($rm); | ||||||
| 		push @queue, $add; | 		push @queue, $add; | ||||||
| 	} | 	} | ||||||
| 	print @queue; | 	$line_cb->(@queue); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| sub highlight_pair { | sub highlight_pair { | ||||||
| @ -1,5 +1,20 @@ | |||||||
| # nothing to build | all: diff-highlight | ||||||
| all: |  | ||||||
|  |  | ||||||
| test: | PERL_PATH = /usr/bin/perl | ||||||
|  | -include ../../config.mak | ||||||
|  |  | ||||||
|  | PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) | ||||||
|  |  | ||||||
|  | diff-highlight: shebang.perl DiffHighlight.pm diff-highlight.perl | ||||||
|  | 	cat $^ >$@+ | ||||||
|  | 	chmod +x $@+ | ||||||
|  | 	mv $@+ $@ | ||||||
|  |  | ||||||
|  | shebang.perl: FORCE | ||||||
|  | 	@echo '#!$(PERL_PATH_SQ)' >$@+ | ||||||
|  | 	@cmp $@+ $@ >/dev/null 2>/dev/null || mv $@+ $@ | ||||||
|  |  | ||||||
|  | test: all | ||||||
| 	$(MAKE) -C t | 	$(MAKE) -C t | ||||||
|  |  | ||||||
|  | .PHONY: FORCE | ||||||
|  | |||||||
| @ -99,6 +99,36 @@ newHighlight = "black #aaffaa" | |||||||
| --------------------------------------------- | --------------------------------------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Using diff-highlight as a module | ||||||
|  | -------------------------------- | ||||||
|  |  | ||||||
|  | If you want to pre- or post- process the highlighted lines as part of | ||||||
|  | another perl script, you can use the DiffHighlight module. You can | ||||||
|  | either "require" it or just cat the module together with your script (to | ||||||
|  | avoid run-time dependencies). | ||||||
|  |  | ||||||
|  | Your script may set up one or more of the following variables: | ||||||
|  |  | ||||||
|  |   - $DiffHighlight::line_cb - this should point to a function which is | ||||||
|  |     called whenever DiffHighlight has lines (which may contain | ||||||
|  |     highlights) to output. The default function prints each line to | ||||||
|  |     stdout. Note that the function may be called with multiple lines. | ||||||
|  |  | ||||||
|  |   - $DiffHighlight::flush_cb - this should point to a function which | ||||||
|  |     flushes the output (because DiffHighlight believes it has completed | ||||||
|  |     processing a logical chunk of input). The default function flushes | ||||||
|  |     stdout. | ||||||
|  |  | ||||||
|  | The script may then feed lines, one at a time, to DiffHighlight::handle_line(). | ||||||
|  | When lines are done processing, they will be fed to $line_cb. Note that | ||||||
|  | DiffHighlight may queue up many input lines (to analyze a whole hunk) | ||||||
|  | before calling $line_cb. After providing all lines, call | ||||||
|  | DiffHighlight::flush() to flush any unprocessed lines. | ||||||
|  |  | ||||||
|  | If you just want to process stdin, DiffHighlight::highlight_stdin() | ||||||
|  | is a convenience helper which will loop and flush for you. | ||||||
|  |  | ||||||
|  |  | ||||||
| Bugs | Bugs | ||||||
| ---- | ---- | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								contrib/diff-highlight/diff-highlight.perl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								contrib/diff-highlight/diff-highlight.perl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | package main; | ||||||
|  |  | ||||||
|  | # Some scripts may not realize that SIGPIPE is being ignored when launching the | ||||||
|  | # pager--for instance scripts written in Python. | ||||||
|  | $SIG{PIPE} = 'DEFAULT'; | ||||||
|  |  | ||||||
|  | DiffHighlight::highlight_stdin(); | ||||||
|  | exit 0; | ||||||
		Reference in New Issue
	
	Block a user
	 Junio C Hamano
					Junio C Hamano