diff kitten: Show overall diff stats

This commit is contained in:
Kovid Goyal 2018-05-18 14:19:25 +05:30
parent f8b6b532e0
commit 6020aadbf2
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 26 additions and 1 deletions

View File

@ -29,6 +29,7 @@ class Collection:
self.removes = set() self.removes = set()
self.all_paths = [] self.all_paths = []
self.type_map = {} self.type_map = {}
self.added_count = self.removed_count = 0
def add_change(self, left_path, right_path): def add_change(self, left_path, right_path):
self.changes[left_path] = right_path self.changes[left_path] = right_path
@ -44,11 +45,15 @@ class Collection:
self.adds.add(right_path) self.adds.add(right_path)
self.all_paths.append(right_path) self.all_paths.append(right_path)
self.type_map[right_path] = 'add' self.type_map[right_path] = 'add'
if isinstance(data_for_path(right_path), str):
self.added_count += len(lines_for_path(right_path))
def add_removal(self, left_path): def add_removal(self, left_path):
self.removes.add(left_path) self.removes.add(left_path)
self.all_paths.append(left_path) self.all_paths.append(left_path)
self.type_map[left_path] = 'removal' self.type_map[left_path] = 'removal'
if isinstance(data_for_path(left_path), str):
self.removed_count += len(lines_for_path(left_path))
def finalize(self): def finalize(self):
self.all_paths.sort(key=path_name_map.get) self.all_paths.sort(key=path_name_map.get)

View File

@ -68,6 +68,13 @@ class DiffHandler(Handler):
def generate_diff(self): def generate_diff(self):
self.start_job('diff', generate_diff, self.collection, self.current_context_count) self.start_job('diff', generate_diff, self.collection, self.current_context_count)
def calculate_statistics(self):
self.added_count = self.collection.added_count
self.removed_count = self.collection.removed_count
for patch in self.diff_map.values():
self.added_count += patch.added_count
self.removed_count += patch.removed_count
def render_diff(self): def render_diff(self):
self.diff_lines = tuple(render_diff(self.collection, self.diff_map, self.args, self.screen_size.cols, self.image_manager)) self.diff_lines = tuple(render_diff(self.collection, self.diff_map, self.args, self.screen_size.cols, self.image_manager))
self.ref_path_map = defaultdict(list) self.ref_path_map = defaultdict(list)
@ -223,10 +230,17 @@ class DiffHandler(Handler):
self.draw_status_line() self.draw_status_line()
def draw_status_line(self): def draw_status_line(self):
if self.state < DIFFED:
return
self.cmd.set_cursor_position(0, self.num_lines) self.cmd.set_cursor_position(0, self.num_lines)
self.cmd.clear_to_eol() self.cmd.clear_to_eol()
scroll_frac = styled('{:.0%}'.format(self.scroll_pos / self.max_scroll_pos), fg=self.opts.margin_fg) scroll_frac = styled('{:.0%}'.format(self.scroll_pos / self.max_scroll_pos), fg=self.opts.margin_fg)
suffix = scroll_frac counts = '{}{}{}'.format(
styled(str(self.added_count), fg=self.opts.highlight_added_bg),
styled(',', fg=self.opts.margin_fg),
styled(str(self.removed_count), fg=self.opts.highlight_removed_bg)
)
suffix = counts + ' ' + scroll_frac
prefix = styled(':', fg=self.opts.margin_fg) prefix = styled(':', fg=self.opts.margin_fg)
filler = self.screen_size.cols - wcswidth(prefix) - wcswidth(suffix) filler = self.screen_size.cols - wcswidth(prefix) - wcswidth(suffix)
text = '{}{}{}'.format(prefix, ' ' * filler, suffix) text = '{}{}{}'.format(prefix, ' ' * filler, suffix)
@ -308,6 +322,7 @@ class DiffHandler(Handler):
return return
self.state = DIFFED self.state = DIFFED
self.diff_map = diff_map self.diff_map = diff_map
self.calculate_statistics()
self.render_diff() self.render_diff()
self.scroll_pos = 0 self.scroll_pos = 0
if self.restore_position is not None: if self.restore_position is not None:

View File

@ -84,6 +84,7 @@ class Hunk:
self.left_start -= 1 # 0-index self.left_start -= 1 # 0-index
self.right_start -= 1 # 0-index self.right_start -= 1 # 0-index
self.title = title self.title = title
self.added_count = self.removed_count = 0
self.chunks = [] self.chunks = []
self.current_chunk = None self.current_chunk = None
self.largest_line_number = max(self.left_start + self.left_count, self.right_start + self.right_count) self.largest_line_number = max(self.left_start + self.left_count, self.right_start + self.right_count)
@ -115,10 +116,12 @@ class Hunk:
def add_line(self): def add_line(self):
self.ensure_diff_chunk() self.ensure_diff_chunk()
self.current_chunk.add_line() self.current_chunk.add_line()
self.added_count += 1
def remove_line(self): def remove_line(self):
self.ensure_diff_chunk() self.ensure_diff_chunk()
self.current_chunk.remove_line() self.current_chunk.remove_line()
self.removed_count += 1
def context_line(self): def context_line(self):
self.ensure_context_chunk() self.ensure_context_chunk()
@ -159,6 +162,8 @@ class Patch:
def __init__(self, all_hunks): def __init__(self, all_hunks):
self.all_hunks = all_hunks self.all_hunks = all_hunks
self.largest_line_number = self.all_hunks[-1].largest_line_number if self.all_hunks else 0 self.largest_line_number = self.all_hunks[-1].largest_line_number if self.all_hunks else 0
self.added_count = sum(h.added_count for h in all_hunks)
self.removed_count = sum(h.removed_count for h in all_hunks)
def __iter__(self): def __iter__(self):
return iter(self.all_hunks) return iter(self.all_hunks)