Merge pull request #65 from YouTwitFace/add-reverse-sort
Add reverse sort
This commit is contained in:
12
babi/file.py
12
babi/file.py
@@ -641,9 +641,9 @@ class File:
|
|||||||
self.buf[self.buf.y] += self.buf.pop(self.buf.y + 1)
|
self.buf[self.buf.y] += self.buf.pop(self.buf.y + 1)
|
||||||
self.buf.restore_eof_invariant()
|
self.buf.restore_eof_invariant()
|
||||||
|
|
||||||
def _sort(self, margin: Margin, s_y: int, e_y: int) -> None:
|
def _sort(self, margin: Margin, s_y: int, e_y: int, reverse: bool) -> None:
|
||||||
# self.buf intentionally does not support slicing so we use islice
|
# self.buf intentionally does not support slicing so we use islice
|
||||||
lines = sorted(itertools.islice(self.buf, s_y, e_y))
|
lines = sorted(itertools.islice(self.buf, s_y, e_y), reverse=reverse)
|
||||||
for i, line in zip(range(s_y, e_y), lines):
|
for i, line in zip(range(s_y, e_y), lines):
|
||||||
self.buf[i] = line
|
self.buf[i] = line
|
||||||
|
|
||||||
@@ -652,17 +652,17 @@ class File:
|
|||||||
self.buf.scroll_screen_if_needed(margin)
|
self.buf.scroll_screen_if_needed(margin)
|
||||||
|
|
||||||
@edit_action('sort', final=True)
|
@edit_action('sort', final=True)
|
||||||
def sort(self, margin: Margin) -> None:
|
def sort(self, margin: Margin, reverse: bool = False) -> None:
|
||||||
self._sort(margin, 0, len(self.buf) - 1)
|
self._sort(margin, 0, len(self.buf) - 1, reverse=reverse)
|
||||||
|
|
||||||
@edit_action('sort selection', final=True)
|
@edit_action('sort selection', final=True)
|
||||||
@clear_selection
|
@clear_selection
|
||||||
def sort_selection(self, margin: Margin) -> None:
|
def sort_selection(self, margin: Margin, reverse: bool = False) -> None:
|
||||||
(s_y, _), (e_y, _) = self.selection.get()
|
(s_y, _), (e_y, _) = self.selection.get()
|
||||||
e_y = min(e_y + 1, len(self.buf) - 1)
|
e_y = min(e_y + 1, len(self.buf) - 1)
|
||||||
if self.buf[e_y - 1] == '':
|
if self.buf[e_y - 1] == '':
|
||||||
e_y -= 1
|
e_y -= 1
|
||||||
self._sort(margin, s_y, e_y)
|
self._sort(margin, s_y, e_y, reverse=reverse)
|
||||||
|
|
||||||
DISPATCH = {
|
DISPATCH = {
|
||||||
# movement
|
# movement
|
||||||
|
|||||||
@@ -433,6 +433,12 @@ class Screen:
|
|||||||
else:
|
else:
|
||||||
self.file.sort(self.margin)
|
self.file.sort(self.margin)
|
||||||
self.status.update('sorted!')
|
self.status.update('sorted!')
|
||||||
|
elif response == ':sort!':
|
||||||
|
if self.file.selection.start:
|
||||||
|
self.file.sort_selection(self.margin, reverse=True)
|
||||||
|
else:
|
||||||
|
self.file.sort(self.margin, reverse=True)
|
||||||
|
self.status.update('sorted!')
|
||||||
elif response is not PromptResult.CANCELLED:
|
elif response is not PromptResult.CANCELLED:
|
||||||
self.status.update(f'invalid command: {response}')
|
self.status.update(f'invalid command: {response}')
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ def test_sort_entire_file(run, unsorted):
|
|||||||
assert unsorted.read() == 'a\nb\nc\nd\n'
|
assert unsorted.read() == 'a\nb\nc\nd\n'
|
||||||
|
|
||||||
|
|
||||||
|
def test_reverse_sort_entire_file(run, unsorted):
|
||||||
|
with run(str(unsorted)) as h, and_exit(h):
|
||||||
|
trigger_command_mode(h)
|
||||||
|
h.press_and_enter(':sort!')
|
||||||
|
h.await_text('sorted!')
|
||||||
|
h.await_cursor_position(x=0, y=1)
|
||||||
|
h.press('^S')
|
||||||
|
assert unsorted.read() == 'd\nc\nb\na\n'
|
||||||
|
|
||||||
|
|
||||||
def test_sort_selection(run, unsorted):
|
def test_sort_selection(run, unsorted):
|
||||||
with run(str(unsorted)) as h, and_exit(h):
|
with run(str(unsorted)) as h, and_exit(h):
|
||||||
h.press('S-Down')
|
h.press('S-Down')
|
||||||
@@ -32,6 +42,18 @@ def test_sort_selection(run, unsorted):
|
|||||||
assert unsorted.read() == 'b\nd\nc\na\n'
|
assert unsorted.read() == 'b\nd\nc\na\n'
|
||||||
|
|
||||||
|
|
||||||
|
def test_reverse_sort_selection(run, unsorted):
|
||||||
|
with run(str(unsorted)) as h, and_exit(h):
|
||||||
|
h.press('Down')
|
||||||
|
h.press('S-Down')
|
||||||
|
trigger_command_mode(h)
|
||||||
|
h.press_and_enter(':sort!')
|
||||||
|
h.await_text('sorted!')
|
||||||
|
h.await_cursor_position(x=0, y=2)
|
||||||
|
h.press('^S')
|
||||||
|
assert unsorted.read() == 'd\nc\nb\na\n'
|
||||||
|
|
||||||
|
|
||||||
def test_sort_selection_does_not_include_eof(run, unsorted):
|
def test_sort_selection_does_not_include_eof(run, unsorted):
|
||||||
with run(str(unsorted)) as h, and_exit(h):
|
with run(str(unsorted)) as h, and_exit(h):
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
|
|||||||
Reference in New Issue
Block a user