Colorized 'svn diff' filter for terminals

3 points by makecheck ↗ HN
Here's a quick script I wrote to add a bit of styling to 'svn diff' output so that it's easier to see where the changes are. Of course the basic code can be tweaked to match output from other programs that you care about.

- Unchanged text becomes italicized (in some terminals).

- Added text is black on a green background, removed text is red on a dark red background.

- Large begin/end markers are there to help when scrolling back; colorization won't work if you pipe to a pager like "less".

To use it, pipe the 'svn diff' output into the script, e.g. "svn diff [whatever] | /path/to/this/script".

Script:

  #!/usr/bin/env perl
  # by Kevin Grant (kmg@mac.com)
  print "\033#3BEGIN DIFF\n";
  print "\033#4BEGIN DIFF\n\033#5";
  while (<>) {
    if (/^\+/ && !/^\+\+/) {
      print "\033[48;5;149m", "\033[2K", "\033[38;5;235m", "\033[1m";
    } elsif (/^\-/ && !/^\-\-/) {
      print "\033[48;5;52m", "\033[2K", "\033[38;5;124m";
    } else {
      print "\033[3m";
    }
    chomp;
    print;
    print "\033[0m\n";
  }
  print "\033#3END DIFF\n";
  print "\033#4END DIFF\n\033#5";

2 comments

[ 7.0 ms ] story [ 725 ms ] thread
Hah.. In the OSX console all the diff lines (+ or -) blink!
The notation "38;5;[whatever]" or "48;5;[whatever]" is specific to an 88-color or 256-color xterm terminal. Make sure that mode is enabled. This works with the Mac OS X 10.7 (Lion) version of Terminal and with MacTerm in 256-color mode.

By itself, a "5m" means "blink", so maybe older Terminal versions are just dropping the parts that they don't understand.

Here's a modified version that tries to adapt when xterm colors don't work:

  #!/usr/bin/env perl
  # by Kevin Grant (kmg@mac.com)
  my $term = (exists $ENV{'TERM'} && defined $ENV{'TERM'}) ? $ENV{'TERM'} : 'vt100';
  my $is_xterm = ($term =~ /xterm/);
  print "\033#3BEGIN DIFF\n";
  print "\033#4BEGIN DIFF\n\033#5";
  while (<>) {
    if (/^\+/ && !/^\+\+/) {
      if ($is_xterm) {
        print "\033[48;5;149m", "\033[2K", "\033[38;5;235m", "\033[1m";
      } else {
        print "\033[42m", "\033[2K", "\033[30m", "\033[1m";
      }
    } elsif (/^\-/ && !/^\-\-/) {
      if ($is_xterm) {
        print "\033[48;5;52m", "\033[2K", "\033[38;5;124m";
      } else {
        print "\033[41m", "\033[2K", "\033[37m";
      }
    } else {
      print "\033[3m";
    }
    chomp;
    print;
    print "\033[0m\n";
  }
  print "\033#3END DIFF\n";
  print "\033#4END DIFF\n\033#5";
The colors aren't quite as nice that way, but it's something.