"[" and "]" cycle over changes (hunks)
This commit is contained in:
@@ -21,7 +21,7 @@ Keys inside the review view:
|
|||||||
| `s` / `u` / `d` | stage / unstage / discard the file (uncommitted mode) |
|
| `s` / `u` / `d` | stage / unstage / discard the file (uncommitted mode) |
|
||||||
| `C` or `m` | commit the staged files, typing the message in an input panel |
|
| `C` or `m` | commit the staged files, typing the message in an input panel |
|
||||||
| `o` or Enter | open the real file at this line |
|
| `o` or Enter | open the real file at this line |
|
||||||
| `]` / `[` | next / previous change |
|
| `]` / `[` | next / previous change (wraps at the ends) |
|
||||||
| `n` / `p` | next / previous file of the current list (wraps at the ends) |
|
| `n` / `p` | next / previous file of the current list (wraps at the ends) |
|
||||||
| `j` / `k` | move down / up one line (vim keys) |
|
| `j` / `k` | move down / up one line (vim keys) |
|
||||||
| `r` | refresh |
|
| `r` | refresh |
|
||||||
|
|||||||
@@ -403,3 +403,51 @@ def test_first_step_without_a_shown_file_picks_an_end(loading, rings):
|
|||||||
assert requested_path(queue) == "f4.py"
|
assert requested_path(queue) == "f4.py"
|
||||||
# neither is a wrap: there was no position to run past
|
# neither is a wrap: there was no position to run past
|
||||||
assert rings == []
|
assert rings == []
|
||||||
|
|
||||||
|
|
||||||
|
def at_change(blocks, row):
|
||||||
|
"""A rendered view with `blocks` as its changes and the caret on `row`"""
|
||||||
|
view = sublime.View()
|
||||||
|
st = state.ViewState("/repo")
|
||||||
|
st.blocks = blocks
|
||||||
|
view.text = "\n" + "\n".join("l{}".format(i) for i in range(20))
|
||||||
|
view.sel().add(sublime.Region(commands.render.index_point(view, row)))
|
||||||
|
return view, st
|
||||||
|
|
||||||
|
|
||||||
|
def test_next_change_wraps_past_the_last(rings):
|
||||||
|
view, st = at_change([(2, 4), (7, 8)], 7)
|
||||||
|
|
||||||
|
commands.ACTIONS["next_change"](view, None, st)
|
||||||
|
assert commands.render.caret_index(view) == 2 and len(rings) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_prev_change_wraps_before_the_first(rings):
|
||||||
|
view, st = at_change([(2, 4), (7, 8)], 2)
|
||||||
|
|
||||||
|
commands.ACTIONS["prev_change"](view, None, st)
|
||||||
|
assert commands.render.caret_index(view) == 7 and len(rings) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_stepping_inside_the_changes_does_not_ring(rings):
|
||||||
|
view, st = at_change([(2, 4), (7, 8), (12, 13)], 7)
|
||||||
|
|
||||||
|
commands.ACTIONS["next_change"](view, None, st)
|
||||||
|
commands.ACTIONS["prev_change"](view, None, st)
|
||||||
|
assert commands.render.caret_index(view) == 7 and rings == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_single_change_rings_and_stays_put(rings):
|
||||||
|
view, st = at_change([(2, 4)], 2)
|
||||||
|
|
||||||
|
commands.ACTIONS["next_change"](view, None, st)
|
||||||
|
commands.ACTIONS["prev_change"](view, None, st)
|
||||||
|
assert commands.render.caret_index(view) == 2 and len(rings) == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_file_without_changes_neither_moves_nor_rings(rings):
|
||||||
|
view, st = at_change([], 3)
|
||||||
|
|
||||||
|
commands.ACTIONS["next_change"](view, None, st)
|
||||||
|
commands.ACTIONS["prev_change"](view, None, st)
|
||||||
|
assert commands.render.caret_index(view) == 3 and rings == []
|
||||||
|
|||||||
@@ -380,11 +380,15 @@ def _step_file(delta):
|
|||||||
def _step_change(delta):
|
def _step_change(delta):
|
||||||
def act(view, window, st):
|
def act(view, window, st):
|
||||||
starts = [start for start, _ in st.blocks]
|
starts = [start for start, _ in st.blocks]
|
||||||
|
if not starts:
|
||||||
|
status("no changes")
|
||||||
|
return
|
||||||
row = render.caret_index(view)
|
row = render.caret_index(view)
|
||||||
position = bisect.bisect_right(starts, row) if delta > 0 else bisect.bisect_left(starts, row) - 1
|
position = bisect.bisect_right(starts, row) if delta > 0 else bisect.bisect_left(starts, row) - 1
|
||||||
if not 0 <= position < len(starts):
|
wrapped = not 0 <= position < len(starts)
|
||||||
status("no more changes")
|
position %= len(starts) # -1 is the last change, len(starts) the first
|
||||||
return
|
if wrapped:
|
||||||
|
render.flash(view)
|
||||||
point = render.index_point(view, starts[position])
|
point = render.index_point(view, starts[position])
|
||||||
view.sel().clear()
|
view.sel().clear()
|
||||||
view.sel().add(sublime.Region(point))
|
view.sel().add(sublime.Region(point))
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ Key = namedtuple("Key", "keys label short actions")
|
|||||||
|
|
||||||
KEY_GROUPS = [
|
KEY_GROUPS = [
|
||||||
("Navigate", True, [
|
("Navigate", True, [
|
||||||
Key("] [", "next / previous change", "change", ("next_change", "prev_change")),
|
Key("] [", "next / previous change (wraps)", "change", ("next_change", "prev_change")),
|
||||||
Key("n p", "next / previous file (wraps)", "file", ("next_file", "prev_file")),
|
Key("n p", "next / previous file (wraps)", "file", ("next_file", "prev_file")),
|
||||||
Key("o \u23ce", "open the real file at this line", "open", ("open",)),
|
Key("o \u23ce", "open the real file at this line", "open", ("open",)),
|
||||||
Key("j k", "down / up one line (vim)", "", ("line_down", "line_up")),
|
Key("j k", "down / up one line (vim)", "", ("line_down", "line_up")),
|
||||||
|
|||||||
Reference in New Issue
Block a user