Browse Source

Add terminal size fit for side by side view

Fabien Meghazi 10 years ago
parent
commit
6befc2a7bf
1 changed files with 33 additions and 1 deletions
  1. 33
    1
      cdiff.py

+ 33
- 1
cdiff.py View File

@@ -503,6 +503,7 @@ class DiffMarker(object):
503 503
         except IndexError:
504 504
             max1 = max2 = 0
505 505
         num_width = max(len(str(max1)), len(str(max2)))
506
+        width -= num_width
506 507
 
507 508
         # Setup lineno and line format
508 509
         left_num_fmt = colorize('%%(left_num)%ds' % num_width, 'yellow')
@@ -664,6 +665,27 @@ def decode(line):
664 665
 
665 666
     return '*** cdiff: undecodable bytes ***\n'
666 667
 
668
+def terminal_size():
669
+    """
670
+    Returns terminal size.
671
+
672
+    Taken from this gist:
673
+    https://gist.github.com/marsam/7268750
674
+    """
675
+    width, height = None, None
676
+    if sys.platform == 'win32':
677
+        import win32utils
678
+        width, height = win32utils.get_console_size(defaultx=width, defaulty=height)
679
+    else:
680
+        try:
681
+            import struct, fcntl, termios
682
+            s = struct.pack('HHHH', 0, 0, 0, 0)
683
+            x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
684
+            height, width = struct.unpack('HHHH', x)[0:2]
685
+        except (IOError, AttributeError):
686
+            pass
687
+    return width, height
688
+
667 689
 
668 690
 def main():
669 691
     signal.signal(signal.SIGPIPE, signal.SIG_DFL)
@@ -701,7 +723,8 @@ def main():
701 723
         help='enable side-by-side mode')
702 724
     parser.add_option(
703 725
         '-w', '--width', type='int', default=80, metavar='N',
704
-        help='set text width for side-by-side mode, default is 80')
726
+        help='set text width for side-by-side mode. If set to "0", cdiff ' \
727
+             'will attempt to fit the terminal width.')
705 728
     parser.add_option(
706 729
         '-l', '--log', action='store_true',
707 730
         help='show log with changes from revision control')
@@ -717,6 +740,15 @@ def main():
717 740
 
718 741
     opts, args = parser.parse_args()
719 742
 
743
+    if opts.width == 0 and opts.side_by_side:
744
+        # Autodetection of text width according to terminal size
745
+        try:
746
+            # width = half the terminal size minus the 3 minimum padding chars
747
+            opts.width = (terminal_size()[0] - 3) / 2
748
+        except Exception:
749
+            # If terminal detection failed, set back to default
750
+            opts.width = 80
751
+
720 752
     if opts.log:
721 753
         diff_hdl = revision_control_log(args)
722 754
         if not diff_hdl: