From a65c807a4aead1aed199ae160714bdc4a506d27d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 9 May 2018 08:12:40 +0530 Subject: [PATCH] diff: Add keyboard shortcuts to got to next/previous change --- kittens/diff/main.py | 15 +++++++++++++++ kittens/diff/render.py | 16 +++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/kittens/diff/main.py b/kittens/diff/main.py index 11f285dcf..75bc7547c 100644 --- a/kittens/diff/main.py +++ b/kittens/diff/main.py @@ -97,6 +97,18 @@ class DiffHandler(Handler): def num_lines(self): return self.screen_size.rows - 1 + def scroll_to_next_change(self, backwards=False): + if backwards: + r = range(self.scroll_pos - 1, -1, -1) + else: + r = range(self.scroll_pos + 1, len(self.diff_lines)) + for i in r: + line = self.diff_lines[i] + if line.is_change_start: + self.scroll_lines(i - self.scroll_pos) + return + self.cmd.bell() + def set_scrolling_region(self): self.cmd.set_scrolling_region(self.screen_size, 0, self.num_lines - 2) @@ -191,6 +203,9 @@ class DiffHandler(Handler): else: new_ctx += (-1 if text == '-' else 1) * 5 self.change_context_count(new_ctx) + if text in 'np': + self.scroll_to_next_change(backwards=text == 'p') + return def on_key(self, key_event): if key_event.type is RELEASE: diff --git a/kittens/diff/render.py b/kittens/diff/render.py index bd0747fd0..f38e89eb1 100644 --- a/kittens/diff/render.py +++ b/kittens/diff/render.py @@ -45,16 +45,18 @@ class Reference(Ref): class Line: - __slots__ = ('text', 'ref') + __slots__ = ('text', 'ref', 'is_change_start') - def __init__(self, text, ref): + def __init__(self, text, ref, change_start=False): self.text = text self.ref = ref + self.is_change_start = change_start -def yield_lines_from(iterator, reference): +def yield_lines_from(iterator, reference, is_change_start=True): for text in iterator: - yield Line(text, reference) + yield Line(text, reference, is_change_start) + is_change_start = False def human_readable(size, sep=' '): @@ -305,7 +307,7 @@ def lines_for_chunk(data, hunk_num, chunk, chunk_num): x.extend(repeat(data.filler_line, count)) for wli, (left_line, right_line) in enumerate(zip(ll, rl)): ref = Reference(ref_path, LineRef(ref_ln, wli)) - yield Line(left_line + right_line, ref) + yield Line(left_line + right_line, ref, i == 0 and wli == 0) def lines_for_diff(left_path, right_path, hunks, args, columns, margin_size): @@ -340,7 +342,7 @@ def all_lines(path, args, columns, margin_size, is_add=True): '', _('This file was added') if is_add else _('This file was removed'), 'filler', margin_size, available_cols) text = (empty + hl) if is_add else (hl + empty) - yield Line(text, ref) + yield Line(text, ref, line_number == 0 and i == 0) def rename_lines(path, other_path, args, columns, margin_size): @@ -363,7 +365,7 @@ def render_diff(collection, diff_map, args, columns): for path, item_type, other_path in collection: item_ref = Reference(path) is_binary = isinstance(data_for_path(path), bytes) - yield from yield_lines_from(title_lines(path, other_path, args, columns, margin_size), item_ref) + yield from yield_lines_from(title_lines(path, other_path, args, columns, margin_size), item_ref, False) if item_type == 'diff': if is_binary: ans = yield_lines_from(binary_lines(path, other_path, columns, margin_size), item_ref)