diff --git a/core/commands/inline_diff.py b/core/commands/inline_diff.py index bec1abf4c..d664dc1ed 100644 --- a/core/commands/inline_diff.py +++ b/core/commands/inline_diff.py @@ -26,6 +26,41 @@ diff_view_hunks = {} +def capture_cur_position(view): + try: + sel = view.sel()[0] + except Exception: + return None + + return view.rowcol(sel.begin()) + + +def place_cursor_and_show(view, row, col): + view.sel().clear() + pt = view.text_point(row, col) + view.sel().add(sublime.Region(pt, pt)) + view.show_at_center(pt) + # The following shouldn't strictly be necessary, but Sublime sometimes jumps + # to the right when show_at_center for a column-zero-point occurs. + _, vp_y = view.viewport_position() + view.set_viewport_position((0, vp_y), False) + + +def translate_row_to_inline_diff(diff_view, row): + hunks = diff_view_hunks[diff_view.id()] + deleted_lines_before_row = 0 + + for hunk_ref in hunks: + if hunk_ref.section_start > row + deleted_lines_before_row: + break + + for type in hunk_ref.line_types: + if type == "-": + deleted_lines_before_row += 1 + + return row + deleted_lines_before_row + + class GsInlineDiffCommand(WindowCommand, GitCommand): """ @@ -34,12 +69,10 @@ class GsInlineDiffCommand(WindowCommand, GitCommand): hunks or individual lines, and to navigate between hunks. """ - def run(self, **kwargs): - sublime.set_timeout_async(lambda: self.run_async(**kwargs), 0) - - def run_async(self, settings=None, cached=False): + def run(self, settings=None, cached=False, match_current_position=False): + file_view = self.window.active_view() + cur_pos = capture_cur_position(file_view) if match_current_position else None if settings is None: - file_view = self.window.active_view() syntax_file = file_view.settings().get("syntax") settings = { "git_savvy.file_path": self.file_path, @@ -82,7 +115,7 @@ def run_async(self, settings=None, cached=False): self.window.focus_view(diff_view) - diff_view.run_command("gs_inline_diff_refresh") + diff_view.run_command("gs_inline_diff_refresh", {"match_position": cur_pos}) diff_view.run_command("gs_handle_vintageous") def augment_color_scheme(self, target_view, file_ext): @@ -144,7 +177,7 @@ class GsInlineDiffRefreshCommand(TextCommand, GitCommand): are not supported in `cached` mode. """ - def run(self, edit): + def run(self, edit, match_position=None): file_path = self.file_path in_cached_mode = self.view.settings().get("git_savvy.inline_diff_view.in_cached_mode") ignore_eol_arg = ( @@ -176,25 +209,22 @@ def run(self, edit): inline_diff_contents, replaced_lines = \ self.get_inline_diff_contents(indexed_object_contents, diff) - cursors = self.view.sel() - if cursors: - row, col = self.view.rowcol(cursors[0].begin()) + if match_position is None: + cur_pos = capture_cur_position(self.view) self.view.set_read_only(False) self.view.replace(edit, sublime.Region(0, self.view.size()), inline_diff_contents) - if cursors: - if (row, col) == (0, 0) and self.savvy_settings.get("inline_diff_auto_scroll", False): + if match_position is None: + if cur_pos == (0, 0) and self.savvy_settings.get("inline_diff_auto_scroll", False): self.view.run_command("gs_inline_diff_navigate_hunk") - else: - self.view.sel().clear() - pt = self.view.text_point(row, 0) - self.view.sel().add(sublime.Region(pt, pt)) - self.view.show_at_center(pt) - # The following shouldn't strictly be necessary, but Sublime sometimes jumps - # to the right when show_at_center for a column-zero-point occurs. - _, vp_y = self.view.viewport_position() - self.view.set_viewport_position((0, vp_y), False) + elif cur_pos: + row, _ = cur_pos + place_cursor_and_show(self.view, row, 0) + else: + row, col = match_position + new_row = translate_row_to_inline_diff(self.view, row) + place_cursor_and_show(self.view, new_row, col) self.highlight_regions(replaced_lines) self.view.set_read_only(True)